Autor Mahir Uysal

Kako izgraditi vrhunski AI s konverzacijom s učenjem prijenosa

Prije nekoliko godina, stvaranje chatbota - koliko je tada bilo ograničeno - moglo bi potrajati mjesecima 🗓, od dizajniranja pravila do zapravo pisanja tisuća odgovora na neke od tema razgovora.

S nedavnim napretkom u dubokom učenju za NLP, sada se možemo riješiti ovog sitnog posla i izgraditi mnogo moćniji razgovorni AI za samo nekoliko sati kao što ćete vidjeti u ovom vodiču.

Postavili smo demonstracijski program koji će pokretati pretraženi model koji ćemo zajedno izraditi u ovom vodiču na adresi convai.huggingface.co. Obavezno provjerite!
Internetska demonstracija pretraženog modela koji ćemo izraditi u ovom vodiču na adresi convai.huggingface.co. 'Prijedlozi' (dno) također su zasnovani na modelu koji se stavlja u cipele korisnika.

Evo što ćemo danas naučiti i igrati:

  • Kako možete koristiti Transfer Learning da biste izradili vrhunski agent dijaloga temeljen na modelima jezika OpenAI GPT i GPT-2 Transformer,
  • Kako možete reproducirati model koji smo koristili u dijaloškom natjecanju NevIPS 2018 ConvAI2 koji je pobijedio u zapisu s automatskim metrikama,
  • Kako smo destilirali 3k + linije natjecateljskog koda u manje od 250 redaka komentiranog koda za trening (s distribuiranim i FP16 opcijama!) I
  • Kako možete trenirati ovaj model za manje od 20 USD na primjeru u oblaku ili samo koristiti naš unaprijed obučeni model s otvorenim izvorima.
Zajedno s ovim postom objavili smo čistu i komentiranu bazu kodova s ​​provjerenim modelom! Ovdje pogledajte Github repo

Priča o ovom postu započela je prije nekoliko mjeseci u Montrealu gdje je Hugging Face završio 1. mjesto u automatskom zapisu Conversational Intelligence Challenge 2 (ConvAI2), dijaloškom natjecanju na NeurIPS-u 2018.

Naš tajni umak bio je opsežni unaprijed obučeni jezični model, OpenAI GPT, u kombinaciji s tehnikom preciznog prilagođavanja Transfer Learning.

S brzim tempom natjecanja, završili smo s preko 3k redaka koda istražujući mnoge varijante treninga i arhitekture.

Jasno je da objavljivanje takvog sirovog koda ne bi bilo pošteno.

U međuvremenu smo započeli s izradom i otvorenim izvorom skladišta modela za učenje o transferu koji se zove pytorch-pretraženi-BERT koji se na kraju preuzimao više od 150 000 puta i nudili su implementacije velikih jezičnih modela poput OpenAI GPT-a i njegov je nasljednik GPT-2

Prije nekoliko tjedana odlučio sam ponovno presuditi naš natjecateljski kôd u čistu i komentiranu bazu kodova izgrađenu na vrhu provjerenog BERT-a i objasniti naš pristup i kod.

Pa evo nas, zaronimo u

AI s osobnošću

Izgradit ćemo razgovorni AI s personi.

Naš agent za dijalog imat će bazu znanja za spremanje nekoliko rečenica koje opisuju tko je (persona) i povijest dijaloga. Kad će korisnik primiti novu izjavu, agent će kombinirati sadržaj te baze znanja s novoprimljenom izjavom kako bi stvorio odgovor.

Slijedi opća shema:

Kad treniramo agente za dijalog temeljene na dubokom učenju, sve do kraja, suočeni smo s velikim problemom:

Dijaloški skupovi podataka su mali i teško je naučiti dovoljno o jeziku i zdravom razumu da biste mogli generirati tečne i relevantne odgovore.

Neki pristupi to pokušavaju riješiti filtriranjem rezultata modela kako bi se poboljšala kvaliteta pomoću pretraživanja pametnim snopom. Evo sljedećeg puta koji je pokupio ogroman interes tijekom posljednjih mjeseci: Transfer Learning.

Ideja ovog pristupa prilično je jednostavna:

  • započnite s pretragom jezičnog modela na vrlo velikom korpusu teksta kako biste mogli generirati dugačke dionice neprekidnog koherentnog teksta,
  • precizno prilagodite ovaj jezični model kako biste ga prilagodili našem krajnjem zadatku: dijalogu.

