recipe.toml 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. # GLM-5.2 NF4 Lloyd-Experts-GPTQ — 4× DGX Spark (GB10, sm_121a), TP=4, DCP=4.
  2. #
  3. # Model: aidendle94/GLM-5.2-NF4-Lloyd-Experts-GPTQ
  4. # → https://huggingface.co/aidendle94/GLM-5.2-NF4-Lloyd-Experts-GPTQ
  5. #
  6. # Lloyd-codebook NF4 routed-expert overlay for GLM-5.2 (744B MoE, 256
  7. # experts/layer, 8 activated/token, 78 layers, sparse-MLA). Expert weights
  8. # quantized to 4-bit with a fitted Lloyd–Max codebook (−16.8% expert
  9. # reconstruction error vs E2M1/MXFP4 baseline on the same GPTQ pipeline).
  10. # Codes are indices into per-layer grids/L{n}.json — NOT the E2M1 table.
  11. #
  12. # LOADING: the Lloyd repo is experts-only (L{n}.safetensors + grids/). It
  13. # cannot be served standalone. The base checkpoint is
  14. # aidendle94/GLM-5.2-MXFP4-Experts-GPTQ (full model: config.json with
  15. # quant_method="hybrid_mxfp4_ct", hybrid-ct-*.safetensors non-expert weights
  16. # in block-FP8/NVFP4, tokenizer, mtp-draft). The Lloyd NF4 experts REPLACE
  17. # the MXFP4 E2M1 experts for layers 3–77 (all 75 MoE layers): the Lloyd
  18. # L{n}.safetensors files have the same filenames and tensor names as the
  19. # MXFP4 repo's, so they must be copied into the MXFP4 snapshot directory
  20. # (filesystem overlay). vLLM loads them through the standard weight loader;
  21. # the nf4_e8m0_k32 kernel (baked in production-hybrid-1.4) decodes them with
  22. # the global _NF4_CODEBOOK instead of the E2M1 bit-twiddle. Which layers use
  23. # the NF4 path is controlled by VLLM_NF4_LAYERS — a path to a JSON file
  24. # {"layers": [3, 4, ..., 77]}, NOT a range string.
  25. #
  26. # Image: sparkrun-vllm-ds4-gb10:glm52
  27. # Built from docker-images/glm52/Dockerfile, which FROMs
  28. # aidendle94/sparkrun-vllm-ds4-gb10:production-hybrid-1.4 (bakes the
  29. # nf4_e8m0_k32 / nf4_packed kernel — inert without VLLM_NF4_LAYERS).
  30. #
  31. # PREREQUISITES (manual, on EVERY node):
  32. # 1. Download both repos via HF_HOME:
  33. # huggingface-cli download aidendle94/GLM-5.2-MXFP4-Experts-GPTQ
  34. # huggingface-cli download aidendle94/GLM-5.2-NF4-Lloyd-Experts-GPTQ
  35. # (MXFP4 base ~390 GB, Lloyd experts ~385 GB)
  36. # 2. Overlay the Lloyd NF4 experts onto the MXFP4 snapshot directory (same
  37. # filenames, same tensor names — they replace the E2M1 experts with
  38. # NF4-packed codes). Use RELATIVE symlinks (ln -snrf), not copies: the
  39. # HF cache is mounted at /root/.cache/huggingface inside the container
  40. # (vs /home/<user>/.cache/huggingface on the host), so absolute symlinks
  41. # would break — relative paths resolve the same under both roots, like
  42. # HF's own snapshot→blob links. -n is critical: it stops ln from
  43. # dereferencing the existing MXFP4 symlink (without -n, ln would replace
  44. # the BLOB the link points to, corrupting the 390 GB MXFP4 cache).
  45. # Lightweight: ~75 symlinks, no 385 GB copy.
  46. # MXFP4=$(readlink -f ~/.cache/huggingface/hub/models--aidendle94--GLM-5.2-MXFP4-Experts-GPTQ/snapshots/main)
  47. # LLOYD=$(readlink -f ~/.cache/huggingface/hub/models--aidendle94--GLM-5.2-NF4-Lloyd-Experts-GPTQ/snapshots/main)
  48. # for f in "$LLOYD"/L*.safetensors; do ln -snrf "$f" "$MXFP4/$(basename "$f")"; done
  49. # Without this overlay the kernel decodes E2M1 weights with the NF4
  50. # codebook → garbage output (the model card warns about this).
  51. # 3. Create the NF4 layer-list JSON in the Lloyd snapshot dir (the kernel
  52. # reads this via VLLM_NF4_LAYERS — {{lloyd_experts}}/nf4_layers.json):
  53. # echo "{\"layers\":[$(seq -s, 3 77)]}" > "$LLOYD"/nf4_layers.json
  54. #
  55. # REFERENCE:
  56. # https://huggingface.co/aidendle94/GLM-5.2-NF4-Lloyd-Experts-GPTQ
  57. # https://huggingface.co/aidendle94/GLM-5.2-MXFP4-Experts-GPTQ
  58. engine = "vllm"
  59. name = "GLM-5.2 NF4 Lloyd-Experts-GPTQ (vLLM)"
  60. docker_image = "sparkrun-vllm-ds4-gb10:glm52"
  61. model = "aidendle94/GLM-5.2-MXFP4-Experts-GPTQ"
  62. required_nodes = 4
  63. tensor_parallel_size = 4
  64. pipeline_parallel_size = 1
  65. distributed_backend = "mp"
  66. shm_size = "10gb"
  67. docker_image_dir = "glm52"
  68. entrypoint = ["vllm", "serve"]
  69. args = [
  70. # Model name
  71. "--served-model-name", "glm52",
  72. # General
  73. "--trust-remote-code",
  74. "--reasoning-parser", "glm45",
  75. "--tool-call-parser", "glm47",
  76. "--enable-auto-tool-choice",
  77. "--enable-prefix-caching",
  78. # DCP (Decode Context Parallelism)
  79. "--decode-context-parallel-size", "4",
  80. "--dcp-comm-backend", "ag_rs",
  81. # Engine backends
  82. "--attention-backend", "B12X_MLA_SPARSE",
  83. # HF overrides — 78-char index_topk_pattern (GLM-5.2 MLP/expert routing)
  84. "--hf-overrides", """
  85. '{"index_topk_pattern":"FFFSSSFSSSFSSSFSSSFSSSFSSSFSSSFSSSFSSSFSSSFSSSFSSSFSSSFSSSFSSSFSSSFSSSFSSSFSSS"}'""",
  86. # KV cache — NVFP4 with per-token scaling (nvfp4_ds_mla)
  87. "--kv-cache-dtype", "nvfp4_ds_mla",
  88. "--kv-cache-memory-bytes", "5500000000",
  89. # Context & batch config
  90. "--max-model-len", "262144",
  91. "--max-num-batched-tokens", "2048",
  92. "--max-num-seqs", "3",
  93. "--gpu-memory-utilization", "0.89",
  94. # Speculative decode — MTP k=4 with adaptive depths
  95. # {{mtp_draft}} is substituted per-node with the resolved HF cache path
  96. # (refs/main → latest snapshot) so symlinks resolve correctly.
  97. "--speculative-config", """
  98. '{"model":"{{mtp_draft}}","method":"mtp","num_speculative_tokens":4,"draft_attention_backend":"B12X_MLA_SPARSE","adaptive_speculative_tokens_window":32}'""",
  99. # Compilation — FULL_AND_PIECEWISE with all custom ops, 8 capture sizes
  100. "--compilation-config", """
  101. '{"cudagraph_mode":"FULL_AND_PIECEWISE","custom_ops":["all"],"cudagraph_capture_sizes":[1,2,3,4,5,6,8]}'""",
  102. # Timeout safety net (cold boot: ranks finish minutes apart)
  103. "--distributed-timeout-seconds", "3600",
  104. "--cpu-distributed-timeout-seconds", "3600",
  105. ]
  106. # Persistent JIT/torch-inductor cache (avoids ~20 min recompilation on cold boot).
  107. # `alias = "jit_cache"` resolves via [mount_aliases] in config.toml; if absent,
  108. # falls back to host "~/.cache/jit" (expanded to /home/<ssh_user>/.cache/jit).
  109. # `env` injects -e XDG_CACHE_HOME=/root/.cache/jit so vLLM/torch write there.
  110. [[extra_mounts]]
  111. alias = "jit_cache"
  112. host = "~/.cache/jit"
  113. container = "/root/.cache/jit"
  114. env = "XDG_CACHE_HOME"
  115. # MTP draft model — from the MXFP4 base checkpoint's repo. Resolved at serve
  116. # time, per node, from the HF cache (refs/main → latest snapshot), so the
  117. # path survives `huggingface-cli download` updates without a fragile symlink.
  118. # The recipe references {{mtp_draft}} in --speculative-config; the launcher
  119. # substitutes the resolved full HF cache path per-node (no bind-mount — the
  120. # HF cache is already mounted at /root/.cache/huggingface, so symlinks
  121. # resolve correctly).
  122. [[extra_mounts]]
  123. repo = "aidendle94/GLM-5.2-MXFP4-Experts-GPTQ"
  124. subfolder = "mtp-draft"
  125. container = "mtp_draft"
  126. # Lloyd repo path reference — resolved at serve time, per node, from the HF
  127. # cache (refs/main → latest snapshot). {{lloyd_experts}} is substituted into
  128. # VLLM_NF4_LAYERS below so the kernel can find the nf4_layers.json file
  129. # (created by the operator in step 3 of the prerequisites above). This is a
  130. # path reference, NOT a bind-mount — the HF cache is already mounted at
  131. # /root/.cache/huggingface, so the resolved path's symlinks resolve correctly.
  132. [[extra_mounts]]
  133. repo = "aidendle94/GLM-5.2-NF4-Lloyd-Experts-GPTQ"
  134. container = "lloyd_experts"
  135. [env]
  136. # ── NF4 Lloyd expert overlay ──────────────────────────────────────────────
  137. # Path to a JSON file listing which layers use the nf4_e8m0_k32 decode path
  138. # (vs the default fp4_e8m0_k32 E2M1 bit-twiddle). The kernel reads this file
  139. # at init: {"layers": [3, 4, ..., 77]}. {{lloyd_experts}} is substituted
  140. # per-node with the resolved HF cache path to the Lloyd repo snapshot, where
  141. # the operator creates nf4_layers.json (see PREREQUISITES step 3 above).
  142. VLLM_NF4_LAYERS = "{{lloyd_experts}}/nf4_layers.json"
  143. # ── b12x suite ────────────────────────────────────────────────────────────
  144. VLLM_USE_V2_MODEL_RUNNER = "1"
  145. VLLM_USE_B12X_MOE = "1"
  146. VLLM_USE_B12X_SPARSE_INDEXER = "1"
  147. VLLM_DCP_SHARD_DRAFT = "1"
  148. VLLM_DCP_GLOBAL_TOPK = "1"
  149. VLLM_DSV4_INDEXER_SP = "1"
  150. # ── MLA CKV gather (sparse gather for decode) ─────────────────────────────
  151. VLLM_B12X_MLA_CKV_GATHER = "1"
  152. VLLM_B12X_MLA_CKV_GATHER_MAX_TOKENS = "262144"
  153. VLLM_B12X_MLA_DECODE_SPARSE_GATHER = "1"
  154. VLLM_B12X_MLA_DECODE_GATHER_V2 = "1"
  155. # ── Speculative decode ────────────────────────────────────────────────────
  156. VLLM_ADAPTIVE_SPEC_DEPTHS = "2,4"
  157. # ── NVFP4 KV cache ────────────────────────────────────────────────────────
  158. VLLM_NVFP4_MLA_PER_TOKEN_SCALE = "1"
  159. # ── Timeout safety net ────────────────────────────────────────────────────
  160. VLLM_ENGINE_READY_TIMEOUT_S = "3600"
  161. VLLM_EXECUTE_MODEL_TIMEOUT_SECONDS = "1800"
  162. VLLM_ALLOW_LONG_MAX_MODEL_LEN = "1"
  163. # ── MUST unset baked VLLM_PREFIX_CACHE_RETENTION_INTERVAL ─────────────────
  164. # The image bakes a value that GLM-5.2's KV coordinator rejects.
  165. # Empty string = unset at runtime.
  166. VLLM_PREFIX_CACHE_RETENTION_INTERVAL = ""
  167. # ── Architecture (aarch64/sm_121a DGX Spark) ──────────────────────────────
  168. CUTE_DSL_ARCH = "sm_121a"
  169. TORCH_CUDA_ARCH_LIST = "12.1a"
  170. # ── JIT cache ──────────────────────────────────────────────────────────────
  171. # Persisted via the [[extra_mounts]] jit_cache entry above: XDG_CACHE_HOME is
  172. # injected from that mount, pointing at /root/.cache/jit (no hardcoded dupe).
  173. # ── NCCL overrides ─────────────────────────────────────────────────────────
  174. # Cluster config provides NCCL_IB_HCA, NCCL_IB_GID_INDEX, NCCL_SOCKET_IFNAME
  175. # Launcher defaults: NCCL_IGNORE_CPU_AFFINITY=1, NCCL_NET=IB, NCCL_DEBUG=WARN
  176. NCCL_IB_DISABLE = "0" # enable IB (override launcher default)
  177. NCCL_MAX_NCHANNELS = "4"
  178. NCCL_MIN_NCHANNELS = "4"
  179. NCCL_CUMEM_ENABLE = "0"
  180. # ── Compute ────────────────────────────────────────────────────────────────
  181. OMP_NUM_THREADS = "4"