Экономика инференса · P/D-дисагрегация

Разделять ли prefill и decode? Математика стоимости инференса

Дисагрегацию продают как способ развести две фазы инференса, чтобы они не мешали друг другу. Но облачному провайдеру важно другое: сколько GPU-часов уйдёт на тот же поток запросов. Мы построили простую модель из ресурсов, узких мест и упаковки и проверили, когда раздельные пулы экономят деньги, а когда только оставляют железо простаивать.

Коротко
  • На одном типе GPU раздельные пулы не могут быть дешевле совместного, пока фазы не мешают друг другу сильнее, чем если бы шли по очереди. Это следует из того, что prefill и decode упираются в разные ресурсы: при разделении каждый пул недоиспользует то, что нужно другому.
  • Платить за разделение стоит по двум причинам: специализация и синхронизация. Раздельный пул может работать иначе: в другой конфигурации параллелизма, с другим размером батча, на другом железе. Если это ускоряет его в s раз, разделение окупается при s > (1+ρ)/(1+θρ). А если помехи θ больше единицы, как в wide-EP, разделение окупается и без специализации. Буквы объясняем ниже.
  • Баланс фаз задаёт не cache hit, а отношение некэшированного входа к выходу. На наших замерах GPU делает prefill примерно в 12 раз быстрее, чем decode. Поэтому агент с hit 90% всё ещё почти сбалансирован, и только при ~99% prefill становится мелочью.
  • Крупный MoE на стойке — особый случай. Wide-EP decode синхронизирует десятки GPU на каждом слое, и вставка prefill тормозит их все. Там разделение выигрывает за счёт специализации, а не за счёт «отсутствия помех».
  • При высоком cache hit архитектура почти не важна. Стоимость определяют объём и полоса HBM, время жизни KV в памяти и маршрутизация, которая возвращает сессию к её кэшу.

01 · ВОПРОССначала утверждение, потом вопрос «а дешевле ли?»

Работа языковой модели над запросом делится на две фазы. Сначала модель читает весь промпт (prefill), затем пишет ответ по одному токену (decode). Распространённый совет: выделить под фазы разные GPU, чтобы длинный промпт одного пользователя не замедлял генерацию у остальных. Так задержки становятся ровнее. Это и называют дисагрегацией, или P/D.

С задержкой совет работает. Но провайдер продаёт токены, а платит за GPU-часы. Он старается переиспользовать как можно больше KV-кэша: всё, что уже посчитано, не пересчитывать. Агентские сессии с длинным контекстом и короткими добавками доводят долю переиспользования до 90–99%. Тогда prefill-работы становится мало, и отдельный prefill-пул рискует простаивать. В общем же пуле достаточно масштабировать один ресурс — тот, которого не хватает.

В этой статье мы строим модель, которая отвечает на вопрос количественно. Это та же задача, что и в классическом планировании кластеров, где серверы упаковывают по CPU и памяти. У задач разные профили ресурсов, у машин есть ёмкость по каждому ресурсу, а простаивающая часть железа стоит денег. Термины, которыми мы пользуемся (prefill, decode, KV-кэш, cache hit, HBM, SLO), собраны в словаре в конце статьи.

02 · ДВЕ ФАЗЫЧто потребляет каждая фаза

Зачем об этом думать: всё дальнейшее строится на том, что фазы едят разное. Prefill — это большие матричные умножения, где каждый прочитанный из памяти байт весов используется для тысяч токенов сразу. Decode на каждом шаге читает те же веса ради одного токена в каждой последовательности батча. Поэтому одна и та же GPU обрабатывает на prefill на порядок больше токенов в секунду, чем выдаёт на decode.

загрузка ресурсов GPU по фазамиллюстрация

Prefill

Весь промпт одним проходом

вычисления
полоса HBM
объём HBM
упирается в арифметику · ≈ 82K ток/с на GPU

Decode