Pretraživanje jezičnog modela skupa je operacija, pa je obično bolje pokrenuti od modela koji je već pretražen i proizlazi iz otvorenih izvora.

Što bi bio dobar ispitivani model za našu svrhu?

Što je veće bolje, trebamo i model koji može generirati tekst. Najčešće korišteni pretraženi NLP model, BERT, pretražuje se samo na cijelim rečenicama i ne može dovršiti nedovršene rečenice. Još dva modela, otvorena s OpenAI, zanimljiviji su za naš slučaj upotrebe: GPT i GPT-2.

Pogledajmo ih

OpenAI GPT i GPT-2 modeli

U 2018. i 2019. Alec Radford, Jeffrey Wu i njihovi suradnici na OpenAI modelu s otvorenim izvorima s dva jezika obučeni su na vrlo velikoj količini podataka: GPT i GPT-2 (gdje GPT označava Generative pretraživani transformator).

Dekoder / kauzalni transformator sudjeluje u lijevom kontekstu radi generiranja sljedećih riječi

GPT i GPT-2 dva su vrlo slična jezika utemeljena na transformatorima. Ti se modeli zovu dekoderski ili kauzalni modeli što znači da koriste lijevi kontekst za predviđanje sljedeće riječi (vidi lijevu sliku).

Mnogi radovi i postovi na blogovima opisuju modele Transformatora i kako oni koriste mehanizme pažnje za obradu uzastopnih ulaza tako da neću trošiti vrijeme na njihovo predstavljanje u detalje. Nekoliko pokazatelja ako niste upoznati s ovim modelima: EMNLP slajdovi Emme Strubell su moj osobni favorit, a „Ilustrirani transformator“ Jaya Alammara vrlo je detaljan uvod.

U naše će svrhe jezični model biti samo model koji uzima kao ulaz sekvencu tokena i generira vjerojatnost raspodjele preko vokabulara za sljedeći token koji slijedi nakon unosa. Jezični modeli se obično treniraju paralelno, kao što je prikazano na gornjoj slici, predviđajući token koji slijedi nakon svakog tokena u dugom ulaznom slijedu.

Pregledavanje ovih modela na velikom korpusu skupo je operacija, pa ćemo krenuti od modela i tokenizera koje je pretraživao OpenAI. Tokenizator će se pobrinuti za dijeljenje ulaznog niza u tokene (riječi / pod-riječi) i pretvaranje tih tokena u ispravne numeričke indekse vokabulara modela.

Na modelu BERT OpenAI GPT i njegovim tokenizerima koji se pretražuju u pytorch-u lako se mogu kreirati i učitati s provjerene kontrolne točke poput ove:

Vjerojatno ste primijetili da smo postavili model zvan OpenAI GPT Double Heads Model koji zvuči malo složenije od jezičnog modela o kojem smo maloprije razgovarali i u pravu ste!

To je zato što svoj model moramo prilagoditi dijalogu. Da vidimo kako to ide!

Prilagođavanje jezičnog modela dijaloškom zadatku

Naš jezični model trenira se s jednim ulazom: nizom riječi.

Ali kao što smo vidjeli u postavkama dijaloga, naš će model morati koristiti nekoliko vrsta konteksta za generiranje izlaznog slijeda:

  • jedna ili više persona rečenica,
  • povijest dijaloškog okvira s najmanje zadnjim izrazom korisnika,
  • tokeni izlazne sekvence koji su već generirani otkad generiramo izlaznu sekvencu riječ po riječ.
Kako iz tih različitih konteksta možemo izraditi doprinos za naš model?

Jednostavan odgovor je samo spajanje segmenata konteksta u jedan niz, stavljajući odgovor na kraju. Zatim možemo generirati dopunu tokena odgovora tokenom nastavljajući niz:

Slijed unosa: spajanje persona (plava), povijest (ružičasta) i odgovor (zelena) s razlučivačima (svijetlo ružičasta). Ovdje generiramo riječ

