Назад к блогу

DeepSeek-V4.1 Flash: как устроено сжатие KV-кэша в новой модели

DeepSeek-V4.1 Flash: как устроено сжатие KV-кэша в новой модели

Новая модель DeepSeek-V4.1 Flash обещает радикально снизить стоимость обслуживания сверхдлинного контекста — до миллиона токенов — за счёт многоуровневого сжатия KV-кэша. Разбираем, как устроена схема Causal Encoder-Decoder, что даёт переход на FP4 и почему это меняет экономику агентных сценариев с частыми вызовами инструментов.

DeepSeek представила DeepSeek-V4.1 Flash — мультимодальную модель с архитектурой mixture-of-experts на 552B параметров, нативно поддерживающую контексты до 1 миллиона токенов. Ключевое отличие от предыдущей DeepSeek-V4-Flash — более агрессивное сжатие KV-кэша: при той же длине последовательности runtime-хранилище кэша составляет около 1/4 от прежнего, а persistent-хранилище — около 1/8.

Что именно изменилось

Сжатие достигается совместной оптимизацией по трём измерениям.

В канальном измерении 512-мерный латентный вектор совместно представляет ключи и значения всех голов внимания. В последовательностном измерении энкодер объединяет 2 соседние позиции в 1 запись кэша, а декодер, напротив, хранит записи по позициям.

В слоевом измерении несколько слоёв разделяют один глобальный KV, и вся сеть хранит только 3 копии кэша энкодера и 1 копию кэша декодера.

Дополнительно для Main KV применяется FP4-квантование в формате MXFP4 — в отличие от остального кэша, который хранится в более точных форматах. Перед вычислением внимания значения кэша деквантуются в более точный формат — FP4 служит для уменьшения объёма хранения, а не для ускорения матричного умножения. По умолчанию FP4 Main KV стал поведением модели: объём одной записи снизился с 584 B до 288 B.

Предыстория

Ранние подходы к сжатию решали задачу лишь частично. MLA в DeepSeek-V2/V3 сжимает представления по канальному измерению. Native Sparse Attention — обучаемый разреженный механизм, сочетающий грубую компрессию токенов с точным выбором токенов. Cross-Layer Attention позволяет части слоёв внимания читать KV, созданные более ранними слоями, избегая независимого кэша на каждом слое, — но экономит хранение, а не вычисления, так как каждый слой всё равно считает своё внимание.

Ограничения других схем: IndexCache разделяет Top-K индексы между слоями, сокращая число запусков Indexer, но основной KV всё ещё хранится послойно; YOIO экономит половину KV-кэша, но требует, чтобы несколько слоёв разреженного внимания совместно использовали один набор выбранных TopK-кандидатов, что влияет на качество модели; HySparse использует полное внимание для создания KV, и его эффективность всё ещё влияет на производительность.

Почему это сделали

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

Замеры по DeepSeek-V4-Flash: 43 слоя, каждый независимо хранит собственный глобальный кэш без кросс-слойного переиспользования, что даёт 3514 байт на токен. После перехода к кросс-слойному переиспользованию, ослабления сжатия последовательности и FP4 для Main KV расход удалось снизить до 890 байт на токен. По сравнению с FP8 Main KV у DeepSeek-V4 новый формат почти вдвое уменьшает объём в HBM и при выгрузке на SSD.

Как устроена архитектура CED

Causal Encoder-Decoder делит модель на две части по 20 слоёв: нижние слои Transformer считаются Causal Encoder, верхние — Decoder.

Для global attention KV верхних слоёв больше не берутся из их собственных скрытых состояний, а проецируются из скрытого состояния последнего слоя энкодера. Это позволяет на prefill считать только первую половину слоёв. CED снижает сложность prefill с O(L²) до O(L·l), фактически вдвое уменьшая общий объём вычислений.

