dimhold.by
← Артыкулы

Я задаў сваім нататкам 15 пытанняў без адказу і атрымаў 13 адказаў

Гэты блог бліжэй за ўсё да таго, што ў мяне можна назваць нататкамі: 16 пастоў з 2011 па 2014 год. Калі мне трэба адтуль лік, напрыклад колькі часу ўстаўляліся 10 мільёнаў выпадковых uuid, я адкрываю пост і шукаю па старонцы. Гэта працуе, калі я памятаю, у якім ён пасце.

Retrieval augmented generation, ідэя Льюіса і суаўтараў 2020 года, павінна вырашаць якраз гэтую задачу. Знаходзіш абзацы, якія выглядаюць падыходнымі, аддаеш іх мадэлі разам з пытаннем і яна піша адказ. Я хацеў паглядзець, што яна робіць на маіх уласных тэкстах.

Перад першым прагонам я запісаў, чаго чакаю. Пошук страціць больш адказаў, чым мадэль, якая чытае. На пытаннях, адказу на якія ў нататках няма, абедзве мадэлі ўсё роўна адкажуць, амаль кожны раз. Большасць пытанняў без адказу я ўзяў з раздзела ў канцы амаль кожнага паста, “What I did not check”. Я пісаў гэтыя раздзелы як спісы таго, чаго не ведаю. І лічыў, што машына прачытае іх гэтаксама.

Як уладкавана

Нататкі гэта англійскія версіі 16 пастоў, разрэзаныя на 383 абзацы. Яшчэ да першага прагону я напісаў 75 пытанняў. У 60 адказ у пастах ёсць. Для кожнага з іх я пазначыў той абзац, дзе ён ляжыць. У 15 адказу няма. 12 пытаюцца пра тое, што ў пастах пералічана як неправеранае, напрыклад як тэст з uuid прайшоў бы на InnoDB. 1 пытаецца пра дэталь, якую я нідзе не запісаў, версію PostgreSQL. 2 пра тэмы, пра якія я не пісаў наогул.

Пытанні я пісаў адразу пасля таго, як перачытаў пасты, таму ў іх мае ж словы. Каб убачыць, наколькі гэта дапамагае, я падзяліў вынікі па медыяне долі слоў пытання, якія ёсць у патрэбным абзацы. Медыяна 0,5.

Для пошуку я ўзяў BM25 з rank_bm25 0.2.2, ён лічыць агульныя словы. Побач 2 мадэлі sentence-transformers мінулага жніўня, all-MiniLM-L6-v2 і multi-qa-MiniLM-L6-cos-v1, яны параўноўваюць сэнс як вектары. Чацвёрты варыянт злівае спіс BM25 са спісам другой вектарнай мадэлі праз reciprocal rank fusion. Паўторная праверка DPR летась паказала, што сумесь ацэнак BM25 і шчыльнага пошуку лепшая за адзін шчыльны. Я змешваю месцы ў спісе замест ацэнак.

Для адказу я ўзяў UnifiedQA-v2 на T5-large, якую AllenAI выпусціў у лютым і навучыў адказваць па пададзеным ёй тэксце. Другой мадэллю мела стаць OPT-1.3B, якую Meta выклала ў гэтым месяцы як адкрытую альтэрнатыву GPT-3. Усё лічыцца на працэсары прагным дэкадаваннем, на transformers 4.19.2, sentence-transformers 2.2.0 і torch 1.11. У машыны 4 ядры і 8 ГБ памяці, з іх вольных каля 4,5 ГБ, астатняе трымаюць іншыя сэрвісы.

Гэтая памяць і стала першай праблемай. torch 1.11 не змог загрузіць T5-large праз from_pretrained у вольную памяць, ядро сістэмы забіла працэс. Я разрэзаў вагі на кавалкі і загрузіў іх па адным. OPT-1.3B у float32 гэта 5,3 ГБ вагаў, больш за вольнае. У bfloat16 яна змяшчаецца, але адзін адказ у 40 токенаў на пытанне зусім без нататак заняў 9 хвілін. Так другой мадэллю стала OPT-350m з таго ж рэлізу, у float32.

Пошук знаходзіць пост, але не той абзац

З гібрыдам патрэбны абзац трапляе ў тройку для 40 пытанняў з 60. Адзін BM25 дае 38, 2 вектарныя мадэлі 38 і 39. Гэта менш, чым я чакаў, але промахі блізкія. З гібрыдам патрэбны пост у тройцы для ўсіх 60. У 13 промахах з 20 у тройцы ляжыць абзац за 1 ці 2 абзацы ад патрэбнага.

патрэбны абзац у тройцы, паводле долі агульных слоў пытання і абзаца агульных слоў палова і больш (32) BM25 28/32 all-MiniLM 25/32 multi-qa 24/32 гібрыд 26/32 агульных слоў менш за палову (28) 10/28 13/28 15/28 14/28
60 пытанняў з адказам, падзеленыя па медыяне долі агульных слоў з патрэбным абзацам.

Калі ў пытання з абзацам агульная хаця б палова слоў, BM25 знаходзіць 28 з 32, вектарныя мадэлі 24 ці 25. Ніжэй за гэтую мяжу BM25 падае да 10 з 28, а другая вектарная мадэль дае 15. Вектары дапамагаюць там, дзе я шукаў бы не тым словам, але ў сярэднім яны не лепшыя.

Я паспрабаваў адно відавочнае паляпшэнне. Я дапісаў загаловак паста да кожнага абзаца перад індэксаваннем. Гібрыд зрушыўся з 40 на 39, гэта шум. Загаловак разам з папярэднім абзацам апусціў яго да 35. Думаю, абзацы аднаго паста становяцца падобнымі адзін да аднаго.

