Инференс LLM за один проход: архитектура Jev, KV-кэш и алгоритм RLCD

freeCodeCamp.org 35,3 тыс. 1 ч 25 мин 12 мин 27.10.2026
Главное

Современные языковые модели традиционно решают задачи классификации и принятия решений через авторегрессионную генерацию структурированного текста (например, JSON), что создает значительные накладные расходы по задержке и вычислительным ресурсам. Инженер и автор обучающих курсов Вивек Кальянаранган в материале для платформы freeCodeCamp детально разбирает концепцию Jev — архитектурного подхода, заменяющего многоэтапный декодинг одиночным прямым проходом (prefill-only) с фиксацией детерминированных вероятностей. В рамках курса рассматриваются реализации на базе как энкодеров, так и декодеров, тонкости построения кастомных масок внимания для параллельной обработки вопросов, а также алгоритмы обучения с подкреплением RLCD и GRPO.

⚡ Что такое Jev: отказ от авторегрессии в пользу Prefill-Only 1:12

Классический цикл инференса большой языковой модели состоит из двух фундаментально разных фаз: префилла (prefill) и декодинга (decode) . В фазе префилла модель параллельно обрабатывает весь входящий промпт; данная операция ограничена преимущественно вычислительной мощностью процессора или видеокарты (compute-bound) . В фазе декодинга модель генерирует ответ авторегрессионно — строго по одному токену за шаг, возвращая сгенерированный токен обратно на вход сети .

По словам Вивека Кальянарангана, если контекст задачи составляет 500 токенов, для получения ответа модель сначала прогоняет 500 токенов, затем 501, 502 и так далее, пока не упрется в стоп-токен . При решении прикладных инженерных задач — маршрутизации тикетов, классификации транзакций или скоринге рисков — такой подход приводит к двум фундаментальным проблемам:

Идея системы Jev заключается в полном исключении фазы декодинга . Вся задача формулируется таким образом, чтобы модель выдавала готовое решение за один прямой проход (single forward pass) в рамках фазы префилла . Это гарантирует строго ограниченную задержку и математически предсказуемый вывод в виде вероятностного распределения по заранее определенным категориям .

🛠️ Интерфейсы решений и требования к стеку 3:26

Архитектура Jev предоставляет разработчику унифицированный API для трех ключевых типов логических запросов :

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

Для воспроизведения рассматриваемых пайплайнов не требуется кластер GPU — весь инференс можно выполнять на CPU . Ключевыми требованиями являются уверенное владение PyTorch, понимание механизма внимания (Self-Attention), структуры KV-кэша, а также концепций логитов и Softmax . В качестве основы для разбора используются открытые предобученные модели из экосистемы Hugging Face .

🐢 Базовый уровень: почему посимвольный авторегрессионный декодинг неэффективен 8:00

Для демонстрации недостатков стандартного подхода автор разбирает сценарий антифрод-мониторинга . Модели передается контекст: с банковской карты, оканчивающейся на 4412, совершено 9 транзакций за 3 минуты в четырех странах, при этом владелец заявляет, что физическая карта находится у него в кармане .

В стандартной парадигме разработчик отправляет промпт через интерфейс, аналогичный OpenAI API или библиотеке Pydantic, ожидая JSON следующего формата :

{
  "priority": "high",
  "decision": "fraud",
  "escalate": true
}

