vovannovig2's picture
FP8-Dynamic quantization of Kwaipilot/KAT-Coder-V2.5-Dev (vLLM-ready, shared_expert_gate kept BF16)
28f3401 verified
|
Raw
History Blame Contribute Delete
28 kB
metadata
base_model: Kwaipilot/KAT-Coder-V2.5-Dev
license: apache-2.0
language:
  - en
  - ru
  - code
library_name: vllm
pipeline_tag: text-generation
tags:
  - vllm
  - fp8
  - fp8-dynamic
  - quantized
  - llmcompressor
  - compressed-tensors
  - qwen3.5
  - qwen3.6
  - qwen3_5_moe
  - moe
  - code
  - coding
  - agentic
  - tool-use
  - dgx-spark
  - gb10
  - llama-swap
  - ngram
quantized_from: Kwaipilot/KAT-Coder-V2.5-Dev
quant_method: compressed-tensors
bits: 8

KAT-Coder-V2.5-Dev FP8-Dynamic (vLLM-ready)

An FP8-Dynamic post-training quantization of Kwaipilot/KAT-Coder-V2.5-Dev, a 35B (3B-active) hybrid-attention MoE coding model from the Kwaipilot KAT-Coder V2.5 family. This checkpoint halves VRAM and roughly doubles KV-cache capacity versus the BF16 original while keeping >99.9% of parameters in FP8, and is verified to load and serve on a single NVIDIA DGX Spark (GB10 / sm_121a) under vLLM.

Base model Kwaipilot/KAT-Coder-V2.5-Dev (Qwen3.6-35B-A3B)
Architecture Qwen3_5MoeForConditionalGeneration (qwen3_5_moe)
Params 35B total / 3B active (MoE: 256 experts, 8 per token)
Layers 40, hybrid [linear, linear, linear, full] × 10 (Gated-DeltaNet linear attention + full attention, 3:1)
Hidden / vocab 2048 / 248,320
Context 262,144 tokens (native max_position_embeddings)
Quantization FP8-Dynamic: W8A8 float, per-channel weights (static, memoryless_minmax), per-token activations (dynamic)
dtype mix 94.0% float8_e4m3fn (33.62 GB) + 6.0% bfloat16 (2.14 GB)
Checkpoint size 35.77 GB (single model.safetensors)
VRAM @ util 0.80 weights 33.52 GiB + KV cache 64.16 GiB on a 121.6 GiB device
License Apache-2.0 (inherited from base)

What this model is

KAT-Coder-V2.5-Dev is a coder/agentic model from the Kwaipilot KAT-Coder V2.5 technical report, fine-tuned on top of the Qwen3.6-35B-A3B base. The base is a hybrid linear/full-attention MoE: 40 layers in a 3× linear-attention (Gated DeltaNet) + 1× full-attention repeating pattern, with 256 routed experts (8 activated per token) plus a shared expert. Only ~3B params fire per token, which makes decode cheap on memory-bound devices like the DGX Spark, while the full 35B capacity is available for quality.

This derivative applies data-free FP8-Dynamic PTQ via llmcompressor so the model fits a single 128 GB-class GPU with a large KV budget, enabling many concurrent agent sessions.


⚠️ Critical: shared_expert_gate is kept BF16 (read before re-quantizing)

This is the single most important gotcha when serving this checkpoint with vLLM.

vLLM's Qwen3_5 / Qwen3Next MoE implementation instantiates shared_expert_gate as an unquantized ReplicatedLinear (see vllm/model_executor/models/qwen3_next.py, the self.shared_expert_gate = ReplicatedLinear(..., quant_config=None, ...) line). If you quantize that module to FP8 and ship a weight_scale, vLLM will fail at load time with:

ValueError: There is no module or parameter named 'layers.0.mlp.shared_expert_gate.weight_scale'
in Qwen3_5Model. The available parameters belonging to layers.0.mlp.shared_expert_gate
(ReplicatedLinear) are: {'layers.0.mlp.shared_expert_gate.weight'}