Один токен за шаг для каждой последовательности

вычисления
полоса HBM
объём HBM
упирается в память · ≈ 6,9K ток/с на GPU
Длины полос — иллюстрация, а не профилировщик. Скорости в нижней строке — наши замеры DeepSeek-V4.1-Flash-1017 на 8×B300 в vLLM: prefill 658K ток/с на узел для промптов 8K и decode 55K ток/с на узел для 1K → 1K при 2048 одновременных запросах, всё делённое на 8 GPU.

Из этих двух замеров получается главная константа статьи. Обозначим её κ (каппа): во сколько раз GPU быстрее делает prefill, чем decode. У нас κ ≈ 82K / 6,9K ≈ 12. Иначе говоря, один выходной токен стоит GPU-времени примерно как 12 некэшированных входных.

Что это значит. Фазы не конкурируют за один и тот же ресурс. Prefill загружает арифметику и оставляет простаивать полосу памяти. Decode загружает полосу и объём памяти и оставляет простаивать арифметику. Такие нагрузки выгодно упаковывать вместе.

03 · УЗКОЕ МЕСТОРесурсы как векторы: закон узкого места

Зачем нужна модель: без неё спор «вместе или раздельно» сводится к сравнению графиков из разных статей. Модель позволяет увидеть, откуда берётся выигрыш, и посчитать его на своих числах.

Опишем каждый класс запросов (RAG, reasoning, агент) вектором ресурсов: сколько секунд работы одной GPU он отнимает по каждому ресурсу. Ресурсов четыре:

Каждая GPU даёт за секунду ровно одну «GPU-секунду» каждого ресурса. Тогда число GPU, необходимое для потока, в идеальной упаковке (без очередей и всплесков) равно:

N = maxrΣj λj · aj,rCr

Здесь j — класс запросов, λj — сколько таких запросов в секунду, aj,r — сколько ресурса r нужно одному запросу, Cr — сколько ресурса r даёт одна GPU. Максимум берётся по ресурсам: флот определяется ресурсом, которого не хватает. Остальные ресурсы куплены, но частично простаивают.

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

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

04 · ТЕОРЕМАПочему на одном типе GPU раздельно не дешевле

Обозначим суммарную потребность prefill-фазы в каждом ресурсе как Pr, а decode-фазы как Dr. Монолит покрывает сумму потребностей, раздельные пулы на тех же GPU — каждую фазу по отдельности. Максимум суммы не больше суммы максимумов, поэтому:

Nвместе = maxrPr + DrCr
Nраздельно = maxrPrCr + maxrDrCr
Nраздельно ≥ Nвместе · равенство, только если у обеих фаз одно узкое место

У prefill узкое место — вычисления, у decode — память. Поэтому при одинаковом железе раздельные пулы всегда оставляют больше ресурсов простаивать. В лучшем случае совместный пул обходится вдвое дешевле: это происходит, когда обе фазы нагружают GPU одинаково.

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

Что это значит. Дисагрегация сама по себе не экономит GPU. Если она где-то экономит, источник экономии — в чём-то другом, и его надо назвать явно.

05 · ПОМЕХИθ: насколько фазы на самом деле мешают друг другу

Зачем вводить ещё одну букву: она переводит слово «интерференция» в число, которое можно измерить. Когда движок кладёт в один шаг и decode, и кусок чужого prefill (это называют chunked prefill), шаг длится дольше, чем чистый decode. Опишем длительность такого шага так:

T = max(Tвыч, Tпам) + θ · min(Tвыч, Tпам)

Tвыч — сколько шаг занял бы, если бы упирался только в арифметику, Tпам — только в чтение памяти. Коэффициент θ (тета) неотрицателен. При θ = 0 работа одной фазы полностью прячется в простое другой: prefill «едет зайцем» на decode. При θ = 1 фазы выполняются строго по очереди, как если бы GPU делила время между ними. θ может быть и больше единицы: так бывает, когда движок синхронизирует много GPU на каждом шаге, и кусок prefill на одной из них задерживает все остальные (раздел 07). Тогда совместный шаг длится дольше, чем две фазы по очереди.