Для SWA локальные KV каждого слоя напрямую выводятся из скрытого состояния текущего слоя, то есть per-layer вычисление сохраняется во всех слоях. Чтобы не пересчитывать весь prompt, применяется Decoder SWA Bounded Replay: для декодера вычисляется SWA только последних токенов prefill. Этого достаточно, потому что эффективное рецептивное поле SWA на практике существенно меньше теоретического.

Для global attention такого ограниченного реплея недостаточно: представления последних позиций в глубоких слоях всё ещё зависят от более ранних позиций за пределами окна, и точное восстановление требует прослеживания назад примерно на позиций. Bounded Replay ограничивает восстановление последними позициями и допускает приближённое состояние Local KV, но глобальная память при этом не усекается — декодер по-прежнему может читать Global KV более длинной истории по правилам причинного и разреженного внимания.

Три режима CSA2

CSA2 — механизм, в котором один слой рассматривается как «маленький компьютер», а три режима соответствуют трём состояниям попадания в кэш. Режимы различаются тем, как получаются Main KV, Indexer K и Top-K индексы.

  • Full вычисляет собственные Main KV и Indexer Q, получает Indexer K проекцией из Main KV и запускает Indexer, порождая новые Top-K индексы.
  • Reindex переиспользует последние доступные Main KV и соответствующий Indexer K, но вычисляет собственный Indexer Q, заново оценивает переиспользованные ключи и порождает новые Top-K индексы.
  • Reuse переиспользует последние доступные Main KV и последние Top-K индексы, вычисленные предыдущим слоем Full или Reindex, не вычисляя Indexer Q и не оценивая индексы.

Все три режима вычисляют Main Q и SWA KV на текущем слое. Совместно они образуют грубо-тонкое расписание обновления: Full перестраивает KV-кэш и является якорем, Reindex сохраняет содержимое и перевыбирает Top-K внутри пула кандидатов, Reuse только делает Q-проекцию, SWA и один sparse_attn.

В Encoder-блоке из 6 слоёв первый слой работает в Full mode CSA2 и вычисляет весь Main KV и TopK-индексы, а последующие 5 слоёв — в Reuse mode CSA2, переиспользуя их и изменяя только Q. В декодере Full (слой 20) определяет содержимое, задаёт пул кандидатов из 16384 позиций и даёт собственный Top-512; Reindex (слои 24, 28, 32, 36) при неизменном содержимом заново выбирает собственные Top-512 внутри пула; Reuse следует за Top-512, опубликованным самым свежим индексным слоем, и лишь перезаписывает query.

Hierarchical Sparse Indexer

HSI — иерархический разреженный индексатор, который строит блочный отбор как Candidate Pool для последующего Reindex Mode CSA2. Первый Full Mode CSA2 скорит все причинно видимые позиции main KV, получая Top-K индексы для собственного внимания, и одновременно выполняет блочный отбор кандидатов: выбираются несколько блоков с наибольшими скорами, а позиции этих блоков собираются в candidate pool, который больше финального Top-K набора. Например, выбираются 2048 блоков по 8 позиций, что даёт 16384 кандидатные позиции.

Candidate pool определяет «где искать» для последующего Indexer, а финальный Top-K определяет «какие записи читать» для каждого слоя. Пул разделяется между индексными слоями, а финальный выбор может различаться. При фиксированном размере пула число скорируемых позиций на запрос у каждого последующего Indexer не зависит от длины контекста и ограничено, тогда как первый Full mode слой всё ещё сканирует весь причинно видимый диапазон.

FP4 Main KV Cache

Кэш использует формат E2M1, где каждые 16 каналов совместно используют один scale factor в формате E4M3, как в NVFP4, но без второго глобального scale factor. После его отбрасывания формат всё ещё поддерживает максимальную величину, значительно превышающую верхнюю границу величины кэша: максимальная величина веса RMSNorm около 1, после нормализации L2-норма 512-канальной KV-латентной переменной не более примерно корня из 512, RoPE сохраняет эту норму, а максимальная наблюдённая при обучении величина около 10. Поэтому отбрасывание глобального scale factor не даёт измеримой деградации точности и упрощает раскладку кэша.

