Ugrás a tartalomra
8/308/30. fejezet

Következő token előrejelzése: embeddingek és mit jelent a perplexitás

Karaktermodellt tanítunk 32 033 néven, gradient descent újrafelfedezi a számlálótáblát, majd kiderül, miért nem egyeznek a perplexitások.

Ezen az oldalon

Íme tíz név, amelyet egy olyan program állított elő, amely még soha nem látott szót:

TEXT
cexze   momakurailezitynn   konimittain   llayn   ka
da      moliellavo          emia          sade    ftlsp

Egyik sem név. Szinte mindegyik próbálkozik. Kiejthetők, ott érnek véget, ahol a nevek véget szoktak érni, és az egyikük — emia — csak egyetlen betűre van egy valóditól. A program, amely előállította őket, 729 számot tartalmaz, nincs fogalma szóról, szótagról vagy személyről, és mindössze egymás melletti betűpárok egyszeri megszámlálásával lett illesztve.

A fejezet végére egy neurális hálózat ugyanazon a mérésen harmadával lejjebb viszi ennek a programnak a pontszámát. Amiért érdemes maradni, az az, amit a hálózat először csinál: három tizedesjegy pontossággal reprodukálja a számlálótáblát minden jól benépesített soron, prompt nélkül, mert a két objektum ugyanarra a kérdésre adott válasz. Minden ezután az, amire a számlálás soha nem lett volna képes.

A célfüggvény azonosság, nem tervezési döntés

Link a szakaszhoz: A célfüggvény azonosság, nem tervezési döntés

A 7. fejezet egy egész számokból álló sorozatot hagyott rád, és semmi okot arra, hogy az egyik miért követné a másikat. Íme az ok, és ez a 2. fejezet egyetlen sora.

Egy nyelvi modell olyan függvény, amely megkapja az eddigi tokeneket, és eloszlást ad vissza arra, melyik token következik: egy számot minden szókészletbeli elemhez, nemnegatívat, amelyek összege egy. Semmi mást. Ahhoz, hogy ebből egy teljes dokumentum valószínűségét kapjuk, alkalmazzuk a valószínűség láncszabályát:

P(x1,x2,,xT)=t=1TP(xtx1,,xt1)P(x_1, x_2, \ldots, x_T) = \prod_{t=1}^{T} P(x_t \mid x_1, \ldots, x_{t-1})

Ez egy azonosság, bármilyen dolgok bármilyen sorozatára igaz, feltételezések nélkül. Tehát egy modell, amely elvégzi a kis feladatot — a következő token megadását az előzőek alapján —, már elvégezte a nagy feladatot is: pontosan és ingyen valószínűséget rendel minden lehetséges dokumentumhoz. Az a népszerű keretezés, hogy ez olcsó trükk („csak a következő szót jósolja meg”), fordítva érti a logikát: a következő token előrejelzése maga a közös eloszlás modellezése. Soha nem volt egy második teendő.

A veszteség ugyanilyen mechanikusan következik. Minden pozíciónál a modell egy qq eloszlást állít elő, az igazság pedig egyetlen ismert token, ezért a 4. fejezet keresztentrópiája változtatás nélkül alkalmazható:

L=1Tt=1Tlogqθ(xtx<t)L = -\frac{1}{T}\sum_{t=1}^{T} \log q_\theta(x_t \mid x_{<t})

Ez az átlagos negatív log-likelihood — a 2. fejezet receptje, csak a Gauss-eloszlás helyén kategorikus eloszlással. És mivel a valódi eloszlás one-hot, az entrópiája nulla, így a 4. fejezet azonossága szerint a keresztentrópia egyenlő a KL-divergenciával: ennek a számnak a csökkentése és a modell hiedelmeinek az adatok felé húzása ugyanaz a cselekedet.

Egy következmény megérdemel egy saját mondatot, mert ez az egész terület alatti gazdasági tény. A címkék maguk az adatok, eggyel eltolva. Senki nem annotál semmit. Egybillió tokennyi szöveg egybillió előre címkézett példa, ezért egy modern modell tanító korpusza „az internet”, nem pedig „egy adathalmaz, amelyet valaki felépített”.

Bármilyen hálózat előtt a baseline: 32 033 név, soronként egy, és a feladat, hogy betűről betűre továbbiakat állítsunk elő.1

A szókészlet 26 betűből és egy . határszimbólumból áll, amely egy név elejét és végét is jelöli, így a modellnek meg kell tanulnia, hol kezdődnek és hol állnak meg a nevek. Ez 27 szimbólum, és a lehető legkisebb modell egy tábla arról, hogy az egyes szimbólumok milyen gyakran követték egymást.

bigram.pyPYTHON
N = torch.zeros((27, 27), dtype=torch.int32)
for w in words:
    cs = ["."] + list(w) + ["."]
    for a, b in zip(cs, cs[1:]):
        N[stoi[a], stoi[b]] += 1

P = N.float()
P = P / P.sum(1, keepdim=True)            # one distribution per row   

Két sor aritmetika, és a modell illesztve van — és ez nem heurisztika: a számlálások sorösszegekkel való osztása a maximum likelihood becslés egy kategorikus eloszláshoz, vagyis a 2. fejezet receptje már elvégzett kalkulussal.

TEXT
names: 32033        train/val/test: 25626 / 3203 / 3204
training bigrams: 182583

