Среди друзей я пользуюсь репутацией «ты ж программист», поэтому у меня нередко интересуются, как именно работают «под капотом» такие известные инструменты как ChatGPT, Claude, Grok или DeepSeek. Со временем я отточил ответ на этот вопрос — и потому, что нашёл способы лучше на него отвечать, и потому, что научился сам создавать большую языковую модель с нуля. Поэтому и сам понимать большие языковые модели я стал гораздо лучше.

В этой статье я попытаюсь простыми словами описать, что именно в них происходит. Пост состоит из серии объяснений, причём каждое последующее из них основано на предыдущих, но немного уточняет их. Так мы постепенно дойдём до такого объяснения, которое будет совершенно строгим и верным, но могло бы немного вас ошеломить, если выдать его без подготовки.

Если вы — технарь, и читаете эту статью, чтобы больше узнать об ИИ, то настоятельно рекомендую вам дочитать её до конца. Если вы открыли ссылку просто из интереса, то можете смело читать до тех пор, пока вам будет интересно. Возможно, вы станете более уверенно понимать, что происходит в трансформерах, даже если не уловите всех мелких деталей.

Но прежде чем отправиться в путь, отмечу: ИИ-боты — это не просто чат-боты. Многие из них являются мультимодальными — например, ChatGPT может как анализировать изображения, которые вы ему предоставите, так и генерировать картинки самостоятельно. Кроме того, у моделей есть «раздумывающий» режим, в котором они сначала взвешивают ответ, а потом выдают. Я не буду останавливаться на всех этих аспектах, а расскажу лишь о системах, предназначенных строго для обработки текста — таких, какими они были примерно в конце 2024 года. Ещё нужно сказать, что в этой статье будет рассмотрен только логический вывод (инференс). Это означает, что мы будем пользоваться имеющимся ИИ, а не заниматься его обучением, то есть, не станем создавать новую модель.

Итак, после всех этих оговорок — в путь! Для начала рассмотрим, как прогнозируется следующее слово.

Прогнозирование следующего слова

В основе ИИ-чатботов лежат большие языковые модели, БЯМ. Большинство БЯМ базируются на той или иной версии генеративных предобученных трансформеров (GPT) — данную архитектуру изобрела компания OpenAI. Отсюда, например, название «ChatGPT». При этом отметим, что устройство GPT основано на многих других разработках, например, на основополагающей статье «Всё что вам нужно — это внимание». Перевод статьи на Хабре: часть 1, часть 2.

В основе работы БЯМ лежит предсказание следующего токена. Пока давайте считать, что «токен» — это «слово» в тексте, который получила на обработку модель.

Допустим, вы скормили такой модели следующий текст:

The fat cat sat on // Толстый кот сел на

Она может спрогнозировать, что следующим словом будет «the».

Этот пример можно использовать для генерации более длинных текстов. Допустим, вы просто добавили к исходному тексту слово, спрогнозированное на предыдущем шаге, и вновь подали его на ввод модели:

The fat cat sat on the // Толстый кот сел на…

...в данном случае модель может спрогнозировать, что следующим пойдёт слово «mat» (коврик). Вот почему GPT называют «генеративным»: он генерирует текст.

Чатботы работают, всякий раз проворачивая умный фокус с этой операцией прогнозирования следующего фокуса. Предположим, вы — бот, и пользователь начинает беседу с вами с вопроса «Какой город — столица Франции?» Вы вставляете этот вопрос в шаблон и скармливаете вашей БЯМ. В ответ получаете нечто подобное:

(Далее следует начало транскрипта беседы между пользователем, «User» и ИИ-ботом «Bot» в переводе на русский язык. Бот услужлив и дружелюбен)

User: What is the capital of France? // Какой город — столица Франции?

Bot:

…после чего боту поручается спрогнозировать следующее слово. Помните, что БЯМ будет рассматривать весь текст целиком, после чего попытается логически заключить, какое слово с наибольшей вероятностью последует за уже имеющимися в данном конкретном контексте.

Он может предложить слово «The» — в конце концов, вполне разумный выбор для воображаемого бота в этом транскрипте, как раз то слово, с которого стоит начинать ответ. Вы подадите боту на вход весь имеющийся текст, присовокупив к нему это «The», и бот может предположить, что далее должно идти слово «capital» (столица). Повторяйте этот процесс снова и снова, и постепенно вы можете добиться от бота ответа, который заканчивается на: «of France is Paris. Is there anything else I can help you with?» (…Франции — Париж. Могу ли ещё чем-нибудь быть вам полезен?).