Теперь нормируем нагрузку. U — сколько GPU понадобилось бы, если бы они делали только prefill всего потока. V — то же для decode. Тогда:

Nвместе = max(U, V) + θ · min(U, V)
Nраздельно = U + V
сколько prefill и decode успевает одна GPUквадрат против хорды
0 0 0,5 0,5 1 1 prefill, доля от максимума GPU decode, доля от максимума GPU склейка, θ = 0: весь квадрат θ = 0,5 раздельные пулы = склейка при θ = 1 нагрузка (0,6; 0,6)
Оси — доля от того, что GPU успевает, занимаясь только одной фазой. Раздельные пулы дают прямую: каждая GPU делает либо одно, либо другое. Идеальная склейка (θ = 0) — весь квадрат: GPU делает максимум обеих фаз сразу. Реальная склейка лежит между ними. Белая точка — нагрузка (0,6; 0,6): одной совместной GPU с малым θ её хватает, раздельным пулам нужно 1,2 GPU.

Чему θ равен на практике? Лучшая известная нам точка — работа «Not All Prefills Are Equal» (PPD, 2026): Llama-3.1-8B на одной H100, prefill 1 024 токена. При батче 200 полный prefill нового промпта увеличил время шага decode (TPOT) на 48%, а короткая добавка к уже закэшированному контексту — всего на 2%. Значит, θ зависит от вида prefill: для коротких добавок агента он близок к нулю, для длинных холодных промптов — большой.

Что это значит. Холодные длинные промпты действительно мешают decode, и их стоит увести. Короткие добавки к тёплому контексту выгоднее оставлять на decode-GPU рядом с их кэшем. Так устроен гибридный подход PPD и разделение cold/warm prefill у Together AI.

06 · СПЕЦИАЛИЗАЦИЯs: первая причина платить за разделение

При s = 1 формулы выше всегда говорят «вместе». Раздельные пулы могут выиграть только тогда, когда каждый из них работает эффективнее, чем работал бы в общем пуле. Обозначим этот выигрыш s: во сколько раз специализированный пул быстрее на своей фазе. Откуда он берётся:

Последняя буква — ρ (ро), баланс фаз: меньшее из U и V, делённое на большее. ρ = 1 означает, что фазы требуют поровну GPU, ρ → 0 — что одна фаза почти исчезла. Сравнив U/s + V/s с формулой для монолита, получаем условие (для простоты считаем, что оба пула выигрывают одинаково; в общем виде раздельная схема стоит U/sP + V/sD, и sP может оказаться меньше единицы):

раздельно дешевле, если s > 1 + ρ1 + θ·ρ
граница решения для нескольких θs = (1+ρ)/(1+θρ)
0,8 1,0 1,2 1,4 1,6 1,8 2,0 0 0,25 0,50 0,75 1 ρ — баланс фаз: 0 = одна фаза, 1 = поровну s — выигрыш специализации θ = 0 θ = 0,25 θ = 0,5 θ = 1 θ = 1,5 (wide-EP) выше своей кривой — дешевле раздельно ниже — дешевле вместе
Для каждого θ своя кривая. Над кривой раздельные пулы дешевле, под ней дешевле общий пул. При θ = 1 кривая — горизонталь s = 1, и разделение окупается при любой специализации. При θ > 1 (это случай wide-EP, раздел 07) кривая опускается ниже единицы: разделение выгодно, даже если пулы ничем не лучше.

Что видно на карте:

Что это значит. Аргумент «развести, чтобы не мешали» относится к задержкам. Для стоимости вопрос другой: даёт ли специализация пулу выигрыш s, превышающий потерю от худшей упаковки. Карта показывает, сколько именно нужно выиграть.