the six most likely letters after 'a':
    a -> '.'  0.1944   a -> 'n'  0.1600   a -> 'r'  0.0967
    a -> 'l'  0.0749   a -> 'h'  0.0690   a -> 'y'  0.0606

Mintavételezz belőle — válassz egy betűt az aktuális betű sorából, lépj át abba a sorba, ismételd, amíg fel nem bukkan a határszimbólum —, és megkapod a fejezet elején látható neveket. Sajátos és tanulságos módon buknak el: lokálisan hihetőek, globálisan értelmetlenek. A momakurailezitynn minden szomszédos betűpárja olyan pár, amely valódi nevekben előfordul; csak éppen tizenhét van belőlük egymás után. A modellnek egy betűnyi memóriája van, ezért nem tudhatja, hogy már túl sokáig megy.

A veszteség a félretett neveken 2,4546 nat. Ez a szám önmagában semmit sem jelent, ezért létezik a perplexitás:

PPL=exp ⁣(1Ttlogq(xtx<t))=eL\mathrm{PPL} = \exp\!\left(-\frac{1}{T}\sum_t \log q(x_t \mid x_{<t})\right) = e^{L}

Kiírva, anélkül hogy egy könyvtár végezné a munkát:

perplexity.pyPYTHON
@torch.no_grad()
def perplexity(logits, Y):
    logp = F.log_softmax(logits, dim=1)          # log q for every symbol
    chosen = logp[torch.arange(len(Y)), Y]       # log q of the one that came next   
    return torch.exp(-chosen.mean())             

Az exponenciálás visszacsinálja a logaritmust, és a számot visszaviszi a dolgok számlálásának egységeibe. A legegyszerűbb úgy látni, mit számlál, ha megmérünk egy modellt, amely egyáltalán nem tud semmit — olyat, amely minden szimbólumnak 1/271/27 valószínűséget rendel, kontextustól függetlenül:

TEXT
uniform over 27 symbols            loss 3.2958 nats   ppl  27.000
bigram counts, add-one smoothed    loss 2.4546 nats   ppl  11.642

Pontosan 27,000, mert elog27=27e^{\log 27} = 27. A perplexitás annak az effektív száma, hány egyformán valószínű opció közül választ a modell. A 27-es perplexitás azt jelenti: „fogalmam sincs, bármi lehet”. A számlálómodell 11,642-je azt jelenti, hogy egy betűnyi kontextus után a bizonytalansága olyan, mintha valaki vakon nagyjából tizenkét opcióból választana huszonhét helyett — ezért idézik a perplexitást, és nem a nyers veszteséget.

Két dolog romlik el vele, és a második publikált cikkekben is elromlik.

A nulla valószínűségek végzetesek. A tábla 729 cellájából 113 soha nem fordul elő a tanításban — 15,5%-a üres. Ez addig rendben van, amíg a félretett halmaz bele nem esik valamelyikbe, és a validációban hét bigram beleesik, köztük a dq, a zj és kétszer a qo. A nulla valószínűség log -\infty-t jelent, ami végtelen veszteséget és végtelen perplexitást jelent: háromezerből egy név tönkreteszi a metrikát. A szokásos folt az, hogy normalizálás előtt minden számláláshoz hozzáadunk 1-et, ami itt szinte semmibe sem kerül (2,4546 a 2,4524 helyett). De a folt beismerés. Egy számlálómodell egyáltalán nem tud generalizálni. Nincs módja gyanítani, hogy a qo hihető, mert a qu gyakori, és a o máshol úgy viselkedik, mint a u, mivel nincs fogalma arról, hogy két szimbólum hasonlíthat egymásra. Minden cellát külön tanul meg, és ennek kijavításáról szól a fejezet hátralévő része.

A perplexitás tokenenkénti ár, és a token szabad paraméter. Ez az a hiba, amely állandóan felbukkan modellek összehasonlításakor, és könnyű észrevenni, ha ránézel. Vedd ugyanazt az angol prózakorpuszt a 7. fejezetből, ugyanazt az interpolált bigram modellt, és csak azt változtasd meg, hogyan darabolod fel a szöveget:

egységszókészlettokenek a tesztbenkeresztentrópiaperplexitásbit karakterenként
karakterek7614 4692,521712,453,6378
BPE, 512 összevonás3296 8713,854747,212,6407
BPE, 2 048 összevonás1 8204 2335,7468313,202,4254
szavak2 9916 2843,562735,262,2322

A perplexitás 25-szörös tartományban változik ezek között a sorok között. A modellben semmi sem változott; csak annak a dolognak a mérete, amelyet meg kell jósolni. Egy egész szó megjóslása nehezebb, mint egy betűé, ezért előrejelzésenként többe kerül — és kevesebb előrejelzést kell tenni.

Most olvasd az utolsó oszlopot, amely ehelyett a teljes költséget a karakterek számával osztja el, és bitekre váltja. Átrendezi a táblát. Perplexitás szerint a rangsor: karakterek, szavak, BPE-512, BPE-2048; bit per karakter szerint: szavak, BPE-2048, BPE-512, karakterek. A karaktermodell első helyről az utolsóra kerül. A 2 048 összevonásos modell, amely perplexitás alapján 6,6-szor rosszabbnak látszik az 512 összevonásosnál, valójában a jobb a kettő közül: 2,4254 bit a 2,6407-tel szemben.

