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

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

Чего? Тогда спросим у Claude Sonnet 4.5:

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

Что здесь происходит? Возможно, Gemini 2.5 Pro справится лучше?

«Да, эмодзи морского конька есть! Seahorse»

Хм, что-то непонятное творится. Будем разбираться, в чём причина.

LLM действительно думают, что эмодзи морского конька существует

Вот ответы, которые можно получить, если сто раз спросить у множества разных моделей, существует ли эмодзи морского конька:

Существует ли эмодзи морского конька, да или нет? Ответь одним словом, без пунктуации.

  • 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 вполне логично могут предполагать (и даже обобщать) наличие такого удивительного животного. Эмодзи морского конька даже было предложено формально, но в 2018 году это предложение отклонили.

Какой бы ни была первопричина, многие LLM начинают каждое новое окно контекста со свежей ошибочной верой в существование такого эмодзи. Но почему возникает такое странное поведение? На самом деле, я и сам раньше думал, что эмодзи морского конька есть, но если бы я захотел отправить его другу, то просто посмотрел бы на клавиатуру и осознал, что его там нет, не отправил бы неправиль��ое эмодзи. Какие внутренние механизмы заставляют LLM вести себя подобным образом?

Смотрим через логитный объектив

Давайте посмотрим на этот вопрос через любимый, но недооценённый инструмент интерпретируемости — логитный объектив!

Используем префикс промпта — шаблон чата со стандартным системным промптом 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

Слой 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» создаст нужные ей токены.

Немного рассуждений

Можно задаться вопросом, а не является ли эта проблема частью преимуществ обучения с подкреплением LLM — она даёт модели информацию о её lm_head, которую в противном случае было бы сложно получить, потому что он находится в конце стека слоёв.

(Надо помнить о том, что базовые модели не обучаются на своих собственных выходных данных и пробных прогонах (rollout), это происходит только при обучении с подкреплением).

Код

Если вы хотите попробовать самостоятельно, то начальный скрипт можно найти на Github.