07 · КРУПНЫЙ MoEПочему DeepSeek-класс всё-таки разделяют

Зачем отдельный раздел: крупные провайдеры моделей вроде DeepSeek запускают их именно с дисагрегацией, и модель должна это объяснять. Сначала два термина.

MoE (mixture of experts) — модель, в которой каждый слой состоит из сотен «экспертов», а каждый токен проходит только через несколько из них. Expert parallelism (EP) — раскладка, при которой эксперты распределены по GPU, и на каждом слое токены пересылаются туда, где лежат их эксперты. Wide-EP — то же самое на десятках GPU: на каждую приходится меньше экспертов, поэтому на шаге decode она читает меньше весов.

узел против стойки: где лежат экспертыDeepSeek-V4.1-Flash
Один узел · 8×B300 · DEP8 общий пул: prefill и decode на одних GPU attention 48 эксп. attention 48 эксп. attention 48 эксп. attention 48 эксп. attention 48 эксп. attention 48 эксп. attention 48 эксп. attention 48 эксп. NVSwitch · all-to-all на каждом MoE-слое каждая GPU: своя копия attention, свой KV-кэш и 48 из 384 экспертов; на каждом шаге 8 рангов ждут друг друга Стойка · GB300 NVL72 · 72 GPU раскладка vLLM 8P1D · один NVLink-домен prefill · 8 инстансов DEP2 · 16 GPU 192 эксперта на GPU, без резервных decode · 1 инстанс DEP32 · 32 GPU 12 экспертов на GPU + резервные от EPLB 24 GPU в этом бенчмарке не заняты Сколько экспертов читает одна GPU на шаге decode 384 маршрутизируемых + 1 общий на слой · 6 на токен · чем шире EP, тем меньше весов на GPU DEP2 192 prefill DEP4 96 MoE-часть шага 13,4 мс DEP8 48 наш узел DEP32 12 MoE-часть шага 6,0 мс время MoE-части — пост vLLM, GB200, 64 запроса на GPU, контекст 128K · остальная часть шага ≈ 10 мс
Слева — наш узел: восемь копий attention, у каждой свой KV-кэш и 48 из 384 экспертов; на каждом MoE-слое токены едут к своим шести экспертам через NVSwitch и обратно. Справа — раскладка vLLM на стойке GB300 NVL72 в конфигурации 8P1D: восемь prefill-инстансов по 2 GPU и один decode-инстанс на 32 GPU, остальные 24 GPU в этом бенчмарке свободны. Чем шире EP, тем меньше экспертов и весов на GPU за шаг decode — и тем больше GPU ждут самую медленную.

Итак, для DeepSeek-класса на стойке θэфф > 1 и s заметно больше единицы. Обе причины толкают к разделению. Но это выигрыш специализации и синхронизации, а не следствие слогана «фазы мешают друг другу».

На одном узле из 8 GPU выбор другой, хотя помехи есть и там. Наш замер на 8×B300 показал, что vLLM в одной общей конфигурации DEP8 даёт 658K ток/с prefill и 55K ток/с decode, а на смеси 8K → 1K тот же узел выдаёт 29,5K ток/с decode, тратя 36% prefill-мощности. Если decode на 8K-контексте не медленнее, чем на 1K, из этих чисел по формуле раздела 05 получается θ ≈ 1,3: восемь рангов DEP8 синхронизируются так же, как тридцать два. Но разделить такой узел на 2 GPU для prefill и 6 для decode значило бы потерять wide-EP с обеих сторон, то есть получить s < 1 на decode. Здесь разделение проигрывает не потому, что помех нет, а потому, что специализация на 8 GPU невозможна.

Что это значит. Дисагрегация — это инструмент масштаба. Она окупается там, где decode-инстанс занимает десятки GPU. Для одного узла, плотной модели или небольшого MoE базовый выбор — общий пул с chunked prefill.

