Перейти к содержанию
Данные и AI

12 вопросов по теме «ML Engineering: Инференс LLM» на собеседовании

В этом материале — 12 вопросов из русской колоды RecallDeck по теме «ML Engineering: Инференс LLM». Сначала сформулируйте короткий ответ сами, затем откройте подробный разбор и проверьте примеры, ограничения и отказные случаи.

10 мин чтения12 подробных ответовПроверено 24 августа 2026
Главная мысль

Сначала зафиксируйте grain данных, допущения, метрику и риск leakage, затем обсуждайте модель, инструмент или инфраструктуру.

Вопросы и ответы

12 подробных ответов

01

Что такое KV-cache и какую проблему он решает?

Короткий ответ: KV-cache — это сохранённые по слоям матрицы K и V всех уже обработанных токенов. Без него авторегрессионная генерация на каждом шаге пересчитывала бы K и V для всего префикса — O(n²) работы на последовательность; с кэшем каждый шаг декодирования считает K, V и Q только для одного нового токена — O(n) суммарно.

Подробно:

  1. Почему это работает — K и V прошлых токенов не зависят от будущих: посчитав их один раз, можно переиспользовать на всех следующих шагах.
  2. Что кэшируется — только K и V, отдельно для каждого слоя. Q текущего токена считается заново: он нужен ровно один раз — чтобы этот токен «посмотрел» на прошлое — и никогда не переиспользуется.
  3. Цена — память: кэш растёт линейно с длиной контекста и размером батча и на длинных контекстах спорит по объёму с самими весами.
Без кэша:  шаг t → пересчитать K,V токенов 1..t   (O(t) на шаг, O(n²) всего)
С кэшем:   шаг t → K,V только токена t + чтение
           кэша токенов 1..t-1 из HBM             (O(1) вычислений, O(n) всего)

⚠️ Частая ошибка: сказать «кэшируются Q, K и V». Q не кэшируется — запрос токена используется ровно один раз, в момент его генерации.

02

Оцените размер KV-cache для 7B-модели класса Llama при контексте 4k в fp16.

Короткий ответ: ≈ 0,5 МБ на токен → при контексте 4k ≈ 2 ГБ на одну последовательность. При батче 16 это ≈ 32 ГБ — больше, чем сами веса (14 ГБ в fp16). Это каноническая арифметика LLM-инфраструктуры.

Подробно:

Формула: 2 (K и V) × n_layers × n_kv_heads × head_dim × байт/элемент.

Llama-2-7B, fp16:
  2 × 32 (слои) × 32 (KV-головы) × 128 (head_dim) × 2 Б
  = 524 288 Б ≈ 0,5 МБ на токен

Контекст 4096:  0,5 МБ × 4096 ≈ 2 ГБ на последовательность
Батч 16:        2 ГБ × 16    ≈ 32 ГБ   (веса — всего 14 ГБ)
  1. Вывод №1 — на длинных контекстах память ест кэш, а не веса: именно поэтому существуют GQA, PagedAttention и квантизация KV-cache.
  2. Вывод №2 — максимальный батч, а значит и пропускная способность сервинга, упирается в KV-память, а не в compute.

⚠️ Частая ошибка: забыть множитель 2 (K и V) или посчитать «на батч» там, где спрашивали «на последовательность».

03

Prefill и decode: почему одна фаза compute-bound, а другая memory-bound?

Короткий ответ: Prefill обрабатывает весь промпт параллельно — большие matmul, высокая арифметическая интенсивность → упирается в FLOPs. Decode выдаёт по одному токену, но на каждый шаг стримит из HBM все веса и весь KV-cache → упирается в пропускную способность памяти, а вычислители простаивают.

Подробно:

Prefill Decode
Токенов за проход весь промпт 1
Форма matmul матрица × матрица вектор × матрица
Арифм. интенсивность высокая ~1 FLOP на байт
Узкое место FLOPs (compute-bound) HBM bandwidth (memory-bound)
Что помогает chunked prefill, кэш префикса квантизация, GQA, батчинг
  1. Ключевой факт — в decode на каждый токен нужно прочитать все веса модели: скорость ≈ bandwidth ÷ размер модели в байтах.
  2. Следствие — почти каждая оптимизация инференса адресует ровно одну из двух фаз; эта асимметрия — каркас всей темы.