Postoje dva problema s ovom jednostavnom postavkom:

  • Naš transformator je slijep u boji! Oznake razgraničenja daju samo slabu predodžbu u koji segment svaka riječ pripada. Na primjer, riječ "NYC" označena je plavom bojom (persona) na našoj ilustraciji, ali naš će model teško izvući ove podatke samo iz razgraničivača: trebali bismo dodati više informacija o segmentima.
  • Naš transformator je slijep! Pažnja je simetrični točkast proizvod, tako da bismo trebali dodati podatke o položaju za svaki token.

Jednostavan način dodavanja ovih podataka je izgradnja triju paralelnih ulaznih nizova za riječ, položaj i segmente i njihovo spajanje u jednom nizu, zbrajajući tri vrste ugrađenja: ugradnje riječi, položaja i segmenata:

Zbir tri ulaza ulaza koji označavaju riječi (siva), položaj (gradijent) i segmente (plava / ružičasta / zelena)

Kako to provoditi?

Prvo ćemo našem vokabularu dodati posebne tokene za razgraničitelje i pokazatelje segmenata. Ti tokeni nisu bili dio pretraživanja našeg modela, pa ćemo za njih morati stvoriti i uvježbati nove ugrade.

Dodavanje posebnih tokena i novih ugrađivanja u vokabular / model prilično je jednostavno s klasama koje pretražuju pytorch. Dodajmo pet posebnih tokena u naš rječnik i ugrađivanje modela:

Ove posebne metode za označavanje dodaju naših pet posebnih tokena u vokabular tokenizatora i stvaraju pet dodatnih ugrađenja u model.

Sada imamo sve što je potrebno da izgradimo svoj ulazni niz iz persona, povijesti i početka konteksta odgovora. Evo jednostavnog primjera:

Losses Gubici s više zadataka

Sada smo inicijalizirali naš pretraženi model i ugradili svoje ulaze za trening, a preostaje nam samo odabrati gubitak koji će se optimizirati tijekom finog prilagođavanja.

Koristit ćemo gubitak s više zadataka kombinirajući jezično modeliranje s ciljem predviđanja sljedeće rečenice.
Cilj predviđanja sljedeće rečenice dio je istraživanja BERT-a. Sastoji se od nasumičnog uzorkovanja distraktora iz skupa podataka i osposobljavanja modela da razlikuje da li ulazni niz završava zlatnim odgovorom ili distraktorom. Osposobljava model da sagledava globalne segmente koji znače osim lokalnog konteksta.

Sad vidite zašto smo naložili model "Double-Head". Jedna će glava izračunati jezična modeliranja predviđanja, dok će druga glava predvidjeti klasifikacijske oznake za sljedeću rečenicu. Pogledajmo kako se izračunavaju gubici:

Cilj obuke s više zadataka - model je opremljen s dvije glave za predviđanje jezičnog modeliranja (narančasta) i klasifikacija sljedećih rečenica (plava)

Ukupni gubitak bit će ponderirani zbroj gubitaka za modeliranje jezika i gubitka predviđanja u sljedećoj rečenici koji se izračunavaju na sljedeći način:

  • Jezično modeliranje: projiciramo skriveno stanje na matricu za ugradnju riječi da bismo dobili logits i primijenili gubitak unakrsne entropije na dijelu cilja koji odgovara zlatnom odgovoru (zelene naljepnice na gornjoj slici).
  • Predviđanje sljedeće rečenice: prosljeđujemo skriveno stanje posljednjeg tokena (token završetka sekvence) kroz linearni sloj da dobijemo ocjenu i primijenimo gubitak unakrsne entropije kako bismo pravilno odredili zlatni odgovor među distraktorima.

Pogledajmo kako to možemo kodirati:

Sada imamo sve ulaze potrebne za naš model i možemo pokrenuti napredni prolaz modela kako bismo dobili dva gubitka i ukupni gubitak (kao ponderirani zbroj):

Spremni smo započeti trening

Obuka na dijaloškom skupu podataka

Konkurencija ConvAI2 koristila je zanimljiv skup podataka koji je Facebook objavio prošle godine: PERSONA-CHAT.

Radi se o prilično velikom skupu dijaloga (10k dijaloga) koji je stvoren gužvanjem rečenica ličnosti i traženjem uparenih radnika iz gužve da razgovaraju dok igraju dio određenog lika (primjer je naveden na lijevoj slici).

Ovaj je skup podataka dostupan u obliku sirovog tokeniziranog teksta u lijepoj Facebookovoj biblioteci ParlAI. Da vas obučimo, prenijeli smo i verziju formatirane u JSON koju možete preuzeti i tokenizirati pomoću GPT-ovog tokenizatora kao što je ovaj:

JSON verzija PERSONA-CHAT omogućuje brz pristup svim relevantnim ulazima za obučavanje našeg modela kao ugniježđeni rječnik popisa:

Organizacija verzije JSON OSOBE-CHAT

Pomoću fantastičnog PyTorch ignite okvira i novog API-ja za automatsku mješovitu preciznost (FP16 / 32) koji pruža NVIDIA-in vrh, uspjeli smo destilirati naših + 3k redaka natjecateljskog koda u manje od 250 linija koda treninga s distribuiranim i FP16 opcijama!

Opisali smo bitne dijelove koda u gornjim popisima, pa ću vam samo dopustiti da pročitate komentirani kôd da biste vidjeli kako se sve zajedno uklapa.

Trening (vlak.py) kod je ovdje ➱

Obuka ovog modela na AWS instanci s 8 V100 GPU traje manje od sat vremena (trenutno manje od 25 USD na najvećoj p3.16xlarge AWS instanci) i daje rezultate bliske SOTA-i dobivenoj tijekom ConvAI2 natjecanja s Hits @ 1 preko 79, zbunjenost od 20,5 i F1 od 16,5.

Nekoliko razlika objašnjava nešto niže rezultate u odnosu na naš model natjecanja, oni su detaljno opisani u readmeu ovdje kodnog repoa i uglavnom se sastoje u podešavanju ugradbenih pozicija i upotrebi različitog dekodera.

Razgovor s modelom - dekoder

Nevjerojatna stvar dijaloških modela je da s njima možete razgovarati

Za interakciju s našim modelom, moramo dodati jedno: dekoder koji će izraditi pune sekvence iz sljedećih tokena predviđanja našeg modela.

U posljednjih nekoliko mjeseci došlo je do vrlo zanimljivog razvoja dekodera i želio sam ih ovdje brzo predstaviti kako bih vas upoznao s najnovijim datumima.

Dva najčešća dekodera za generiranje jezika nekada su bila pohlepno dekodiranje i pretraživanje snopa.

Generiranje rečenice riječ po riječ (izvor)

Pohlepno dekodiranje najjednostavniji je način stvaranja rečenica: za svaki vremenski korak odabiremo najvjerojatniji sljedeći token prema modelu dok ne dođemo do tokena na kraju niza. Jedan rizik kod pohlepnog dekodiranja je taj što se vrlo vjerojatan token može sakriti nakon tokena male vjerojatnosti i biti propušten.

Pretragom putem zračenja pokušajte ublažiti ovaj problem održavanjem snopa nekoliko mogućih sekvenci koje konstruiramo riječ po riječ. Na kraju postupka odabiremo najbolju rečenicu među gredama. Tijekom posljednjih nekoliko godina, pretraga snopom bio je standardni algoritam dekodiranja za gotovo sve zadatke za generiranje jezika, uključujući dijalog (vidi nedavnu [1]).

Međutim, dogodilo se nekoliko događaja u 2018. / početkom 2019. godine. Prvo, bilo je sve većih dokaza da je traženje snopa bilo jako osjetljivo na duljinu izlaza, a najbolji rezultati mogli su se dobiti kada se duljina izlaza predvidjela prije dekodiranja ([2, 3] u EMNLP 2018). Iako to ima smisla za zadatke s niskom entropijom poput prijevoda, gdje se duljina izlaznog niza može otprilike predvidjeti iz unosa, čini se proizvoljnim za zadatke visoke entropije, poput dijaloga i generiranja priča, gdje ishodi različitih duljina obično podjednako vrijede.

Paralelno s tim, objavljena su barem dva utjecajna rada ([4, 5]) o zadacima generacije visoke entropije u kojima je pohlepno / dekodiranje pretraživanja zamijenjeno uzorkovanjem iz sljedeće raspodjele tokena u svakom koraku. Ovi su radovi koristili varijantu uzorkovanja nazvanu uzorkovanje top-k u kojoj se uzorak dekodera vrši samo iz top-k najvjerojatnijih tokena (k je hiperparametar).