Tehát egy perplexitás csak két olyan modell között hasonlítható össze, amelyek ugyanazt a tokenizert használják, és különböző tokenizerekkel rendelkező modelleket csak bit per karakterben lehet összevetni — abban a mennyiségben, amelyet Shannon 1951-ben mért úgy, hogy emberekkel találgattatta az angol szöveg következő betűjét, és nagyjából egy bit per karakterre korlátozta.2 A legjobb bigram modellünk 2,23 biten áll, ami korrekt összefoglalója annak, milyen messzire kell még eljutnia ennek a fejezetnek.

Most építsük meg ugyanezt a modellt hálózatként. Nagyságrendekkel több aritmetikára lesz szüksége, hogy ugyanoda jusson, és éppen az a lényeg, hogy ugyanoda jut.

Cseréljük le a táblát egy WW súlymátrixra, amelynek alakja 27×2727 \times 27. Alakítsuk az aktuális betűt one-hot vektorrá, szorozzuk meg, és nevezzük az eredményt logitoknak — a 4. fejezet normalizálatlan pontszámainak. Aztán softmax, aztán keresztentrópia, aztán gradient descent.

neural_bigram.pyPYTHON
W = torch.randn((27, 27), requires_grad=True)

for step in range(3000):
    logits = W[xs]                            
    loss = F.cross_entropy(logits, ys)
    W.grad = None
    loss.backward()
    W.data -= 50.0 * W.grad

A kiemelt sor egy olyan definíciót tartalmaz, amelyet érdemes megtartani. Egy one-hot vektor mátrixszal való szorzása kiválasztja annak egyik sorát, tehát a szorzás lookup — és minden implementáció kihagyja az aritmetikát, és közvetlenül a lookupot végzi el, vagyis azt, ami a W[xs].

Ez egy embedding table. Mátrix egy sorral minden szókészletbeli elemhez, token id alapján indexelve. Nincs geometria, nincs szemantika, nincs külön algoritmus: egy lookup tábla, amelynek tartalmát történetesen gradient descent tanulja meg minden mással együtt. Az „embedding space”-ről szóló minden misztikus állítás itt ér földet.

Tanítsd, és nézd meg, hová tart:

TEXT
  step     1   train 3.7550   val 3.3882   max gap to the count table 0.757269
  step   100   train 2.4732   val 2.4726   max gap to the count table 0.388354
  step  1000   train 2.4557   val 2.4549   max gap to the count table 0.041862
  step  3000   train 2.4547   val 2.4544   max gap to the count table 0.004048

Az utolsó oszlop a legnagyobb abszolút különbség a softmax(W) bármely cellája és a számlálótábla megfelelő cellája között, és nullához tart. 3 000 lépés után a 729 cella bármelyikében a legnagyobb eltérés 0,004048, az átlag pedig 0,000224. A legrosszabb cella a qi, amelyet a teljes tanítóhalmazban tizenkétszer láttunk; a 22 olyan sor között, amely több mint ezer előfordulást tartalmaz, a legrosszabb eltérés 0,000562.

TEXT
                 count table   network
    a -> '.'        0.1945     0.1945
    a -> 'n'        0.1601     0.1601
    a -> 'r'        0.0967     0.0967

A gradient descent, amely véletlen számokból indult, és semmi mást nem mondtak neki, csak azt, hogy „tedd naggyá a következő betű log-valószínűségét”, újrafelfedezte a számlálótáblát. És muszáj volt neki: a számlálások a maximum likelihood becslések, a keresztentrópia a negatív log-likelihood, tehát mindkét eljárás ugyanazt a célfüggvényt optimalizálja, és ennek a célfüggvénynek egy optimuma van. A hálózat nem valami számláláshoz hasonlót tanult. Konvergált a számláláshoz, lassan.

Ami felveti a jogos kérdést, hogy miért bajlódna ezzel bárki. Azért, mert a számlálótábla innen nem tud hová menni, a hálózat viszont igen.

A kontextus a szűk keresztmetszet, nem a kapacitás

Link a szakaszhoz: A kontextus a szűk keresztmetszet, nem a kapacitás

Terjesszük ki a modellt, hogy egynél több előző karakterre nézzen. Ez Bengio 2003-as architektúrája, a kurzus hátralévő részében szereplő minden modell közvetlen őse:4 vedd az utolsó három karaktert, mindegyiket képezd le egy embedding table segítségével 10 dimenziós sorra, fűzd össze a sorokat 30 számmá, told át őket az 5. fejezet rejtett rétegén, és fejezd be egy kimeneti réteggel, amely szókészletbeli elemenként egy logitot állít elő.

mlp.pyPYTHON
C  = torch.randn((27, 10))          # the embedding table
W1 = torch.randn((3 * 10, 200))     # the hidden layer from Chapter 5
W2 = torch.randn((200, 27))         # one output per vocabulary entry

emb = C[X].view(-1, 30)             # three lookups, concatenated   
h = torch.tanh(emb @ W1 + b1)
logits = h @ W2 + b2                
loss = F.cross_entropy(logits, Y)