08 · ПРИМЕРТри типа нагрузки на одних числах

Зачем пример: увидеть, как формулы ведут себя на реалистичных размерах запросов. Скорости GPU взяты из нашего замера (82K ток/с prefill и 6,9K ток/с decode на GPU, KV 3 309 байт на токен, 160 GiB под KV на GPU). Сами нагрузки — иллюстрация:

GPU на поток, идеальная упаковкаиллюстрация на наших скоростях
вместе, θ = 0,2 вместе, θ = 0,5 раздельно, s = 1 RAG ρ = 0,30 15,5 16,8 19,0 Reasoning ρ = 0,01 11,6 11,7 11,7 Агент, hit 90% ρ = 0,84 6,8 8,2 10,7 Агент, hit 99% ρ = 0,08 5,9 6,0 6,3 Смесь трёх ρ = 0,90 25,7 31,6 41,4
Монолит при θ = 0,2 и 0,5 против раздельных пулов без специализации. ρ — баланс фаз каждого сценария. В таблице ниже — векторы ресурсов и необходимый выигрыш специализации s*.
Векторы ресурсов и порог s* по сценариям
СценарийВычисленияПолоса HBMОбъём HBMρВместе θ=0,2Вместе θ=0,5Раздельно s=1s*, θ=0,2…0,5
RAG14,64,30,20,3015,516,819,01,13…1,22
Reasoning0,111,60,40,0111,611,711,71,01…1,01
Агент, hit 90%4,95,83,20,846,88,210,71,30…1,58
Агент, hit 99%0,55,83,20,085,96,06,31,04…1,07
Смесь RAG + reasoning + агент 90%19,621,73,80,9025,731,641,41,31…1,61

Числа — GPU-эквиваленты в секунду. Decode-пул упирается в больший из двух ресурсов HBM. s* — во сколько раз должны ускориться пулы, чтобы раздельная схема сравнялась с общей.

Формула баланса проста:

UV = некэшированный входвыход · 1κ · фазы уравновешены, когда некэшированного входа в κ раз больше, чем выхода

Посчитайте на своих числах

GPU вместе
GPU раздельно
баланс фаз ρ

Калькулятор считает по формулам выше с нашими скоростями GPU (82K и 6,9K ток/с, шаг decode 29 мс, как в замере 1K → 1K) и идеальной упаковкой: без очередей, запаса и ограничения на размер инстанса. Варианты KV: DeepSeek-V4.1-Flash (FP8), GLM-5.3-Flash (BF16), условная промежуточная точка и плотная 70B-модель с GQA (BF16). Скорости prefill и decode при этом не меняются — это сознательное упрощение, чтобы был виден эффект одного объёма KV.

Что это значит. Смотреть надо не на cache hit, а на отношение некэшированного входа к выходу. Сравните его с κ на вашем железе — так вы поймёте, в каком углу карты из раздела 06 находится ваш поток.

09 · ЦЕНЫТеневые цены: сколько на самом деле стоит токен каждой фазы

Зачем: провайдер выставляет разные цены за вход, кэшированный вход и выход. Модель показывает, сколько эти токены стоят ему самому.

Выбор флота — задача линейного программирования. Есть набор возможных конфигураций (железо × роль × параллелизм × политика батча), у каждой своя цена за час и своя производительность по prefill и decode. Нужно покрыть спрос минимальной суммой. У такой задачи есть два полезных свойства:

Сравним с прайсом. Публичные цены DeepSeek на V4.1-Flash: $0,30 за 1M некэшированных входных токенов, $0,006 за кэшированные, $1,20 за выходные. Если взять условные $9,50 за GPU-час и наши скорости при полной загрузке, вычисления стоят около $0,03 за 1M prefill-токенов и около $0,38 за 1M decode-токенов. Иллюстрация: без запаса под пики, SLO и простои.

