Границите на модела
Накратко: Езиковият модел халюцинира: уверено пише правдоподобни, но неверни неща, защото предсказва вероятен текст, а не проверява истината; затова отговорът се сверява с източника.
Проблем
Тридесет дни, които ги няма
Асистентът на поддръжката отговаря на клиент: „Можете да върнете якето до 30 дни от получаването.“ Отговорът е учтив, гладък и уверен. Политиката на магазина е 14 дни.
На двадесетия ден клиентът праща якето обратно. Складът го връща, а клиентът пише отзив с една звезда и цитира асистента.
Никой не е програмирал „30 дни“. Откъде се взе числото и как да се пазиш от следващото?
Идеята
Моделът пише вероятен текст, не проверени факти
Езиковият модел е научен да продължава текст с вероятна следваща дума. Той не пази таблица с факти и не проверява отговора си. Ако в текста, на който е учен, „до“ често е следвано от число, той ще сложи число. Кое число, решава вероятността, а не политиката на магазина.
Гладък и уверен отговор, който е грешен или измислен, се казва халюцинация (hallucination). Тя не е бъг, който ще се поправи с една кръпка. Тя идва от самия начин, по който моделът пише: за него вярното и грешното изречение са просто по-вероятен и по-малко вероятен текст.
Виж го
Малък модел, който обещава грешно
Моделът от урока за следващия токен, в най-малкия си вид: за всяка дума пази думите, които са я следвали в текста. Повторенията остават, затова думата, която се среща по-често, се тегли по-често.
// за всяка дума: думите, които са я следвали в текстаfunction train(corpus) { const follows = new Map(); for (const sentence of corpus) { const words = (sentence + " .").split(" "); for (let i = 0; i + 1 < words.length; i++) { if (!follows.has(words[i])) follows.set(words[i], []); follows.get(words[i]).push(words[i + 1]); } } return follows;}Текстът са десет изречения от поддръжката на магазина:
const corpus = [ "връщането е до 14 дни от получаването", "доставката до софия е до 2 дни", "доставката до пловдив е до 2 дни", "доставката до варна е до 3 дни", "парите се връщат до 5 работни дни", "гаранцията е 24 месеца", "плащането с карта е сигурно", "куриерът се обажда преди доставката", "поръчка над 50 евро е с безплатна доставка", "отказаната пратка се връща до 7 дни",];Най-вероятната дума всеки път:
// най-честата (при равенство първата в текста)function mostCommon(options) { const count = (w) => options.filter((o) => o === w).length; return options.reduce((best, o) => count(o) > count(best) ? o : best);}
function greedy(follows, start) { const words = start.split(" "); while (words.length < 12) { const last = words[words.length - 1]; const word = mostCommon(follows.get(last)); if (word === ".") break; words.push(word); } return words.join(" ");}И с избор по вероятност, с генератор със семе, за да е изходът еднакъв при всяко пускане:
function sample(follows, start, rng) { const words = start.split(" "); while (words.length < 12) { const options = follows.get(words[words.length - 1]); const word = options[Math.floor(rng.next() * options.length)]; if (word === ".") break; words.push(word); } return words.join(" ");}const follows = train(corpus);console.log("най-вероятната дума всеки път:");console.log(" " + greedy(follows, "връщането"));console.log("шест пускания, думата се тегли по вероятност:");const rng = new Rng(3876);for (let i = 1; i <= 6; i++) { const answer = sample(follows, "връщането", rng); const mark = corpus.includes(answer) ? "има го в текста" : "няма го в текста"; console.log(` ${i}. ${answer} (${mark})`);}най-вероятната дума всеки път: връщането е до 2 днишест пускания, думата се тегли по вероятност: 1. връщането е 24 месеца (няма го в текста) 2. връщането е до 14 дни от получаването (има го в текста) 3. връщането е сигурно (няма го в текста) 4. връщането е до 5 работни дни (няма го в текста) 5. връщането е до 2 дни (няма го в текста) 6. връщането е до варна е 24 месеца (няма го в текста)Най-вероятният отговор е „връщането е до 2 дни“, а в текста пише 14. От шестте изтеглени отговора само един е изречение от текста. Останалите са гладки и грешни: „връщането е 24 месеца“ е взето от гаранцията, а „до 5 работни дни“ от връщането на парите.
Виж го
Откъде дойде числото
// най-честата (при равенство първата в текста)function mostCommon(options) { const count = (w) => options.filter((o) => o === w).length; return options.reduce((best, o) => count(o) > count(best) ? o : best);}
function greedy(follows, start) { const words = start.split(" "); while (words.length < 12) { const last = words[words.length - 1]; const word = mostCommon(follows.get(last)); if (word === ".") break; words.push(word); } return words.join(" ");}// най-честата (при равенство първата в текста)function mostCommon(options) { const count = (w) => options.filter((o) => o === w).length; return options.reduce((best, o) => count(o) > count(best) ? o : best);}
function greedy(follows, start) { const words = start.split(" "); while (words.length < 12) { const last = words[words.length - 1]; const word = mostCommon(follows.get(last)); if (word === ".") break; words.push(word); } return words.join(" ");}// всяко число в отговора трябва да го има в източникаfunction check(answer, source) { const known = numbers(source); const claimed = numbers(answer); if (claimed.length === 0) { return "? няма число за проверка"; } for (const n of claimed) { if (!known.includes(n)) { return `✗ ${n} го няма в източника`; } } return "✓ числата са в източника";}
function numbers(text) { return text .split(" ") .map((w) => w.replace(/[.,]/g, "")) .filter((w) => /^\d+$/.test(w));}Стъпка по стъпка, с думи
- Моделът продължава „връщането“, всеки път с най-честата следваща дума.
- „е до“ е в 4 изречения, едното от тях е за връщането. Дотук е вярно.
- След „до“ най-често идва „2“: от двете изречения за доставката.
- После точка. Гладко изречение, което го няма в текста: „връщането е до 2 дни“.
- Проверката взима числата от отговора и от политиката за връщане.
- 2 го няма в политиката. Там пише 14 дни.
- Всяка двойка думи е от текста на магазина. Цялото изречение е грешно, а звучи толкова уверено, колкото вярното.
Всяка двойка думи в отговора е вярна някъде в текста. Цялото изречение не е вярно никъде. Големите модели гледат много повече от една дума назад и грешат много по-рядко, но принципът е същият: те пишат вероятно, а не проверено.
Пробвай
Предвиди изхода
Моделът е научен на три изречения. Какво ще напише с най-вероятната дума всеки път, ако започне от думата за доставката?
const corpus = [ "доставката до софия е 2 дни", "доставката до варна е 3 дни", "смяната на размер е 3 дни",];console.log(greedy(train(corpus), "доставката"));След „доставката“ двата пъти идва „до“. След „до“ идват „софия“ и „варна“ по веднъж: при равенство печели първата в текста, „софия“. После „е“, а след „е“ „3“ се среща два пъти (Варна и смяната на размер), а „2“ веднъж. Така излиза „доставката до софия е 3 дни“, изречение, което го няма в текста и е грешно: до София е 2 дни.
Идеята
Същият въпрос, друг отговор
Когато думата се тегли по вероятност, всяко пускане може да даде друг отговор. В програмата шестте пускания дадоха пет различни изречения. Това е недетерминизъм: един и същ вход, различен изход. Тестовете, логовете и оплакванията на клиентите стават по-трудни, защото „при мен работи“ вече не значи нищо.
Температура 0 (най-вероятната дума всеки път) прави отговора повторим, но не и верен. Програмата даде „до 2 дни“ при всяко пускане. При истинските доставчици дори температура 0 не обещава напълно еднакъв отговор: сметките на сървъра не вървят винаги в същия ред.
Идеята
Датата на знанията
Моделът знае само текста, на който е учен. Той е събран до определена дата, датата на знанията (knowledge cutoff). Каквото е станало след нея, моделът не го знае: новата политика за връщане, новият продукт, цената от днес.
И не знае нищо, което никога не е било в текста му: статусът на поръчка 1042 е в базата на магазина, не в модела. По подразбиране моделът не казва „не знам“. Той пише вероятен отговор и тук се ражда „пристига утре“, което никой не е проверил.
Затова фактите влизат в заявката: политиката като текст в промпта, статусът на поръчката от програмата. Как моделът сам поисква статуса, е в урока за инструментите.
Идеята
Провери отговора срещу източника
Щом отговорът трябва да стъпва на документ, програмата може да провери поне част от него. Най-грубата проверка: всяко число в отговора трябва да го има в източника.
// всяко число в отговора трябва да го има в източникаfunction check(answer, source) { const known = numbers(source); const claimed = numbers(answer); if (claimed.length === 0) { return "? няма число за проверка"; } for (const n of claimed) { if (!known.includes(n)) { return `✗ ${n} го няма в източника`; } } return "✓ числата са в източника";}
function numbers(text) { return text .split(" ") .map((w) => w.replace(/[.,]/g, "")) .filter((w) => /^\d+$/.test(w));}Шестте отговора от програмата горе срещу политиката за връщане:
const source = "Връщането е до 14 дни от получаването. Парите се връщат до 5 работни дни.";const answers = [ "връщането е 24 месеца", "връщането е до 14 дни от получаването", "връщането е сигурно", "връщането е до 5 работни дни", "връщането е до 2 дни", "връщането е до варна е 24 месеца",];for (const a of answers) { console.log(`${a} → ${check(a, source)}`);}връщането е 24 месеца → ✗ 24 го няма в източникавръщането е до 14 дни от получаването → ✓ числата са в източникавръщането е сигурно → ? няма число за проверкавръщането е до 5 работни дни → ✓ числата са в източникавръщането е до 2 дни → ✗ 2 го няма в източникавръщането е до варна е 24 месеца → ✗ 24 го няма в източникаПроверката хвана три грешни отговора. Но пусна „връщането е до 5 работни дни“: 5 го има в политиката, само че за връщането на парите. И не може да каже нищо за „връщането е сигурно“, защото там няма число. Груба проверка намалява риска, без да го маха. Затова в истински системи проверките са няколко, а където грешката е скъпа, гледа човек.
Пробвай
Намери грешката
Колега опростява проверката. Сега отговорът „връщането е до 4 дни“ минава като верен, макар че в политиката пише 14. На кой ред е грешката?
Избери реда с грешката.
Числото се търси като част от текста на източника. „4“ е част от „14“, затова проверката го намира. Числата трябва да се сравняват цели: първо се вадят числата на източника и после се търси същото число сред тях.
Пробвай
Попълни
Моделът спира изречението, когато най-вероятната следваща дума е краят. Как изглежда краят в текста за обучение?
function greedy(follows, start) {
const words = start.split(" ");
while (words.length < 12) {
const last = words[words.length - 1];
const word = mostCommon(follows.get(last));
if (word === ) break;
words.push(word);
}
return words.join(" ");
}При обучението всяко изречение получава " ." накрая, затова точката е отделна дума. Когато моделът избере нея, изречението свършва. Без тази проверка моделът пише до границата от 12 думи.
Идеята
Кога езиковият модел е грешният инструмент
- Има точен отговор, който се смята. Сумата на поръчката, ДДС, остатъкът по сметка. Един ред код не греши, моделът може да сбърка цифра.
- Данните са живи. Статус на поръчка, наличност, днешна цена. Те са в базата. Моделът може да ги поиска чрез инструмент, но не бива да ги „помни“.
- Правилото е твърдо. „Връщане до 14 дни“ е
if, не промпт. Каквото трябва да е винаги еднакво, се пише в кода. - Решението трябва да се обясни и провери после. Отказано плащане или кредит иска причина, която се повтаря. За такива решения има модели като логистичната регресия, а правилата се пишат явно.
- Грешката струва повече от мълчанието. Медицински, правни, финансови отговори към клиент. Тогава моделът пише чернова, а човек решава.
Къде моделът е силен: чернови, резюмета, превод, подреждане на свободен текст (за кой отдел е писмото), извличане на данни от текст, отговори по документ, които се проверяват. Задачи, в които малката неточност се хваща лесно и не струва скъпо.
По-точно, за любопитните
Защо и големите модели халюцинират. Те са научени на огромен текст, а после още малко да следват инструкции и да казват „не знам“. Това намалява грешките, но не ги маха: моделът пак избира вероятен текст. Особено опасни са редките факти (номер на член от закон, цитат, име на функция в малка библиотека), където в текста за обучение има малко примери.
Какво помага, на слоеве. Фактите в заявката (политиката като текст, модулът за търсене по смисъл и RAG по-нататък в курса прави точно това). Изход по схема и проверка в кода (структуриран изход). Тестов набор с въпроси и правилни отговори, който се пуска при всяка смяна (оценяване). Отговор „не знам, предавам на колега“, когато проверката не мине. И човек там, където грешката е скъпа.
Колко е малък моделът тук. Биграмният модел помни една дума назад и е научен на десет изречения. Голям модел гледа хиляди токени назад и е научен на трилиони. Затова той рядко лепи „връщането е до 2 дни“ от две изречения. Но когато в контекста няма отговор, той пак пише най-вероятното продължение, а не „не знам“.
Измерването на халюцинации. Процентът грешни отговори зависи от задачата и от данните. Числата от чужди тестове не казват нищо за твоя асистент. Мериш ги ти, на твоите въпроси, както в урока за оценяването.
Упражнение
Отговорите за доставката
Реши задачата в редактора си.
Асистентът отговаря за доставката, а източникът е: „Доставката до София е до 2 работни дни. До Варна е до 3 работни дни. Над 50 евро доставката е безплатна.“ Провери пет отговора със същото правило (всяко число в отговора трябва да го има в източника) и отпечатай присъдата за всеки:
- Доставката до София е до 2 дни.
- Доставката до Варна е до 4 дни.
- Доставката е безплатна над 30 евро.
- Доставката до Пловдив е до 1 ден.
- Доставката е безплатна за всички поръчки.
Доставката до София е до 2 дни. → ✓ числата са в източникаДоставката до Варна е до 4 дни. → ✗ 4 го няма в източникаДоставката е безплатна над 30 евро. → ✗ 30 го няма в източникаДоставката до Пловдив е до 1 ден. → ✗ 1 го няма в източникаДоставката е безплатна за всички поръчки. → ? няма число за проверкаПоследният отговор е грешен, а проверката не може да го хване: в него няма число.
Още задачи
- Число на място. Проверявай не само дали числото го има, а и думата преди него: „до 2“ за София. Кои отговори хваща сега?
- Отказ. Когато проверката не мине, програмата да връща „Ще ви свържа с колега.“ вместо отговора на модела.
Тест
Провери се
Свързани уроци
Раздел „Свързани уроци“- Нужно отпреди: Методите на масива · Текстът на парчета: токени · Предсказване на следващия токен · Прозорецът на контекста
- Продължава в: Извикване на модел през API · Промптът е код · Структуриран изход: JSON по схема · Инструменти: моделът пита, програмата прави
- Задачи по темата: Как работи езиков модел