Figyeld meg, mi új és mi nem. A rejtett réteg az 5. fejezeté, változatlanul; a veszteség a 4. fejezeté, változatlanul. Az újdonságok az elöl lévő embedding table és egy olyan széles kimeneti réteg, mint a 7. fejezet szókészlete — és ez a második minden valaha épített nyelvi modell drága része, mert egy valódi szókészletnek 100 000 eleme van, és ez a mátrixszorzás minden pozíción lefut.

Ugyanaz a kód, ugyanúgy tanítva, csak a context window mérete változik:

kontextusparaméterekvalidációs veszteségvalidációs perplexitás
számlálás, 1 karakter7292,454611,642
neurális, 1 karakter7 8972,457711,678
neurális, 3 karakter11 8972,11458,285
neurális, 8 karakter21 8972,05067,773

A második sor az érdekes. Egy 200 egységes rejtett réteggel és a számlálótáblánál tizenegyszer több paraméterrel rendelkező hálózat pontosan olyan jól teljesít, mint a számlálótábla, és semmivel sem jobban. A korlát soha nem a kapacitás volt. Egy karakter kontextus bizonyos veszteséget enged meg, és semmi, amit rácsavarsz, nem mehet alá, mert az információ nincs ott.

Adj neki három karaktert, és a perplexitás 11,68-ról 8,29-re esik — 29%-os csökkenés, 4 000 extra paraméterért. Pontosan azért veri itt a számlálást, amit korábban diagnosztizáltunk: egy háromkarakteres kontextusokon működő számlálómodellnek 273=19,68327^3 = 19{,}683 sorra lenne szüksége, ezek többsége üres vagy egyetlen megfigyelést tartalmaz, és mindegyiket külön tanulja. A hálózat megoszt. Ha a a, e és i hasonló embedding sorokkal végződnek, akkor amit a bra után megtanul, az átkerül a bre-re anélkül, hogy valaha látta volna a bre-t. Ez az átvitel az embedding table teljes értéke, és ez a különbség a második és harmadik sor között.

A minták ennek megfelelően javulnak:

TEXT
deliah   nellara   joce     kael      quintis
salayson  reety    khyrmin  mahnen    madiaryxia

Még mindig nem valódi nevek listája. De a deliah, a nellara és a kael nem lógnának ki egy ilyesmiből, és az elnyúló szörnyetegek eltűntek: a számlálómodell húsz mintájából a leghosszabb tizenkilenc betű, ebből pedig húszból a leghosszabb tizenhárom.

Mi van valójában az embedding table belsejében

Link a szakaszhoz: Mi van valójában az embedding table belsejében

A tábla 27×1027 \times 10: karakterenként egy tíz számból álló sor, mind véletlenül inicializálva, és csak a következő karakter veszteségének gradiense mozgatta őket. Senki nem tett oda semmit. Akkor mi került bele?

A kérdés eszköze a koszinusz-hasonlóság, amely az 1. fejezet skalárszorzata, csak a hosszok ki vannak osztva belőle:

cos(a,b)=abab\cos(\mathbf{a}, \mathbf{b}) = \frac{\mathbf{a} \cdot \mathbf{b}}{\lVert \mathbf{a} \rVert \, \lVert \mathbf{b} \rVert}

Két vektor közötti szöget méri, és figyelmen kívül hagyja a hosszukat, pontosan ezt akarod, amikor egy sor hossza inkább azt tükrözi, milyen gyakran jelent meg a tokenje, nem azt, mit jelent. Előbb normalizálj minden vektort 1 hosszúságúra — ahogy valódi rendszerek is teszik, egyszer, indexelési időben —, és a koszinusz-hasonlóság egyszerűen a skalárszorzat.

Íme néhány karakter legközelebbi szomszédai a betanított táblában:

TEXT
  'c' -> 'k':+0.598      'j' -> 'z':+0.650      'i' -> 'y':+0.541
  'u' -> 'e':+0.482      'a' -> 'h':+0.367      '.' -> 'q':+0.077

Ennek egy része az, amit a folklór ígér. A c és a k felcserélhető nevekben, ahogy a i és a y is; a j és a z egyaránt ritka, többnyire kezdő mássalhangzó, amelyek hasonlóan viselkednek. A . határszimbólum semmihez sincs igazán közel — 0,077 a legközelebbi betűig —, mert ez az egyetlen szimbólum, amely pozíciót jelöl, nem hangot.

Egy része pedig nem ilyen. A a legközelebbi szomszédja h, nem egy másik magánhangzó. Az összes párra átlagolva:

TEXT
mean cosine, vowel to vowel         : +0.1889
mean cosine, consonant to consonant : +0.0765
mean cosine, vowel to consonant     : -0.0042

A magánhangzók jobban hasonlítanak egymásra, mint a mássalhangzókra, és a hatás valódi, de kicsi. 2 000 véletlenszerűen választott ötbetűs csoporttal összevetve 58 ilyen csoport különül el legalább ilyen tisztán — a különbség nagyjából p=0.03p = 0.03 szinten szignifikáns. Tehát valódi, de egyáltalán nem olyan éles geometriai sziget, mint amit az embeddingekről szóló népszerű beszámolók sugallnak.

Ez az embedding table őszinte leírása, és érdemes megtartani a kurzus hátralévő részére. Nem jelentéstérkép. Megtanult, nem megtervezett koordinátaváltás, amelynek egyetlen feladata, hogy megkönnyítse a következő réteg dolgát — ugyanaz a mondat, amelyet az 5. fejezet használt arra a rejtett rétegre, amely összehajtotta a síkot az XOR megoldásához. Bármilyen struktúrát találsz benne, azért van ott, mert csökkentette a veszteséget; az a struktúra pedig, amely nem csökkenti a veszteséget, egyszerűen nincs ott.