Posljednji kamen u ovom nedavnom trendu rada je studija koju su nedavno objavili Ari Holtzman i sur. [6] što je pokazalo da se raspodjela riječi u tekstovima generiranim pomoću pretraživanja snopom i pohlepnim dekodiranjem vrlo razlikuje od distribucije riječi u tekstovima koje stvara čovjek. Jasno je da traženje snopa i pohlepno dekodiranje ne reproduciraju neke distribucijske aspekte ljudskih tekstova, kao što je također primijećeno u [7, 8] u kontekstu dijaloških sustava:

Lijevo: Vjerojatnost dodijeljena tokenima generiranim od strane ljudi i pretraživanju snopa pomoću GPT-2 (Primjetite snažnu varijancu u ljudskom tekstu koja nije reproducirana pretraživanjem snopa) Desno: N-gram distribucije u ljudskim i strojno generiranim tekstovima (imajte na umu potpuno razdvajanje pohlepnih / pretraživanja snopa i metoda dekodiranja uzoraka).

Trenutno su dva najperspektivnija kandidata za uspjeh dekodiranja snopa / pohlepnih uzoraka top-k i nukleus (ili top-p). Općenito načelo ove dvije metode je uzorkovanje iz distribucije sljedećeg tokena nakon filtriranja ove distribucije kako bi se zadržali samo gornji k tokeni (top-k) ili gornji tokeni s kumulativnom vjerojatnošću malo iznad praga (jezgra / gornji kôd- p).

Evo kako možemo dekodirati pomoću uzorka top-k i / ili nukleusa / top-p:

Sada smo spremni za razgovor s našim modelom

Ovdje je interaktivna skripta (interact.py), a ako ne želite pokrenuti skriptu, možete se jednostavno igrati s našim demo prikazom koji je ovdje

Evo primjera dijaloškog okvira:

Primjer upotrebe interaktivnih skripti sa zadanim postavkama - Osobnost Bota: Čitam dvadeset knjiga godišnje. Ja sam kaskader koji mi je drugi posao. Jedem samo košer. Odgojena sam u domaćinstvu s jednim roditeljem.

Zaključak

Završili smo ovaj post u kojem je opisano kako možete izraditi jednostavan vrhunski razgovorni AI koristeći transfer prijenos i veliki jezični model poput OpenAI GPT.

Kao što smo naučili iz Hugging Face-a, brzo i brzo pokrenite svoj razgovorni AI najbolji je recept za uspjeh, pa se nadamo da će nekima od vas pomoći upravo to!

Provjerite pridruženi demo i kôd:

  • demo uživo je tu i
  • ovdje su kôd s otvorenim izvorom i pretraženi modeli.

Kao i uvijek, ako vam se ovaj post svidio, dajte nam nekoliko da nas obavijestite i podijelimo vijesti oko vas!

Reference:

[1] ^ Važnost strategije pretraživanja u modeliranju neuronskog dijaloga Ilya Kulikov, Alexander H. Miller, Kyunghyun Cho, Jason Weston (http://arxiv.org/abs/1811.00907)

[2] ^ Ispravljanje pristranosti duljine u prijevodu neuronskih strojeva Kenton Murray, David Chiang (http://arxiv.org/abs/1808.10006)

[3] ^ Rješavanje prokletstva pretraživanja grede: Studija (ponovno) metoda bodovanja i zaustavljanje kriterija za prijevod neuronskog stroja Yilin Yang, Liang Huang, Mingbo Ma (https://arxiv.org/abs/1808.09582)

[4] ^ Hijerarhijska generacija neuronskih priča Angele Fan, Mike Lewis, Yann Dauphin (https://arxiv.org/abs/1805.04833)

[5] ^ Jezični modeli su nepregledani višesatni učenici Alec Radford, Jeff Wu, Rewon Child, David Luan, Dario Amodei i Ilya Sutskever (https://openai.com/blog/better-language-models/)

[6] ^ Znatiželjni slučaj degeneracije neuralnog teksta Ari Holtzman, Jan Buys, Maxwell Forbes, Yejin Choi (https://arxiv.org/abs/1904.09751)

[7] ^ Dohvati i pročisti: poboljšani modeli generacije slijeda za dijalog Jason Weston, Emily Dinan, Alexander H. Miller (https://arxiv.org/abs/1808.04776)

[8] ^ Drugi razgovorni izazov inteligencije (ConvAI2) Emily Dinan i sur. (Https://arxiv.org/abs/1902.00098)