Autor Mahir Uysal

Kuidas luua tipptasemel vestlusalust AI koos siirdeõppega

Mõni aasta tagasi võis vestlusoboti loomine - kui see oli piiratud, kuna see oli toona piiratud - aega võtta mitu kuud the, alates reeglite väljatöötamisest kuni tuhandete vastuste kirjutamiseni, et kajastada mõnda vestluse teemat.

Hiljutise NLP süvaõppe edusammude abil saame nüüd sellest väiklasest tööst lahti saada ja ehitada vaid mõne tunni jooksul much palju võimsama vestlusliku AI, nagu näete selles õpetuses.

Oleme koostanud demo, mis käivitab eelõpetatud mudeli, mille ehitame selles õpetuses kokku saidil convai.huggingface.co. Tutvuge kindlasti!
Eelkoolitatud mudeli veebidemo, mille loome selles õpetuses aadressil convai.huggingface.co.

Siin on see, mida me täna õpime ja mängime:

  • Kuidas saate programmi Transfer Transfer abil moodustada tipptehnoloogia dialoogi agenti, mis põhineb OpenAI GPT ja GPT-2 Transformeri keelemudelitel,
  • Kuidas saate reprodutseerida mudelit, mida kasutasime NeurIPS 2018 dialoogikonkursil ConvAI2, mis võitis automaatse mõõdikute raja,
  • Kuidas destilleerisime 3k + võistluskoodi rida vähem kui 250 kommentaaritud treeningkoodiridaga (koos jaotatud ja FP16 võimalustega!) Ja
  • Kuidas saate seda mudelit vähem kui 20 dollari eest pilveeksamil treenida või lihtsalt kasutada meie avatud lähtekoodiga eelkoolitatud mudelit.
Koos selle postitusega andsime välja puhta ja kommenteeritud koodialuse koos eelkoolitatud mudeliga! Vaata Githubi repo siit

Selle postituse lugu algas mõni kuu tagasi Montrealis , kus Hugging Face lõpetas NeurIPS 2018 dialoogivõistluse Conversational Intelligence Challenge 2 (ConvAI2) automaatse raja 1. koha.

Meie salajane kaste oli suuremahuline eelkoolitatud keelemudel, OpenAI GPT, koos peenhäälestamise tehnikaga Transfer Learning.

Võistluste kiire tempoga jõudsime enam kui 3k rea koodideni, kus uuriti paljusid koolitus- ja arhitektuurivariante.

On selge, et sellise toore koodi avaldamine poleks olnud õiglane.

Vahepeal olime hakanud ehitama ja avatud lähtekoodiga siirdeõppe mudelite hoidlat nimega pytorch-pretrained-BERT, mida laaditi alla enam kui 150 000 korda ja mis pakkus suuremahuliste keelemudelite, näiteks OpenAI GPT ja selle järeltulija rakendusi GPT-2

Mõni nädal tagasi otsustasin meie võistluskoodi ümber arvestada puhtas ja kommenteeritavas koodipõhjas, mis on üles ehitatud ettevalmistatud pytorch-BERT-i peale, ja kirjutada üksikasjalik ajaveebi postitus, mis selgitab meie lähenemisviisi ja koodi.

Nii et siin me oleme, sukeldugem sisse

Isiksusega AI

Ehitame vestluskaaslase AI-ga.

Meie dialoogiagendil on teadmistebaas, kuhu saab salvestada paar lauset, milles kirjeldatakse, kes see on (persona), ja dialoogi ajalugu. Kui kasutaja saab uue ütluse, ühendab agent vastuse genereerimiseks selle teadmistebaasi sisu värskelt saadud lausungiga.

Siin on üldine skeem:

Süvaõppel põhinevate dialoogiagentide koolitamisel otsast lõpuni seisame silmitsi suure probleemiga:

Dialoogiandmekogumid on väikesed ja nende sujuva ja asjakohase vastuse genereerimiseks on raske neilt piisavalt keelt ja mõistust õppida.

Mõni lähenemisviis püüab seda lahendada, filtreerides mudeli väljundi, et kvaliteeti nutika kiirotsingu abil parandada. Valime siin järgmise tee, mis on viimaste kuude jooksul kogunud tohutut huvi: õppimise ülekandmine.

Selle lähenemisviisi idee on üsna lihtne:

  • alustage keelemudeli ettevalmistamist väga suurele tekstikorpusele, et oleks võimalik genereerida külgneva sidusa teksti pikad lõigud,
  • täpsustage seda keelemudelit, et kohandada see meie lõppülesande: dialoogiga.