Что это значит. Цена кэшированного входа — это цена хранения, а не вычислений. Экономика агентского инференса определяется тем, где и сколько лежит KV, а не тем, разделены ли пулы.

10 · ЗАПАС И ДРЕЙФЧто теряется на реальных, неровных нагрузках

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

Отсюда практичный вариант — гибкие роли: узлы с одной моделью, которые переключаются между prefill и decode, когда меняется смесь. Цена переключения — время рестарта движка с другим профилем. Для DeepSeek-V4.1-Flash на 8×B300 холодный старт vLLM занимал у нас 930 с, а восстановление из тёплого снимка warmctl — 88 с. Это не аргумент за или против P/D, а условие, при котором гибкий флот вообще работает.

Что это значит. Даже там, где разделение окупается в среднем, жёсткое соотношение P:D — плохая идея. Выгоднее флот, который двигает границу между пулами вслед за cache hit.

11 · KVДержать кэш или пересчитать

Зачем: при высоком cache hit основной расход — хранение KV между ходами. Нужно правило, где и сколько его держать. Два простых порога.

Загрузить или пересчитать. Загрузка KV по сети быстрее пересчёта, если канал быстрее, чем B* = (байт KV на токен) × (скорость prefill). Для DeepSeek-V4.1-Flash это ≈ 0,25 ГБ/с на GPU, для GLM-5.3-Flash ≈ 1 ГБ/с. Для плотной 70B-модели с GQA при той же скорости prefill получилось бы ≈ 27 ГБ/с; при реалистичных для неё 30–50K ток/с на GPU — 10–16 ГБ/с. Для моделей с компактным KV любая серверная сеть быстрее пересчёта, а передача KV между пулами стоит копейки: промпт в 8K токенов — это 27 МБ.

Сколько держать. KV сессии стоит держать в ярусе памяти i на время паузы T, если ожидаемая экономия на пересчёте больше стоимости хранения:

держать, пока T < T* = pповтор · Cпересчётci · байты KV

Здесь pповтор — вероятность, что сессия вернётся, Cпересчёт — стоимость повторного prefill, ci — цена хранения байта в секунду в ярусе i (HBM, DRAM хоста, локальный NVMe, удалённое хранилище). Для HBM формула упрощается: T* равно времени, за которое GPU своим prefill заполнила бы весь свой KV-бюджет. Для DeepSeek-V4.1-Flash это около 10 минут при p = 0,9. Для плотной модели со стократно большим KV — секунды, поэтому там нужны DRAM и NVMe.

Тонкость: ci — теневая цена. Если HBM не заполнена, хранение в ней бесплатно, и держать кэш стоит до упора. Цена появляется, только когда объём HBM становится узким местом. У агентов с длинными паузами это происходит первым.

Что это значит. Новые модели с KV в единицы килобайт на токен смещают экономику от пересчёта к хранению. Ярусы памяти и маршрутизация, которая возвращает сессию к её кэшу, дают больше, чем выбор между монолитом и P/D.

12 · ЛИТЕРАТУРАЧто статьи на самом деле показали

Зачем: большинство громких множителей получено против конкретного, часто старого, базового варианта. Их нельзя складывать или перемножать — в каждой работе свои модель, железо, длины и метрика.

Ещё источники и их базовые варианты
РаботаЧто показалаПротив чего
ThunderServe (MLSys 2025)до 2,1×, в среднем 1,7× пропускной способности при сопоставимой ценеРазнородные облачные GPU; выигрыш от разнородности, а не от P/D как такового
Llumnix (OSDI 2024)до −36% стоимости при том же хвосте задержкиМиграция запросов и KV между инстансами; не P/D
Preble (ICLR 2025)1,5–14,5× по средней задержкеRound-robin без учёта префиксов; это эффект маршрутизации
SGLang (NeurIPS 2024)до 6,4× всей системыДвижки на момент публикации; не изолирует ни кэш, ни P/D
MegaScale-Infer (SIGCOMM 2025)до 1,9× на GPUРазделение attention и экспертов — другая ось, не P/D
CacheBlend (EuroSys 2025)2,2–3,3× по TTFTПолный пересчёт; переиспользует непрефиксные фрагменты RAG с частичным пересчётом
Cake (ICML 2025)в среднем 2,6× по TTFTТолько загрузка или только пересчёт KV; делает и то и другое параллельно
vLLM, P/D + wide-EP (окт. 2026)DEP2 prefill + DEP32 decode на стойкеСравнение конфигураций внутри vLLM; числа см. раздел 07