Кэш квантуется после RoPE, при этом non-RoPE и RoPE компоненты используют один и тот же формат квантования. Для чувствительного к квантованию KV-кэша sliding window attention сохраняется точность FP8.

Что это меняет на практике

Совместное использование Main KV и Indexer K уменьшает объём хранилища KV-кэша, а переиспользование Top-K индексов позволяет избежать дополнительных вычислений Indexer. В Encoder-блоке все 5 слоёв Reuse переиспользуют Main KV и TopK-индексы, созданные первым слоем, — фактически каждый слой изменяет только Q.

В режиме Reuse содержимое и адрес берутся из более раннего слоя-источника и не зависят от собственного скрытого состояния слоя, поэтому их частные производные по входу равны нулю: зависимость выхода от входа остаётся только через query. Поскольку key = value = c, выход внимания есть выпуклая комбинация словарных векторов — readout фиксированного словаря, и переписывание Q лишь перемещает точку внутри выпуклой оболочки. Если запрос слоя Reuse записать как baseline-запрос источника плюс обучаемую пертурбацию, логит получает дополнительное слагаемое, и распределение весов претерпевает экспоненциальный наклон вдоль направления пертурбации с последующей перенормировкой. Достижимое множество наклонов ограничено: при полном ранге пертурбации достижима любая перевзвеска, а в конфигурации DeepSeek-V4.1-Flash наклон ограничен подпространством размерности не более 128. RoPE применяет позиционно-зависимое ортогональное вращение только к rope tail каналов Q и K, которое поглощается скалярным произведением и не меняет аргумент о выпуклой оболочке и наклоне.

Цифры

Backbone: dim = 5120, n_layers = 40 (первые 20 слоёв — Encoder, последние 20 — Decoder), n_mtp_layers = 3, vocab_size = 129280. Engram: engram_layer_ids = [1, 14], engram_num_embeddings = [384006168, 384016682], engram_max_ngram_size = 4, engram_n_heads = 8, engram_head_dim = 256, engram_vocab_size = 16000000.

Замеры по объёму KV-кэша на токен: Global KV Sum = 890 B/token; Main KV entry = 288 B/entry; Indexer K entry = 68 B/entry. Для DeepSeek-V4-Flash Main KV entry = 584 B. Net efficiency при relax sequence compression 4→2 (Encoder) / 1 (Decoder) считается как переход от 3514 B/token к 1630 B/token, затем к 890 B/token.

Ограничения и открытые вопросы

Ограничение по входным изображениям до примерно 1344×1344 объясняется бюджетом vision_max_n_token=1024: после масштабирования и добавления тегов число токенов не должно превышать этот лимит.

Для Reuse mode авторы перечисляют три ограничения: верхняя граница recall (контент с большим значением не достижим, и ошибка TopK-отбора выше по стеку не исправляется ниже), неподвижность вершин (выход зафиксирован в выпуклой оболочке) и невозможность смены геометрии наклона (достижимое распределение — фиксированное экспоненциальное семейство).

Открытым остаётся вопрос о спекулятивном механизме отображения KV-пространства следующего слоя обратно в текущий слой через обучаемые Q-aware параметры: авторы предполагают, что при стабильном остатке пространство KV позднего слоя можно отобразить назад в пространство раннего слоя, а само отображение «впитать» в MoE/FFN и Engram на этапе обучения. Этот материал зафиксирован во внутренних документах, и связанный экспериментальный анализ ещё ведётся.

Диапазон покрытия reuse output — это образ mean map: при свободном обходе query и полном ранге образ равен симплексу, но это лишь верхняя граница способности, а не гарантия доступа ко всему множеству.

Источники

Похожее