Keelemudeli ettevalmistamine on kallis toiming, nii et tavaliselt on parem alustada juba ettevalmistatud ja avatud lähtekoodiga mudelist.

Milline oleks meie jaoks hea eelkoolitatud mudel?

Mida suurem, seda parem, kuid vajame ka mudelit, mis suudaks teksti genereerida. Kõige sagedamini kasutatav eelkoolitatud NLP-mudel BERT on eelõpe ainult täislausetes ega suuda lõpetamata lauseid täita. Meie kasutuses on huvitavamad veel kaks OpenAI avatud allikaga mudelit: GPT ja GPT-2.

Vaatame neid kiirelt

Models OpenAI GPT ja GPT-2 mudelid

2018. ja 2019. aastal treenisid Alec Radford, Jeffrey Wu ja nende kaastöötajad OpenAI avatud lähtekoodiga kahes keelemudelis väga suure andmemahu osas: GPT ja GPT-2 (kus GPT tähistab generatiivset ettevalmistustrafot).

Dekooder / põhjuslik trafo viib järgmiste sõnade genereerimiseks vasakpoolsesse konteksti

GPT ja GPT-2 on kaks väga sarnast trafodel põhinevat keelemudelit. Neid mudeleid nimetatakse dekoodri- või põhjuslikeks mudeliteks, mis tähendab, et nad kasutavad järgmise sõna ennustamiseks vasakpoolset konteksti (vt vasakpoolset joonist).

Paljud ajalehed ja ajaveebipostitused kirjeldavad trafode mudeleid ja seda, kuidas nad kasutavad järjestikuste sisendite töötlemiseks tähelepanu mehhanisme, nii et ma ei kulutaks aega nende üksikasjalikule tutvustamisele. Mõned näpunäited, kui te pole nende mudelitega tuttavad: Emma Strubelli EMNLP-slaidid on minu isiklik lemmik ja Jay Alammari “Illustreeritud trafo” on väga üksikasjalik sissejuhatus.

Meie jaoks on keelemudel lihtsalt mudel, mis võtab sisendina kasutusele žetoonide jada ja genereerib tõenäosusjaotuse sõnavaras järgmise sisestusjärjekorra järgmiseks märgiks. Keelemudeleid koolitatakse tavaliselt paralleelselt, nagu on näidatud ülaltoodud joonisel, ennustades igale märgile järgnevat märki pikas sisestusjärjestuses.

Nende mudelite ettevalmistamine suurel korpusel on kulukas toiming, nii et alustame OpenAI poolt eelnevalt ettevalmistatud mudelitest ja žetoonidest. Tokenizer hoolitseb sisestusstringi tükeldamise eest tokkides (sõnad / alamsõnad) ja teisendab need tunnused mudelisõnavara õigete numbriliste indeksite järgi.

Pytorch-eelkoolitatud BERT-is saab OpenAI GPT mudelit ja selle žetooni hõlpsasti eelkoolitatud kontrollpunktist luua ja laadida järgmiselt:

Tõenäoliselt märkasite, et oleme laadinud mudeli nimega OpenAI GPT topeltpea mudel, mis kõlab natuke keerukamalt kui see keelemudel, millest me just rääkisime ja teil on õigus!

Seda seetõttu, et peame oma mudeli kohandama dialoogiks. Vaatame, kuidas see läheb!

Keelemudeli kohandamine dialoogiülesandega

Meie keelemudel on koolitatud ühe sisestusega: sõnajada.

Kuid nagu me varem nägime, peab meie mudel kasutama väljundjärjestuse genereerimiseks dialoogiseadetes mitut tüüpi kontekste:

  • üks või mitu personaalset lauset,
  • dialoogi ajalugu vähemalt kasutaja viimase lausungiga,
  • väljundjärjestuse sümboleid, mis on juba loodud, kuna genereerime väljundjada sõnahaaval.
Kuidas saaksime nendest erinevatest kontekstidest oma mudeli sisendi luua?

Lihtne vastus on lihtsalt kontekstisegmentide ühendamine ühes järjestuses, pannes vastuse lõppu. Seejärel saame genereerida vastuse tokeni lõpu lõpuleviimisega, jätkates jada:

Sisestusjärjestus: persooni liitmine (sinine), ajalugu (roosa) ja vastus (roheline) eraldajatega (heleroosa). Genereerime vastuse vormistamiseks sõna „teie”.