Что это значит. Литература не даёт универсального победителя. Она даёт механизмы: специализацию, разнородное железо, маршрутизацию с учётом кэша и разделение cold/warm. Каждый из них — отдельное слагаемое модели, и считать их надо на своей нагрузке.

13 · РЕШЕНИЕКогда разделять

14 · ДАЛЬШЕЧто мы хотим измерить

Главная неизвестная модели — θ для современного MoE на реальном движке. Её можно оценить на одном узле без всякой дисагрегации. Наш опубликованный прогон 8K → 1K на 8×B300 дал 29,5K выходных токенов в секунду. При этом prefill входящих 8K-промптов занимал около 36% prefill-мощности узла. Если отдельно измерить чистый decode на том же контексте (с prefix cache, без нового prefill), из формулы раздела 05 получится θ. Например, чистый decode 36K ток/с дал бы θ ≈ 0,5, а 46K — θ ≈ 1. Если же decode на 8K-контексте так же быстр, как измеренные 55K на 1K-контексте, θ ≈ 1,3 — то есть на DEP8 фазы мешают друг другу сильнее, чем если бы шли по очереди. Это и есть первое, что стоит измерить.

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


Словарь терминов

Токен
Кусочек текста, обычно часть слова. Модель читает и пишет токенами, провайдеры считают цену за миллион токенов отдельно для входа и выхода.
Prefill
Первая фаза: модель обрабатывает весь промпт одним проходом. Тысячи токенов идут параллельно, поэтому GPU загружена арифметикой.
Decode
Вторая фаза: модель выдаёт ответ по одному токену за шаг. На каждом шаге GPU заново читает из памяти веса модели и накопленный контекст. Арифметики на шаг мало, чтения много.
KV-кэш
Промежуточные результаты prefill для каждого токена контекста (ключи и значения внимания, отсюда K и V). Decode читает их на каждом шаге, поэтому они лежат в памяти GPU всё время, пока жив запрос. Размер — байты на токен, у разных моделей он отличается в сотню раз.
Cache hit
Доля входных токенов, для которых KV-кэш уже есть: например, тот же системный промпт или прошлые ходы агента. Такие токены не надо пересчитывать, и API продают их дешевле. Остальные называем некэшированными.
HBM
Память на самом GPU. У неё два разных ресурса: объём (сколько гигабайт весов и KV помещается) и полоса (сколько терабайт в секунду можно прочитать).
Compute-bound / memory-bound
Что упирается первым: арифметика (compute-bound, это prefill) или чтение из памяти (memory-bound, это decode).
TTFT, ITL
Time to first token — сколько ждать первого токена ответа. Inter-token latency — пауза между следующими токенами. Prefill определяет TTFT, decode — ITL.
SLO
Обещанный уровень сервиса, например «ITL p95 ≤ 50 мс». Запросы, уложившиеся в SLO, называют goodput.
Пул
Группа GPU с одной ролью. В монолите один общий пул делает и prefill, и decode. При дисагрегации два пула, и KV-кэш передаётся из prefill-пула в decode-пул по сети.
GPU-час, TCO
Аренда одной GPU на час — основная статья расходов провайдера. TCO (total cost of ownership) — полная стоимость: GPU-часы плюс сеть, хранилище, эксплуатация.

Источники