word2vec, GloVe és az aritmetika, amelyet mindenki idéz

Link a szakaszhoz: word2vec, GloVe és az aritmetika, amelyet mindenki idéz

Ha a hasznos rész a tábla, közvetlenül rá is mehetsz. Ez a word2vec: tartsd meg az embedding lookupot, dobd el a nyelvi modellt.5

A skip-gram with negative sampling célfüggvény egy sor. Egy valós (középső, kontextus) párnál, amely a korpuszból származik, nyomd fel a skalárszorzatukat; kk zajeloszlásból húzott hamis párnál nyomd le:6

logσ(vcvo)+i=1klogσ(vcvni)\log \sigma(\mathbf{v}_c \cdot \mathbf{v}_o) + \sum_{i=1}^{k} \log \sigma(-\mathbf{v}_c \cdot \mathbf{v}_{n_i})

Ez bináris osztályozás — „ez a két szó tényleg együtt fordult elő?” —, és éppen azért olcsó, mert soha nem érinti a teljes szókészletet; ez tette gyakorlativá a milliárdnyi szón való tanítást 2013-ban. A GloVe hasonló vektorokhoz az ellenkező irányból jut el: a globális együttelőfordulási számlálások mátrixát faktorizálja, ahelyett hogy példákon streamelne végig.7 Mindkettő pontosan arra a statisztikára van illesztve, amelyből a számlálótábla épült. Számlálás, összenyomva.

A text8-n tanítva — 17 005 207 angol Wikipédia-szó, közülük 71 290 legalább ötször fordul elő, 100 dimenzió, három menet — a vektorok előállnak azzal a tulajdonsággal, amely híressé tette őket:

TEXT
king     -> charles 0.700, son 0.693, queen 0.686, henry 0.669, throne 0.667
physics  -> chemistry 0.672, electromagnetism 0.661, quantum 0.654, theoretical 0.624
guitar   -> bass 0.733, vocals 0.732, acoustic 0.728, guitars 0.703, drums 0.685
three    -> seven 0.892, two 0.877, one 0.875, five 0.871, four 0.870

Senki nem adott meg kategóriát hangszerekhez vagy számnevekhez. Most a híres rész: vedd a king-t, vond ki a man-t, add hozzá a woman-t, és keresd meg az eredményhez legközelebbi vektort.

TEXT
king - man + woman
   nothing excluded : king 0.693, elizabeth 0.657, wife 0.629, woman 0.607
   a, b, c excluded : elizabeth 0.657, wife 0.629, mary 0.607   (queen is 4th, 0.604)

A king - man + woman-hez legközelebbi vektor king. Ez nem egyetlen példa furcsasága. Mikolov értékelőhalmaza a : b :: c : ? alakú kérdéseket tesz fel — 8 869 szemantikusat (paris : france :: rome : italy) és 10 675 szintaktikusat (walking : walked :: swimming : swam) —, és azon a 4 103 szemantikus kérdésen, amelyre ez a szókészlet válaszolni tud, a győztes az esetek 99,8%-ában a három bemeneti szó egyike. A publikált demonstrációk ezt nem említik, mert a standard pontozási szabály törli a a, b és c szavakat, mielőtt megnézné az eredményt. Ez legitim szabály, és több munkát végez, mint az aritmetika:

hogyan választjuk a választszemantikusszintaktikus
offset, a bemenetek kizárva (standard)17,0%11,9%
offset, semmi sincs kizárva0,1%0,4%
csak a c legközelebbi szomszédja, bemenetek kizárva13,1%9,3%
csak a b legközelebbi szomszédja, bemenetek kizárva2,3%0,4%

A harmadik sor az, amelynél érdemes megállni. Dobd el a a-t és a b-t, egyáltalán ne végezz aritmetikát, add vissza azt, ami legközelebb van a c-hez — és megtartod a szemantikus pontszám 77%-át. Annak nagy része, ami analógiás következtetésnek látszik, közelség plusz egy szabály, amely tiltja a nyilvánvaló válaszokat; ezt mérte Linzen megfelelően tanított vektorokon, és ezt replikálják a fenti baseline-ok.8 Ezek a konkrét vektorok kicsik — 17 millió szó a publikált modellek mögötti milliárdokkal szemben —, ezért a százalékokat alakzatként, ne state of the artként olvasd. Az alakzat az, ami minden skálán megmarad: az aritmetika valódi, és sokkal gyengébb annál az egy demonstrációnál, amelyet mindenki idéz.

Statikus és kontextuális: szavanként egy vektor, vagy előfordulásonként egy

Link a szakaszhoz: Statikus és kontextuális: szavanként egy vektor, vagy előfordulásonként egy

Eddig mindenben be van építve egy kemény korlát az adatstruktúrába. Egy táblának tokenenként egy sora van. A bank szó egy vektort kap, ugyanazt egy folyóról szóló mondatban és egy jelzálogról szóló mondatban — szükségszerűen, mert az id szerinti lookup nem függhet semmi mástól.

