Чому так відбувається? Модель вважає, що існує емодзі морського коника, звичайно, але чому це змушує його виводити *інший* смайлик? Ось підказка від усіма улюбленого недооціненого інструменту для інтерпретації, Logit Lens! У Logit Lens ми дивним чином використовуємо lm_head моделі. Як правило, lm_head використовується для перетворення залишку (внутрішнього стану, накопиченого над шарами моделі) в набір ймовірностей токенів після фінального шару. Але в Logit Lens ми використовуємо lm_head після *кожного* шару, показуючи нам, які токени видала б модель, якби цей шар був фінальним шаром. Для ранніх шарів це призводить до станів, які важко інтерпретувати. Але в міру того, як ми рухаємося по шарах, модель ітеративно уточнює залишок спочатку в бік понять, корисних для продовження тексту, а потім до остаточного прогнозу. Дивлячись на зображення знову, на завершальному шарі, ми маємо фактичний вихід моделі - ĠðŁ, IJ, ł - він же, префікс байта емодзі, за яким слідує решта емодзі риби. (Це виглядає як нісенітниця Unicode через дивацтва токенізації - не хвилюйтеся про це. Якщо вам цікаво, запитайте Клода про цей рядок коду: 'bytes([byte_decoder[c] для c в 'ĠðŁIJł']).decode('utf-8') == ' 🐠 '') Але подивіться, що відбувається в середніх шарах - ми не просто отримуємо байти емодзі! Ми отримуємо ці *поняття*, зокрема поняття морського коника. Наприклад, на 52 шарі ми отримуємо «Морського коника-коня». пізніше, в топ-к, ми отримуємо суміш слів «море», «кінь» і приставки емодзі, «ĠðŁ». Так про що ж думає модель? Морський коник + емодзі! Він намагається побудувати залишкове представлення емодзі морського коника. Чому вона це робить? Що ж, давайте подивимося, як насправді працює lm_head. lm_head являє собою величезну матрицю векторів залишкового розміру, пов'язаних з ідентифікаторами токенів. Коли залишок передається в нього, він порівнює цей залишок з кожним вектором токена, і в координації з вибірником вибирає ID токена з вектором, найбільш схожим на залишковий. (Більш технічно: це лінійний шар без зміщення, тому v @ w.T робить точкові продукти з кожним вектором вбудовування, потім log_softmax і зразок argmax/temperature.) Отже, якщо модель хоче вивести слово "Hello", їй потрібно побудувати залишок, подібний до вектора, для вихідного токена "Hello", який lm_head може перетворити на ідентифікатор токена Hello. І якщо модель хоче вивести емодзі морського коника, їй потрібно побудувати залишок, подібний до вектора, для вихідного токена(ів) Seahorse emoji - який теоретично може бути будь-яким довільним значенням, Але на практиці це морський коник + емодзі, стиль word2vec. Єдина проблема полягає в тому, що емодзі морського коника не існує! Тому, коли цей залишковий смайлик морського коника + потрапляє на lm_head, він робить свій точковий добуток по всіх векторах, а семплер вибирає найближчий токен - емодзі риби. Тепер ця дискретизація є цінною інформацією! На прикладі Armistice ви можете бачити, що коли токен повертається в контекст авторегресивно, модель може сказати, що це не емодзі морського коника. Тому він намагається знову, похитує залишками і отримує трохи інший емодзі, промивайте і повторюйте, поки не зрозуміє, що відбувається, здасться або не закінчаться вихідні токени. Але поки модель не отримає неправильний вихідний токен з lm_head, вона просто не знає, що в lm_head немає емодзі морського коника. Він передбачає, що Seahorse + Emoji виготовить потрібний йому токен(и). ------------------ Щоб спекулювати (навіть більше), я задаюся питанням, чи є це частиною переваг RL - це дає моделям інформацію про їх lm_head, до якої інакше важко дістатися, тому що вона знаходиться в кінці стека шарів. (Пам'ятайте, що базові моделі не тренуються на власних виходах / розгортаннях - таке буває тільки в RL.)