Kaynağa Gözat

r31 version profile + r31/eugr recipes + night shift 09-10 plan

- docker-images/glm53-jovian-r27/profiles/glm53-r31.env: R31 source lock
  (vLLM 55769270 + b12x 3edbcbce + LMCache f868580a, clone-at-pin)
- recipes/glm53-flash-r31-{4x-dcp4,2x}: r28 forks + --prefill-compute-share
  0.4 + NCCL_NCHANNELS=16 (their qualified runtime)
- recipes/glm53-flash-eugr-2x: verbatim mirror of eugr's GLM-5.3-Flash yaml
  on the prebuilt spark-vllm-b12x nightly-20260909 image
- history/night-shifts/2026-09-10.md: campaign plan + baselines
Alexander Korolev 1 ay önce
ebeveyn
işleme
df77baae75

+ 40 - 0
docker-images/glm53-jovian-r27/profiles/glm53-r31.env

@@ -0,0 +1,40 @@
+# Version profile: GLM-5.3-Flash r31 source lock (2026-09-09 cut, all forks).
+#
+# Referenced from recipes via `build_profile = "glm53-r31"`; merged over this
+# image dir's versions.env (profile wins, then recipe [build.versions] wins
+# last). Only the keys that differ from versions.env are listed — the rest
+# (CUDA base, torch/flashinfer, apt) stay at the image dir's pins.
+#
+# Pinned by commit + tree hash (the Dockerfile gates HEAD + HEAD^{tree} per
+# repo); branch names are provenance, not the contract:
+#   vLLM    voipmonitor/vllm    integration/jovian-warmup-buffer-reuse-20260909
+#           (R31 cut: MoE warmup buffer reuse across route-id dtypes on top of
+#           the R28.1-R30 line: scheduler hardening, FP8 checkpoint serving,
+#           engine-driven async SHM LMCache + atomic recurrent checkpoints,
+#           GLM Flash MTP projection loader fix — our upstream issue,
+#           FlashInfer GDN prefill on SM12x)
+#   b12x    voipmonitor/b12x    integration/glm-fp8-checkpoint-serving-20260908
+#           (frozen since the 09-08 cut; unchanged across R28.1-R31)
+#   LMCache local-inference-lab/LMCache
+#           integration/jovian-write-through-restore-headroom-20260909
+#           (write-through L1 headroom reclaim on top of the 09-09 dedup line)
+#
+# The R31 cut is the latest published lock
+# (rtx6kpro models/glm-5.3-flash/validation/warmup-retention-r31.source.lock,
+# "qualified" status, published image
+# localinferencelab/vllm:jovian-judgement-community-20260909-r31).
+#
+# Build-dep gates verified against the r31 vLLM tree (55769270):
+# deepgemm.cmake still declares 8b1392b9 (= our versions.env pin, no bump),
+# requirements/cuda.txt still pins torch 2.13.0 + flashinfer 0.6.17.
+VLLM_PIN=5576927057cf71b6ec61d120932338b333efa089
+VLLM_TREE=6a2da27b08a1f062b00719c17cffdfa087ae4210
+VLLM_PRETEND_VERSION=0.1.dev0+glm53.r31.55769270
+
+B12X_PIN=3edbcbce70f491741b82f5eab9c1b30b39447228
+B12X_TREE=c4bfeee9f3c9457400d191c870eb2e44fbcd5c2e
+B12X_PRETEND_VERSION=0.1.dev0+glm53b12x.r31.3edbcbce
+
+LMCACHE_PIN=f868580a475b7e6f7fd81e586526481d4dbead0e
+LMCACHE_TREE=6e5f080f794962bf8c667ffcdb46b210d7023b15
+LMCACHE_VERSION=0.5.5.dev0+glm53cache.engine.f868580a

+ 76 - 0
history/night-shifts/2026-09-10.md