Но на этом останавливаться совершенно не обязательно. Бот прогнозирует развитие транскрипта, поэтому далее он предложит «User:» и будет пытаться угадать, о чём пользователь попробует спросить его далее. Таким образом, после спрогнозированного токена «User:» вы должны остановить бот и передать управление беседой тому пользователю, который с ним работает, так, чтобы пользователь мог сформулировать следующий вопрос.

Когда пользователь введёт свой вопрос и щёлкнет мышью кнопку для отправки этого текста чатботу, мы должны возобновить процесс прогнозирования. БЯМ не запоминает всех разговоров — она всякий раз начинает работу со свежим текстом с нуля, пытаясь логически вывести, каков может быть следующий токен. Поэтому мы предоставляем БЯМ весь транскрипт, имеющийся у нас на данный момент — зачин, предыдущий вопрос пользователя и ответ бота, новое сообщение от пользователя и, наконец, токен «Bot:». Получив его, БЯМ знает, что далее нужно генерировать новый ответ бота.

Те БЯМ, которыми мы пользуемся в повседневной практике, в сущности, делают именно это. Конечно же, многие детали отличаются (например, в том, что БЯМ обучаются на тысячах транскриптов), и кроме того есть многие другие достижения, но суть именно такова.

Итак, что же представляют собой эти БЯМ? Большую языковую модель получают, настроив глубокую нейронную сеть. В простейшем приближении, это программа, имитирующая при работе принцип действия человеческого мозга. Но для БЯМ нужны глубокие нейронные сети особого класса, так называемые «трансформеры». После этого их обучают на колоссальном объёме данных — например, на корпусе всех текстов, содержащихся в Интернете. Эти тексты из Интернета скачивают и (до какой-то степени) подчищают.

Модель начинается с большого количества случайных чисел, управляющих тем, как работает сеть (они называются параметрами или весами — такие модели как ChatGPT оперируют сотнями миллиардов параметров). Далее мы показываем модели текст, а она уточняет эти числа, и в результате всё лучше и лучше прогнозирует, какое слово должно идти следующим. Этот этап (что весьма логично) называется обучением, точнее предобучением, которому как раз соответствует «P» в аббревиатуре GPT. 

Бывает и постобучение — этап, когда вы постфактум предлагаете модели информацию на нужную тему, чтобы нейросеть лучше справлялась с поставленной задачей. Например, если вы обучали модель на текстах общего содержания из Интернета, а затем показываете ей набор транскриптов из разных чатов, чтобы она специализировалась на их автозавершении. Так вы сделаете хороший чатбот.

Подытоживая уже сказанное, вот наше первое рабочее описание процесса: БЯМ получает на вход некоторый текст и определяет, какое слово с наибольшей вероятностью будет в этом тексте следующим. В данном случае полезно, что мы можем подцепить это слово к оригинальному тексту — и повторить процесс, продолжая наращивать текст. Далее эту модель можно превратить в чатбот, который попытается дополнить транскрипт беседы между ботом и пользователем. В рамках транскрипта мы сообщим боту и реальные сообщения, полученные от пользователя, и все более ранние ответы, сгенерированные ботом в пределах этого транскрипта.

Токены

В естественном языке (например, в английском) очень много слов, и мы, конечно же, не хотим, чтобы наша БЯМ «держала в уме» их все. Также мы не хотим ограничиваться английским, поскольку было бы удобно обрабатывать произвольный материал. Например, если в качестве вопроса пользователь введёт skjflksdjflsdfjsd, то нас не устроит отказ модели по причине «неизвестное слово».

Таким образом, будем разбивать наш текст на токены. Токены — это последовательности символов, которые часто фигурируют в учебных данных. Токенов бывает достаточно много. Например, токенизатор, созданный компанией OpenAI для версии 2 оригинального GPT учитывает список из 50 000 токенов! Таким образом (как минимум, в английском), свои токены будут у большинства коротких слов. При применении токенизатора GPT-2 последовательность «The fat cat» подразделяется на три следующих токена:

'The', ' fat', ' cat'