A javítás az, hogy ne a táblából olvassuk ki a vektort, hanem kezdjük el kiszámítani a mondatból. Ez a contextual embedding, amelyet az ELMo vezetett be 2018-ban, és ugyanabban az évben a BERT tett standarddá.910 A valódi modellen mérve a számok élesebbek, mint a magyarázat:

TEXT
sentence A: "He sat on the bank of the river and watched the water go by."
sentence B: "She deposited the cheque at the bank on the corner of the street."

static vector for 'bank' (a row of the input embedding table)
    cosine A vs B ........................ 1.000000

contextual vector for 'bank', layer by layer
    layer  |  A vs B  |  A vs another river sentence  |  B vs another money sentence
        0  |  0.9512  |            0.9512             |            0.9359
        4  |  0.5647  |            0.8987             |            0.7716
        9  |  0.4284  |            0.8699             |            0.7568
       12  |  0.5278  |            0.8702             |            0.7335

Az első sor pontos, nem közelítő: a bank statikus vektora ugyanaz a 768 szám mindkét mondatban, így a koszinusz konstrukció szerint 1. Kilenc réteggel később a két előfordulás 0,43-nál ül, míg a bank két különböző folyós mondatban 0,87-en marad. Senki nem címkézett jelentést sehol ebben a folyamatban; a jelentések azért váltak szét, mert szétválasztásuk megkönnyíti a tanítási célfüggvény — egy elrejtett token kitalálása a szomszédaiból — kielégítését.

Két részlet megéri a figyelmet. A 0. réteg már 0,9512, nem 1,0, mert position embeddingek lettek hozzáadva, és a szó más helyen áll a két mondatban. A hasonlóság pedig újra nő a 11. és 12. rétegben: egy pretrained modell utolsó rétegei a tanítási célfüggvényére specializálódnak, és gyakran nem ezek a legjobb helyek reprezentáció kinyerésére.

Részletek megjelenítése

Opcionális: weight tying.

A bert-base-uncased-ben az embedding table 30,522×76830{,}522 \times 768 — 23 440 896 szám, a modell 109 482 240 paraméterének 21,4%-a. Egy kis nyelvi modellben az arány még nagyobb, ezért egy trükk szinte univerzális: a bemeneti tábla és a logitokat előállító kimeneti réteg ugyanaz a mátrix, egyszer sor lookupként, egyszer transzponálva használva.11 A kimeneti réteg már amúgy is vektort rendel minden szókészletbeli elemhez — skalárszorzatot vesz mindegyikkel —, a tying pedig azt mondja, hogy a token olvasásához használt vektor és az írásához használt vektor legyen ugyanaz az objektum. Egyszerre csökkenti a paramétereket és javítja a perplexitást, ami elég ritka ahhoz, hogy észrevegyük.

Ahhoz, hogy jelentés alapján keress egy korpuszban, mondatonként egy vektorra van szükséged. Ha ezek megvannak, a keresés triviális — ez a szemantikus visszakeresés egésze, és a 19. fejezet mindenről szól, ami körülötte van:

search.pyPYTHON
E = normalise(embed(sentences))       # (200, d), every row of length 1
q = normalise(embed([query]))         # (1, d)
scores = q @ E.T                      # one matrix multiply   
top5 = scores[0].argsort()[::-1][:5]

Az egyetlen valódi kérdés tehát az, honnan jön a embed. A kézenfekvő lépés az, hogy fogunk egy pretrained nyelvi modellt, átfuttatunk rajta minden mondatot, és átlagoljuk a token vektorokat. Íme ez a módszer négy alternatívával szemben, kétféleképpen pontozva: a koszinusz és az emberi hasonlósági ítéletek rangkorrelációja az STS benchmark 1 379 párján, valamint top-1 retrieval egy olyan indexen, amely a legerősebben parafrazeált 200 párból épült — minden pár egyik oldala indexelve, a másik queryként használva.

hogyan készül a mondat embeddingrangkorrelációtop-1 egy 200 mondatos indexen
bináris szóátfedés (modell nélkül)0,550089,0%
a fent tanított statikus vektorok átlaga0,526385,5%
BERT, a [CLS] token0,203067,0%
BERT, token vektorok átlaga0,472984,0%
MiniLM, kontrasztívan tanítva0,820392,0%

Olvasd a középső három sort az első kettőhöz képest. Egy 109 millió paraméteres pretrained transformer, a kézenfekvő módon használva, rosszabb mondathasonlóság megítélésében, mint megszámolni, hány közös szava van két mondatnak — és rosszabb, mint az imént tanított 100 dimenziós text8 vektorok átlagolása. A [CLS] token, amelyet oktatóanyagok még mindig ajánlanak, mert a BERT-et mondatszintű célfüggvénnyel is pretrainedelték, ennek a felénél is rosszabb.

Ez nem a BERT hibája. Ez a célfüggvény. Egy nyelvi modellt úgy tanítanak, hogy a hidden state-ek token előrejelzésére szolgáljanak; semmi sem kéri, hogy két parafrázis egymás közelébe kerüljön, és semmi sem jutalmaz olyan geometriát, amelyben a koszinusz „azonos jelentést” jelent. Az utolsó sor egy ötödakkora modell (22 713 216 paraméter), amelyet teljesen más veszteségen tanítottak: kontrasztív tanuláson, ahol a példák párok — egy kérdés és a válasza, egy mondat és a parafrázisa —, a cél pedig az igaz párok összehúzása, miközben a mintavételezett negatívokat széttolja. Ez a Sentence-BERT hozzájárulása és az egész embedding model iparág eredete.12 A Dense Passage Retrieval ugyanezt a receptet alkalmazza közvetlenül keresésre, egy encoderrel a querykhez és egy másikkal a passage-ekhez.13