Мадэль чытае нармальна, калі ёй даць патрэбны абзац

UnifiedQA з патрэбным абзацам адказвае правільна на 52 пытанні з 60. З тройкай з гібрыда на 34, зусім без кантэксту на 2.

Пасля пошуку яна памыляецца на 26 пытаннях. У 18 з іх патрэбнага абзаца ў тройцы не было. З 20 пытанняў, дзе пошук прамахнуўся, мадэль усё роўна адказала правільна на 2. У абодвух выпадках той жа факт ёсць у пасце яшчэ ў адным месцы, прычым у адным з іх толькі ў загалоўку. Значыць, большая частка правалаў гэта правалы пошуку, як я і чакаў.

60 пытанняў з адказам, UnifiedQA дадзены патрэбны абзац 52 8 тройка з пошуку 32 8 2 18 абзац у тройцы: 40 абзаца ў тройцы няма: 20 без кантэксту 2 58 правільна няправільна
З 26 няправільных адказаў пасля пошуку 18 прыпадаюць на пытанні, дзе пошук не вярнуў патрэбны абзац.

6 з 8 правалаў там, дзе пошук патрэбны абзац вярнуў, гэта няправільны лік з таго самага тэксту, які ёй далі. Я спытаў, колькі запытаў з пачкі ў 300 прапусціць вядро ёмістасцю 10. Яна адказала 90, а гэта колькасць запытаў, якія вядро адхіліла. Я спытаў, праз колькі раўндаў медыяна стала вагацца менш чым на 3 працэнты. Яна адказала 30, апошні радок спісу, а патрэбны быў першы, дзе медыяна ўжо ўкладвалася ў 3 працэнты.

OPT-350m тут не чытач наогул. З патрэбным абзацам яна дае 20 з 60 паводле аўтаматычнай праверкі. Прынамсі палова з іх гэта доўгі кавалак абзаца, перапісаны слова ў слова, з патрэбным лікам недзе ўнутры. З тройкай з пошуку 7. У промпце было сказана адказваць “not in my notes”, калі ў нататках адказу няма. Яна не зрабіла гэтага ніводнага разу. Аднойчы яна выпадкова аказалася блізка: на пытанне пра InnoDB перапісала мой радок “I have not run this on InnoDB”. Далей гаворка толькі пра UnifiedQA.

13 адказаў на 15 пытанняў без адказу

З 15 пытанняў, адказу на якія ў нататках няма, UnifiedQA адмовілася адказваць на 2. Астатнія 13 атрымалі кароткі ўпэўнены адказ.

У 12 выпадках з 15 у тройцы быў абзац пра тое, чаго я не правяраў. 11 з іх з раздзела “What I did not check”. 5 адказаў спісаныя наўпрост з такіх абзацаў. На “How did BigDecimal handle currencies with 3 decimals?” прыйшло “splitting one amount across several invoice lines”. Узята гэта з радка “Still open: currencies with 3 decimals. Splitting one amount across several invoice lines…”. Гэта спіс адкрытых пытанняў. Мадэль адказала наступным пунктам.

На “What does the load average show inside a container?” прыйшло “the load average belongs to the host, while the limits belong to the cgroup”. Гэта амаль даслоўна мая фраза з абзаца, які пачынаецца з “Whether” і канчаецца словамі “I expect that to be its own kind of misleading”. Гэты абзац у пасце стаіць унутры спісу таго, што я не правяраў.

Яшчэ 5 адказаў гэта лік з іншага абзаца тройкі, які наогул пра іншае. На “How much slower were random uuid inserts on InnoDB?” прыйшло 172414,407 ms. Гэта лік PostgreSQL з таго ж паста, з коскай, якую надрукаваў psql. Апошніх 3 адказаў у гэтых 3 абзацах няма зусім. На пытанне, колькі жыве недасяжны каміт git да prune, мадэль адказала “15 minutes”. Адкуль гэта, я не ведаю, у маіх пастах такога няма.

15 пытанняў, адказу на якія ў нататках няма, UnifiedQA на тройцы 2 адмовы 5 узятыя з абзаца "What I did not check" 5 лікі з іншага абзаца тройкі 3 у 3 абзацах гэтага няма наогул
Кропка значыць, што ў тройцы быў абзац пра тое, чаго я не правяраў. У 11 выпадках з 12 ён з раздзела "What I did not check".

Найбольшы косінус другой вектарнай мадэлі ў пытанняў без адказу ніжэйшы, медыяна 0,56 супраць 0,66, але 2 групы перакрываюцца. Найлепшы адзіны парог пакідае 59 з 60 добрых пытанняў і адсякае толькі 5 з 15 дрэнных. Па ацэнках BM25 той жа прыём адсякае не больш за 1.

Чаго я не правяраў

Большыя мадэлі, у тым ліку GPT-3. На 18 пытаннях, дзе пошук не вярнуў абзац, мацнейшая мадэль можа толькі адгадваць.

Пытанні, напісаныя кімсьці іншым або мной праз год. Падзел па агульных словах паказвае кірунак, але гэтую праверку не замяняе.

Пераранжыраванне, іншы памер абзацаў, іншыя промпты. І гэта адзін прагон на 75 пытаннях, так што розніца ў 1 ці 2 пытанні паміж метадамі нічога не значыць.

Першае, што я змяню, гэта самі пасты. Раздзелам з адкрытымі пытаннямі патрэбная метка, па якой пошук зможа іх прапусціць. Або метка, якая скажа мадэлі, што яна чытае спіс таго, чаго я не ведаю. Ні тое, ні другое я яшчэ не спрабаваў.