Selle lihtsa seadistamisega on kaks probleemi:

  • Meie trafo on värvipime! Piiritlevad märgid annavad vaid nõrga ettekujutuse sellest, millisesse osasse iga sõna kuulub. Näiteks on sõna "NYC" tähistatud meie illustratsioonil siniselt (persona), kuid meie mudelis on keeruline seda teavet ainult piiritlejatest välja tõmmata: peaksime segmentide kohta rohkem teavet lisama.
  • Meie trafo on positsiooniväline! Tähelepanu on sümmeetriline punkttoode, seega peaksime lisama iga märgise asukohateabe.

Lihtne viis selle teabe lisamiseks on luua kolm paralleelset sisestusjada sõna, positsiooni ja segmentide jaoks ning sulandada need ühte jada, liites kokku kolm manustamise tüüpi: sõna, positsiooni ja segmendi manused:

Kolme sisendite manustamise tüübi liitmine, mis tähistab sõnu (hall), positsiooni (gradient) ja segmente (sinine / roosa / roheline)

Kuidas me seda rakendame?

Esiteks lisame oma sõnavarasse piiritlejate ja segmentide indikaatorite jaoks spetsiaalsed märgid. Need märgid ei kuulunud meie mudeli ettevalmistamisse, seetõttu peame nende jaoks looma ja koolitama uusi manuseid.

Spetsiaalsete märkide ja uute manuste lisamine sõnavarale / mudelile on pytorch-eelkoolitatud-BERT-klassidega üsna lihtne. Lisage meie tokenisti sõnavarale ja mudeli manustustele viis spetsiaalset žetooni:

Need spetsiaalsete märkide meetodid lisavad vastavalt meie viis spetsiaalset žetooni tokenisti sõnavarale ja loovad mudelisse viis täiendavat manustust.

Nüüd on meil kõik, mida vajame, et oma sisestusjada üles ehitada lähtudes isikust, ajaloost ja vastuste taustast. Siin on lihtne näide:

Losses Kaotus mitme ülesande täitmisel

Oleme nüüd oma ettevalmistatud mudeli initsialiseerinud ja välja töötanud meie treeningsisendid, jääb üle vaid valida kahjum, mida optimeerimise ajal optimeerida.

Kasutame mitme ülesande kaotust, ühendades keele modelleerimise järgmise lause ennustamise eesmärgiga.
Järgmise lause ennustamise eesmärk on osa BERTi eelkoolitusest. See koosneb distraktsioonide juhuslikust valimisest andmekogumist ja mudeli koolitamisest, et eristada, kas sisestusjada lõppeb kuldse vastusega või segaja abil. See õpetab mudelit vaatama lisaks kohalikule kontekstile ka globaalseid segmente.

Nüüd näete, miks laadisime topeltpea mudeli. Üks pea arvutab keele modelleerimise ennustusi, teine ​​pea aga järgmise lause klassifikatsiooni silte. Vaatame, kuidas kahjusid arvutatakse:

Mitme ülesande väljaõppe eesmärk - mudel on varustatud kahe peaga keele modelleerimise ennustamiseks (oranž) ja järgmise lause klassifitseerimiseks (sinine)

Kogukahjum on keele modelleerimise kaotuse ja järgmise lause ennustuskao kaalutud summa, mis arvutatakse järgmiselt:

  • Keele modelleerimine: projitseerime varjatud oleku sõna manustamismaatriksisse, et saada logisid ja rakendada rist-entroopia kadu sellele osale, mis vastab kullavastusele (rohelised sildid ülaltoodud joonisel).
  • Järgmise lause ennustus: tulemuse saamiseks läbime viimase märgi (jada lõpu tunnuse) varjatud oleku läbi lineaarse kihi ja rakendame rist-entroopiakaotust, et kuldvastus õigesti klassifitseerida distrakteerijate hulgas.

Vaatame, kuidas seda kodeerida:

Nüüd on meil olemas kõik meie mudelis nõutavad sisendid ja saame kahe mudeli ja kogukaalu (kaalutud summana) saamiseks mudeli edastamise edasi:

Oleme valmis koolitusi alustama

Dialoogi andmestiku koolitus

ConvAI2 võistlusel kasutati huvitavat andmekogu, mille Facebook avaldas eelmisel aastal: PERSONA-CHAT.

See on üsna mahukas dialoogiandmekogum (10-osalised dialoogid), mis loodi isiksuse lausete hulgimüügist ja paludes paarilistel rahvahulga töötajatel antud tegelase osa mängimise ajal vestelda (näide vasakpoolsel joonisel).