@@ -0,0 +1,76 @@
+# Night shift 2026-09-10 (CEST) — r31 + eugr campaign
+
+Window: ~01:45–08:00 local. Operator approval: "Начинаем через 1.5 часа.
+Остановишь прод и вперед." (00:20 local, 2026-09-10).
+
+## Context
+
+- Production at window start: `glm53-flash-r28-4x-dcp4` on 4nodes-switch
+  (r28 stack: vLLM 62f6385c / b12x 7216f6b9 / LMCache 934c287a; 155/159
+  hardmode, ~46.8 tok/s decode, RoCEnante on).
+- Update scan (2026-09-09/10) found a full new release line R28.1 → R29 →
+  R30 → **R31 (qualified)** in `local-inference-lab/rtx6kpro` source locks
+  (models/glm-5.3-flash/validation/*):
+  - R31 = vLLM `55769270` (integration/jovian-warmup-buffer-reuse-20260909)
+    + b12x `3edbcbce` (frozen since 09-08) + LMCache `f868580a`.
+  - Carries the **GLM Flash MTP projection loader fix** (our upstream
+    eh_proj.weight O_DIRECT issue), FlashInfer GDN prefill on SM12x,
+    b12x TP2 graph peer-push fix, scheduler hardening (fixed prefill
+    compute share 0.4), engine-driven async SHM LMCache + atomic
+    recurrent checkpoints, 16-channel NCCL.
+  - Published image for cross-check:
+    `localinferencelab/vllm:jovian-judgement-community-20260909-r31`.
+- **eugr lane** (operator: "eugr — это тоже b12x вариант, тоже интересно
+  для glm53"): `eugr/spark-vllm-docker` (MIT) ships a cluster_only
+  dual-Spark GLM-5.3-Flash recipe on their experimental b12x stack
+  (`--load-format b12x` loader, MTP k=5 "humming", 1M ctx, 8 GiB KV,
+  GMU 0.87). Prebuilt image `eugr/spark-vllm-b12x:nightly-20260909`
+  (Docker Hub, ~11 GB). Their vLLM ref = `local-inference-lab/vllm` @
+  `dev/jovian-judgement` (mainline line, 41ea64ae — diverged from the
+  integration release cuts: +16/-39 vs r28).
+
+## Artifacts (prepared before the window, no prod impact)
+
+- `docker-images/glm53-jovian-r27/profiles/glm53-r31.env` — named version
+  profile (clone-at-pin: vLLM 55769270/tree 6a2da27b, b12x 3edbcbce/tree
+  c4bfeee9, LMCache f868580a/tree 6e5f080f). Build-dep gates verified
+  against the r31 tree: deepgemm.cmake still 8b1392b9, cuda.txt still
+  torch 2.13.0 / flashinfer 0.6.17 — the r27 image dir's gates hold.
+- `recipes/glm53-flash-r31-4x-dcp4/` — fork of the r28 4x recipe (model
+  GLM-5.3-Flash-NVFP4, 16 GiB KV pin); delta: `--prefill-compute-share
+  0.4` + `NCCL_NCHANNELS=16`.
+- `recipes/glm53-flash-r31-2x/` — fork of r28-spark 2x (model
+  GLM-5.3-Flash-NVFP4-Spark, 10 GiB KV pin); same delta.
+- `recipes/glm53-flash-eugr-2x/` — verbatim mirror of eugr's
+  `recipes/glm-5.3-flash.yaml` on the prebuilt nightly-20260909 image
+  (no build: no docker_image_dir).
+- eugr image pull started on dgx1+dgx2 pre-window.
+- LMCache engine-driven SHM deliberately NOT enabled in the first A/B:
+  the r31-vs-r28 comparison must isolate the engine line; the LMCache
+  connector (kv_transfer lmcache offload) is a separate axis for a later
+  window. `--recurrent-checkpoint-policy` defaults to `auto` in r31 (no
+  flag needed).
+
+## Plan
+
+| # | Step | Command / note |
+|---|------|----------------|
+| 1 | Stop prod | `sm121 stop --recipe glm53-flash-r28-4x-dcp4` + 15 s settle + verify no containers on 4 nodes |
+| 2 | Build r31 | `sm121 build --recipe glm53-flash-r31-4x-dcp4 --build-node dgx1.lan` (~1 h, clone-at-pin; image syncs to the other nodes) |
+| 3 | r31 4x A/B | `sm121 serve --recipe glm53-flash-r31-4x-dcp4` → API gate 88.14:30000 → `sm121 bench --recipe glm53-flash-r31-4x-dcp4 --cluster 4nodes-switch --label r31-4x` |
+| 4 | r31 2x A/B | stop → `sm121 serve --recipe glm53-flash-r31-2x` → bench label `r31-2x` on 2nodes-dac |
+| 5 | eugr 2x | stop → `sm121 serve --recipe glm53-flash-eugr-2x` → bench label `eugr-2x` on 2nodes-dac |
+| 6 | Verdict + restore | best 4x-candidate to prod (r31 vs r28); `sm121 serve` + API verify |
+| 7 | Report | this file + glm53-recipe-state.md score table + commit/push |
+
+Baselines (seed 42, hardmode, tool-eval-bench 2.6.1.dev46, 88 scenarios):
+
+| Lane | Score | Perf (pp/tg/TTFT, d0 c1) |
+|------|-------|---------------------------|
+| r28 4x DCP4 (PROD) | 155/159 (90) | ~1,500-1,600 / ~46.8 / — |
+| r28 2x DAC (spark) | 158/176 (90) | 1,475 / 27.2 / 1,362 |
+| eugr 2x (their yaml) | — | — |
+
+## Results
+
+(pending — filled as the shift progresses)

+ 105 - 0
recipes/glm53-flash-eugr-2x/recipe.toml

@@ -0,0 +1,105 @@
+# eugr b12x lane (2026-09-10) — verbatim mirror of eugr/spark-vllm-docker
+# recipes/glm-5.3-flash.yaml (their cluster_only dual-Spark B12X recipe),
+# run on the eugr/prebuilt image instead of their build-and-copy.sh flow.
+#
+# Image: eugr/spark-vllm-b12x:nightly-20260909 (Docker Hub, ~11 GB). Built
+# by their --exp-b12x path from the FLOATING refs: vLLM
+# local-inference-lab/vllm @ dev/jovian-judgement (41ea64ae at 09-10, the
+# mainline line — NOT the integration/glm53-r31 release cut) + b12x master.
+# Provenance: https://github.com/eugr/spark-vllm-docker (MIT).
+#
+# This is a third-party independent b12x stack, A/B'd against our r28/r31
+# lanes on the SAME model (GLM-5.3-Flash-NVFP4-Spark) and fabric. Their
+# notable deviations vs our stack:
+#   * --load-format b12x (their experimental b12x loader, 09-06: "faster and
+#     more memory efficient than Instanttensor") — NOT instanttensor
+#   * --moe-backend b12x + --linear-backend b12x (W4A4 linear kernels — our
+#     r17 bisect found these destructive on the r17 stack; their new loader
+#     may have fixed numerics, the bench decides)
+#   * MTP k=5 with moe_backend "humming" (vs our k=3)
+#   * 1M ctx, max-num-seqs 4 (vs our 512K/16), KV pinned 8 GiB, GMU 0.87
+#   * V2 model runner + AOT/MEGA-AOT on, spawn workers, PCIE AR off
+#
+# Baseline for the A/B: glm53-flash-r31-2x / glm53-flash-r28-spark on
+# 2nodes-dac (r28: 158/176, 1475 pp / 27.2 tg / 1362 ms d0 c1).
+
+engine = "vllm"
+name = "GLM-5.3-Flash NVFP4-Spark (eugr b12x img, 2x)"
+docker_image = "eugr/spark-vllm-b12x:nightly-20260909"  # prebuilt (no build: no docker_image_dir)
+model = "local-inference-lab/GLM-5.3-Flash-NVFP4-Spark"
+required_nodes = 2
+tensor_parallel_size = 2
+pipeline_parallel_size = 1
+distributed_backend = "mp"
+shm_size = "32gb"
+entrypoint = ["vllm", "serve"]
+
+args = [
+    "--served-model-name", "glm53",
+    "--trust-remote-code",
+    "--distributed-executor-backend", "mp",
+    "--mamba-cache-mode", "align",
+    "--enable-prefix-caching",
+    "--enable-chunked-prefill",
+    "--dtype", "bfloat16",
+    "--kv-cache-dtype", "fp8",
+    "--quantization", "modelopt_mixed",
+    "--attention-backend", "B12X",
+    "--block-size", "256",
+    "--moe-backend", "b12x",
+    "--linear-backend", "b12x",
+    "--no-enable-flashinfer-autotune",
+    "--load-format", "b12x",
+    "--max-model-len", "1048576",
+    "--max-num-seqs", "4",
+    "--max-num-batched-tokens", "4096",
+    "--speculative-config", """
+'{"method":"mtp","num_speculative_tokens":5,"moe_backend":"humming","attention_backend":"B12X"}'""",
+    "--reasoning-parser", "glm45",
+    "--tool-call-parser", "glm47",
+    "--enable-auto-tool-choice",
+    "--kv-cache-memory-bytes", "8589934592",
+    "--gpu-memory-utilization", "0.87",
+    # Their launcher bakes these envs into the image; kept explicit here so
+    # the recipe stays self-documenting (the image's own env is the default,
+    # ours overrides with identical values).
+]
+
+[env]
+HF_HUB_OFFLINE = "1"
+CUTE_DSL_ARCH = "sm_121a"
+SAFETENSORS_FAST_GPU = "1"
+VLLM_ENABLE_ROCE_ALLREDUCE = "1"
+VLLM_ROCE_ALLREDUCE_MAX_SIZE = "2MB"
+VLLM_WORKER_MULTIPROC_METHOD = "spawn"
+VLLM_SSM_CONV_STATE_LAYOUT = "DS"
+VLLM_USE_AOT_COMPILE = "1"
+VLLM_USE_MEGA_AOT_ARTIFACT = "1"
+VLLM_USE_V2_MODEL_RUNNER = "1"
+VLLM_ENABLE_PCIE_ALLREDUCE = "0"
+B12X_POLICY_MODE = "auto"
+INSTANTTENSOR_BACKEND = "BUFFERED"
+INSTANTTENSOR_BUFFER_SIZE = "67108864"
+INSTANTTENSOR_CHUNK_SIZE = "8388608"
+INSTANTTENSOR_CONCURRENCY = "1"
+INSTANTTENSOR_IO_DEPTH = "3"
+# JIT caches persist per-node (self-namespace by engine version key)
+OMP_NUM_THREADS = "2"
+MAX_JOBS = "2"
+VLLM_ENGINE_READY_TIMEOUT_S = "3600"
+
+[[extra_mounts]]
+host = "~/sm121-cache/glm53-jit-121f/b12x"
+container = "/root/.cache/b12x"
+
+[[extra_mounts]]
+host = "~/sm121-cache/jit-121f/flashinfer"
+container = "/root/.cache/flashinfer"
+
+[[extra_mounts]]
+host = "~/sm121-cache/jit-121f/torchinductor"
+container = "/root/.cache/torchinductor"
+
+[[extra_mounts]]
+host = "~/sm121-cache/jit-121f/vllm"
+container = "/root/.cache/vllm"

+ 225 - 0
recipes/glm53-flash-r31-2x/recipe.toml

@@ -0,0 +1,225 @@
+# GLM-5.3-Flash NVFP4 — local-inference-lab quant (vLLM) — 2× DGX Spark, TP=2.
+#
+# local-inference-lab mixed quant: NVFP4 routed experts (layers 3–44,
+# group-16) + MXFP8 MTP experts (layer 45) + W4A4 input scales. Best agent
+# quant so far: tool-eval-bench 89/100 (vs 85 LibertAIDAI, 90 official FP8).
+# Model: https://huggingface.co/local-inference-lab/GLM-5.3-Flash-NVFP4
+#        (~186 GB → 92.72 GiB weights/node; KV pinned at 10 GiB, see below)
+#
+# Image: glm53-flash-nvfp4-lab:local (docker-images/glm53-flash-nvfp4-lab/ —
+# day-0 arm64 image + NoPE-MLA mod + the four FujitsuPolycom lab-checkpoint
+# patches: model naming shim, modelopt MTP namespace fix, persistent_topk
+# CC-12.x guards). Their launch config is mirrored below.
+# PROVENANCE: https://github.com/FujitsuPolycom/glm53-flash-tp2-spark
+#             (Apache-2.0; see patches/UPSTREAM.md) + forum 381350 #41.
+#
+# Deviations from their launch script (intentional):
+#   * no --kda-prefill-backend flashkda (needs their base-image patch — skipped)
+#   * --kv-cache-dtype fp8_ds_mla instead of `fp8` (same packed layout; this
+#     spelling is what the NoPE-MLA mod booted with on the LibertAIDAI stack)
+#   * --language-model-only + no mm-renderer patch/env (text-only)
+#   * no bundled NCCL/LD_PRELOAD, no NCCL_* fabric block (our switched fabric
+#     is configured via [nccl.ds4] + launcher GID auto-detect)
+#   * no --moe-backend marlin: their proven stack uses the default backend for
+#     THIS quant and reports clean evals. Sanity-check output for token loops
+#     anyway (the silent FP4 MoE corruption gotcha) before trusting a new node.
+#   * flashinfer autotune disabled via --kernel-config (their proven boot);
+#     VLLM_ENGINE_READY_TIMEOUT_S stays high regardless.
+#
+# Boot success markers (engine log, in order):
+#   "Model loading took 92.72 GiB" → "[quantprobe] ... algo=MXFP8" (MTP fix
+#   active; algo=None means broken) → "GPU KV cache size: 1,164,369 tokens" →
+#   "Application startup complete". ~700 s sequential weight load.
+#
+# Test request: chat completions need "chat_template_kwargs":{"reasoning_effort"
+# :"low"} — omitted/other values select MAX reasoning effort (empty content on
+# short max_tokens).
+#
+# Optional: instanttensor loader (~30 s weight load vs ~700 s):
+#   FROM glm53-flash-nvfp4-lab:local + pip install --no-deps --no-build-isolation
+#   instanttensor==0.1.9, then add --load-format instanttensor (--no-deps is
+#   required: resolution would downgrade the image's NCCL).
+#
+# PREREQUISITES: weights cached on both nodes:
+# [A/B CELL 2026-09-03] ship recipe verbatim, checkpoint swapped to the lab
+# non-Spark NVFP4 (isolates checkpoint from image lineage vs the lab-image cell).
+# [BISECT A2 2026-09-03] EXACT 90/100 recipe (236ce5a) + instanttensor + JIT
+# mounts, on the CURRENT eugr-patched image. Isolates image lineage from the
+# execution-env/flag cluster (AOT/V2/b12x/card-env). Comparator: 124/138.
+# GLM-5.3-Flash NVFP4-Spark — local-inference-lab quant with the speculative
+# layers embedded — 2× DGX Spark, TP=2.
+#
+# local-inference-lab/GLM-5.3-Flash-NVFP4-Spark (rev 06972cdee7280cec849aedf05a02062b3e870246):
+# NVFP4 routed experts (layers 3+, group-16) + NVFP4 MTP expert layer in the
+# separate model-mtp-0000x.safetensors shards (mtp_tokens: 5 per their
+# lil.yaml), amax/nonexpert/inputscales side shards, Glm5NextForConditionalGeneration.
+# THE "DSpark speculative embedded" checkpoint — no separate DFlash2 download
+# needed; lil.yaml: default_speculator mtp, dflash2_tokens 7 (r12 doc fr: their
+# standalone-Q: MTP:3 254 tok/s CC1, 333 Sieve, 94 steps/s).
+#
+# Image: glm53-flash-nvfp4-lab:local (same proven day-0 arm64 stack + NoPE-MLA
+# mod + modelopt MTP namespace patch used by the 92/100 lab lane). The MTP
+# layer here is NVFP4 (not MXFP8) — the quantprobe marker may print
+# algo=NVFP4/- different; algo=None = patch missed (fall back to 4p67 image).
+#
+# Deviations from lab (unchanged mechanics): same fabric/env/GMU/KV pinning.
+# lil.yaml launch mirrors: block 256, disable_flashinfer_autotune, mm data
+# mode — our text-only flags identical to glm53-flash-nvfp4-lab.
+#
+# Boot markers: "Model loading took ~XX GiB" → "[quantprobe] ..." →
+# "GPU KV cache size" → "Application startup complete".
+#
+# PREREQUISITES: weights on the NAS hub (175 GiB): hf download local-inference-lab/GLM-5.3-Flash-NVFP4-Spark
+
+engine = "vllm"
+name = "GLM-5.3-Flash NVFP4-Spark (r31 img, 2x DAC)"
+docker_image = "glm53-jovian-r31:local"  # r27 clone-at-pin build (docker-images/glm53-jovian-r27)
+docker_image_dir = "glm53-jovian-r27"
+build_profile = "glm53-r31"
+# Required: the clean r12 image follows the solar contract (ENTRYPOINT []
+# + CMD bash), so the recipe carries the entrypoint (the old day-0-based
+# r12 image had ["vllm","serve"] baked in, which is why this was absent
+# until the clean rebuild).
+entrypoint = ["vllm", "serve"]
+model = "local-inference-lab/GLM-5.3-Flash-NVFP4-Spark"
+required_nodes = 2
+tensor_parallel_size = 2
+pipeline_parallel_size = 1
+distributed_backend = "mp"
+shm_size = "32gb"
+
+args = [
+    # R31 delta (their r28.1-r31 locks): adaptive prefill/decode
+    # compute-time sharing with a fixed 40% prefill floor.
+    "--prefill-compute-share", "0.4",
+    # Stable served name — quant-agnostic (shared across glm53 quants)
+    "--served-model-name", "glm53",
+    "--trust-remote-code",
+    "--distributed-executor-backend", "mp",
+    # GMU is ONLY a startup guardrail here (KV pool is pinned below): 0.90
+    # demands 109.46 GiB free on GB10's 121.63 GiB, but driver reserve +
+    # page cache routinely leave ~108.5 -> flaky
+    # "Free memory ... less than desired" boot deaths (this was the class
+    # of the old "54-second death"), and post-crash reruns see ~106.6 GiB.
+    # 0.82 = 99.7 GiB, below any realistic dip; does NOT change what gets
+    # allocated (weights ~93 + pinned KV 10 + activations).
+    # 0.88 (not 0.90): the startup admission gate is free-mem >= GMU*total
+    # (107.0 vs 109.5 GiB); ~12 GiB of starting vLLM processes + docker
+    # daemon can push the 0.90 check under the line (2026-09-08, #48140).
+    # KV is explicitly pinned (--kv-cache-memory-bytes) so capacity is unchanged.
+    "--gpu-memory-utilization", "0.88",
+    # Pinned 10 GiB KV (≈1.16M tokens) — GMU sizing has no headroom at
+    # 92.72 GiB weights/node; pinning also keeps warmup off the swap path
+    "--kv-cache-memory-bytes", "10737418240",
+    "--kv-cache-dtype", "nvfp4_ds_mla",
+    # The GLM5Next model wires the B12X sparse-MLA backend (sm_120/sm_121)
+    # when the global backend is B12X (glm5next/nvidia/attention.py:
+    # _select_sparse_backend); the sm12x auto-priority list never offers it
+    # (FLASHINFER_MLA_SPARSE_SM120 only supports head 576, not GLM's 512).
+    "--attention-backend", "B12X",
+    # pure I/O loader (kept across every config; 171 GB in ~5.5 min vs ~16 NFS)
+    "--load-format", "instanttensor",
+    # [R17 FULL-CLUSTER TEST] lil manifest backends (quality gate: hardmode
+    # must stay ≥88; r12-era this cluster dropped it to 74 — r17 may carry
+    # the fix through — one boot decides).
+    "--block-size", "256",
+    # FINAL BISECT (2026-09-03, hardmode 176pt, r17 img):
+    #   knobs-only 87: d0 c1 24.1, d8192 23.8
+    #   +moe b12x  88: d0 c1 23.5, d8192 26.6  <- SHIP (2 pts d8192)
+    #   +linear b12x 44: W4A4 linear kernel destroys numerics (param-precision 0%)
+    #   +align     88: but d0 c1 18.6 (-5) — perf-negative, dropped
+    # (all three together = 44-74; the lab needs its private packed package)
+    "--max-model-len", "524288",
+    "--max-num-seqs", "16",
+    "--max-num-batched-tokens", "4096",
+    "--enable-chunked-prefill",
+    "--async-scheduling",
+    "--enable-prefix-caching",
+    # NO --disable-custom-all-reduce here: in the r27 fork the RoCEnante
+    # adapter is gated on the custom-all-reduce enable flag
+    # (use_roce_allreduce = use_custom_allreduce && VLLM_ENABLE_ROCE_ALLREDUCE).
+    # On 2x/4x 1-GPU-node clusters vLLM's own CUDA-IPC custom AR is functionally
+    # inert (no cross-node P2P), so dropping the flag only opens the b12x path;
+    # the b12x-PCIe branch stays off (VLLM_ENABLE_PCIE_ALLREDUCE defaults False).
+    # Their proven boot: no flashinfer autotune, no CuTe-DSL warmup
+    "--kernel-config", """
+'{"enable_cutedsl_warmup":false,"enable_flashinfer_autotune":false}'""",
+    # Built-in MTP draft, 3 tokens (the r12-qualified "mtp:3" mode — their
+    # x86 numbers: 254 tok/s CC1, 2.37 accept; the checkpoint embeds up to
+    # 5 via the model-mtp-0000x shards but 3 is the verified depth). This is
+    # the checkpoint's own MTP head (Glm5NextMTPModel), NOT dspark — dspark
+    # is the DeepSeek-V4 family's mechanism; GLM's other r12 mode is
+    # dflash2:7 with a separate trained draft checkpoint.
+    # The draft model's vllm_config takes its attention backend from the
+    # SPECULATIVE config, not the global flag (eagle/utils.py:
+    # _make_eagle_draft_vllm_config) — B12X here mirrors the main model's.
+    "--speculative-config", """
+'{"method":"mtp","num_speculative_tokens":3,"attention_backend":"B12X"}'""",
+    "--language-model-only",
+    # MTP + CUDA graphs degrades OUTPUT QUALITY on the glm53 day-0 dev build
+    # (forum #381350/#44, CONFIRMED by A/B bench 2026-08-28: same seed/flags,
+    # graphs on = 89/100, eager = 92/100; decode unchanged 28.4 t/s @ c1,
+    # c2 -7%, TTFT +1.6s). The b12x glm52 stack does NOT need this (its
+    # graphs+MTP combo benches clean at 100/100) — bug is build-specific.
+    # graphs moved BEFORE tool-call-parser; enforce-eager removed for the
+    # r17-graphs test (bisect A2 was 88/100 eager; graphs+MTP fix is public
+    # in r17 refs? verify by bench).
+    "--tool-call-parser", "glm47",
+    "--enable-auto-tool-choice",
+    "--reasoning-parser", "glm45",
+]
+
+[env]
+
+# R31 lock: 16 NCCL channels (their qualified runtime).
+NCCL_NCHANNELS = "16"
+HF_HUB_OFFLINE = "1"
+# RoCEnante (b12x one-shot RoCE all-reduce/all-gather) — default on for r27
+# lanes since the 2026-09-08 A/B (4x DCP4: decode +31..+90%, quality 160 vs
+# 155, prefill within noise; specs/tech-architecture/glm53-recipe-state.md,
+# history/night-shifts/2026-09-07.md). Needs the CX-7 RoCE fabric (all of
+# ours); single-node serves skip it silently. Caps default 2MB AR / 16MB AG.
+VLLM_ENABLE_ROCE_ALLREDUCE = "1"
+# FlashInfer JIT (mxfp8_gemm_cutlass_sm120, ~12 kernels) compiles at first
+# boot with 12 parallel nvcc jobs -> OOM-killed (code 137) on GB10's
+# 121 GB unified while the 93 GB weights + 10 GB KV pin are resident.
+# MAX_JOBS caps ninja parallelism so the JIT fits in the remaining ~20 GB.
+MAX_JOBS = "2"
+# NoPE-MLA rope-pad runtime gate (mod baked into the image)
+VLLM_MLA_NOPE_PAD_ROPE = "1"
+VLLM_ENGINE_READY_TIMEOUT_S = "3600"
+# Upstream launch-script env (memory + compile knobs)
+PYTORCH_CUDA_ALLOC_CONF = "expandable_segments:True"
+VLLM_USE_AOT_COMPILE = "0"
+VLLM_USE_STANDALONE_COMPILE = "1"
+VLLM_USE_FLASHINFER_SAMPLER = "1"
+VLLM_USE_BREAKABLE_CUDAGRAPH = "0"
+TORCH_USE_RTLD_GLOBAL = "1"
+VLLM_NO_USAGE_STATS = "1"
+
+# Architecture (aarch64 / sm_121a DGX Spark)
+TORCH_CUDA_ARCH_LIST = "12.1a"
+FLASHINFER_CUDA_ARCH_LIST = "12.1f"
+CUTE_DSL_ARCH = "sm_121a"
+CMAKE_CUDA_ARCHITECTURES = "121"
+OMP_NUM_THREADS = "2"
+
+[[extra_mounts]]
+host = "~/sm121-cache/glm53-jit-121f/b12x"
+container = "/root/.cache/b12x"
+
+# JIT caches persist per-node across serves (was: cold /root/.cache per
+# container -> ~20 min flashinfer/torch recompile every serve). The host
+# dirs are shared between lanes of the same arch — each cache
+# self-namespaces by its engine version key internally.
+[[extra_mounts]]
+host = "~/sm121-cache/jit-121f/flashinfer"
+container = "/root/.cache/flashinfer"
+
+[[extra_mounts]]
+host = "~/sm121-cache/jit-121f/torchinductor"
+container = "/root/.cache/torchinductor"
+
+[[extra_mounts]]
+host = "~/sm121-cache/jit-121f/vllm"
+container = "/root/.cache/vllm"

+ 254 - 0
recipes/glm53-flash-r31-4x-dcp4/recipe.toml

@@ -0,0 +1,254 @@
+# r28 4x DCP4 cell (2026-09-08) — clone of the r27 4x-dcp4 recipe (160/176
+# RoCEnante, 46.8 t/s) retargeted at the FULL r28 source lock (cut 2026-09-06
+# ~18:30 UTC across all three forks): vLLM 62f6385c (prefill/decode
+# compute-time sharing + interleaved parallel prefills, chat-template
+# rendering parity, GLM boundary restore, partial prefix-cache hits),
+# b12x 7216f6b9 (21 commits over r27: GLM/DeepSeek loader fixes, W4A4 FC1
+# fusion, M8 route prep, M1 FC2 overlap, GDN/MHC perf), LMCache 934c287a
+# (3 MP-transfer robustness fixes). Same model/flags/KV pin; the image is
+# the r27 build dir with the named version profile profiles/glm53-r28.env
+# (clone-at-pin fetches each commit directly, the tree gates verify them).
+
+# GLM-5.3-Flash NVFP4 — local-inference-lab quant (vLLM) — 2× DGX Spark, TP=2.
+#
+# local-inference-lab mixed quant: NVFP4 routed experts (layers 3–44,
+# group-16) + MXFP8 MTP experts (layer 45) + W4A4 input scales. Best agent
+# quant so far: tool-eval-bench 89/100 (vs 85 LibertAIDAI, 90 official FP8).
+# Model: https://huggingface.co/local-inference-lab/GLM-5.3-Flash-NVFP4
+#        (~186 GB → 92.72 GiB weights/node; KV pinned at 10 GiB, see below)
+#
+# Image: glm53-flash-nvfp4-lab:local (docker-images/glm53-flash-nvfp4-lab/ —
+# day-0 arm64 image + NoPE-MLA mod + the four FujitsuPolycom lab-checkpoint
+# patches: model naming shim, modelopt MTP namespace fix, persistent_topk
+# CC-12.x guards). Their launch config is mirrored below.
+# PROVENANCE: https://github.com/FujitsuPolycom/glm53-flash-tp2-spark
+#             (Apache-2.0; see patches/UPSTREAM.md) + forum 381350 #41.
+#
+# Deviations from their launch script (intentional):
+#   * no --kda-prefill-backend flashkda (needs their base-image patch — skipped)
+#   * --kv-cache-dtype fp8_ds_mla instead of `fp8` (same packed layout; this
+#     spelling is what the NoPE-MLA mod booted with on the LibertAIDAI stack)
+#   * --language-model-only + no mm-renderer patch/env (text-only)
+#   * no bundled NCCL/LD_PRELOAD, no NCCL_* fabric block (our switched fabric
+#     is configured via [nccl.ds4] + launcher GID auto-detect)
+#   * no --moe-backend marlin: their proven stack uses the default backend for
+#     THIS quant and reports clean evals. Sanity-check output for token loops
+#     anyway (the silent FP4 MoE corruption gotcha) before trusting a new node.
+#   * flashinfer autotune disabled via --kernel-config (their proven boot);
+#     VLLM_ENGINE_READY_TIMEOUT_S stays high regardless.
+#
+# Boot success markers (engine log, in order):
+#   "Model loading took 92.72 GiB" → "[quantprobe] ... algo=MXFP8" (MTP fix
+#   active; algo=None means broken) → "GPU KV cache size: 1,164,369 tokens" →
+#   "Application startup complete". ~700 s sequential weight load.
+#
+# Test request: chat completions need "chat_template_kwargs":{"reasoning_effort"
+# :"low"} — omitted/other values select MAX reasoning effort (empty content on
+# short max_tokens).
+#
+# Optional: instanttensor loader (~30 s weight load vs ~700 s):
+#   FROM glm53-flash-nvfp4-lab:local + pip install --no-deps --no-build-isolation
+#   instanttensor==0.1.9, then add --load-format instanttensor (--no-deps is
+#   required: resolution would downgrade the image's NCCL).
+#
+# PREREQUISITES: weights cached on both nodes:
+# [A/B CELL 2026-09-03] ship recipe verbatim, checkpoint swapped to the lab
+# non-Spark NVFP4 (isolates checkpoint from image lineage vs the lab-image cell).
+# [BISECT A2 2026-09-03] EXACT 90/100 recipe (236ce5a) + instanttensor + JIT
+# mounts, on the CURRENT eugr-patched image. Isolates image lineage from the
+# execution-env/flag cluster (AOT/V2/b12x/card-env). Comparator: 124/138.
+# GLM-5.3-Flash NVFP4-Spark — local-inference-lab quant with the speculative
+# layers embedded — 2× DGX Spark, TP=2.
+#
+# local-inference-lab/GLM-5.3-Flash-NVFP4-Spark (rev 06972cdee7280cec849aedf05a02062b3e870246):
+# NVFP4 routed experts (layers 3+, group-16) + NVFP4 MTP expert layer in the
+# separate model-mtp-0000x.safetensors shards (mtp_tokens: 5 per their
+# lil.yaml), amax/nonexpert/inputscales side shards, Glm5NextForConditionalGeneration.
+# THE "DSpark speculative embedded" checkpoint — no separate DFlash2 download
+# needed; lil.yaml: default_speculator mtp, dflash2_tokens 7 (r12 doc fr: their
+# standalone-Q: MTP:3 254 tok/s CC1, 333 Sieve, 94 steps/s).
+#
+# Image: glm53-flash-nvfp4-lab:local (same proven day-0 arm64 stack + NoPE-MLA
+# mod + modelopt MTP namespace patch used by the 92/100 lab lane). The MTP
+# layer here is NVFP4 (not MXFP8) — the quantprobe marker may print
+# algo=NVFP4/- different; algo=None = patch missed (fall back to 4p67 image).
+#
+# Deviations from lab (unchanged mechanics): same fabric/env/GMU/KV pinning.
+# lil.yaml launch mirrors: block 256, disable_flashinfer_autotune, mm data
+# mode — our text-only flags identical to glm53-flash-nvfp4-lab.
+#
+# Boot markers: "Model loading took ~XX GiB" → "[quantprobe] ..." →
+# "GPU KV cache size" → "Application startup complete".
+#
+# PREREQUISITES: weights on the NAS hub (175 GiB): hf download local-inference-lab/GLM-5.3-Flash-NVFP4-Spark
+
+engine = "vllm"
+name = "GLM-5.3-Flash NVFP4 (r31 img, lab ckpt, 4x DCP4)"
+docker_image = "glm53-jovian-r31:local"  # full r28 lock (build_profile) over the r27 image tree
+docker_image_dir = "glm53-jovian-r27"
+# NOTE: build_profile must stay a TOP-LEVEL key — a bare key after
+# [[extra_mounts]] would parse into the last mount table and be silently
+# ignored (2026-09-08).
+# FULL r28 source lock (2026-09-06 cut, all three forks): the named version
+# profile docker-images/glm53-jovian-r27/profiles/glm53-r28.env — vLLM
+# 62f6385c + b12x 7216f6b9 (21 commits over r27: GLM/DeepSeek loader fixes,
+# MoE perf) + LMCache 934c287a (3 MP-transfer fixes). Merged over the image
+# dir's versions.env and folded into the build checksum, so this is a
+# distinct image (tag glm53-jovian-r28:local) sharing the r27 build tree.
+# Clone-at-pin fetches each commit directly; the Dockerfile gates HEAD + tree
+# hash per repo. Both r28 branches are strictly ahead of their r27/r26 pins
+# (0 behind) — a clean superset. The r28 vLLM tree has NO requirements/cmake
+# changes vs r27 (verified via the GitHub compare API, 13 commits / 29 files),
+# so the fetch-deps.sh dep gates still hold.
+build_profile = "glm53-r31"
+# Required: the clean r12 image follows the solar contract (ENTRYPOINT []
+# + CMD bash), so the recipe carries the entrypoint (the old day-0-based
+# r12 image had ["vllm","serve"] baked in, which is why this was absent
+# until the clean rebuild).
+entrypoint = ["vllm", "serve"]
+model = "local-inference-lab/GLM-5.3-Flash-NVFP4"
+required_nodes = 4
+tensor_parallel_size = 4
+pipeline_parallel_size = 1
+distributed_backend = "mp"
+shm_size = "32gb"
+
+args = [
+    # R31 delta (their r28.1-r31 locks): adaptive prefill/decode
+    # compute-time sharing with a fixed 40% prefill floor.
+    "--prefill-compute-share", "0.4",
+    # Stable served name — quant-agnostic (shared across glm53 quants)
+    "--served-model-name", "glm53",
+    "--trust-remote-code",
+    "--distributed-executor-backend", "mp",
+    # GMU is ONLY a startup guardrail here (KV pool is pinned below): 0.90
+    # demands 109.46 GiB free on GB10's 121.63 GiB, but driver reserve +
+    # page cache routinely leave ~108.5 -> flaky
+    # "Free memory ... less than desired" boot deaths (this was the class
+    # of the old "54-second death"), and post-crash reruns see ~106.6 GiB.
+    # 0.82 = 99.7 GiB, below any realistic dip; does NOT change what gets
+    # allocated (weights ~93 + pinned KV 10 + activations).
+    # 0.88 (not 0.90): the startup admission gate is free-mem >= GMU*total
+    # (107.0 vs 109.5 GiB); ~12 GiB of starting vLLM processes + docker
+    # daemon can push the 0.90 check under the line (2026-09-08, #48140).
+    # KV is explicitly pinned (--kv-cache-memory-bytes) so capacity is unchanged.
+    "--gpu-memory-utilization", "0.88",
+    # Pinned 10 GiB KV (≈1.16M tokens) — GMU sizing has no headroom at
+    # 92.72 GiB weights/node; pinning also keeps warmup off the swap path
+    "--kv-cache-memory-bytes", "17179869184",  # 16 GiB: 4x NVFP4 has the headroom (47.1 GiB weights/node vs 108 usable); 2x stays 10
+    "--decode-context-parallel-size", "4",
+    "--cp-kv-cache-interleave-size", "4",
+    # No --kv-cache-dtype: let the r12 fork pick its default (the explicit
+    # fp8 / fp8_ds_mla both failed auto-selection on this build).
+    # The GLM5Next model wires the B12X sparse-MLA backend (sm_120/sm_121)
+    # when the global backend is B12X (glm5next/nvidia/attention.py:
+    # _select_sparse_backend); the sm12x auto-priority list never offers it
+    # (FLASHINFER_MLA_SPARSE_SM120 only supports head 576, not GLM's 512).
+    "--attention-backend", "B12X",
+    # pure I/O loader (kept across every config; 171 GB in ~5.5 min vs ~16 NFS)
+    "--load-format", "instanttensor",
+    # [R17 FULL-CLUSTER TEST] lil manifest backends (quality gate: hardmode
+    # must stay ≥88; r12-era this cluster dropped it to 74 — r17 may carry
+    # the fix through — one boot decides).
+    "--block-size", "256",
+    # FINAL BISECT (2026-09-03, hardmode 176pt, r17 img):
+    #   knobs-only 87: d0 c1 24.1, d8192 23.8
+    #   +moe b12x  88: d0 c1 23.5, d8192 26.6  <- SHIP (2 pts d8192)
+    #   +linear b12x 44: W4A4 linear kernel destroys numerics (param-precision 0%)
+    #   +align     88: but d0 c1 18.6 (-5) — perf-negative, dropped
+    # (all three together = 44-74; the lab needs its private packed package)
+    "--max-model-len", "524288",
+    "--max-num-seqs", "16",
+    "--max-num-batched-tokens", "4096",
+    "--enable-chunked-prefill",
+    "--async-scheduling",
+    "--enable-prefix-caching",
+    # NO --disable-custom-all-reduce here: in the r27 fork the RoCEnante
+    # adapter is gated on the custom-all-reduce enable flag
+    # (use_roce_allreduce = use_custom_allreduce && VLLM_ENABLE_ROCE_ALLREDUCE).
+    # On 2x/4x 1-GPU-node clusters vLLM's own CUDA-IPC custom AR is functionally
+    # inert (no cross-node P2P), so dropping the flag only opens the b12x path;
+    # the b12x-PCIe branch stays off (VLLM_ENABLE_PCIE_ALLREDUCE defaults False).
+    # Their proven boot: no flashinfer autotune, no CuTe-DSL warmup
+    "--kernel-config", """
+'{"enable_cutedsl_warmup":false,"enable_flashinfer_autotune":false}'""",
+    # Built-in MTP draft, 3 tokens (the r12-qualified "mtp:3" mode — their
+    # x86 numbers: 254 tok/s CC1, 2.37 accept; the checkpoint embeds up to
+    # 5 via the model-mtp-0000x shards but 3 is the verified depth). This is
+    # the checkpoint's own MTP head (Glm5NextMTPModel), NOT dspark — dspark
+    # is the DeepSeek-V4 family's mechanism; GLM's other r12 mode is
+    # dflash2:7 with a separate trained draft checkpoint.
+    # The draft model's vllm_config takes its attention backend from the
+    # SPECULATIVE config, not the global flag (eagle/utils.py:
+    # _make_eagle_draft_vllm_config) — B12X here mirrors the main model's.
+    "--speculative-config", """
+'{"method":"mtp","num_speculative_tokens":3,"attention_backend":"B12X"}'""",
+    "--language-model-only",
+    # MTP + CUDA graphs degrades OUTPUT QUALITY on the glm53 day-0 dev build
+    # (forum #381350/#44, CONFIRMED by A/B bench 2026-08-28: same seed/flags,
+    # graphs on = 89/100, eager = 92/100; decode unchanged 28.4 t/s @ c1,
+    # c2 -7%, TTFT +1.6s). The b12x glm52 stack does NOT need this (its
+    # graphs+MTP combo benches clean at 100/100) — bug is build-specific.
+    # graphs moved BEFORE tool-call-parser; enforce-eager removed for the
+    # r17-graphs test (bisect A2 was 88/100 eager; graphs+MTP fix is public
+    # in r17 refs? verify by bench).
+    "--tool-call-parser", "glm47",
+    "--enable-auto-tool-choice",
+    "--reasoning-parser", "glm45",
+]
+
+[env]
+
+# R31 lock: 16 NCCL channels (their qualified runtime).
+NCCL_NCHANNELS = "16"
+HF_HUB_OFFLINE = "1"
+# RoCEnante (b12x one-shot RoCE all-reduce/all-gather) — default on for r27
+# lanes since the 2026-09-08 A/B (4x DCP4: decode +31..+90%, quality 160 vs
+# 155, prefill within noise; specs/tech-architecture/glm53-recipe-state.md,
+# history/night-shifts/2026-09-07.md). Needs the CX-7 RoCE fabric (all of
+# ours); single-node serves skip it silently. Caps default 2MB AR / 16MB AG.
+VLLM_ENABLE_ROCE_ALLREDUCE = "1"
+# FlashInfer JIT (mxfp8_gemm_cutlass_sm120, ~12 kernels) compiles at first
+# boot with 12 parallel nvcc jobs -> OOM-killed (code 137) on GB10's
+# 121 GB unified while the 93 GB weights + 10 GB KV pin are resident.
+# MAX_JOBS caps ninja parallelism so the JIT fits in the remaining ~20 GB.
+MAX_JOBS = "2"
+# NoPE-MLA rope-pad runtime gate (mod baked into the image)
+VLLM_MLA_NOPE_PAD_ROPE = "1"
+VLLM_ENGINE_READY_TIMEOUT_S = "3600"
+# Upstream launch-script env (memory + compile knobs)
+PYTORCH_CUDA_ALLOC_CONF = "expandable_segments:True"
+VLLM_USE_AOT_COMPILE = "0"
+VLLM_USE_STANDALONE_COMPILE = "1"
+VLLM_USE_FLASHINFER_SAMPLER = "1"
+VLLM_USE_BREAKABLE_CUDAGRAPH = "0"
+TORCH_USE_RTLD_GLOBAL = "1"
+VLLM_NO_USAGE_STATS = "1"
+
+# Architecture (aarch64 / sm_121a DGX Spark)
+TORCH_CUDA_ARCH_LIST = "12.1a"
+FLASHINFER_CUDA_ARCH_LIST = "12.1f"
+CUTE_DSL_ARCH = "sm_121a"
+CMAKE_CUDA_ARCHITECTURES = "121"
+OMP_NUM_THREADS = "2"
+
+[[extra_mounts]]
+host = "~/sm121-cache/glm53-jit-121f/b12x"
+container = "/root/.cache/b12x"
+
+# JIT caches persist per-node across serves (was: cold /root/.cache per
+# container -> ~20 min flashinfer/torch recompile every serve). The host
+# dirs are shared between lanes of the same arch — each cache
+# self-namespaces by its engine version key internally.
+[[extra_mounts]]
+host = "~/sm121-cache/jit-121f/flashinfer"
+container = "/root/.cache/flashinfer"
+
+[[extra_mounts]]
+host = "~/sm121-cache/jit-121f/torchinductor"
+container = "/root/.cache/torchinductor"
+
+[[extra_mounts]]
+host = "~/sm121-cache/jit-121f/vllm"
+container = "/root/.cache/vllm"
+