- BrainTools - https://www.braintools.ru -

Существует ли эмодзи морского конька? Давайте спросим об этом у GPT-5 Instant:

«Да, эмодзи морского конька существует» [Далее следует долгий перебор эмодзи с попыткой найти нужный.]
Чего? Тогда спросим у Claude Sonnet 4.5:

«Да! 🐎 Хотя нужно уточнить, что это эмодзи лошади. Вот эмодзи морского конька: 🦈. Хотя нет, это акула!»
Что здесь происходит? Возможно, Gemini 2.5 Pro справится лучше?

«Да, эмодзи морского конька есть! Seahorse»
Хм, что-то непонятное творится. Будем разбираться, в чём причина.
Вот ответы, которые можно получить, если сто раз спросить у множества разных моделей, существует ли эмодзи морского конька:
Существует ли эмодзи морского конька, да или нет? Ответь одним словом, без пунктуации.
gpt-5-chat
100% «Да»
gpt-5
100% «Да»
claude-4.5-sonnet
100% «Да»
llama-3.3-70b
83% «да»
17% «Да»
Не стоит и говорить, что популярные языковые модели крайне уверены в том, что эмодзи морского конька есть. И в этой уверенности они не одиноки: вот пост на Reddit с сотнями комментариев от людей, чётко помнящих о существовании такого эмодзи:

Таких источников целая куча — загуглите «seahorse emoji», и вы найдёте кучу тиктоков, видео на Youtube и даже мемкойны (уже не действующие), связанные с исчезновением эмодзи морского конька, в существовании которого уверены люди. Но, разумеется, его никогда не было.
Возможно, LLM считают, что этот эмодзи существует, потому что так считают многие люди в обучающих данных. Или, возможно, эта вера возникла из-за схождения — в Unicode есть много других морских животных, поэтому и люди, и LLM вполне логично [1] могут предполагать (и даже обобщать) наличие такого удивительного животного. Эмодзи морского конька даже было предложено формально [2], но в 2018 году это предложение отклонили.
Какой бы ни была первопричина, многие LLM начинают каждое новое окно контекста со свежей ошибочной верой в существование такого эмодзи. Но почему возникает такое странное поведение [3]? На самом деле, я и сам раньше думал, что эмодзи морского конька есть, но если бы я захотел отправить его другу, то просто посмотрел бы на клавиатуру и осознал, что его там нет, не отправил бы неправильное эмодзи. Какие внутренние механизмы заставляют LLM вести себя подобным образом?
Давайте посмотрим на этот вопрос через любимый, но недооценённый инструмент интерпретируемости — логитный объектив [4]!
Используем префикс промпта — шаблон чата со стандартным системным промптом llama-3.3-70b, вопрос о эмодзи морского конька и частичный ответ модели перед тем, как она выводит сам эмодзи:
<|begin_of_text|><|begin_of_text|><|start_header_id|>system<|end_header_id>
Cutting Knowledge Date: December 2023
Today Date: 26 Jul 2024
<|eot_id|><|start_header_id|>user<|end_header_id|>
Is there a seahorse emoji?<|eot_id|><|start_header_id|>assistant<|end_header_id|>
Yes, there is a seahorse emoji:
Мы можем взять lm_head модели, который обычно используется только в выводе последнего слоя, и применить его к каждому слою для генерации промежуточных прогнозов токенов. Этот процесс даст нам следующую таблицу, демонстрирующую для каждого четвёртого слоя наиболее вероятный токен для следующих трёх позиций после префикса (токены 0, 1 и 2) и пять наиболее вероятных прогнозов для первой позиции (токен 0 topk 5):
|
слой |
токены |
токены |
токен 0 |
||
|---|---|---|---|---|---|
|
|
0 |
1 |
2 |
объединённые |
(topk 5) |
|
0 |
83244’ĠBail’ |
15591’ĠHarr’ |
5309’Ġvert’ |
Bail Harr vert |
[‘ĠBail’, ‘ĠPeanut’, ‘ĠãĢ’, ‘orr’, ‘ĠâĢĭâĢĭ’] |
|
4 |
111484’emez’ |
26140’abi’ |
25727’avery’ |
emezabiavery |
[’emez’, ‘Ġunm’, ‘ĠOswald’, ‘Ġrem’, ‘rix’] |
|
8 |
122029’chyb’ |
44465’ĠCaps’ |
15610’iller’ |
chyb Capsiller |
[‘chyb’, ‘ĠSund’, ‘ترÛĮ’, ‘resse’, ‘Ġsod’] |
|
12 |
1131’…’ |
48952’ĠCliff’ |
51965’ĠJackie’ |
… Cliff Jackie |
[‘…’, ‘ages’, ‘dump’, ‘qing’, ‘Ġexp’] |
|
16 |
1131’…’ |
12676’365′ |
31447’ĠAld’ |
…365 Ald |
[‘…’, ‘…Ċ’, ‘Ġindeed’, ‘Ġboth’, ‘ĠYes’] |
|
20 |
1131’…’ |
109596’éļĨ’ |
51965’ĠJackie’ |
…隆 Jackie |
[‘…’, ‘…Ċ’, ‘Z’, ‘Ġboth’, ‘ĠHust’] |
|
24 |
12′-‘ |
31643’ï¸ı’ |
287’ing’ |
-️ing |
[‘-‘, ‘…’, ‘â̦’, ‘…Ċ’, ’em’] |
|
28 |
1131’…’ |
96154’ĠGaut’ |
51965’ĠJackie’ |
… Gaut Jackie |
[‘…’, ‘-‘, ‘…Ċ’, ‘-Ċ’, ‘Ġ’] |
|
32 |
1131’…’ |
96154’ĠGaut’ |
6892’Ġing’ |
… Gaut ing |
[‘…’, ‘â̦’, ‘…Ċ’, ‘O’, ‘zer’] |
|
36 |
1131’…’ |
12′-‘ |
88’y’ |
…-y |
[‘…’, ‘â̦’, ‘…Ċ’, ‘Ġ’, ‘u’] |
|
40 |
1131’…’ |
31643’ï¸ı’ |
88’y’ |
…️y |
[‘…’, ‘u’, ‘â̦’, ‘Âł’, ‘…Ċ’] |
|
44 |
80435’ĠScor’ |
15580’Ġhorse’ |
15580’Ġhorse’ |
Scor horse horse |
[‘ĠScor’, ‘u’, ‘ĠPan’, ‘in’, ‘Ġhttps’] |
|
48 |
15580’Ġhorse’ |
15580’Ġhorse’ |
15580’Ġhorse’ |
horse horse horse |
[‘Ġhorse’, ‘Âł’, ‘ĠPan’, ‘ĠHomes’, ‘ĠHorse’] |
|
52 |
9581’Ġsea’ |
15580’Ġhorse’ |
15580’Ġhorse’ |
sea horse horse |
[‘Ġsea’, ‘Ġhorse’, ‘ĠHorse’, ‘ĠSea’, ‘âĢij’] |
|
56 |
9581’Ġsea’ |
43269’ĠSeah’ |
15580’Ġhorse’ |
sea Seah horse |
[‘Ġsea’, ‘ĠSea’, ‘ĠSeah’, ‘Ġhippoc’, ‘Ġhorse’] |
|
60 |
15580’Ġhorse’ |
15580’Ġhorse’ |
15580’Ġhorse’ |
horse horse horse |
[‘Ġhorse’, ‘Ġsea’, ‘ĠSeah’, ‘Ġse’, ‘horse’] |
|
64 |
15580’Ġhorse’ |
15580’Ġhorse’ |
15580’Ġhorse’ |
horse horse horse |
[‘Ġhorse’, ‘Ġse’, ‘ĠHorse’, ‘horse’, ‘Ġhors’] |
|
68 |
60775’horse’ |
238’IJ’ |
15580’Ġhorse’ |
horse� horse |
[‘horse’, ‘Ġse’, ‘Ġhorse’, ‘Ġhippoc’, ‘ĠSeah’] |
|
72 |
513’Ġse’ |
238’IJ’ |
513’Ġse’ |
se� se |
[‘Ġse’, ‘Ġhippoc’, ‘horse’, ‘ĠðŁ’, ‘Ġhorse’] |
|
76 |
513’Ġse’ |
238’IJ’ |
513’Ġse’ |
se� se |
[‘Ġse’, ‘Ġhippoc’, ‘hip’, ‘Ġhorse’, ‘ĠHipp’] |
|
80 |
11410’ĠðŁ’ |
238’IJ’ |
254’ł’ |
🐠 |
[‘ĠðŁ’, ‘ðŁ’, ‘ĠðŁĴ’, ‘Ġ’, ‘ĠðŁij’] |
Это и есть логитный объектив: мы используем lm_head модели для создания логитов (вероятностей токенов) для изучения внутренних состояний. Стоит отметить, что токены и вероятности, получаемые из логитного объектива, не эквивалентны полным внутренним состояниям модели! Для их получения нам был понадобилась более сложная методика наподобие representation reading или sparse autoencoders. Мы получили только объектив состояния — он показывает, каким был бы выходной токен, если бы этот слой оказался последним. Но несмотря на это ограничение, логитный объектив всё равно полезен. С его помощью может быть сложно интерпретировать ранние слои, но двигаясь по стеку, мы сможем наблюдать, как модель итеративно совершенствует эти состояния в направлении окончательного прогноза — эмодзи рыбы.
(Почему необъединённые токены выглядят, как символы «ĠðŁ», «IJ», «ł»? Это особенность токенизатора — такие токены кодируют байты UTF-8 эмодзи рыбы. Это не относится к теме статьи, но если вам любопытно, то попросите Claude или другую LLM объяснить этот параграф и эту строку кода: bytes([bpe_byte_decoder[c] for c in 'ĠðŁIJł']).decode('utf-8') == ' 🐠')
Однако посмотрите, что происходит в средних слоях — это не просто странности ранних слоёв и не байты эмодзи окончательного прогноза! Вместо них мы получаем слова, относящиеся к полезным концепциям; в частности, к концепции морского конька. Например, в слое 52 мы получаем «sea horse horse» — три позиции скрытого состояния подряд, кодирующие концепцию «seahorse». Позже, в top-k для первой позиции, мы получаем смесь «sea», «horse» и префикса последовательности байтов эмодзи «ĠðŁ».
О чём же думает модель? «seahorse + emoji»! Она пытается сконструировать представление скрытого состояния морского конька в сочетании с эмодзи. Почему модель пытается создать эту комбинацию? Давайте разберёмся, как работает lm_head.
Слой lm_head языковой модели — это огромная матрица, состоящая из векторов размерностью скрытого состояния. Каждому токену в словаре (их примерно 300 тысяч) соответствует один такой вектор. Когда ему передаётся скрытое состояние (или при обычной передаче по модели, или на ранних этапах, потому что кто-то использовал логитный объектив), lm_head сравнивает это скрытое состояние ввода с каждым вектором размерностью скрытого состояния в этой большой матрице и (согласованно с сэмплером) выбирает идентификатор токена, связанного с вектором матрицы, наиболее близким к скрытому состоянию ввода.
(Выражаясь более технически, lm_head — это линейный слой без смещения, поэтому x @ w.T выполняет скалярное произведение с каждым вектором анэмбеддинга для получения сырых оценок. Затем выполняется обычный log_softmax и сэмплирование argmax/temperature.)
Это значит, что если модель хочет вывести «hello», например, в ответ на приветствие со стороны пользователя, ей нужно создать скрытое состояние, как можно более схожее с вектором токена «hello», которое lm_head затем может превратить в идентификатор токена hello. И при помощи логитного объектива мы можем увидеть, что именно это и происходит в ответ на «Hello :-)»:
|
слой |
токены |
токены |
токен 0 |
||
|---|---|---|---|---|---|
|
|
0 |
1 |
2 |
объединённые |
(topk 5) |
|
0 |
0′!’ |
0′!’ |
40952’opa’ |
!!opa |
[‘”‘, ‘!’, ‘#’, ‘%’, ‘$’] |
|
8 |
121495’ÅĻiv’ |
16’1′ |
73078’iae’ |
řiv1iae |
[‘ÅĻiv’, ‘-‘, ‘(‘, ‘.’, ‘,’] |
|
16 |
34935’Ġconsect’ |
7341’arks’ |
13118’Ġindeed’ |
consectarks indeed |
[‘Ġobscure’, ‘Ġconsect’, ‘äºķ’, ‘ĠпÑĢоÑĦеÑģÑģионалÑĮ’, ‘Îŀ’] |
|
24 |
67846′<[‘ |
24748’Ġhello’ |
15960’Ġhi’ |
<[ hello hi |
[‘<[‘, ‘arks’, ‘outh’, ‘ĠHam’, ‘la’] |
|
32 |
15825′-back’ |
2312’ln’ |
14451’UBL’ |
-backlnUBL |
[‘ÂŃi’, ‘-back’, ‘Ġquestion’, ‘ln’, ‘ant’] |
|
40 |
15648’Ġsmile’ |
14262’Welcome’ |
1203’Ġback’ |
smileWelcome back |
[‘Ġsmile’, ‘ĠÑĥлÑĭб’, ‘Ġsmiled’, ‘ĠSmile’, ‘etwork’] |
|
48 |
15648’Ġsmile’ |
21694’ĠHi’ |
1203’Ġback’ |
smile Hi back |
[‘Ġsmile’, ‘Ġsmiled’, ‘ĠHello’, ‘Ġsmiling’, ‘Ġhello’] |
|
56 |
22691’ĠHello’ |
15960’Ġhi’ |
1203’Ġback’ |
Hello hi back |
[‘ĠHello’, ‘Ġhi’, ‘Ġsmile’, ‘Ġhello’, ‘Hello’] |
|
64 |
4773′-sm’ |
24748’Ġhello’ |
1203’Ġback’ |
-sm hello back |
[‘-sm’, ‘ĠHello’, ‘ĠSm’, ‘sm’, ‘Hello’] |
|
72 |
22691’ĠHello’ |
22691’ĠHello’ |
1203’Ġback’ |
Hello Hello back |
[‘ĠHello’, ‘Ġhello’, ‘Hello’, ‘ĠHEL’, ‘Ġhel’] |
|
80 |
271’ĊĊ’ |
9906’Hello’ |
0′!’ |
Hello! |
[‘ĊĊ’, ‘ĊĊĊ’, ‘<|end_of_text|>’, ‘ĊĊĊĊ’, ‘”ĊĊ’] |
(«Ċ» — это ещё одна особенность токенизатора, обозначающая разрыв строки. «Ġ» — это пробел.)
Аналогично, если модель хочет вывести эмодзи морского конька, то ей нужно создать скрытое состояние, схожее с вектором выходных токенов эмодзи морского конька, который, теоретически, может быть любым произвольным значением, но на практике это «seahorse + emoji» в стиле word2vec. Мы можем проверить это на примере реального эмодзи рыбы:
<|begin_of_text|><|begin_of_text|><|start_header_id|>system<|end_header_id|>
Cutting Knowledge Date: December 2023
Today Date: 26 Jul 2024
<|eot_id|><|start_header_id|>user<|end_header_id|>
Is there a fish emoji?<|eot_id|><|start_header_id|>assistant<|end_header_id|>
Yes, there is a fish emoji:
|
слой |
токены |
токены |
токен 0 |
||
|---|---|---|---|---|---|
|
|
0 |
1 |
2 |
объединённые |
(topk 5) |
|
0 |
83244’ĠBail’ |
15591’ĠHarr’ |
5309’Ġvert’ |
Bail Harr vert |
[‘ĠBail’, ‘ĠPeanut’, ‘ĠãĢ’, ‘orr’, ‘ĠâĢĭâĢĭ’] |
|
8 |
122029’chyb’ |
44465’ĠCaps’ |
15610’iller’ |
chyb Capsiller |
[‘chyb’, ‘…’, ‘ترÛĮ’, ‘ĠSund’, ‘resse’] |
|
16 |
1131’…’ |
12676’365′ |
65615’ĠSole’ |
…365 Sole |
[‘…’, ‘…Ċ’, ‘Ġboth’, ‘Ġindeed’, ‘ĠYes’] |
|
24 |
12′-‘ |
31643’ï¸ı’ |
51965’ĠJackie’ |
-️ Jackie |
[‘-‘, ‘…’, ‘â̦’, ’em’, ‘…Ċ’] |
|
32 |
1131’…’ |
96154’ĠGaut’ |
88’y’ |
… Gauty |
[‘…’, ‘â̦’, ‘…Ċ’, ‘O’, ‘u’] |
|
40 |
220’Ġ’ |
6″‘” |
7795’Ġfish’ |
‘fish |
[‘Ġ’, ‘…’, ‘â̦’, ‘Âł’, ‘u’] |
|
48 |
7795’Ġfish’ |
7795’Ġfish’ |
7795’Ġfish’ |
fish fish fish |
[‘Ġfish’, ‘ĠFish’, ‘ĠBerk’, ‘â̦’, ‘Âł’] |
|
56 |
7795’Ġfish’ |
7795’Ġfish’ |
7795’Ġfish’ |
fish fish fish |
[‘Ġfish’, ‘ĠFish’, ‘fish’, ‘Fish’, ‘é±¼’] |
|
64 |
7795’Ġfish’ |
238’IJ’ |
7795’Ġfish’ |
fish� fish |
[‘Ġfish’, ‘ĠFish’, ‘ĠPis’, ‘Fish’, ‘ĠÙħاÙĩ’] |
|
72 |
7795’Ġfish’ |
238’IJ’ |
253’Ł’ |
fish�� |
[‘Ġfish’, ‘ĠFish’, ‘ĠðŁ’, ‘Ġ’, ‘ÂŁ’] |
|
80 |
11410’ĠðŁ’ |
238’IJ’ |
253’Ł’ |
🐟 |
[‘ĠðŁ’, ‘ðŁ’, ‘Ġ’, ‘ĠĊĊ’, ‘ĠâĻ’] |
В этом случае всё работает идеально. Модель создаёт скрытое состояние «fish + emoji» — взгляните на topk слоя 72, где есть и «fish», и префикс байтов эмодзи «ĠðŁ»; это означает, что на этом этапе скрытое состояние схоже и с «fish», и с «emoji», как и можно было ожидать. Когда этот вектор передаётся в lm_head после последнего слоя, мы видим 🐟, как и ожидала модель.
Но в отличие от 🐟, эмодзи морского конька не существует. Модель пытается сконструировать вектор «seahorse + emoji», как делала бы это для реального эмодзи, и в слое 72 мы даже видим очень похожую с эмодзи рыбы конструкцию: « se», «horse» и префикс байтов эмодзи:
|
слой |
токены |
токены |
токен 0 |
||
|---|---|---|---|---|---|
|
|
0 |
1 |
2 |
объединённые |
(topk 5) |
|
72 |
513’Ġse’ |
238’IJ’ |
513’Ġse’ |
se� se |
[‘Ġse’, ‘Ġhippoc’, ‘horse’, ‘ĠðŁ’, ‘Ġhorse’] |
Но, увы, у ĠðŁ нет продолжения, соответствующего seahorse, поэтому оценка схожести lm_head вместо него выбирает максимум в виде байтов эмодзи лошади или эмодзи, связанного с морским животным, из-за чего сэмплируется не тот эмодзи, который ожидала модель.
Это сэмплирование — важная информация для модели! Это можно увидеть в примере ниже с Claude 4.5 Sonnet, где токены авторегрессивно добавляются к контексту и модель понимает, что они не образуют требуемый эмодзи морского конька. lm_head привязывает предыдущую нечёткую концепцию «seahorse + emoji» к реально существующему эмодзи, например, к тропической рыбе или лошади.

После этого модель сама решает, что делать дальше. Некоторые модели, например, 4.5 Sonnet, пробуют снова, и рано или поздно обновляют свидетельство меняя промежуточный ответ на утверждение о том, что эмодзи морского конька не существует. Другие модели, например, gpt-5-chat, ходят кругами дольше, иногда так и не восстанавливаясь. Прочие модели остаются в блаженном неведении о некорректности эмодзи, а некоторые даже мгновенно исправляют себя, увидев лишь единственный некорректный сэмпл.
Но пока модель не получит ошибочный токен вывода от lm_head, она просто не знает об ошибочности своего исходного убеждения о существовании эмодзи морского конька. Она может лишь предполагать, что «seahorse + emoji» создаст нужные ей токены.
Можно задаться вопросом, а не является ли эта проблема частью преимуществ обучения [5] с подкреплением [6] LLM — она даёт модели информацию о её lm_head, которую в противном случае было бы сложно получить, потому что он находится в конце стека слоёв.
(Надо помнить о том, что базовые модели не обучаются на своих собственных выходных данных и пробных прогонах (rollout), это происходит только при обучении с подкреплением.)
Если вы хотите попробовать самостоятельно, то начальный скрипт можно найти на Github: https://gist.github.com/vgel/025ad6af9ac7f3bc194966b03ea68606 [7]
Автор: PatientZero
Источник [8]
Сайт-источник BrainTools: https://www.braintools.ru
Путь до страницы источника: https://www.braintools.ru/article/20340
URLs in this post:
[1] логично: http://www.braintools.ru/article/7640
[2] было предложено формально: https://unicode.org/emoji/emoji-proposals-status.html
[3] поведение: http://www.braintools.ru/article/9372
[4] логитный объектив: https://www.lesswrong.com/posts/AcKRB8wDpdaN6v6ru/interpreting-gpt-the-logit-lens
[5] обучения: http://www.braintools.ru/article/5125
[6] подкреплением: http://www.braintools.ru/article/5528
[7] https://gist.github.com/vgel/025ad6af9ac7f3bc194966b03ea68606: https://gist.github.com/vgel/025ad6af9ac7f3bc194966b03ea68606
[8] Источник: https://habr.com/ru/articles/953870/?utm_campaign=953870&utm_source=habrahabr&utm_medium=rss
Нажмите здесь для печати.