Эквивалент этой последовательности на португальском «O gato gordo» (пожалуй, не так часто встречающийся в учебных данных, как английский) делится уже на большее количество токенов:

'O', ' g', 'ato', ' g', 'ord', 'o'

Независимо от языка, длинные и сравнительно редкие слова будут делиться на разные токены. Например, фраза «Pseudoscientists prevaricate habitually» (псевдоучёные обычно выражаются уклончиво) в GPT-2 содержит такие токены:

'P', 'se', 'udos', 'cient', 'ists', ' pre', 'var', 'icate', ' habit', 'ually'

(В данном случае можно отметить, что там, где это необходимо, токены включают пробелы между словами — например, 'fat' и ' fat' соответствуют разные токены. В рамках этого поста лучше считать, что «и так тоже бывает»).

БЯМ содержит словарь всех различных токенов, которые ей известны. Так, для GPT-2 это словарь на 50 000 токенов. Это распространённые слова или фрагменты слов плюс все буквы алфавита (в том числе, «специальные» символы, например, «é»), при помощи которых модель может «проговаривать» понятия буква за буквой, если получит на вход нечто необычное. Токенизатор присваивает каждому токену числовой ID. Например, токены в приведённой выше фразе «The fat cat» в GPT-2 имеют ID 464, 3735 и 3797 соответственно.

Итак, вот как можно немного конкретизировать, что именно делает БЯМ: она получает список из ID токенов, соответствующих тому тексту, который мы хотим обработать, и прогнозирует ID того токена, который с наибольшей вероятностью пойдёт следующим.

Логиты и вероятность

Естественно, найдётся достаточно много различных токенов, один из которых может следовать «The fat cat sat on the». Например, вполне подходит «desk» (стол):

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

БЯМ необходимо это отразить. Поэтому она не просто выдаёт спрогнозированный следующий токен, а выводит вектор (т.е., список) чисел, по одному для каждого токена, содержащегося в её словаре. Чем выше n-я позиция конкретного числа в этом списке, тем вероятнее с точки зрения модели, что токен с ID n пойдёт следующим.

«The fat cat sat on the mat» (толстый кот сел на коврик) — это клише, которое, вероятно, многократно встречалось модели в процессе обучения на огромном наборе текстов, поэтому позиция того ID, который соответствует токену «mat», будет в этом векторе очень высокой. Но и вариант «desk» вполне вероятен, поэтому и ID этого токена будет занимать достаточно высокую позицию. С другой стороны, вариант «eat» весьма маловероятен (английская фраза «The fat cat sat on the eat» не имеет смысла), поэтому позиция будет гораздо ниже.

Числа, соответствующие этим позициям, называются логитами. Это специфический термин из области нейронных сетей, в сущности, означающий «числа, выведенные в ИИ по такому принципу, что, если нормализовать их по определённому принципу, то их можно будет осмыслить как вероятности».  

Продолжая уточнять картину, отметим, что БЯМ получает список ID токенов, которые в совокупности соответствуют тому тексту, что мы хотим обработать, а на выход даёт набор логитов: по одному числу для каждого токена в словаре. Каждый логит характеризует, с какой вероятностью именно этот токен будет следующим.

Возвращаемся к примеру с чатботом: при каждой итерации можно просто выбирать наиболее вероятный токен, но на практике полезно внести в работу модели толику случайности. Да, выбор мы будем делать, исходя из вероятностей, так что в большинстве случаев коты у нас будут сидеть на ковриках, но иногда станут присаживаться на стол или на колени к хозяину, а изредка могут сидеть и на собаках. С другой стороны, грамматически некорректные конструкции (как приведенный выше пример со словом «eat») попадаться не будут, так как вероятность для подобного токена очень низкая.

В прогнозе нужно учитывать ВСЕ токены!!!

Картина ещё не совсем точна, но мы близки к цели. Ещё один нюанс заключается в том, что БЯМ не просто предсказывает следующий токен для последовательности слов в целом. Напротив, для каждого токена, который мы предоставляем ей во входной последовательности, она будет прогнозировать следующий на основе не только предыдущего, но и всех тех, которые ему предшествуют.

