Разделять ли 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.
Prefill
Весь промпт одним проходом
Decode
Один токен за шаг для каждой последовательности
Из этих двух замеров получается главная константа статьи. Обозначим её κ (каппа): во сколько раз GPU быстрее делает prefill, чем decode. У нас κ ≈ 82K / 6,9K ≈ 12. Иначе говоря, один выходной токен стоит GPU-времени примерно как 12 некэшированных входных.
Что это значит. Фазы не конкурируют за один и тот же ресурс. Prefill загружает арифметику и оставляет простаивать полосу памяти. Decode загружает полосу и объём памяти и оставляет простаивать арифметику. Такие нагрузки выгодно упаковывать вместе.
03 · УЗКОЕ МЕСТОРесурсы как векторы: закон узкого места
Зачем нужна модель: без неё спор «вместе или раздельно» сводится к сравнению графиков из разных статей. Модель позволяет увидеть, откуда берётся выигрыш, и посчитать его на своих числах.
Опишем каждый класс запросов (RAG, reasoning, агент) вектором ресурсов: сколько секунд работы одной GPU он отнимает по каждому ресурсу. Ресурсов четыре:
- Вычисления — prefill некэшированных токенов: их число делим на скорость prefill одной GPU.
- Полоса HBM — шаги decode: число выходных токенов делим на скорость decode одной GPU.
- Объём HBM × время — KV-кэш, который лежит в памяти, пока запрос жив, включая паузы агента на вызов инструментов. Это закон Литтла: средний занятый объём равен интенсивности запросов × размер KV × время жизни.
- Сеть — байты KV, переданные между пулами. Для современных моделей с компактным KV это почти ноль (раздел 11).
Каждая GPU даёт за секунду ровно одну «GPU-секунду» каждого ресурса. Тогда число GPU, необходимое для потока, в идеальной упаковке (без очередей и всплесков) равно:
Здесь j — класс запросов, λj — сколько таких запросов в секунду, aj,r — сколько ресурса r нужно одному запросу, Cr — сколько ресурса r даёт одна GPU. Максимум берётся по ресурсам: флот определяется ресурсом, которого не хватает. Остальные ресурсы куплены, но частично простаивают.
Это тот же закон, по которому упаковывают серверы в дата-центре. Если одни задачи требуют много CPU и мало памяти, а другие наоборот, их выгодно ставить на одни машины. Отдельные «CPU-серверы» и «серверы памяти» оставили бы половину железа незанятой. На этом наблюдении построены планировщики вроде Borg и вся теория многомерной упаковки.
Что это значит. Вопрос «разделять ли фазы» — частный случай вопроса «упаковывать ли вместе задачи с разными профилями ресурсов». У этого вопроса есть известный ответ, и следующий раздел его выводит.
04 · ТЕОРЕМАПочему на одном типе GPU раздельно не дешевле
Обозначим суммарную потребность prefill-фазы в каждом ресурсе как Pr, а decode-фазы как Dr. Монолит покрывает сумму потребностей, раздельные пулы на тех же GPU — каждую фазу по отдельности. Максимум суммы не больше суммы максимумов, поэтому:
У prefill узкое место — вычисления, у decode — память. Поэтому при одинаковом железе раздельные пулы всегда оставляют больше ресурсов простаивать. В лучшем случае совместный пул обходится вдвое дешевле: это происходит, когда обе фазы нагружают GPU одинаково.
Оговорка «в идеальной упаковке» важна. Теорема предполагает, что арифметика prefill и чтение памяти decode идут на GPU одновременно и не мешают друг другу. В реальности они мешают, и об этом следующий раздел. Там же видно, что при достаточно сильных помехах неравенство переворачивается.
Что это значит. Дисагрегация сама по себе не экономит GPU. Если она где-то экономит, источник экономии — в чём-то другом, и его надо назвать явно.
05 · ПОМЕХИθ: насколько фазы на самом деле мешают друг другу
Зачем вводить ещё одну букву: она переводит слово «интерференция» в число, которое можно измерить. Когда движок кладёт в один шаг и decode, и кусок чужого prefill (это называют chunked prefill), шаг длится дольше, чем чистый decode. Опишем длительность такого шага так:
Tвыч — сколько шаг занял бы, если бы упирался только в арифметику, Tпам — только в чтение памяти. Коэффициент θ (тета) неотрицателен. При θ = 0 работа одной фазы полностью прячется в простое другой: prefill «едет зайцем» на decode. При θ = 1 фазы выполняются строго по очереди, как если бы GPU делила время между ними. θ может быть и больше единицы: так бывает, когда движок синхронизирует много GPU на каждом шаге, и кусок prefill на одной из них задерживает все остальные (раздел 07). Тогда совместный шаг длится дольше, чем две фазы по очереди.
Теперь нормируем нагрузку. U — сколько GPU понадобилось бы, если бы они делали только prefill всего потока. V — то же для decode. Тогда:
Чему θ равен на практике? Лучшая известная нам точка — работа «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: во сколько раз специализированный пул быстрее на своей фазе. Откуда он берётся:
- Разная конфигурация параллелизма. Prefill лучше идёт малыми группами GPU, decode крупного MoE — большими (раздел 07).
- Батч без примесей. Decode-пул может держать больший батч и захватывать шаги в CUDA-графы, не подстраиваясь под prefill.
- Другое железо. Decode можно отдать GPU, у которых больше памяти на доллар, а prefill — GPU, у которых больше арифметики. Именно отсюда выигрыш по стоимости в Splitwise.
Последняя буква — ρ (ро), баланс фаз: меньшее из U и V, делённое на большее. ρ = 1 означает, что фазы требуют поровну GPU, ρ → 0 — что одна фаза почти исчезла. Сравнив U/s + V/s с формулой для монолита, получаем условие (для простоты считаем, что оба пула выигрывают одинаково; в общем виде раздельная схема стоит U/sP + V/sD, и sP может оказаться меньше единицы):
Что видно на карте:
- Сбалансированный поток и малый θ — склейка выигрывает сильно. При ρ = 1 и θ = 0 разделению нужен выигрыш специализации больше 2×, а это редкость.
- Крайняя смесь — архитектура почти не важна. При ρ → 0 все кривые сходятся к s = 1. Стоимость определяет доминирующая фаза, и решают её настройки, а не схема пулов.
- Большой θ — разделение почти бесплатно. Если фазы всё равно выполняются по очереди, общий пул ничего не выигрывает от упаковки.
Что это значит. Аргумент «развести, чтобы не мешали» относится к задержкам. Для стоимости вопрос другой: даёт ли специализация пулу выигрыш s, превышающий потерю от худшей упаковки. Карта показывает, сколько именно нужно выиграть.
07 · КРУПНЫЙ MoEПочему DeepSeek-класс всё-таки разделяют
Зачем отдельный раздел: крупные провайдеры моделей вроде DeepSeek запускают их именно с дисагрегацией, и модель должна это объяснять. Сначала два термина.
MoE (mixture of experts) — модель, в которой каждый слой состоит из сотен «экспертов», а каждый токен проходит только через несколько из них. Expert parallelism (EP) — раскладка, при которой эксперты распределены по GPU, и на каждом слое токены пересылаются туда, где лежат их эксперты. Wide-EP — то же самое на десятках GPU: на каждую приходится меньше экспертов, поэтому на шаге decode она читает меньше весов.
- Wide-EP даёт decode большой выигрыш s. В посте vLLM от 23 октября про DeepSeek-V4.1-Flash на GB200 время MoE-части шага decode упало с 13,4 до 6,0 мс при переходе от 4 к 32 GPU в группе. Остальная часть шага — около 10 мс, так что весь шаг ускорился примерно в 1,46 раза при том же батче на GPU.
- Prefill хочет маленькие группы. В том же посте prefill в группе из 4 GPU дал на GPU лишь 83% от группы из 2. Собственный движок DeepSeek, DeepInfer, в опубликованных замерах держит prefill на группах по 4 GPU, а decode — по 64. Общий пул вынужден выбрать один размер группы и проиграет на одной из фаз.
- Синхронизация делает θ больше единицы. В том же посте прямо сказано, что wide-EP decode синхронизирует все GPU на каждом слое, и одна медленная GPU тормозит весь инстанс. Кусок prefill на одной GPU задерживает все 32. Там же видно, что потери от неравномерной нагрузки растут с размером группы: 5,9% при 2 GPU против 13,6% при 4.
Итак, для 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). Сами нагрузки — иллюстрация:
- RAG — 100 запросов в секунду, 12K некэшированных входных токенов, 300 на выходе.
- Reasoning — 10 запросов в секунду, 1K на входе, 8K рассуждений и ответа на выходе.
- Агент — 100 ходов в секунду, контекст 40K, на каждом ходе добавляется 4K новых токенов (hit 90%) и пишется 400. Между ходами — пауза 30 с на вызов инструмента, KV всё это время лежит в HBM.
Векторы ресурсов и порог s* по сценариям
| Сценарий | Вычисления | Полоса HBM | Объём HBM | ρ | Вместе θ=0,2 | Вместе θ=0,5 | Раздельно s=1 | s*, θ=0,2…0,5 |
|---|---|---|---|---|---|---|---|---|
| RAG | 14,6 | 4,3 | 0,2 | 0,30 | 15,5 | 16,8 | 19,0 | 1,13…1,22 |
| Reasoning | 0,1 | 11,6 | 0,4 | 0,01 | 11,6 | 11,7 | 11,7 | 1,01…1,01 |
| Агент, hit 90% | 4,9 | 5,8 | 3,2 | 0,84 | 6,8 | 8,2 | 10,7 | 1,30…1,58 |
| Агент, hit 99% | 0,5 | 5,8 | 3,2 | 0,08 | 5,9 | 6,0 | 6,3 | 1,04…1,07 |
| Смесь RAG + reasoning + агент 90% | 19,6 | 21,7 | 3,8 | 0,90 | 25,7 | 31,6 | 41,4 | 1,31…1,61 |
Числа — GPU-эквиваленты в секунду. Decode-пул упирается в больший из двух ресурсов HBM. s* — во сколько раз должны ускориться пулы, чтобы раздельная схема сравнялась с общей.
- Агент с hit 90% почти сбалансирован (ρ ≈ 0,84). Каждый ход — 4K некэшированных токенов на 400 выходных, то есть 10:1, а κ ≈ 12. Prefill здесь не мелочь, и склейка экономит до трети GPU.
- При hit 99% prefill исчезает (ρ ≈ 0,08), а с ним и разница между схемами. Остаётся decode, который упирается в полосу HBM и объём под KV, занятый на паузах.
- Reasoning — чистый decode. Схема пулов не важна, важны батч и скорость шага.
- Смесь — самый выгодный случай для склейки. RAG приносит вычисления, reasoning и агенты — нагрузку на память, и вместе они заполняют 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. Нужно покрыть спрос минимальной суммой. У такой задачи есть два полезных свойства:
- Ролей в оптимуме не больше, чем измерений спроса. Это стандартный факт о базисных решениях линейных программ; он точен, пока в задаче нет других ограничений вроде SLO на каждый класс или квот на железо — каждое такое ограничение может добавить роль. Две фазы — не больше двух ролей. Cold prefill, warm prefill и decode — не больше трёх, как у Together AI. Зоопарк из пяти типов пулов почти наверняка неоптимален.
- Двойственные переменные — это себестоимость единицы спроса. Они показывают, сколько стоит ещё один prefill-токен или ещё один decode-токен. Ключевое наблюдение: если общий пул упирается в decode, предельная стоимость prefill-токена равна θ, делённому на скорость prefill. При малом θ она близка к нулю. В раздельной схеме тот же токен стоит полную цену GPU-времени.
Сравним с прайсом. Публичные цены DeepSeek на V4.1-Flash: $0,30 за 1M некэшированных входных токенов, $0,006 за кэшированные, $1,20 за выходные. Если взять условные $9,50 за GPU-час и наши скорости при полной загрузке, вычисления стоят около $0,03 за 1M prefill-токенов и около $0,38 за 1M decode-токенов. Иллюстрация: без запаса под пики, SLO и простои.
- По прайсу выход дороже входа в 4 раза, по GPU-времени — примерно в 12. Значит, запас маржи у провайдера сидит в основном во входных токенах. Чем точнее флот упирается в decode, тем дешевле ему обходится вход.
- Кэшированный токен по $0,006 за 1M нельзя пересчитывать — его надо хранить. Цена ниже стоимости пересчёта примерно в 5 раз. Зато её хватает примерно на 2 минуты хранения этого токена в HBM при 3,3 КБ на токен.
Что это значит. Цена кэшированного входа — это цена хранения, а не вычислений. Экономика агентского инференса определяется тем, где и сколько лежит KV, а не тем, разделены ли пулы.
10 · ЗАПАС И ДРЕЙФЧто теряется на реальных, неровных нагрузках
Зачем: до сих пор мы считали идеальную упаковку при ровном потоке. Реальный поток колеблется, и под колебания нужен запас. Здесь у общего пула есть ещё два преимущества.
- Запас растёт как корень, и делить его невыгодно. По классическому правилу square-root staffing пулу на средней нагрузке в R GPU нужно около R + β√R GPU, где β задаёт допустимую вероятность очереди. Два пула платят β(√RP + √RD) вместо β√(RP+RD). Пример (иллюстрация): 9 и 36 GPU при β = 2 требуют лишних ≈ 4,6 GPU, то есть 10% флота.
- Cache hit дрейфует, а с ним и баланс фаз. Днём преобладают агенты с тёплым кэшем, вечером приходит пакетная обработка холодных документов. Жёсткое разделение должно держать пиковый размер каждого пула по отдельности, то есть платить сумму максимумов. Гибкий флот платит максимум суммы.
- Гранулярность. Если decode-инстанс занимает 32–64 GPU, а prefill-инстанс — 2–4, маленький провайдер просто не может разделить фазы без огромного округления вверх.
Отсюда практичный вариант — гибкие роли: узлы с одной моделью, которые переключаются между 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, если ожидаемая экономия на пересчёте больше стоимости хранения:
Здесь 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 · ЛИТЕРАТУРАЧто статьи на самом деле показали
Зачем: большинство громких множителей получено против конкретного, часто старого, базового варианта. Их нельзя складывать или перемножать — в каждой работе свои модель, железо, длины и метрика.
- DistServe (OSDI 2024): до 7,4× по допустимой нагрузке или до 12,6× по жёсткости SLO. Сравнение с vLLM 2023 года на OPT до 175B, длины до 2048 токенов. Метрика — goodput под SLO, а не стоимость.
- Splitwise (ISCA 2024): 1,4× пропускной способности при −20% стоимости или 2,35× при том же бюджете. Это симуляция на профилях GPU, и выигрыш по стоимости в значительной мере приходит от разного железа для фаз. На нашем языке это s > 1 через железо.
- Sarathi-Serve (OSDI 2024): 2,6–5,6× обслуживаемой нагрузки у совместной схемы с chunked prefill. Это сильный довод за склейку, но тоже против vLLM 2023 года.
- Mooncake (FAST 2025): +115% на A800 и +107% на H800 в продакшене Kimi. Это KV-ориентированная архитектура: кэш в DRAM и на SSD, планировщик, учитывающий кэш, и ранний отказ запросам. Выигрыш нельзя приписать одной дисагрегации.
- NVIDIA «Beyond the Buzz» (MLSys 2026): выгода P/D зависит от размера модели, доли prefill, SLO и соотношения мощностей стадий. Авторы рекомендуют адаптивное соотношение ролей. Основная часть результатов получена на закрытом симуляторе.
- PPD «Not All Prefills Are Equal» (2026): +48% к TPOT от полного prefill и +2% от добавки к кэшированному контексту. Это прямое измерение θ двух видов, правда на одной H100 и моделях 8–30B.
- Together AI, cache-aware disaggregation (2026): +35–40% устойчивого QPS от разделения cold prefill, warm prefill и decode. База сравнения — уже дезагрегированная схема 2P1D, а не общий пул, и это инженерный пост без полной стоимостной модели.
Ещё источники и их базовые варианты
| Работа | Что показала | Против чего |
|---|---|---|
| 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 · РЕШЕНИЕКогда разделять
- Разделять крупный MoE, если decode-инстанс занимает 16–64 GPU с wide-EP. Специализация и синхронизация дают s > 1 и θэфф > 1.
- Разделять, если есть заметно более дешёвое железо для одной из фаз, например decode на GPU с большим объёмом памяти на доллар. Это s через железо.
- Уводить холодные длинные промпты, если ITL под жёстким SLO, а θ для них большой. Короткие добавки к тёплому контексту оставлять на decode-GPU.
- Не разделять на одном узле, на плотных и небольших MoE-моделях и при сбалансированной смеси нагрузок. Общий пул с chunked prefill, prefix cache и маршрутизацией по кэшу дешевле.
- Не ждать чуда при высоком cache hit. Если некэшированного входа меньше, чем κ/5 от выхода, схема пулов почти не влияет на стоимость. Вкладываться стоит в ярусы KV, время его жизни и маршрутизацию.
- Не фиксировать P:D. Если смесь дрейфует, нужен флот с гибкими ролями и быстрым переключением.
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 и для добавок к тёплому контексту — повторить опыт PPD на DeepSeek-классе.
- κ при разных длинах контекста: насколько дорожает шаг decode при 32K–200K.
- Реальный объём KV, передаваемый на запрос, против порога B*.
Это небольшой эксперимент; бюджет и сроки определим позже. Когда появятся числа, подставим их в калькулятор выше вместо иллюстраций.
Словарь терминов
- Токен
- Кусочек текста, обычно часть слова. Модель читает и пишет токенами, провайдеры считают цену за миллион токенов отдельно для входа и выхода.
- 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-часы плюс сеть, хранилище, эксплуатация.
Источники
- Наши замеры: DeepSeek-V4.1-Flash на 8×B300: vLLM против DeepInfer (21 октября 2026).
- vLLM: DeepSeek-V4.1-Flash, P/D и wide-EP (23 октября 2026).
- DistServe · Splitwise · Sarathi-Serve · Mooncake · Beyond the Buzz · Not All Prefills Are Equal · Together AI, cache-aware disaggregation
- ThunderServe · Llumnix · Preble · SGLang · MegaScale-Infer · CacheBlend · Cake
- Цены API: DeepSeek. Цена GPU-часа $9,50 — публичный прайс по требованию на B300 у одного из облаков, октябрь 2026.