Перейти к содержимому
New

DeepSeek V4.1 Flash free for 7 days: 10M tokens a day after a top-up of $10 or more. Until Nov 30.

How it works

Что такое большая языковая модель (LLM)?

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

Начальный11 мин чтенияАвтор: NotHoly

Что такое большая языковая модель

Большая языковая модель (LLM) — это программа, которая на очень большом объёме текста выучила, какие фрагменты текста обычно идут за какими. Вы вводите промпт, а программа выдаёт ответ небольшими кусками, один за другим. На верхнем уровне весь механизм к этому и сводится. Дальше в статье речь о том, как такая простая задача становится полезной и где она ломается.

Слово «большая» относится к двум вещам: к объёму текста для обучения и к количеству числовых значений, параметров, которые обучение подстраивает. Слово «модель» означает, что программа присваивает последовательностям текста вероятности. Она не ищет ответы в базе данных и не хранит список фактов, с которым сверяется перед ответом. Текст она генерирует из закономерностей, усвоенных при обучении.

Если вы пользовались ИИ-чатом, вы пользовались LLM. Продукт оборачивает модель в интерфейс, добавляет инструкции, которых вы никогда не видите, и часто подключает поисковик или другие инструменты. Эта статья о самой модели внутри продукта. Когда ответ продукта выглядит неверным, полезно знать, на каком слое возникла ошибка.

Почему это важно для работы в безопасности

Работа в безопасности держится на утверждениях. Пакет безопасно ставить. Порт закрыт. Настройка отключает проверку. Уязвимость затрагивает конкретную версию. LLM пишет любое утверждение одним и тем же гладким голосом, верно оно или нет. Если не знать, как модель создаёт текст, уверенный абзац легко принять за находку.

Понимание механизма меняет три привычки. Вы перестаёте ждать от модели знаний о том, чего она никогда не видела. Перестаёте считать гладкость речи доказательством. И начинаете спрашивать, где можно проверить каждое утверждение. В NIST Generative AI Profile, опубликованном как NIST AI 600-1, конфабуляция названа среди рисков систем генеративного ИИ. Конфабуляция — это выдача уверенно сформулированного, но неверного содержания. Профиль просит организации планировать с учётом этого риска и не сбрасывать его со счётов.

Как это работает, шаг за шагом

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

Шаг 1: текст становится токенами

Модель не читает напрямую буквы или целые слова. Она читает токены: фрагменты текста, которые выбирает компонент под названием токенизатор. Токеном может быть целое слово, часть слова, пробел, знак препинания или короткая последовательность байтов. Частые слова обычно становятся одним токеном. Редкие слова, идентификаторы в коде и текст на менее распространённых языках часто разбиваются на несколько.

Токенизатор выучивает свои фрагменты на данных ещё до обучения модели. Один из распространённых методов называется byte-pair encoding, сокращённо BPE. Он начинает с отдельных символов и раз за разом сливает пару соседей, которая встречается чаще всего, пока словарь не дорастёт до заданного размера. На выходе получается фиксированный список фрагментов и правило, по которому любой новый текст на них разбивается.

Чтобы идея стала конкретнее, скрипт ниже строит крошечный BPE из нескольких слов. Это игрушка, ни в одной реальной модели такого токенизатора нет, но механизм тот же. Сохраните его как toy_bpe.py и запустите в Python 3:

python
from collections import Counter

corpus = "low low low lower lowest newer newer newer wider wider new new"
words = Counter(tuple(w) + ("</w>",) for w in corpus.split())

def pair_counts(vocab):
    pairs = Counter()
    for word, freq in vocab.items():
        for a, b in zip(word, word[1:]):
            pairs[(a, b)] += freq
    return pairs

def merge(vocab, pair):
    out = Counter()
    for word, freq in vocab.items():
        new, i = [], 0
        while i < len(word):
            if i < len(word) - 1 and (word[i], word[i + 1]) == pair:
                new.append(word[i] + word[i + 1]); i += 2
            else:
                new.append(word[i]); i += 1
        out[tuple(new)] += freq
    return out

merges = []
vocab = words
for step in range(6):
    pairs = pair_counts(vocab)
    if not pairs:
        break
    best = max(pairs, key=lambda p: (pairs[p], p))
    merges.append(best)
    vocab = merge(vocab, best)
    print(f"merge {step + 1}: {best[0]!r} + {best[1]!r} -> {best[0] + best[1]!r} (count {pairs[best]})")