Например, если мы предоставим ей «The fat cat sat on the», то она (параллельно) рассчитает следующий токен с учётом всех нижеприведённых последовательностей:

  • «The»

  • «The fat»

  • «The fat cat»

  • «The fat cat sat»

  • «The fat cat sat on»

  • «The fat cat sat on the»

Итак, мы подаём модели на вход последовательность токенов, а она выдаёт в ответ последовательность векторов, состоящих из логитов — по одному вектору для каждого токена, поступившего на вход. Логиты для каждого токена — это прогнозы последующих токенов, выстраиваемые на основе текста, имеющегося вплоть до рассматриваемого токена включительно. Давайте это немного конкретизируем.

При прогнозировании токенов для первого из выражений, приведённых выше (в составе которого есть только «the») очень много вариантов продолжения — по одному для каждого слова, которое может идти после «the». Поэтому в векторе логитов будет множество вариантов с высокими баллами — это может быть как «cat» (кот), так и с не меньшим успехом «dog» (собака) или «naming» (наименование).

Вторая последовательность, «The fat», предполагает чуть более чётко очерченное множество вариантов, поскольку характеристика «толстый» применима к ограниченному набору сущностей, но всё равно вероятность «man» (мужчина) или «controller» (контроллер) остаётся весьма высока.

Аналогично, и во всех других последовательностях будут варианты, но, как правило, чем длиннее подаваемая на вход последовательность, тем явственнее она будет «сходиться» к конкретному варианту завершения. Поэтому, когда требуется спрогнозировать логиты для полной последовательности, она выглядит очень похоже на узнаваемое клише, поэтому разброс вариантов будет отчётливо тяготеть к центральному токену «mat».

При использовании БЯМ в стандартном для неё режиме прогнозирования следующего токена может показаться, что все эти дополнительные предсказания избыточны — ведь мы проигнорируем все векторы логитов кроме последнего, в котором содержатся прогнозы для полной последовательности. Но прогнозы для сокращённых последовательностей, в сущности, являются побочным продуктом при предсказании следующего токена для последовательности в целом. Впустую ресурсы здесь почти не тратятся.

А на этапе обучения БЯМ этот побочный продукт даже по-своему полезен, так как вы сообщаете ей на вход последовательность ID токенов, соответствующих «The fat cat sat on the», и при этом указываете, что в качестве вывода хотите получить последовательность «fat cat sat on the mat». То есть, входная последовательность сдвинется на один токен вперёд. Модель усвоит, что «fat» — логичное продолжение для последовательности из одного токена «The», что «cat» — хорошее продолжение для «The fat» и т.д. 

Итак, последние штрихи к рассказу о внутреннем устройстве БЯМ. Большая языковая модель получает на вход последовательность ID токенов, которые складываются в тот текст, что мы хотим обработать. На выход она выдаёт последовательность векторов логитов, по одному логиту на каждый токен из входной последовательности. Логиты для каждого токена — это прогноз, что будет дальше, основанный только на токенах от начала последовательности и вплоть до последнего имеющегося токена включительно.  

При программировании чатбота мы просто отбрасываем все их кроме последних и выводим наиболее вероятный следующий токен для продолжения целой последовательности, основываясь на имеющихся логитах.

Вот и всё!

Теперь вы во всеоружии. Вы знаете, какая информация поступает в большую языковую модель, написанную в стиле GPT, какая информация из неё выходит, и как, опираясь на эти знания, написать чатбот.

Если вы прочитали эту статью просто для общего развития — надеюсь, что она в самом деле получилась интересной. Добро пожаловать в комментарии к автору — может быть, что-то осталось неясным или запутанным? Либо он чрезмерно всё разжевал, а здесь всё и так понятно и очевидно?

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

Спасибо Майклу Манжиону и Рикардо Гимарайнсу за комментарии к ранним версиям этой статьи.

Комментарии (2)


  1. Wesha
    21.10.2025 18:12

    как именно работают «под капотом» такие известные инструменты как ChatGPT

    В двух словах: перемножают матрицы

    В пяти словах: подбирают наиболее подходящий следующий токен.


  1. ioleynikov
    21.10.2025 18:12

    К сожалению в статье ничего не сказано про эмбеддинги, которые являются ключом реализации всех нейросетевых алгоритмов NLP. Без четкого понимания сути и смысла дистрибутивного представления сложных сущностей и понятий в векторном виде постичь, что делается "под капотом" ChatGPT не возможно !