Tehát a gyakorlati szabály:

Egy embedding model nem nyelvi modell levágott utolsó réteggel. Más modell más célfüggvényen, általában sokkal kisebb, amelynek koszinusza azért jelenti azt, amit szeretnél, mert olyan párokon tanították, ahol ez volt a cél. A fenti tábla az ára annak, ha az egyiket a másikkal helyettesíted.

És a család elbukik a szórenden. „The dog bit the man” és „the man bit the dog” azonos szózsákokkal rendelkezik, ezért a szóátfedés és a statikusvektor-átlag koszinusza pontosan 1,000000, a mean-pooled BERT pedig, amely lát pozíciót, még mindig majdnem ide ér — és a kontrasztívan tanított MiniLM is 0,979-re teszi őket. Ha a retrieval feladatod azon múlik, ki mit tett kivel, semmilyen koszinuszküszöb nem fog megmenteni.

A 19. fejezet erre az alapra épít production retrieval rendszert, és konkrét koszinuszküszöbig jut. Ennek a fejezetnek az utolsó mérése teszi az ilyen számot védhetővé, nem varázslattá.

A dimenzionalitás átka, egy táblában

Link a szakaszhoz: A dimenzionalitás átka, egy táblában

A valódi embeddingeknek száz vagy ezer komponensük van, és a távolságok odafent furcsán viselkednek. Vegyünk 1 000 véletlen pontot az dd dimenziós egységkockában, és nézzük meg a bármely két pont közötti legnagyobb és legkisebb távolság arányát:

dimenzióklegközelebbi párlegtávolabbi párarány
20,00071,36121921,66
100,23612,33979,91
1003,00475,17521,72
1 00011,780914,03061,19
10 00039,615242,01251,06

Tízezer dimenzióban a legtávolabbi pontpár csak 6%-kal van messzebb egymástól, mint a legközelebbi. Minden nagyjából egyenlő távolságra van minden mástól, a „legközelebbi szomszéd” sok információt veszít, és ez a dimenzionalitás átka — valamint az egyik oka annak, hogy nagy vektoradatbázisok nem végeznek egzakt legközelebbi szomszéd keresést. Ugyanennek az éremnek a másik oldala teszi működőképessé a koszinuszküszöböket: ezer véletlen egységvektor-páron mérve az átlagos koszinusz 0.0052-0.0052 100 dimenzióban és +0.0003+0.0003 768-ban, 0,0968 és 0,0357 szórással — és 768 dimenzióban a véletlen párok mindössze 0,2%-a haladja meg abszolút értékben a 0,1-et. Egy 0,4-es mért hasonlóság tehát nem azt jelenti, hogy „40%-ban hasonló”; messze kívül esik azon, amit a véletlen produkál, ezért választják el a 0,3 és 0,7 közötti küszöbök a jelet a zajtól, ahelyett hogy a közepében ülnének.

A fejezet modellje fix számú előző karaktert olvas, mindegyiket kikeresi, és az eredményeket sorrendben összeragasztja. Ennek a designnak két problémája van, és ezek ugyanaz a probléma.

Nézd meg újra a kontextustáblát: három karakterről nyolcra menni majdnem megduplázta a paramétereket, és 0,06 natot hozott. A költség lineárisan nő a kontextussal — minden extra pozíciónak kell a saját szelete az első súlymátrixból —, a haszon pedig nem. Told fel ezer tokenre, és az első réteg önmagában nehezebb lesz, mint a modell többi része, nagyrészt olyan pozíciókra költve, amelyek az adott előrejelzéshez nem számítanak.

Ez a második probléma is: a modellnek nincs módja eldönteni, melyik korábbi token számít. A második pozíció megkapja a saját súlyait, a hetedik pozíció is a sajátját, véglegesen, bármi is legyen bennük. Amikor a modell a nell-t betűzi, a döntő karakter a közvetlenül előtte álló. Amikor egy mondat névmást tartalmaz, a referensét rögzítő szó negyven tokennel korábban lehet — és nincs fix slot, amelyet a „negyvennel korábbi”-nak lehetne kiosztani, mert legközelebb hat lesz.

Olyan modellt akarunk, amely minden előrejelzéshez kiszámítja, mennyit számítson minden korábbi token — a kontextus fölötti súlyokat, amelyeket a tartalom állít elő, nem az elrendezés rögzít. Írd ezt le óvatosan, és valami teljesen hétköznapiként indul: az előző tokenek átlaga. Aztán engedd, hogy ennek az átlagnak a súlyait megtanulja, és hogy a súlyok attól függjenek, melyik token kérdez.

Ez az attention, és ez a 9. fejezet.


