|
|
@@ -0,0 +1,147 @@
|
|
|
+# GLM-5.3 (FULL, non-Flash) NVFP4-Spark — local-inference-lab quant, 4× DGX Spark, TP=4.
|
|
|
+#
|
|
|
+# Full GLM-5.3 (78 layers / hidden 6144 / 1M ctx, arch GlmMoeDsaForCausalLM)
|
|
|
+# in the lab's GB10-tailored quant: GLM-5.3-NVFP4-Spark (~406 GB →
|
|
|
+# ~101.5 GiB weights/node → 4x only; the plain NVFP4 build is 433 GB).
|
|
|
+# MIXED_PRECISION checkpoint (NVFP4 routed + MXFP8 elsewhere) handled by the
|
|
|
+# lab image's modelopt quant module.
|
|
|
+#
|
|
|
+# Image: glm53-flash-nvfp4-lab:local (same lab vLLM fork — it registers
|
|
|
+# GlmMoeDsaForCausalLM at deepseek_v2.py, which implements SupportsEagle3,
|
|
|
+# unlike the Flash GLM5Next target; that is why the lab's MXFP8 DFlash2
|
|
|
+# drafter is the full-model pairing, not the Flash one).
|
|
|
+#
|
|
|
+# First run: plain (no spec) to prove the stack end-to-end, then add spec.
|
|
|
+# KV pinned 4 GiB (weights leave ~17 GiB/node; pool is small by design —
|
|
|
+# this is a capability/quality lane, not a throughput lane).
|
|
|
+#
|
|
|
+# PREREQUISITES: weights cached in the shared NAS HF cache:
|
|
|
+# models--local-inference-lab--GLM-5.3-NVFP4-Spark (406G, verified 2026-09-04)
|
|
|
+
|
|
|
+engine = "vllm"
|
|
|
+name = "GLM-5.3 (full) NVFP4-Spark-lab (vLLM, 4x Spark)"
|
|
|
+docker_image = "glm53-flash-nvfp4-lab:local"
|
|
|
+docker_image_dir = "glm53-flash-nvfp4-lab"
|
|
|
+model = "local-inference-lab/GLM-5.3-NVFP4-Spark"
|
|
|
+required_nodes = 4
|
|
|
+tensor_parallel_size = 4
|
|
|
+pipeline_parallel_size = 1
|
|
|
+distributed_backend = "mp"
|
|
|
+shm_size = "32gb"
|
|
|
+# required for the launcher's `--entrypoint sh -c` override path (mods below)
|
|
|
+entrypoint = ["vllm", "serve"]
|
|
|
+
|
|
|
+args = [
|
|
|
+ # 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).
|
|
|
+ "--gpu-memory-utilization", "0.82",
|
|
|
+ # Pinned 4 GiB KV — full-model weights are ~101.5 GiB/node (406G/4),
|
|
|
+ # far less headroom than the 92.7 GiB/node Flash lane; no MLA-specific
|
|
|
+ # kv-cache-dtype/block-size here (GlmMoeDsa attention picks its own
|
|
|
+ # native KV defaults — the fp8_ds_mla/256 pair was a Flash-MLA knob)
|
|
|
+ "--kv-cache-memory-bytes", "4294967296",
|
|
|
+ # 4 GiB KV pool holds ~79,616 tokens (engine-computed 2026-09-04);
|
|
|
+ # 524288 would need 26.34 GiB — doesn't fit behind 101.5 GiB weights.
|
|
|
+ # 79K context is far beyond anything the bench uses.
|
|
|
+ "--max-model-len", "79616",
|
|
|
+ "--max-num-seqs", "8",
|
|
|
+ "--max-num-batched-tokens", "4096",
|
|
|
+ "--enable-chunked-prefill",
|
|
|
+ "--async-scheduling",
|
|
|
+ "--enable-prefix-caching",
|
|
|
+ "--disable-custom-all-reduce",
|
|
|
+ # Their proven boot: no flashinfer autotune, no CuTe-DSL warmup
|
|
|
+ "--kernel-config", """
|
|
|
+'{"enable_cutedsl_warmup":false,"enable_flashinfer_autotune":false}'""",
|
|
|
+ # No spec: the lab DFlash2/MTP drafters are for the Flash model; first
|
|
|
+ # full-model run runs plain to prove the stack, then add spec if clean
|
|
|
+ # instanttensor was removed after the first full-model boot hung mid-load
|
|
|
+ # (dgx2, 2026-09-04), then re-enabled for the parked retry run below
|
|
|
+ # (flag at "--load-format", "instanttensor") with MAX_JOBS=2 + persistent
|
|
|
+ # JIT caches as the anti-OOM guardrails.
|
|
|
+ # NOTE: instanttensor + both mods seds ARE configured below (2026-09-04
|
|
|
+ # retry) — the lane PARKED before that run happened: two sparse-MLA
|
|
|
+ # engine crashes on first requests (masked_mha AttributeError +
|
|
|
+ # forward_mha NotImplementedError), both hotfixed via [mods]; the
|
|
|
+ # force-mqa + instanttensor boot never ran because the full-model work
|
|
|
+ # was parked (dgx2 went down twice under this workload that day).
|
|
|
+ # 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.
|
|
|
+ "--enforce-eager",
|
|
|
+ # instanttensor loader (lab-fork feature; default loader is ~27 min here,
|
|
|
+ # instanttensor ~2x faster when the NFS cooperates)
|
|
|
+ "--load-format", "instanttensor",
|
|
|
+ "--tool-call-parser", "glm47",
|
|
|
+ "--enable-auto-tool-choice",
|
|
|
+ "--reasoning-parser", "glm45",
|
|
|
+]
|
|
|
+
|
|
|
+[mods]
|
|
|
+commands = [
|
|
|
+ # Lab-fork bug: mla_attention.py:810 reads self.impl.masked_mha_available
|
|
|
+ # on the sparse MLA impl, which never sets it -> AttributeError on the
|
|
|
+ # first prefill step (engine crash, 2026-09-04). The attribute is
|
|
|
+ # SM100-only anyway (gate: is_device_capability_family(100)); on GB10
|
|
|
+ # (SM121) the masked-MHA path is off by design, so default to False.
|
|
|
+ # 1-line hotfix until the lab image is rebuilt with the fix baked in.
|
|
|
+ "sed -i \"s/and self\\.impl\\.masked_mha_available/and getattr(self.impl, 'masked_mha_available', False)/\" /usr/local/lib/python3.12/dist-packages/vllm/model_executor/layers/attention/mla_attention.py",
|
|
|
+ # Second wall: the dense-MHA split routes prefill to impl.forward_mha,
|
|
|
+ # which is an unimplemented stub on the SM120 sparse impl (engine crash
|
|
|
+ # #2, 2026-09-04). vllm ships an intended escape hatch for exactly this:
|
|
|
+ # attention_config.sparse_mla_force_mqa = True -> \"always use the MQA
|
|
|
+ # path\" (the model's native sparse attention). No CLI flag exists for it
|
|
|
+ # in this build, so set the documented default via sed.
|
|
|
+ "sed -i \"s/sparse_mla_force_mqa: bool = False/sparse_mla_force_mqa: bool = True/\" /usr/local/lib/python3.12/dist-packages/vllm/config/attention.py",
|
|
|
+]
|
|
|
+
|
|
|
+[env]
|
|
|
+HF_HUB_OFFLINE = "1"
|
|
|
+# instanttensor loader knobs (lab image bakes the loader; retrying after the
|
|
|
+# 2026-09-04 dgx2 hang — if that node dies mid-load again, drop this)
|
|
|
+INSTANTTENSOR_BACKEND = "BUFFERED"
|
|
|
+INSTANTTENSOR_CONCURRENCY = "1"
|
|
|
+INSTANTTENSOR_IO_DEPTH = "3"
|
|
|
+INSTANTTENSOR_BUFFER_SIZE = "67108864"
|
|
|
+INSTANTTENSOR_CHUNK_SIZE = "8388608"
|
|
|
+# 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"
|
|
|
+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 = "4"
|
|
|
+# Compile-OOM fix: first boot JIT-compiles the mxfp8 gemm module (12
|
|
|
+# nvcc/cicc jobs ~3 GB each) behind 101.5 GiB of weights -> cicc OOM-killed
|
|
|
+# (aiden lane, 2026-09-04). flashinfer run_ninja reads MAX_JOBS -> cap at 2.
|
|
|
+MAX_JOBS = "2"
|
|
|
+
|
|
|
+# Persistent JIT caches (containers run with --rm; without these every boot
|
|
|
+# re-runs the ~10 min nvcc compile of the mxfp8 gemm module)
|
|
|
+[[extra_mounts]]
|
|
|
+host = "~/.cache/glm53-full-flashinfer"
|
|
|
+container = "/root/.cache/flashinfer"
|
|
|
+
|
|
|
+[[extra_mounts]]
|
|
|
+host = "~/.cache/glm53-full-triton"
|
|
|
+container = "/root/.triton"
|
|
|
+
|