See andmestik on saadaval toekas tokeniseeritud tekstivormingus kena Facebooki ParlAI raamatukogus. Teie üleslaadimiseks laadisime üles ka JSON-vormingus versiooni, mille saate alla laadida ja lubada GPT-i tokeniseri abil järgmiselt:

PERSONA-CHAT JSON-versioon annab kiire juurdepääsu kõigile olulistele sisenditele, et koolitada meie mudelit loendite pesasõnastikuna:

PERSONA-CHAT JSON-i versiooni korraldus

Kasutades vinge PyTorchi süüteraamistikku ja NVIDIA tipu pakutavat uut automaatse segatud täpsuse API-t (FP16 / 32), suutsime destilleerida oma + 3k võistluskoodide read vähem kui 250 treeningkoodirida koos hajutatud ja FP16 võimalustega!

Oleme koodi olulised osad kaetanud ülaltoodud sisus, nii et ma lihtsalt luban teil kommenteeritud koodi lugeda, et näha, kuidas see kõik sobib.

Treeningu (rong.py) kood on siin ➱

Selle mudeli väljaõpetamine 8 V100 GPU-ga AWS-i eksemplaril võtab vähem kui tund (praegu on väikseim p3.16xlarge AWS-i eksemplar vähem kui 25 USD) ja annab tulemused, mis on lähedased SOTA-le, mis saadi ConvAI2 võistluse ajal, kui Hits @ 1 on üle 79, segadus 20,5 ja F1 16,5.

Mõned erinevused selgitavad meie konkurentsimudeli pisut madalamaid hindeid, need on üksikasjalikult esitatud siinse koodirepordi loetelus ja koosnevad enamasti positsioonide manustamise kohandamisest ja erineva dekoodri kasutamisest.

Modelliga vestlemine - dekooder

Dialoogimudelite hämmastav on see, et saate nendega rääkida

Meie mudeliga suhtlemiseks peame lisama ühe asja: dekooderi, mis loob täielikud järjestused meie mudeli järgmistest märgistest.

Nüüd on dekoodrite areng viimastel kuudel olnud väga huvitav ja tahtsin neid siin kiiresti tutvustada, et saaksite end kurssi viia.

Kaks levinumat keele genereerimise dekoodrit olid varem ahne dekodeerimine ja kiirotsing.

Lause genereerimine sõna kaupa (allikas)

Ahne dekodeerimine on lause genereerimise lihtsaim viis: igal ajahetkel valime vastavalt mudelile kõige tõenäolisema järgmise žetooni, kuni jõuame jada lõpus olevate märgiteni. Üks ahne dekodeerimisega seotud oht on see, et suure tõenäosusega märk võib pärast väikese tõenäosusega sümbolit peitu minna ja jääda vahele.

Kiirotsinguga püütakse seda probleemi leevendada, hoides mitmest võimalikust järjestusest koosnevat palki, mida me konstrueerime sõnahaaval. Protsessi lõpus valime talade hulgast parima lause. Viimastel aastatel on kiirotsing olnud peaaegu kõigi keele genereerimise ülesannete, sealhulgas dialoogi jaoks standardne dekodeerimise algoritm (vt hiljutist [1]).

Kuid 2018. aastal / 2019. aasta alguses juhtus mitu arengut. Esiteks oli üha enam tõendeid selle kohta, et kiirotsing oli väljundite pikkuse suhtes ülitundlik ja parimaid tulemusi võis saada siis, kui väljundi pikkust ennustati enne dekodeerimist ([2, 3] EMNLP 2018-l). Kuigi see on mõistlik madala entroopiaga ülesannete puhul, näiteks tõlkimine, mille väljundjärjestuse pikkust saab sisendist ligikaudselt ennustada, tundub see suvalise entroopiaga toimingute puhul, nagu dialoog ja lugude genereerimine, kus erineva pikkusega väljundid on tavaliselt võrdselt kehtivad.

Paralleelselt avaldati vähemalt kaks mõjukat ettekannet ([4, 5]) kõrge entroopia tekitamise ülesannete kohta, milles ahne / kiire otsimise dekodeerimine asendati proovivõtuga järgmisest sümbolijaotusest igal ajahetkel. Nendes paberites kasutati proovivõtmise varianti, mida nimetatakse top-k valimiks, milles dekooder valib ainult kõige k-kõige tõenäolisematest žetoonidest (k on hüperparameeter).