def tokenize(word):
    toks = list(word) + ["</w>"]
    for a, b in merges:
        i = 0
        while i < len(toks) - 1:
            if toks[i] == a and toks[i + 1] == b:
                toks[i:i + 2] = [a + b]
            else:
                i += 1
    return toks

for w in ["lowest", "newest", "widen"]:
    print(w, "->", tokenize(w))

Вывод ниже получен при запуске этого скрипта в Windows 11 с Python 3.12.10. Ваш вывод должен совпасть построчно, потому что случайности в скрипте нет:

text
merge 1: 'r' + '</w>' -> 'r</w>' (count 6)
merge 2: 'e' + 'r</w>' -> 'er</w>' (count 6)
merge 3: 'w' + '</w>' -> 'w</w>' (count 5)
merge 4: 'n' + 'e' -> 'ne' (count 5)
merge 5: 'l' + 'o' -> 'lo' (count 5)
merge 6: 'w' + 'er</w>' -> 'wer</w>' (count 4)
lowest -> ['lo', 'w', 'e', 's', 't', '</w>']
newest -> ['ne', 'w', 'e', 's', 't', '</w>']
widen -> ['w', 'i', 'd', 'e', 'n', '</w>']

Сначала посмотрите на слияния. Самая частая пара в маленьком корпусе состоит из маркера конца слова и r, поэтому это слияние идёт первым. Более поздние слияния строят фрагменты вроде er</w> и lo, в которых видны повторяющиеся написания из корпуса. Затем посмотрите на разбиения. Слово «lowest» распадается на lo, w, e, s, t и маркер конца, потому что игрушечный словарь так и не выучил фрагмента для est или owe. Слово «widen» откатывается почти до отдельных символов. Словарь токенизатора покрывает то, что тот видел при собственном обучении, а всё остальное обходится в большее число фрагментов.

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

Шаг 2: токены становятся векторами

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

С этого момента модель работает с числами, символов она больше не видит. Букв внутри токена она не разглядывает так, как это сделали бы вы. Этим часто объясняют, почему модели иногда ошибаются при подсчёте букв в слове или проваливают простую задачку на написание. Буквы никогда не подавались модели как отдельные элементы.

Шаг 3: внимание и трансформер

Большинство современных LLM построено на архитектуре трансформера, описанной в работе Vaswani и соавторов «Attention Is All You Need», опубликованной в 2017 году (arXiv:1706.03762). Более ранние языковые модели часто читали текст токен за токеном и несли вперёд накапливаемую сводку. Трансформер даёт каждой позиции смотреть на другие позиции напрямую, с помощью механизма внимания.

Для каждого токена в контексте внимание вычисляет, какой вес придать каждому предыдущему токену при построении представления текущего. Сложите много слоёв внимания и небольших сетей прямого распространения, и модель получит подробную картину контекста. Она может связать местоимение с существительным, на которое оно указывает, сопоставить вызов функции с определением несколькими строками выше или заметить, на какую часть вопроса надо ответить.

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

Шаг 4: предсказание следующего токена

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

Возьмём фразу «Столица Франции —». Почти вся вероятность приходится на токен, с которого начинается слово «Париж». Карту модель не открывала. Она выучила, что такое продолжение очень часто встречается в текстах, которые она видела. Тот же механизм справляется и с более сложными запросами: комментарий в коде и сигнатура функции после него, сообщение об ошибке и вероятная причина, вопрос и правдоподобное объяснение. Всё это продолжения, и успех модели зависит от того, насколько выученные закономерности подходят к новому тексту.

Шаг 5: обучение

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

Обучение обычно идёт этапами. Первый этап, который часто называют предобучением (pre-training), и есть описанное выше предсказание следующего токена. На поздних этапах обычно используют примеры инструкций и хороших ответов, а иногда и обратную связь от людей, которые ранжируют ответы. Эти этапы формируют поведение модели, когда ей задают вопрос: она охотнее отвечает в полезной форме и реже продолжает разговор так, будто это веб-страница. Обучающие данные задают круг тем, на которые модель может опираться, а их дата отсечки определяет, докуда дотягивается её обучение на текстах.

Обучение стоит дорого, и занимается им разработчик модели, человек за окном чата в нём не участвует. Обычные сессии чата параметры модели не меняют.

Шаг 6: инференс

Инференс — это запуск обученной модели для получения вывода. Каждый ответ, который вы видите, получен инференсом. Параметры при этом зафиксированы. От запроса к запросу меняется только вход: системные инструкции, переписка к этому моменту, прикреплённые файлы и результаты инструментов, возвращённые в контекст.

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

Контекстное окно

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