Fix (already applied in this checkpoint): the recipe ignores re:.*shared_expert_gate$, so those 40 tensors stay bfloat16 and load cleanly. The routed experts and the shared_expert MLP projections remain FP8 (served by vLLM's TRITON Fp8 MoE backend). If you re-quantize from scratch, you must include this ignore entry.

The full ignore list:

ignore:
  - 're:.*lm_head'              # never quantize the output head
  - 're:.*visual.*'             # text-only release ships no vision weights
  - 're:.*mlp.gate$'            # TopK router (Parameter, auto-skipped — kept for parity)
  - 're:.*shared_expert_gate$'  # ← REQUIRED: vLLM loads this unquantized

Compatibility

  • vLLM ≥ 0.26.0 — verified on ghcr.io/timothystewart6/vllm-gb10:v0.26.0-gb10.6 (vLLM 0.26.1.dev0+g568afb3a1.d20260801, CUDA 13.2, PyTorch 2.11, FlashInfer v0.6.14).
  • --language-model-only is mandatory. The base is a multimodal ConditionalGeneration class but this release ships text-only weights; without the flag vLLM tries to init a vision tower that isn't in the checkpoint.
  • Hardware: DGX Spark (GB10 SoC, sm_121a). The FP8 path runs through Triton scaled_mm + Marlin (CutlassFP8 kernel) + TRITON Fp8 MoE + FlashInfer. DeepGEMM/MXFP4 are not available on sm_121 — leave VLLM_USE_DEEP_GEMM=0.
  • No MTP heads (mtp_num_hidden_layers: 0). For speculation use n-gram (free) or EAGLE3 (if you train a head).

Quick start — vllm serve

docker run --rm --gpus all --ipc host --network host --privileged \
  -v ~/.cache/huggingface:/root/.cache/huggingface \
  -e HF_TOKEN=$HF_TOKEN \
  ghcr.io/timothystewart6/vllm-gb10:v0.26.0-gb10.6 \
  vllm serve vovannovig2/KAT-Coder-V2.5-Dev-FP8-Dynamic \
    --host 0.0.0.0 --port 8000 --served-model-name kat-coder \
    --language-model-only \
    --kv-cache-dtype fp8 \
    --max-model-len 262144 \
    --enable-prefix-caching --enable-chunked-prefill --trust-remote-code \
    --tensor-parallel-size 1 \
    --safetensors-load-strategy prefetch \
    --gpu-memory-utilization 0.80 \
    --max-num-seqs 12 --max-num-batched-tokens 8192 \
    --reasoning-parser qwen3 --enable-auto-tool-choice --tool-call-parser qwen3_coder \
    --generation-config auto \
    --speculative-config '{"method":"ngram","num_speculative_tokens":3,"prompt_lookup_max":4}'

Required / recommended flags:

Flag Why
--language-model-only Skip the absent vision tower. Mandatory.
--kv-cache-dtype fp8 Halves KV memory; confirmed working on sm_121.
--reasoning-parser qwen3 Parses <think>...</think> into OpenAI reasoning_content.
--tool-call-parser qwen3_coder Native tool format <tool_call><function=NAME><parameter=K>V</parameter>… (NOT qwen3_xml).
--speculative-config ngram Free 1.5–2.5× on code (no MTP head shipped).
--enable-prefix-caching Huge wins for agentic / repeated system prompts.
--gpu-memory-utilization 0.80 Reserves OS/CPU headroom on the unified-memory SoC.
--max-num-seqs 12 12 parallel decode streams; KV has headroom for more (see capacity table).

Production deployment on DGX Spark (LiteLLM + llama-swap swap stack)

This checkpoint is served in production behind a swap architecture: only one vLLM model is hot at a time, swapped on-demand so a single 128 GB device can host several large models without contention.

Clients / OpenCode ─► LiteLLM :14000 ─► llama-swap :8000 ─► ONE active vLLM container
                   (aliases, guardrails,   (systemd,        (port auto-assigned alphabetically;
                    prefix-cache, redis)   -watch-config      kat-coder → :8002)
                                            hot-reload)

llama-swap block (config.yaml):

kat-coder:
  name: "KAT-Coder V2.5 Dev (Qwen3.6-35B-A3B MoE FP8-Dynamic)"
  cmd: |
    docker run --rm --name vllm-kat ${docker_common} ${vllm_image} vllm serve
    vovannovig2/KAT-Coder-V2.5-Dev-FP8-Dynamic
    --host 127.0.0.1 --port ${PORT} --served-model-name kat-coder
    --language-model-only --kv-cache-dtype fp8 --max-model-len 262144
    --enable-prefix-caching --enable-chunked-prefill --trust-remote-code
    --tensor-parallel-size 1 --safetensors-load-strategy prefetch
    --gpu-memory-utilization 0.80 --max-num-seqs 12 --max-num-batched-tokens 8192
    --reasoning-parser qwen3 --enable-auto-tool-choice --tool-call-parser qwen3_coder
    --generation-config auto
    --speculative-config '{"method":"ngram","num_speculative_tokens":3,"prompt_lookup_max":4}'
  proxy: http://127.0.0.1:${PORT}
  checkEndpoint: /health
  cmdStop: docker stop -t 60 vllm-kat
  unloadTimeout: 180

LiteLLM entry (config.yaml):

- model_name: kat-coder
  litellm_params:
    model: openai/kat-coder              # MUST match llama-swap key + --served-model-name
    api_base: http://127.0.0.1:8000/v1   # always llama-swap, never the raw vLLM port
    api_key: sk-local-noauth
    temperature: 1.0
    top_p: 0.95
    top_k: 20
    presence_penalty: 1.5
    max_tokens: 65536
  model_info:
    mode: chat
    supports_reasoning: true
    supports_function_calling: true
    max_input_tokens: 262144
    max_output_tokens: 65536

Swapping is request-driven: asking for kat-coder unloads whatever is hot (e.g. ThinkingCap) and cold-loads this model (~6 min end-to-end, see performance table). sendLoadingState: true streams load progress to chat UIs.


Sampling recommendations

Mode temperature top_p top_k presence_penalty
Thinking (default) 1.0 0.95 20 1.5
Non-thinking / instruct 0.7 0.80 20 1.5

The chat template is Qwen3 ChatML with <think>…</think> reasoning delimiters and enable_thinking / preserve_thinking kwargs. generation_config.json ships temperature=1.0, top_k=20, top_p=0.95.


Performance on DGX Spark (measured)

Single DGX Spark, GB10 (sm_121a), 121.63 GiB unified memory, --gpu-memory-utilization 0.80, --kv-cache-dtype fp8, n-gram spec decode (3 tokens), all kernels warm.

Metric Value
Cold load — weights 224.4 s (33.52 GiB, EXT4 prefetch)
Cold load — engine init 99.2 s (compile 29.0 s + profile + CUDA-graph capture)
Total cold start to ready ~6 min
Weight VRAM 33.52 GiB
KV cache VRAM 64.16 GiB (FP8)
GPU KV cache size 5,960,926 tokens
Decode throughput (single stream, E2E via LiteLLM→llama-swap→vLLM) ~47–50 tok/s
Prefill throughput (1 req) ~30 tok/s

Kernels selected by vLLM (verbatim from logs):

  • Selected CutlassFP8ScaledMMLinearKernel for CompressedTensorsW8A8Fp8
  • Using TRITON Fp8 MoE backend (out of AITER/FLASHINFER/DEEPGEMM/MARLIN/…)
  • Using FLASHINFER attention backend
  • FlashInfer resolved … kv_cache_dtype=torch.float8_e4m3fn, arch=sm121
  • Using Triton/FLA GDN prefill kernel (head_k_dim=128) (linear-attention layers)

Subagent / concurrency capacity (one DGX Spark)

The hybrid architecture only stores KV state for the 10 full-attention layers (the 30 linear-attention layers are recurrent/stateful, ~no KV). Combined with FP8 KV cache this yields a very large token budget.

KV budget math: 5,960,926 tokens / 262,144 = 22.7 → up to 22 full 256k-context sessions fit in the KV cache. The scheduler cap (--max-num-seqs) is the binding constraint, not memory.

Concurrency (subagents) Per-agent context Total KV used KV utilization Notes
12 262,144 (full) 3.15 M 52.8% Default config; healthy headroom
12 131,072 (128k) 1.57 M 26.4% Light
12 65,536 (64k) 0.79 M 13.2% Comfortable
22 (raise --max-num-seqs) 262,144 (full) 5.77 M 96.8% Max before OOM; aggressive
8 262,144 (full) 2.10 M 35.2% Conservative; matches dense-model pattern

Recommendation: --max-num-seqs 12 gives 12 parallel coding agents, each with the full 256k window, using only ~53% of KV — the safe production setting. Push to 22 only for pure batch throughput with short-lived sessions.


Reproducing the quantization

# 1. Environment (host or container with CUDA; quantization itself runs CPU-only)
uv pip install "llmcompressor>=0.12" "transformers>=4.57" accelerate

# 2. Free ≥80 GB RAM (unload any other model from the GPU). Add ≥48 GB NVMe swap —
#    the MoE expert linearization pass spikes memory well above the 69 GB BF16 footprint.
sudo fallocate -l 48G /swapfile2 && sudo chmod 600 /swapfile2 && \
  sudo mkswap /swapfile2 && sudo swapon /swapfile2

# 3. Run (data-free PTQ; no calibration dataset needed)
CUDA_VISIBLE_DEVICES="" python quantize.py

quantize.py (verbatim recipe used for this checkpoint):

from llmcompressor import oneshot
from llmcompressor.modifiers.quantization import QuantizationModifier
from llmcompressor.utils import load_context
from transformers import AutoTokenizer, Qwen3_5MoeForConditionalGeneration

MODEL_ID = "Kwaipilot/KAT-Coder-V2.5-Dev"

with load_context(Qwen3_5MoeForConditionalGeneration):
    model = Qwen3_5MoeForConditionalGeneration.from_pretrained(
        MODEL_ID, dtype="bfloat16", low_cpu_mem_usage=True)
tokenizer = AutoTokenizer.from_pretrained(MODEL_ID)

recipe = QuantizationModifier(
    targets="Linear",
    scheme="FP8_DYNAMIC",
    ignore=[
        "re:.*lm_head",
        "re:.*visual.*",
        "re:.*mlp.gate$",
        "re:.*shared_expert_gate$",   # REQUIRED — see "Critical" section above
    ],
)

oneshot(model=model, recipe=recipe)

# text-only release: strip the randomly-initialized vision tower before saving
for owner in (model, getattr(model, "model", None)):
    for attr in ("visual", "vision_tower", "vision_model"):
        if owner is not None and hasattr(owner, attr):
            try: delattr(owner, attr)
            except Exception: setattr(owner, attr, None)

model.save_pretrained("KAT-Coder-V2.5-Dev-FP8-Dynamic", save_compressed=True)
tokenizer.save_pretrained("KAT-Coder-V2.5-Dev-FP8-Dynamic")

recipe.yaml (also shipped in this repo):

default_stage:
  default_modifiers:
    QuantizationModifier:
      targets: [Linear]
      ignore: ['re:.*lm_head', 're:.*visual.*', 're:.*mlp.gate$', 're:.*shared_expert_gate$']
      scheme: FP8_DYNAMIC
      bypass_divisibility_checks: false

Wall time on DGX Spark (CPU-only): ~5 min (load + MoE linearization + RTN + compressed save). Output: 35.77 GB single model.safetensors.


Verification

Boot-time confirmation from a live vLLM serve on DGX Spark:

Model loading took 33.52 GiB memory and 224.445083 seconds
GPU KV cache size: 5,960,926 tokens
Free memory on device (110.54/121.63 GiB) ... Actual usage is 33.52 GiB for weight,
  1.16 GiB for peak activation, -1.86 GiB for non-torch, -0.01 GiB for CUDAGraph.
  Current kv cache memory in use is 64.16 GiB.
FlashInfer resolved ... kv_cache_dtype=torch.float8_e4m3fn, arch=sm121
Starting vLLM server on http://127.0.0.1:8002

Tool-calling (qwen3_coder parser) and <think> reasoning (qwen3 parser) both verified end-to-end through LiteLLM → llama-swap → vLLM.


Attribution



🇷🇺 Русская версия

KAT-Coder-V2.5-Dev FP8-Dynamic (готов для vLLM)

FP8-Dynamic посттренировочная квантизация модели Kwaipilot/KAT-Coder-V2.5-Dev — 35B (3B активных) гибридно-внимательный MoE-кодер из семейства Kwaipilot KAT-Coder V2.5. Этот чекпункт вдвое снижает потребление VRAM и примерно вдвое расширяет ёмкость KV-кэша относительно BF16-оригинала, оставляя >99,9 % параметров в FP8, и проверен на загрузку и инференс на одном NVIDIA DGX Spark (GB10 / sm_121a) под vLLM.

Базовая модель Kwaipilot/KAT-Coder-V2.5-Dev (Qwen3.6-35B-A3B)
Архитектура Qwen3_5MoeForConditionalGeneration (qwen3_5_moe)
Параметры 35B всего / 3B активных (MoE: 256 экспертов, 8 на токен)
Слои 40, гибрид [linear, linear, linear, full] × 10 (линейное внимание Gated DeltaNet + полное внимание, 3:1)
Hidden / словарь 2048 / 248 320
Контекст 262 144 токена (нативный max_position_embeddings)
Квантизация FP8-Dynamic: W8A8 float, веса per-channel (статичные, memoryless_minmax), активации per-token (динамические)
Распределение dtype 94,0 % float8_e4m3fn (33,62 ГБ) + 6,0 % bfloat16 (2,14 ГБ)
Размер чекпойнта 35,77 ГБ (один model.safetensors)
VRAM при util 0.80 веса 33,52 ГиБ + KV-кэш 64,16 ГиБ на устройстве 121,6 ГиБ
Лицензия Apache-2.0 (унаследована от базы)

Что это за модель

KAT-Coder-V2.5-Devкодер/агентная модель из технического отчёта Kwaipilot KAT-Coder V2.5, дообученная на базе Qwen3.6-35B-A3B. База — гибридный linear/full-attention MoE: 40 слоёв в паттерне 3× линейное внимание (Gated DeltaNet) + 1× полное внимание, с 256 маршрутизируемыми экспертами (8 активируются на токен) плюс общий эксперт. На токен срабатывает лишь ~3B параметров, что делает декод дешёвым на устройствах с ограниченной пропускной способностью памяти (как DGX Spark), но сохраняет полную ёмкость 35B для качества.

Этот дериватив применяет data-free FP8-Dynamic PTQ через llmcompressor, чтобы модель уместилась на одном GPU класса 128 ГБ с большим KV-бюджетом — это позволяет держать множество параллельных агентских сессий.


⚠️ Критично: shared_expert_gate остаётся BF16 (прочитать перед повторной квантизацией)

Это единственный и самый важный подводный камень при обслуживании этого чекпойнта в vLLM.

Реализация MoE Qwen3_5 / Qwen3Next в vLLM создаёт shared_expert_gate как неквантованную ReplicatedLinear (см. vllm/model_executor/models/qwen3_next.py, строку self.shared_expert_gate = ReplicatedLinear(..., quant_config=None, ...)). Если этот модуль квантовать в FP8 и приложить weight_scale, vLLM упадёт при загрузке:

ValueError: There is no module or parameter named 'layers.0.mlp.shared_expert_gate.weight_scale'
in Qwen3_5Model. The available parameters belonging to layers.0.mlp.shared_expert_gate
(ReplicatedLinear) are: {'layers.0.mlp.shared_expert_gate.weight'}

Решение (уже применено в этом чекпойнте): рецепт игнорирует re:.*shared_expert_gate$, поэтому эти 40 тензоров остаются bfloat16 и грузятся чисто. Маршрутизируемые эксперты и проекции shared_expert MLP остаются FP8 (обслуживаются TRITON Fp8 MoE-бэкендом vLLM). При повторной квантизации с нуля обязательно включите этот ignore.

Полный ignore-список:

ignore:
  - 're:.*lm_head'              # никогда не квантовать выходную голову
  - 're:.*visual.*'             # text-only релиз не содержит vision-весов
  - 're:.*mlp.gate$'            # TopK-роутер (Parameter, авто-пропуск — для единообразия)
  - 're:.*shared_expert_gate$'  # ← ОБЯЗАТЕЛЬНО: vLLM грузит это неквантованным

Совместимость

  • vLLM ≥ 0.26.0 — проверено на ghcr.io/timothystewart6/vllm-gb10:v0.26.0-gb10.6 (vLLM 0.26.1.dev0+g568afb3a1.d20260801, CUDA 13.2, PyTorch 2.11, FlashInfer v0.6.14).
  • --language-model-only обязателен. База — мультимодальный класс ConditionalGeneration, но этот релиз содержит только текстовые веса; без флага vLLM попытается инициализировать vision-tower, которого нет в чекпойнте.
  • Железо: DGX Spark (SoC GB10, sm_121a). FP8-путь идёт через Triton scaled_mm + Marlin (ядро CutlassFP8) + TRITON Fp8 MoE + FlashInfer. DeepGEMM/MXFP4 на sm_121 недоступны — оставьте VLLM_USE_DEEP_GEMM=0.
  • Голов MTP нет (mtp_num_hidden_layers: 0). Для спекулятивного декода используйте n-gram (бесплатно) или EAGLE3 (если обучите голову).

Быстрый старт — vllm serve

См. английскую секцию выше — команда идентична. Ключевые флаги: --language-model-only (обязателен), --kv-cache-dtype fp8, --reasoning-parser qwen3, --tool-call-parser qwen3_coder (НЕ qwen3_xml), --speculative-config ngram.


Продуктивное развёртывание на DGX Spark (LiteLLM + llama-swap swap-стек)

Этот чекпойнт обслуживается в продакшене за swap-архитектурой: одновременно только одна vLLM-модель горячая и меняется по требованию, что позволяет одному устройству 128 ГБ держать несколько крупных моделей без конфликтов.

Клиенты / OpenCode ─► LiteLLM :14000 ─► llama-swap :8000 ─► ОДИН активный vLLM-контейнер
                   (алиасы, гвардраилы,     (systemd,         (порт назначается по алфавиту;
                    prefix-cache, redis)    -watch-config      kat-coder → :8002)
                                            hot-reload)

Полные YAML-блоки для llama-swap и LiteLLM см. в английской секции. Swap происходит по запросу: обращение к kat-coder выгружает текущую модель (напр. ThinkingCap) и холоднозагружает эту (~6 мин до готовности, см. таблицу производительности). sendLoadingState: true транслирует прогресс загрузки в chat-UI.


Рекомендации по сэмплингу

Режим temperature top_p top_k presence_penalty
Thinking (по умолчанию) 1.0 0.95 20 1.5
Non-thinking / инструкции 0.7 0.80 20 1.5

Чат-шаблон — Qwen3 ChatML с разделителями рассуждения <think>…</think> и параметрами enable_thinking / preserve_thinking. В generation_config.json идут temperature=1.0, top_k=20, top_p=0.95.


Производительность на DGX Spark (замеры)

Один DGX Spark, GB10 (sm_121a), 121,63 ГиБ объединённой памяти, --gpu-memory-utilization 0.80, --kv-cache-dtype fp8, n-gram spec decode (3 токена), все ядра прогреты.

Метрика Значение
Холодный старт — веса 224,4 с (33,52 ГиБ, EXT4 prefetch)
Холодный старт — init engine 99,2 с (compile 29,0 с + profile + захват CUDA-graph)
Полный холодный старт до готовности ~6 мин
VRAM под веса 33,52 ГиБ
VRAM под KV-кэш 64,16 ГиБ (FP8)
Размер GPU KV-кэша 5 960 926 токенов
Декод (один поток, E2E через LiteLLM→llama-swap→vLLM) ~47–50 ток/с
Префилл (1 запрос) ~30 ток/с

Ядра, выбранные vLLM (verbatim из логов): CutlassFP8ScaledMMLinearKernel (веса), TRITON Fp8 MoE (эксперты), FLASHINFER (полное внимание), Triton/FLA GDN (линейное внимание, head_k_dim=128).


Ёмкость под субагентов / конкурентность (один DGX Spark)

Гибридная архитектура хранит KV-состояние только для 10 слоёв полного внимания (30 линейно-внимательных слоёв — рекуррентные/состоянием, почти без KV). В сочетании с FP8 KV-кэшем это даёт очень большой токенный бюджет.

Математика KV-бюджета: 5 960 926 токенов / 262 144 = 22,7 → до 22 полных сессий с окном 256k влезают в KV-кэш. Ограничивающий фактор — cap планировщика (--max-num-seqs), а не память.

Конкурентность (субагенты) Контекст на агента Всего KV занято Утилизация KV Примечание
12 262 144 (полный) 3,15 М 52,8 % Конфиг по умолчанию; здоровый запас
12 131 072 (128k) 1,57 М 26,4 % Лёгкий режим
12 65 536 (64k) 0,79 М 13,2 % Комфортно
22 (поднять --max-num-seqs) 262 144 (полный) 5,77 М 96,8 % Максимум до OOM; агрессивно
8 262 144 (полный) 2,10 М 35,2 % Консервативно; как для dense-моделей

Рекомендация: --max-num-seqs 12 даёт 12 параллельных кодинг-агентов, каждый с полным окном 256k, используя лишь ~53 % KV — безопасный прод-сетап. Поднимайте до 22 только для чисто батчевого throughput с короткими сессиями.


Воспроизведение квантизации

Скрипт, рецепт и требования — см. английскую секцию выше (всё идентично). Время на DGX Spark (только CPU): ~5 мин. На выходе 35,77 ГБ одним model.safetensors.


Атрибуция

  • Базовая модель: Kwaipilot/KAT-Coder-V2.5-Dev — Kwaipilot KAT-Coder V2.5 (Apache-2.0).
  • Квантизация: llmcompressor (схема FP8_DYNAMIC, data-free PTQ).
  • Обслуживание: vLLM — проверено на образе vllm-gb10 для DGX Spark v0.26.0-gb10.6.
  • Лицензия: Apache-2.0 (унаследована).