⚠️ Частая ошибка: оценивать скорость decode по FLOPs GPU — её предсказывает пропускная способность памяти, а не вычислительная мощность.

04

Что такое TTFT и TPOT и какие оптимизации двигают каждую метрику?

Короткий ответ: TTFT (time to first token) — от запроса до первого токена: очередь + prefill. TPOT (time per output token) — интервал между последующими токенами: скорость decode. Полная латентность ≈ TTFT + TPOT × число выходных токенов, поэтому длинные ответы почти целиком определяются TPOT.

Подробно:

Метрика Что измеряет Чем улучшать
TTFT очередь + prefill промпта кэш промпта/префикса, короче промпт, chunked prefill, приоритизация в очереди
TPOT шаг decode квантизация весов, GQA / меньший KV-cache, больше memory bandwidth
  1. Чат — пользователь ощущает TTFT («модель зависла?») и TPOT («скорость печати»).
  2. Длинная генерация — при 1000 выходных токенов TTFT почти незаметен: оптимизируй TPOT.
  3. Разные ручки — ускорение prefill не ускорит decode и наоборот; сначала измерь, какая метрика болит.

⚠️ Частая ошибка: оптимизировать «латентность вообще», не разложив её на TTFT и TPOT — и вложиться не в ту фазу.

05

Какую проблему решает PagedAttention в vLLM?

Короткий ответ: Фрагментацию памяти под KV-cache. Классический подход выделяет каждой последовательности непрерывный буфер под max_seq_len — 60–80% памяти пропадает впустую. PagedAttention режет кэш на блоки фиксированного размера и адресует их через таблицу блоков, как виртуальная память в ОС: почти вся память становится полезной, эффективный батч и пропускная способность резко растут.

Подробно:

  1. Проблема — длина ответа неизвестна заранее: резервируешь под максимум → внутренняя фрагментация; выделяешь непрерывно по факту → внешняя.
  2. Решение — KV-блоки по N токенов, физически разбросанные по HBM; логическую последовательность собирает block table (прямая аналогия страниц и page table).
  3. Бонус — общий префикс (system prompt, few-shot) хранится один раз: блоки шарятся между последовательностями с copy-on-write.
логическая seq:  [блок 0][блок 1][блок 2] …
                     │       │       │        block table
физическая HBM:    #17      #4      #52       (любые свободные блоки)

⚠️ Частая ошибка: описывать vLLM просто как «быстрый движок». Ядро выигрыша — память: больше эффективный батч → выше throughput; сам attention не становится быстрее.

06

Статический и continuous batching в LLM-сервинге: в чём разница?

Короткий ответ: Статический батч формируется целиком и живёт до конца: закончившие последовательности ждут самую длинную (head-of-line blocking). Continuous batching перепланирует состав батча на каждой итерации: завершившиеся сразу заменяются последовательностями из очереди → 2–10× по пропускной способности, утилизация GPU с ~30–40% до 80–90%.

Подробно:

  1. Корень проблемы — длины ответов авторегрессионной модели сильно разбросаны и заранее неизвестны: один ответ — 10 токенов, соседний — 800.
  2. Статический — слоты закончивших простаивают, GPU молотит padding, новые запросы ждут снаружи.
  3. Continuous — планировщик уровня итераций (Orca, vLLM): каждый шаг decode — потенциально новый состав батча.
Статический:   A ████░░░░░░ (ждёт)
               B ██████████
               C ██░░░░░░░░ (ждёт)     → новые запросы ждут снаружи

Continuous:    A ████ D ██████
               B ██████████
               C ██ E ████ F ███      → слот освободился — сразу занят

⚠️ Частая ошибка: объяснять выигрыш «просто большим батчом». Суть — в замене на каждой итерации; без неё батч любого размера страдает от head-of-line blocking.

07

Weight-only int4 квантизация (GPTQ/AWQ): почему она ускоряет именно decode и что теряется в качестве?

Короткий ответ: Decode упирается в чтение весов из HBM; int4 сжимает их в 4 раза → почти во столько же быстрее токен, хотя вычисления по-прежнему идут в fp16 после деквантизации. Плата — обычно ~1–2% на бенчмарках, заметнее на математике, коде и редких доменах.