Viimane kivi selles hiljutises suundumuses on Ari Holtzmani jt hiljuti avaldatud uuring. [6], mis näitas, et sõnade jaotus tekstides, mis on loodud kiirotsingu ja ahne dekodeerimise abil, on väga erinev sõnade jaotusest inimese loodud tekstides. On selge, et kiirotsing ja ahne dekodeerimine ei reprodutseeri inimtekstide mõningaid leviku aspekte, nagu on märgitud ka dialoogisüsteemide kontekstis: [7, 8]:

Vasakpoolne: tõenäosus, mis on omistatud inimeste loodud ja GPT-2 abil kiirte otsimisel genereeritud tokenidele (pange tähele inimese teksti tugevat varieeruvust, mida taasesituse kaudu ei taasesitata). Parempoolne: N-grammine jaotus inimeste ja masina loodud tekstides (arvestage ahne / kiiride otsimise ja valimite dekodeerimise meetodite täielikku eraldamist).

Praegu on kaks kõige paljulubavamat kandidaati, mis õnnestub kiirte otsingu / ahne dekodeerimise õnnestumiseks, tipp-k ja tuuma (või ülemise p) proovivõtt. Nende kahe meetodi üldpõhimõte on pärast järgmise jaotuse filtreerimist proovide võtmine järgmise märgi jaotusest, et hoida ainult ülemised k märgid (ülemine k) või ülemised žetoonid kumulatiivse tõenäosusega veidi üle läve (tuum / ülemine p).

Nii saab dekodeerida, kasutades top-k ja / või tuuma / top-p valimit:

Oleme nüüd valmis oma mudeliga rääkima

Interaktiivne skript on siin (interact.py) ja kui te ei soovi skripti käitada, saate mängida ka meie siin asuva demoga

Siin on näide dialoogist:

Näide interaktiivsete skriptide kasutamisest vaikesätetega - Boti isiksus: loen aastas kakskümmend raamatut. Olen oma teise tööna kahekordne stunt. Ma söön ainult koššerit. Mind kasvatati üksikvanema leibkonnas.

Järeldus

Oleme jõudnud selle postituse lõppu, kus kirjeldatakse, kuidas saate luua lihtsa nüüdisaegse vestlusliku AI, kasutades siirdeõpet ja suuremahulist keelemudelit, näiteks OpenAI GPT.

Nagu me Hugging Face'is õppisime, on parim vestluse AI kiireks käivitamiseks parim edu retsept, nii et loodame, et see aitab mõnel teist seda teha!

Vaadake kindlasti seotud demo ja kood:

  • live demo on siin ja
  • siin on avatud lähtekoodiga ja eelkoolitatud mudelid.

Nagu alati, kui teile see postitus meeldis, andke meile paar , et annaksite meile teada ja jagaksite teie ümber olevaid uudiseid!

Viited:

[1] ^ Otsimisstrateegia tähtsus neuraaldialoogi modelleerimisel: Ilja Kulikov, Alexander H. Miller, Kyunghyun Cho, Jason Weston (http://arxiv.org/abs/1811.00907)

[2] ^ Neurutöötluse pikkuse kõrvalekalde parandamine, autorid Kenton Murray, David Chiang (http://arxiv.org/abs/1808.10006)

[3] ^ Beam otsingukursi murdmine: närvimasinatõlke (ümber) punktimeetodite ja peatumiskriteeriumide uurimine Yilin Yang, Liang Huang, Mingbo Ma (https://arxiv.org/abs/1808.09582)

[4] ^ Hierarhilise neuraalse loo genereerimine - autorid Angela Fan, Mike Lewis, Yann Dauphin (https://arxiv.org/abs/1805.04833)

[5] ^ Keelemudelid on juhendamata mitme ülesandega õppijad, autoriteks Alec Radford, Jeff Wu, Rewon Child, David Luan, Dario Amodei ja Ilja Sutskever (https://openai.com/blog/better-language-models/).

[6] ^ Ari Holtzmani, Jan Buysi, Maxwell Forbesi, Yejin Choi (kurioosne tekstinegeneratsiooni uudishimulik juhtum) (https://arxiv.org/abs/1904.09751)

[7] ^ Hankige ja täpsustage: dialoogi parandatud järjestuste genereerimise mudelid, autorid Jason Weston, Emily Dinan, Alexander H. Miller (https://arxiv.org/abs/1808.04776)

[8] ^ Emily Dinan jt, teine ​​vestlusliku intelligentsuse väljakutse (ConvAI2). (https://arxiv.org/abs/1902.00098)