--- 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`](https://huggingface.co/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](https://github.com/vllm-project/llm-compressor) 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: ```yaml 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` ```bash 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 `...` into OpenAI `reasoning_content`. | | `--tool-call-parser qwen3_coder` | Native tool format `V…` (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`): ```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`): ```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 `` 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 ```bash # 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): ```python 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): ```yaml 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 `` reasoning (`qwen3` parser) both verified end-to-end through LiteLLM → llama-swap → vLLM. --- ## Attribution - **Base model:** [`Kwaipilot/KAT-Coder-V2.5-Dev`](https://huggingface.co/Kwaipilot/KAT-Coder-V2.5-Dev) — Kwaipilot KAT-Coder V2.5 (Apache-2.0). - **Quantization:** [llmcompressor](https://github.com/vllm-project/llm-compressor) (`FP8_DYNAMIC` scheme, data-free PTQ). - **Serving:** [vLLM](https://github.com/vllm-project/vllm) — verified on the [`vllm-gb10`](https://github.com/timothystewart6/vllm-gb10) DGX-Spark image `v0.26.0-gb10.6`. - **License:** Apache-2.0 (inherited). --- --- # 🇷🇺 Русская версия # KAT-Coder-V2.5-Dev FP8-Dynamic (готов для vLLM) **FP8-Dynamic посттренировочная квантизация** модели [`Kwaipilot/KAT-Coder-V2.5-Dev`](https://huggingface.co/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](https://github.com/vllm-project/llm-compressor), чтобы модель уместилась на одном 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-список: ```yaml 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 с разделителями рассуждения `` и параметрами `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`](https://huggingface.co/Kwaipilot/KAT-Coder-V2.5-Dev) — Kwaipilot KAT-Coder V2.5 (Apache-2.0). - **Квантизация:** [llmcompressor](https://github.com/vllm-project/llm-compressor) (схема `FP8_DYNAMIC`, data-free PTQ). - **Обслуживание:** [vLLM](https://github.com/vllm-project/vllm) — проверено на образе [`vllm-gb10`](https://github.com/timothystewart6/vllm-gb10) для DGX Spark `v0.26.0-gb10.6`. - **Лицензия:** Apache-2.0 (унаследована).