Подробно:

  1. Механика — веса хранятся в int4, на лету деквантизируются в fp16 и умножаются: экономится трафик памяти, а не FLOPs.
  2. GPTQ — послойная квантизация с минимизацией ошибки выхода слоя (аппроксимация через Гессиан) на калибровочных данных.
  3. AWQ — по статистике активаций находит ~1% «важных» (salient) каналов весов и защищает их масштабированием, без обратного распространения.
  4. Качество — деградация неравномерна: средний бенчмарк почти не проседает, длинный хвост (math, код, редкие знания) страдает первым.
GPTQ AWQ
Идея минимизация ошибки выхода слоя защита salient-каналов
Сигнал Гессиан на калибровке масштабы активаций

⚠️ Частая ошибка: ждать такого же ускорения на prefill — он compute-bound, и экономия байтов там почти ничего не даёт.

08

Почему активации LLM квантизировать сложнее, чем веса?

Короткий ответ: Из-за выбросов: в отдельных каналах активаций значения на порядки больше остальных. Они растягивают динамический диапазон int8 так, что «нормальные» значения схлопываются в несколько уровней, и точность рушится. Веса же распределены компактно и квантизируются легко.

Подробно:

  1. Природа выбросов — в больших моделях (примерно от 6–7B) систематически возникают каналы с величинами в десятки раз больше медианных; это свойство обученных трансформеров, а не шум.
  2. LLM.int8() — смешанная точность: каналы-выбросы уводятся в отдельный fp16-путь, всё остальное умножается в int8.
  3. SmoothQuant — переносит сложность с активаций на веса: активации делятся на per-channel масштаб s, веса умножаются на s — математически эквивалентно, но оба тензора становятся «удобными» для int8.
активации по каналам:  ▁▁▁▂▁█▁▁▂▁▁█▁   ← 2 канала-выброса задают весь диапазон
после SmoothQuant:     ▂▂▂▃▂▄▂▂▃▂▂▄▂   ← диапазон выровнен, int8 хватает

⚠️ Частая ошибка: «int8 везде работает одинаково». Weight-only int8/int4 почти бесплатен; активации без обработки выбросов ломаются — и именно на больших моделях.

09

Объясните спекулятивное декодирование: как принимаются draft-токены и почему распределение выхода не меняется?

Короткий ответ: Маленькая draft-модель предлагает k токенов, целевая модель проверяет их все за один параллельный форвард. Токен принимается с вероятностью min(1, p_target/p_draft); при первом отказе новый токен сэмплируется из нормализованного (p_target − p_draft)₊. Это rejection sampling: итоговое распределение в точности равно распределению целевой модели — метод без потерь.

Подробно:

  1. Почему быстрее — проверка k токенов идёт одним форвардом с параллелизмом как в prefill; дорогих decode-шагов целевой модели становится меньше.
  2. Правило приёмки — если p_draft ≤ p_target, токен принимается всегда; иначе — с вероятностью p_target/p_draft.
  3. Коррекция при отказе — сэмпл из max(0, p_target − p_draft), перенормированного; именно этот шаг добивает математику до точного равенства распределений.
  4. Ускорение ∝ acceptance rate — чем ближе draft к target по домену и стилю, тем длиннее принятые цепочки; типично 2–3×.
draft:   t1 t2 t3 t4 t5     → target: один форвард по всем пяти
приёмка: ✓  ✓  ✗            → t1,t2 приняты, t3 пересэмплирован,
                              дальше цикл начинается заново

⚠️ Частая ошибка: назвать метод «приближённым» или «с потерями». Он даёт ровно то же распределение — жертвуется только лишний compute, не качество.

10

Нужно снизить стоимость сервинга LLM в 4 раза: квантизация, дистилляция или прунинг — как их секвенировать?

Короткий ответ: Сначала квантизация: без обучения, за часы, ~4× по памяти и заметно быстрее decode. Если этого мало — дистилляция: нужен обучающий бюджет, но она даёт лучшее качество на FLOP и меньшую архитектуру целиком. Прунинг — только структурный: неструктурная разреженность на реальных GPU почти ничего не ускоряет.

Подробно:

Метод Цена внедрения Выигрыш Риск качества
Квантизация (int4/int8) часы, без обучения ~4× память, быстрее decode ~1–2%
Дистилляция недели, GPU-бюджет меньшая модель целиком контролируемый; лучший quality/FLOP
Прунинг структурный дообучение реальное ускорение средний
Прунинг неструктурный ~0 на GPU
  1. Порядок — дешёвое и обратимое раньше дорогого: quantize → (если надо) distill → прунинг как нишевый инструмент.
  2. Методы складываются — дистиллированную модель тоже квантизуют: выигрыш от размера и от битности перемножается.

⚠️ Частая ошибка: предлагать неструктурный прунинг ради скорости — 50% нулей без аппаратной поддержки sparsity не дают почти ничего.

11

Как GQA и MQA снижают стоимость инференса и какова цена?

Короткий ответ: Они делят K/V-головы между группами Q-голов: KV-cache сжимается в n_heads/n_kv_heads раз. У Llama-2-70B 64 Q-головы и 8 KV-голов → кэш в 8 раз меньше → длиннее контексты и больше батч при той же памяти. Цена — небольшая потеря качества; обычно GQA закладывают при обучении с нуля.

Подробно:

MHA GQA MQA
KV-голов = числу Q-голов групп (напр. 8) 1
Сжатие кэша n_heads/n_kv n_heads×
Качество базовое ≈ базовое проседает заметнее
  1. Связь с формулой кэша — в 2 × layers × n_kv_heads × head_dim × bytes GQA уменьшает именно множитель n_kv_heads.
  2. Почему это про decode — на каждом шаге с HBM читается меньше кэша → ниже TPOT и больше конкурентных последовательностей.
  3. Когда применять — при обучении с нуля; конвертация готовой MHA-модели (uptraining) возможна, но требует дообучения.

⚠️ Частая ошибка: «GQA ускоряет обучение». Основной выигрыш — память и bandwidth инференса; FLOPs attention почти не меняются.

12

Один A100 80 ГБ и 13B-модель в fp16: сколько параллельных последовательностей по 2k токенов влезет и как оценить цену токена?

Короткий ответ: Веса: 13B × 2 Б ≈ 26 ГБ → под KV-cache остаётся ~50 ГБ. Для 13B кэш ≈ 1 МБ/токен → 2k токенов ≈ 2 ГБ на последовательность → ~25 конкурентных последовательностей. Дальше: суммарные токены/с и цена GPU-часа → $/1M токенов.

Подробно:

Память:   80 − 26 (веса) − ~4 (активации, буферы) ≈ 50 ГБ на KV
KV:       13B ≈ 1 МБ/токен → 2048 ток. ≈ 2 ГБ/последовательность
Батч:     50 / 2 ≈ 25 конкурентных последовательностей

Скорость: decode memory-bound → ~2 ТБ/с HBM ÷ 26 ГБ весов
          ≈ 75 форвардов/с × батч 25 ≈ ~1500–1900 ток/с (грубо)

Цена:     GPU $2/час → 2 ÷ (1700 × 3600) × 10⁶ ≈ $0.3–0.4 за 1M токенов
  1. Каркас ответа — память → батч → throughput → $/токен; интервьюер оценивает структуру Ферми-оценки, а не третий знак после запятой.
  2. Ручки — int4-веса освобождают ~20 ГБ под кэш и вдвое ускоряют чтение весов; GQA режет 2 ГБ/последовательность в разы.

⚠️ Частая ошибка: посчитать только веса и заявить «влезет много» — на реальном сервинге память съедает именно KV-cache.

Источники

Источники и редакционная политика

Материалы RecallDeck сопоставлены с официальной документацией и открытыми публикациями компаний, когда первичный источник доступен. Мы не связаны с упомянутыми работодателями, не публикуем конфиденциальные задания и не продаём места в подборках. Формат найма может меняться — уточняйте его у рекрутера.

От чтения к воспроизведению

Отрепетируйте полный цикл интервью.

RecallDeck возвращает сложные темы по расписанию и помогает удерживать в памяти язык, SQL, архитектуру и поведенческие истории.

Начать подготовку

Продолжить подготовку

Библиотека собеседований RecallDeck

Подробные русские ответы, разборы этапов найма и планы подготовки для российского IT-рынка.

RSS