Érdemes még mellette olvasni Jurafsky és Martin Speech and Language Processing című könyvének 3. fejezetét, amely az n-gram modelleket, smoothingot és perplexitást sokkal alaposabban tárgyalja, mint amennyi hely itt van rá, beleértve azt is, miért veri az interpoláció és a back-off az egy hozzáadását; a Stanford CS229 jegyzetek 17.1–17.2 szakaszát a nyelvi modellezés valószínűségi oldalához; és Linzen fenti cikkét, amely rövid, és érdemes teljes egészében elolvasni.

  1. A névgenerálási példa, az adathalmaz és a számlálótáblától a Bengio-stílusú hálózatig tartó haladás Andrej Karpathy building makemore sorozatát követi, amelynek első két része a fejezet legjobb kísérője.

  2. Shannon, C. E. Prediction and Entropy of Printed English. Bell System Technical Journal 30(1), 50–64. o. (1951). Emberek találgatják az angol következő betűjét, és az eredeti bit-per-karakter mérés.

  3. Shannon, C. E. A Mathematical Theory of Communication. Bell System Technical Journal 27 (1948). A forráskódolási tétel, valamint az előrejelzés és a tömörítés azonosítása.

  4. Bengio, Y., Ducharme, R., Vincent, P. és Jauvin, C. A Neural Probabilistic Language Model. Journal of Machine Learning Research 3, 1137–1155. o. (2003). A fent használt architektúra: szavanként egy embedding, fix ablakon össze concatenálva, rejtett rétegen át, majd softmax a szókészlet fölött.

  5. Mikolov, T., Chen, K., Corrado, G. és Dean, J. Efficient Estimation of Word Representations in Vector Space. arXiv:1301.3781 (2013). CBOW és skip-gram, valamint a fent használt analógiahalmaz.

  6. Mikolov, T., Sutskever, I., Chen, K., Corrado, G. és Dean, J. Distributed Representations of Words and Phrases and their Compositionality. arXiv:1310.4546 (2013). Negative sampling, gyakori szavak subsamplingje, és a fent használt, 3/4 hatványra emelt zajeloszlás.

  7. Pennington, J., Socher, R. és Manning, C. GloVe: Global Vectors for Word Representation. EMNLP 2014. Szóvektorok a globális együttelőfordulási mátrix faktorizálásából, streamelt lokális ablakok helyett.

  8. Linzen, T. Issues in evaluating semantic spaces using word analogies. RepEval 2016, arXiv:1606.07736. A fent replikált offset nélküli baseline-ok forrása.

  9. Peters, M. et al. Deep contextualized word representations. arXiv:1802.05365 (2018). ELMo: előfordulásonként egy vektor, amelyet bidirectional nyelvi modell számít ki.

  10. Devlin, J., Chang, M.-W., Lee, K. és Toutanova, K. BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding. arXiv:1810.04805 (2018). A bank kísérletben mért modell.

  11. Press, O. és Wolf, L. Using the Output Embedding to Improve Language Models. arXiv:1608.05859 (2016), valamint Inan, H., Khosravi, K. és Socher, R. Tying Word Vectors and Word Classifiers. arXiv:1611.01462 (2016). Két független érv ugyanazért a trükkért.

  12. Reimers, N. és Gurevych, I. Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks. arXiv:1908.10084 (2019). Nyitó mérése — hogy a mean-pooled BERT alulteljesít az átlagolt statikus vektorokhoz képest mondathasonlóságon — az, amit a fenti tábla reprodukál.

  13. Karpukhin, V. et al. Dense Passage Retrieval for Open-Domain Question Answering. arXiv:2004.04906 (2020). Két encoderes retriever kontrasztív tanítása; a 19. fejezet retrieval stackjének közvetlen őse.


Készítette

David Vicente Campos

A NeuraLIA Labs alapítója és a MyRealFood társalapítója

Mérnökinformatikus vagyok, a Leóni Egyetemen végeztem. Társalapítottam a MyRealFoodot, ahol CTO-ként felépítettem azt az alkalmazást, amelyet emberek milliói használtak arra, hogy egészségesebben táplálkozzanak, és megalapítottam a NeuraLIA Labst, ahol AI-termékeket fejlesztek. Itt arról írok, amit menet közben meg kellett értenem, úgy, ahogy szerettem volna, hogy valaki elmagyarázza nekem.

Továbbiak a szerzőről

Közzétette a NeuraLIA Labs.

Kapj új bejegyzéseket a postaládádba

AI-hírek, útmutatók és termékfrissítések — rövid email, amikor valami igazán hasznosat publikálunk.

Kurzusindex

Abstract software decision engine with branching paths, probability nodes, and glowing gates.
jev11 perc olvasás

A Jev AI-modell döntésekre készült, nem prózára

A TypeSafe AI Jev modellje azért kap figyelmet, mert a szoftveres intelligenciát valószínűségi problémaként kezeli: válaszd ki a megfelelő ágat, rendelj hozzá bizalmi szintet, és ne fizess egy LLM-nek szövegírásért, amikor a kódnak döntésre van szüksége.

Abstract agent runtime sorting documents, memory blocks and pointer nodes inside a bounded context frame.
context-engineering11 perc olvasás

Kontextustervezés hosszú távú AI-ügynökökhöz

A hosszú ideig futó ügynökök nem csak azért vallanak kudarcot, mert kicsi az ablak. Akkor hibáznak, amikor a fájlok, eszközkimenetek és elavult előzmények kiszorítják azt a feladatot, amelyet az ügynöknek be kellett volna fejeznie.

Készen állsz, hogy a LIA válasszon helyetted?

Építs az összes AI-modellel egy helyen – kezdd el ma, ingyen.