В демонстрационном коде используется квантованная модель Qwen с 3,6 млрд параметров . Вектор входных идентификаторов промпта (включая системные инструкции и открывающую фигурную скобку {) составляет порядка 130 токенов , .

На каждом шаге авторегрессионного цикла модель вычисляет тензор логитов размерностью [1, 130, 152000], где 152 000 — объем словаря (vocabulary size) . Чтобы получить один токен, скрипт:

  1. Берет срез последнего токена [-1, :] .
  2. Применяет к вектору логитов функцию Softmax .
  3. Находит индекс с максимальной вероятностью через операцию argmax .
  4. Добавляет новый токен в конец последовательности, обновляет KV-кэш и повторяет прямой проход для вычисления следующего токена , .

Модели требуются десятки итераций только для генерации служебных символов: кавычек, двоеточий, переносов строк и названий ключей ("priority", "decision") , . На накладные расходы форматирования тратится львиная доля времени, хотя прикладной системе требовались лишь три конкретных значения .

🧩 Архитектура на базе Encoder-Only: маскирование и эмбеддинги запросов 21:24

Первая альтернатива авторегрессии — использование энкодерных моделей (семейства BERT или аналогичных маскированных языковых моделей, MLM) . Поскольку энкодер обладает двунаправленным вниманием (bidirectional attention), каждый токен видит контекст как слева, так и справа от себя .

Вивек Кальянаранган предлагает нестандартную структуру компоновки входной последовательности: вопрос ставится в самое начало, а исходный контекст (state) помещается в конец :

[CLS] Вопрос [SEP] [MASK] Вариант_A [MASK] Вариант_B [SEP] Контекст [SEP]

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

Главное ограничение энкодерного подхода связано с его двунаправленной природой . В энкодере невозможно переиспользовать кэш ключей и значений (KV-cache) для неизменного контекста: любое изменение вопроса или вариантов ответов в начале последовательности полностью пересчитывает веса внимания для каждого последующего токена . Поэтому при наличии 50 разных вопросов к одному документу энкодер вынужден заново прогонять весь контекст 50 раз .

💻 Реализация Encoder-подхода в PyTorch: от пулинга до линейных голов 25:26

В практическом разборе скрипта encoding.py демонстрируется обработка тикета службы поддержки: клиент жалуется на двойное списание за один заказ и угрожает чарджбэком через банк . Проверяется гипотеза: требует ли клиент возврат средств ("no", "yes") .

Векторизованная последовательность содержит 54 токена, а скрытое состояние (hidden state) последнего слоя имеет размерность [54, 768] . Для извлечения решения выполняются следующие математические преобразования:

Кальянаранган отмечает, что «сырая» предобученная модель BERT без дообучения выдает смещенные вероятности (например, 30% на «yes» вместо уверенного срабатывания), так как внутренние эмбеддинги не калиброваны под вероятностный вывод . Для адаптации энкодера в продакшене автор выделяет три пути :

  1. Линейная голова (Linear Head): добавление слоя Linear(768, 1) поверх скрытого состояния маски для прямого предсказания скалярного логита .
  2. Частичный Fine-Tuning: заморозка основы и обучение только классификатора .
  3. Полное дообучение (Full Backbone Fine-Tuning): сквозная оптимизация всех слоев трансформера .

🔄 Архитектура Decoder-Only: кэширование контекста и упаковка вопросов 40:42

Большинство современных LLM относятся к типу Decoder-Only (семейства Qwen, Llama, Gemma). В отличие от энкодера, каузальное (причинно-следственное) внимание позволяет зафиксировать контекст задачи в самом начале последовательности и закэшировать его в KV-кэш один раз .

Паттерн работы с декодером строится по принципу автодополнения (auto-complete) :

[Контекст документа] Вопрос: <текст вопроса>? Ответ:

После двоеточия модель должна сгенерировать ровно один токен . При расчете распределения первого токена отсекаются все 152 000 логитов словаря, кроме тех индексов, которые соответствуют целевым вариантам (например, идентификаторы слов "yes" и "no") . К оставшимся логитам применяется Softmax .

Модели декодеров способны поддерживать обработку сотен и тысяч вопросов к одному документу без повторного вычисления базового контекста . Если длина контекста модели составляет 32 000 токенов, а сам документ занимает 1 000 токенов, оставшиеся 31 000 позиций можно утилизировать под параллельные цепочки вопросов .

🎛️ Пользовательская причинная маска внимания и переиспользование KV-кэша 46:22

При попытке упаковать несколько вопросов в один контекст возникает фундаментальная проблема утечки внимания (context pollution) . Если вопрос №2 видит токены вопроса №1, итоговое решение модели начинает зависеть от порядка следования вопросов .

Кальянаранган обращает внимание на архитектурный изъян некоторых альтернативных решений (например, открытой реализации Clef от Cloudflare), где вопросы видят друг друга . В Jev применяется строгая изоляция с помощью кастомной 2D-маски видимости :

В коде decoder.py для 38 токенов контекста формируется KV-кэш: 28 слоев, 8 голо Compartment (KV-heads), скрытая размерность 128 , . Далее формируются тензоры сегментов (segments), разделяющие границы вопросов, и через операцию внешнего сравнения seg == seg.T создается маска принадлежности к одному вопросу . Объединение логического И между базовой каузальной маской (arange >= arange.T) и маской сегментов, дополненное полным доступом к токенам контекста, дает результирующую матрицу видимости размером [35, 73] для 35 токенов, формирующих вопросы , .

При вызове прямого прохода модели в PyTorch явно передаются предрассчитанный KV-кэш, позиционные индексы токенов (от 38 до 73 для корректной работы RoPE) и сгенерированная кастомная маска внимания , .

🎯 Извлечение логитов, коллизии токенов и калибровка решений 1:03:52

После выполнения прямого прохода извлекаются логиты точек принятия решений (decision points) — позиций, соответствующих последнему токену перед предполагаемым ответом , :

Проблема коллизии мультитокенов (Multi-Token Collision) 1:09:12

Если варианты ответов начинаются с одного и того же токена, наивный выбор вероятности по первому токену дает сбой . Например, в паре вариантов "fraud" и "fraud review" первый токен идентичен, и декодер не сможет разделить их вероятности за один шаг, выдав распределение 50/50 , .

Кальянаранган предлагает три способа решения коллизий , :

В энкодерах данная проблема отсутствует в принципе, поскольку токен маски привязан к конкретной позиции в предложении .

🎓 Обучение моделей: дистилляция «учитель — ученик» и GRPO 1:11:15

Хотя предобученный декодер способен решать задачи zero-shot, для достижения высокой калибровки вероятностей требуется специальный пайплайн обучения. В основе лежит схема дистилляции знаний «учитель — ученик» (Teacher-Student Distillation) .

В роли учителя выступает более мощная закрытая модель или размеченный датасет, формирующий целевое распределение вероятностей (например: 0.7 для «billing», 0.2 для «technical», 0.1 для «account») . Обучаемая компактная модель (студент) генерирует логиты (например: +1.0, +0.8, +0.2), которые после Softmax дают распределение [0.44, 0.36, 0.19] . Несмотря на сохранение рангового порядка, распределение студента нуждается в подтягивании к учителю .

Для оптимизации используется адаптация алгоритма GRPO (Group Relative Policy Optimization) из области обучения с подкреплением . Поскольку в парадигме prefill-only нет генерации длинных текстовых цепочек (траекторий), альтернативные траектории синтезируются искусственно :

  1. К базовым логитам студента добавляются различные случайные шумы (пертурбации) .
  2. Для каждого возмущенного вектора рассчитывается вознаграждение (reward) на основе близости к распределению учителя .
  3. Вычисляется среднее вознаграждение группы $\mu$ и стандартное отклонение $\sigma$ .
  4. Для каждой траектории вычисляется преимущество (Advantage) по формуле : $$A_i = \frac{R_i - \mu}{\sigma}$$

  5. Траектории с положительным преимуществом ($A_i > 0$) поощряются градиентным спуском, смещая веса студента в сторону учителя , .

📐 Функция потерь RLCD: комбинация Log Loss, Spherical Score и RPS 1:16:54

Фреймворк RLCD (Reinforcement Learning for Calibrated Decisions) опирается на комплексную функцию награды, оценивающую не просто точность совпадения меток, а математическую честность вероятностного распределения .

Награда $R$ складывается из трех ключевых метрик , :

Вивек поясняет необходимость RPS наглядным примером: клиент находится в состоянии «в ярости» . Если модель выбирает между предсказаниями «раздражен» и «спокойный», стандартный Log Loss накажет обе ошибки одинаково . Однако с точки зрения калибровки ответ «раздражен» находится ближе к истине, чем «спокойный» . Метрика RPS вычисляет среднеквадратичную разность между кумулятивными суммами распределений (CDF) студента и учителя, штрафуя далекие промахи сильнее близких :

$$\text{RPS} = \frac{1}{K-1} \sum_{k=1}^{K-1} \left( \sum_{j=1}^k p_{\text{student}, j} - \sum_{j=1}^k p_{\text{teacher}, j} \right)^2$$

Итоговая функция потерь объединяет классическую кросс-энтропию и RL-компонент : $$\mathcal{L} = \mathcal{L}_{\text{CE}} - \left( \text{LogScore} + 0.75 \cdot \text{SphericalScore} - \text{RPS} \right)$$

Оптимизацию можно проводить как на уровне легковесных адаптеров LoRA или единичных классификационных голов, так и через Full Fine-Tuning базовой сети .

⚖️ Encoder против Decoder: инженерные компромиссы и выбор архитектуры 1:23:17

В финальной части курса Вивек Кальянаранган сопоставляет сильные и слабые стороны рассмотренных подходов, формируя матрицу архитектурных компромиссов для инженера :

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

💬 Цитаты

«Что пытается сделать Jev — это полностью пропустить фазу декодинга и сжать постановку задачи в один прямой проход префилла.»

Вивек Кальянаранган 02:21

«Повторяющиеся токены в опциях — это проблема исключительно декодеров, энкодеры от нее свободны.»

Вивек Кальянаранган 1:10:24
👥 Спикер
📚 Упомянутые книги
🔗 Упомянутые сайты и проекты
📖 Термины
Prefill Phase
Начальный этап инференса трансформера, на котором параллельно обрабатывается весь входной промпт.
KV-Cache
Механизм сохранения тензоров ключей и значений предыдущих токенов для исключения повторных вычислений внимания.
GRPO (Group Relative Policy Optimization)
Алгоритм обучения с подкреплением, вычисляющий преимущество на основе относительного ранжирования группы сгенерированных траекторий без отдельной модели критика.
Ranked Probability Score (RPS)
Статистическая метрика оценки качества вероятностных прогнозов для порядковых переменных, учитывающая расстояние между ошибочными классами.
📊 Цифры
⚖️ Другая сторона
Искусственный интеллект Вивек Кальянаранган PyTorch KV-cache GRPO Hugging Face