Размеры окон различаются между моделями и меняются со временем. Смотрите актуальную документацию модели, которой пользуетесь, и не доверяйте числу из статьи, в том числе из этой. Большее окно к тому же не гарантирует, что модель лучше им воспользуется. В длинном контексте нужная деталь может потеряться, поэтому точечный промпт с нужным документом часто выигрывает у длинной кучи текста.

Температура и сэмплирование

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

Температура не определяет, верен ли ответ. Низкое значение может повторить неверное утверждение так же уверенно, как и высокое. Значение ноль тоже не гарантирует одинакового вывода в каждом деплое, потому что базовые вычисления могут различаться на разном железе и в разных версиях ПО. Если для теста нужен воспроизводимый вывод, запишите версию модели, настройки и вход и относитесь к выводу как к образцу, окончательной истиной он не будет.

Почему модели звучат уверенно и всё равно ошибаются

Уверенные неверные ответы вытекают из устройства модели, и редким сбоем их не объяснить.

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

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

Пробелы в знаниях усугубляют дело. Когда детали не хватает, модель подставляет что-то подходящее под шаблон. Конкретику вроде номеров версий, имён функций, идентификаторов CVE, ключей конфигурации и URL проще всего восстановить неверно: по форме она однотипна, но должна совпасть с конкретным фактом. NIST называет это конфабуляцией, и та же картина встречается почти в каждой генеративной системе.

Частые ошибки

  1. Воспринимать ответ как результат поиска. Модель может пересказывать реальные источники, выдумывать другие или смешивать два. Запросите источник и откройте его.
  2. Считать, что модель выполнила команду или скан, которые описывает. Если реальный вывод ей не дал инструмент, она описывает, как обычно выглядит такой запуск.
  3. Вставлять в промпт секреты, учётные данные или данные клиентов, не проверив, как сервис хранит и использует входные данные. Прочитайте политику, прежде чем вставлять что-то чувствительное.
  4. Считать один ответ последним словом о номере версии, настройке по умолчанию, юридическом вопросе или условии лицензии.
  5. Считать, что длинный контекст всегда помогает. Лишний текст может размыть нужную часть.
  6. Верить, что источник существует, раз он правильно оформлен. Авторов, названия и ссылки можно сгенерировать так, что они будут выглядеть правдоподобно.

Что это значит для работы в безопасности

Проверяйте утверждения по первичным источникам. В вопросах безопасности это обычно advisory вендора, соответствующий RFC или стандарт, официальная документация на точную версию, которой вы пользуетесь, запись CVE, публикация NIST или код в вашем репозитории. Модель помогает понять, что проверять и как это тестировать, но последней инстанцией в вопросе о том, что верно, её не считайте.

Ведите короткую запись по каждому утверждению, на которое опираетесь: утверждение, источник, дата проверки, версия, к которой оно относится. Эта привычка ловит и ошибки модели, и ваши собственные. Любую сгенерированную команду считайте черновиком, который надо прочитать перед запуском. Запускайте её только в своей лаборатории и никогда не направляйте сгенерированные шаги сканирования или эксплуатации на систему, для тестирования которой у вас нет письменного разрешения.

Что делать дальше

Прочитайте первый раздел и рисунок с архитектурой из статьи о трансформере. Чтобы увидеть контуры идеи, все уравнения не понадобятся. Затем запустите игрушечный токенизатор на своих словах и посмотрите, где он их режет. Статья Sennrich и соавторов ввела подсловные единицы, построенные с помощью byte-pair encoding, а глава курса Hugging Face разбирает алгоритм с кодом. Потом прочитайте раздел о конфабуляции в профиле NIST, чтобы увидеть, как этот риск сформулирован для организаций.

Следующая статья, Что такое LLM API, рассказывает о вызове модели из собственного кода. Именно так NotHoly открывает свои модели разработчикам, и та же привычка проверять относится к каждому ответу, полученному через API. О том, на каких утверждениях держится работа в безопасности, читайте в статье Что такое уязвимость.

Источники

Источники

  1. Attention Is All You Need (arXiv:1706.03762)
  2. Neural Machine Translation of Rare Words with Subword Units (arXiv:1508.07909)
  3. NIST AI 600-1: Generative AI Profile
  4. Byte-Pair Encoding tokenization, LLM Course

Ещё по теме: LLM-модели и API

LLM-модели и API

Verboo, Venice AI и Drael против NotHoly для задач ИБ

Verboo, Venice AI и Drael рядом с NotHoly, ноябрь 2026: оплата, формат API, условия лицензии, базы моделей и где работают инструменты, с источниками.

Средний8 мин чтения