Proč se to děje? Model věří, že existuje emotikon mořského koníka, jistě, ale proč to z něj dělá *jiný* emotikon? Zde je vodítko od oblíbeného podceňovaného nástroje pro interpretovatelnost, Logit Lens! V Logit Lens používáme lm_head modelu podivným způsobem. Obvykle se lm_head používá k převedení rezidua (vnitřního stavu vytvořeného nad vrstvami modelu) na sadu pravděpodobností tokenu po poslední vrstvě. V Logit Lens ale používáme lm_head po *každé* vrstvě - ukazuje nám, jaké tokeny by model vydal, kdyby tato vrstva byla poslední vrstvou. U raných vrstev to vede k obtížně interpretovatelným stavům. Ale jak se pohybujeme vrstvami, model iterativně zpřesňuje zbytek nejprve směrem ke konceptům užitečným pro pokračování textu a poté směrem ke konečné predikci. Když se znovu podíváme na obrázek, na poslední vrstvě máme skutečný výstup modelu - ĠðŁ, IJ, ł - alias, předponu bajtů emotikonů následovanou zbytkem emotikonu ryby. (Vypadá to jako nesmysl Unicode kvůli tokenizační zvláštnosti - nedělejte si s tím starosti. Pokud jste zvědaví, zeptejte se Clauda na tento řádek kódu: 'bytes([byte_decoder[c] for c in 'ĠðŁIJł']).decode('utf-8') == ' 🐠 '') Ale podívejte se, co se děje ve středních vrstvách - nedostáváme jen bajty emotikonů! Dostáváme tyto *koncepty*, konkrétně koncept mořského koníka. Například ve vrstvě 52 dostaneme "kůň mořského koníka". Později, v top-k, dostaneme směs slov "moře", "kůň" a předpony emotikonů "ĠðŁ". O čem tedy model přemýšlí? mořský koník + emoji! Snaží se vytvořit zbytkovou reprezentaci emotikonu mořského koníka. Proč by to dělala? Pojďme se podívat na to, jak lm_head vlastně funguje. lm_head je obrovská matice vektorů o zbytkové velikosti spojených s ID tokenů. Když je do něj předán zbytek, porovná se tento zbytek s každým vektorem tokenu a v koordinaci se vzorkovačem se vybere ID tokenu s vektorem, který se nejvíce podobá reziduu. (Techničtější je, že je to lineární vrstva bez zkreslení, takže v @ w.T dělá bodové součiny s každým vektorem bez vložení, pak log_softmax a argmax/temperature vzorek.) Pokud tedy chce model vygenerovat slovo "Hello", musí vytvořit zbytek podobný vektoru pro výstupní token "Hello", který může lm_head proměnit na ID tokenu Hello. A pokud chce model vytvořit emotikon mořského koníka, musí vytvořit zbytek podobný vektoru pro výstupní token(y) emotikonů mořského koníka - což by teoreticky mohla být libovolná hodnota, Ale v praxi je mořský koník + emoji, word2vec styl. Jediným problémem je, že emotikon mořského koníka neexistuje! Když tedy tento reziduum mořského koníka + emotikon zasáhne lm_head, udělá svůj tečkový součin přes všechny vektory a vzorkovač vybere nejbližší token - emotikon ryby. Tato diskretizace je cenná informace! na příkladu Armistice můžete vidět, že když se token automaticky umístí zpět do kontextu, model pozná, že se nejedná o emotikon mořského koníka. Zkusí to tedy znovu, zatřese zbytkem a dostane trochu jiný emotikon, opláchne a opakuje, dokud si neuvědomí, co se děje, nevzdá to nebo mu nedojdou výstupní tokeny. Dokud však model nezíská z lm_head špatný výstupní token, prostě neví, že v lm_head není emotikon mořského koníka. Předpokládá, že Seahorse + Emoji vytvoří token(y), který chce. ------------------ Abych mohl spekulovat (ještě více), zajímalo by mě, zda je to součástí výhody RL - dává modelkám informace o jejich lm_head, ke kterým je jinak obtížné se dostat, protože je na konci zásobníku vrstev. (Nezapomeňte, že základní modely nejsou trénovány na svých vlastních výstupech / rolloutech - to se děje pouze v RL.)