recipe.toml 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. # DeepSeek-V4.1-Flash EXL3 3bpw — coolbho3k "2x DGX Spark" production recipe,
  2. # adapted to sm121 (rc2 image, pinned at release commit 878e0ee).
  3. #
  4. # 2x Spark over 200G RoCE (8nodes-switch, first two free ranks):
  5. # TP2/DCP2, DSpark K=3 drafter, EXL3 3bpw experts, FP4 main KV + FP8 SWA,
  6. # 1M context, GMU 0.92, max-num-seqs 2 (C2; the runtime's cooperative
  7. # profile validates 1..6), prefill batch 3072.
  8. #
  9. # 2 GB headless-RAM unlock: the runtime's display-pool KV (1.75 GiB of the
  10. # firmware's 2 GB display reserve per GPU) needs nvidia_drm remoded with
  11. # modeset=1 fbdev=0. That is TEMPORARY by design (technology still in
  12. # approval): before_serve remods per boot, after_stop restores the plain
  13. # module. No UEFI change, no /etc/modprobe.d entry, resets on reboot.
  14. #
  15. # Model + drafter overlay: node-local NVMe mirror of the NAS hub at
  16. # /home/kilork/hf-local/hub (EXL3 streams weights on EVERY decode step — from
  17. # NFS that costs ~2/3 of decode; staged here per node, the read is local).
  18. # Mirror rule: same hub-root-relative layout; refs/main stays pinned to the
  19. # NAS (authoritative). Files not staged locally — engram-page15-v1 (optional
  20. # per its release notes, +1.4% decode) — resolve through the NAS fallback,
  21. # read-only. The launch nodes bind every referenced file per-path at /model
  22. # and /draft-exl3 (the runtime hard-requires the model at exactly /model).
  23. #
  24. # Cgroup: the runtime's serving guard hard-requires a 9 GiB / no-swap /
  25. # <=6-CPU cgroup (memory.max==9g, swap 0, cpu quota <=6) — memory_limit +
  26. # cpus below.
  27. engine = "vllm"
  28. docker_image = "ghcr.io/coolbho3k/deepseek-v4.1-flash-exl3-3bpw-2x-dgx-spark:20260917-rc2"
  29. model = ""
  30. name = "DeepSeek-V4.1-Flash EXL3 3bpw (2x Spark, TP2/DCP2, DSpark K=3, 1M)"
  31. required_nodes = 2
  32. cluster = "8nodes-switch"
  33. tensor_parallel_size = 2
  34. pipeline_parallel_size = 1
  35. distributed_backend = "mp"
  36. shm_size = "2g"
  37. devices = ["/dev/dri/card0"]
  38. memory_limit = "9g"
  39. cpus = 6
  40. extra_mounts_manifest = "/tmp/sm121-exl3-mounts.txt"
  41. # /model + /draft-exl3 are the exact mounts the runtime validates.
  42. entrypoint = [
  43. "/opt/ds41-venv/bin/python",
  44. "/opt/ds41-serving/serve.py",
  45. "serve",
  46. "/model",
  47. "--config",
  48. "/opt/ds41-serving/conservative.yaml",
  49. "--worker-cls",
  50. "combined_worker.CombinedWorker",
  51. "--disable-custom-all-reduce",
  52. ]
  53. args = [
  54. "--served-model-name",
  55. "deepseek-v41-flash-exl3",
  56. "--enable-auto-tool-choice",
  57. "--tool-call-parser",
  58. "deepseek_v41",
  59. "--reasoning-parser",
  60. "deepseek_v41",
  61. ]
  62. before_serve = [
  63. { script = "unlock_display_ram" },
  64. # Model + drafter staging: the hub snapshot's internal relative symlinks
  65. # (../../../blobs/…) only resolve at the real hub depth. The full repo dir
  66. # (blobs/ + snapshots/) is mounted at /hub, and the staging dir at /model
  67. # holds RELATIVE symlinks (../hub/...) into it — the kernel lands on the
  68. # real correct-depth tree and the inner links resolve.
  69. "python3 - models--coolbho3k--DeepSeek-V4.1-Flash-EXL3-3bpw $(cat /mnt/nas/ai/huggingface/hub/models--coolbho3k--DeepSeek-V4.1-Flash-EXL3-3bpw/refs/main) /model models--coolbho3k--DeepSeek-V4.1-Flash-DSpark-EXL3-3bpw $(cat /mnt/nas/ai/huggingface/hub/models--coolbho3k--DeepSeek-V4.1-Flash-DSpark-EXL3-3bpw/refs/main) /draft-exl3 <<'GENSTAGE'\nimport os, sys\nHUB = '/home/kilork/hf-local/hub'; NAS = '/mnt/nas/ai/huggingface/hub'\ndef fin(p):\n r = os.path.realpath(p)\n return r if os.path.exists(r) else r.replace(HUB, NAS, 1)\nMANIFEST = '/tmp/sm121-exl3-mounts.txt'\ndef gen(repo, rev, out):\n snap = os.path.join(HUB, repo, 'snapshots', rev)\n lines = []\n for name in sorted(os.listdir(snap)):\n src = os.path.join(snap, name)\n real = fin(src)\n if os.path.isdir(real):\n for root, _, files in os.walk(real):\n for fn in sorted(files):\n fp = os.path.join(root, fn)\n freal = fin(fp)\n sub = os.path.relpath(fp, real)\n lines.append(freal + '\\t' + os.path.join(out, name, sub))\n else:\n lines.append(real + '\\t' + os.path.join(out, name))\n ns = set(os.listdir(snap))\n nasnap = os.path.join(NAS, repo, 'snapshots', rev)\n for name in sorted(os.listdir(nasnap)):\n if name in ns:\n continue\n src = os.path.join(nasnap, name)\n if not os.path.isdir(src):\n continue\n for root, _, files in os.walk(src):\n for fn in sorted(files):\n fp = os.path.join(root, fn)\n sub = os.path.relpath(fp, src)\n lines.append(fp + '\\t' + os.path.join(out, name, sub))\n with open(MANIFEST, 'a') as f:\n f.write('\\n'.join(lines) + '\\n')\n print('manifest', MANIFEST, len(lines), 'mounts for', out, flush=True)\nrepo, rev, out, drepo, drev, dout = sys.argv[1:7]\nopen(MANIFEST, 'w').close() # truncate once before both gens\ngen(repo, rev, out)\ngen(drepo, drev, dout)\nGENSTAGE",
  70. # The runtime kit (serve.py + conservative.yaml + overlay .so + AOT gemm)
  71. # is NOT in the image — it is the pinned release/runtime tree, staged once
  72. # per node and bind-mounted as overlays (serving/ -> /opt/ds41-serving,
  73. # aot/... -> flashinfer AOT dir). One-time git clone at the pinned commit.
  74. "mkdir -p /home/kilork/exl3-cache",
  75. "sudo rm -rf /home/kilork/exl3-cache/ds41-backend-attestation /home/kilork/exl3-cache/ds41-combined-ready /home/kilork/exl3-cache/ds41-display-kv",
  76. "if [ ! -f /home/kilork/exl3-kit/878e0ee/serving/serve.py ]; then rm -rf /home/kilork/exl3-kit/.src-878e0ee /home/kilork/exl3-kit/878e0ee && git clone --quiet https://github.com/coolbho3k/DeepSeek-v4.1-Flash-2x-DGX-Spark.git /home/kilork/exl3-kit/.src-878e0ee && (cd /home/kilork/exl3-kit/.src-878e0ee && git checkout --quiet 878e0eecd893fadc69ad2d58b2df0fabb0fae2ee) && mv /home/kilork/exl3-kit/.src-878e0ee/release/runtime /home/kilork/exl3-kit/878e0ee && rm -rf /home/kilork/exl3-kit/.src-878e0ee; fi && test -f /home/kilork/exl3-kit/878e0ee/serving/serve.py",
  77. ]
  78. after_stop = [{ script = "restore_display_ram", on_failure = "warn" }]
  79. # Hub dir (both repos + hub-level blobs/): the repo blobs/ is itself a layer
  80. # of relative symlinks into the sibling hub-level blobs/<xx>/<sha>, so the
  81. # whole hub tree must be in scope for the chain to resolve.
  82. [[extra_mounts]]
  83. host = "/mnt/nas/ai/huggingface/hub"
  84. container = "/hub"
  85. read_only = true
  86. # /model and /draft-exl3 are NOT dir-mounted: the runtime opens the shard
  87. # files with O_NOFOLLOW (symlink final component => ELOOP), so the
  88. # before-serve hook generates a per-file bind manifest instead
  89. # (extra_mounts_manifest) — the container sees regular files only.
  90. # Runtime kit overlays (pinned 878e0ee): the image's /opt/ds41-serving is
  91. # shadowed by the kit's serving tree; the AOT gemm dir is bind-mounted ro.
  92. [[extra_mounts]]
  93. host = "/home/kilork/exl3-kit/878e0ee/serving"
  94. container = "/opt/ds41-serving"
  95. read_only = true
  96. [[extra_mounts]]
  97. host = "/home/kilork/exl3-kit/878e0ee/aot/mxfp8_gemm_cutlass_sm120"
  98. container = "/usr/local/lib/python3.12/dist-packages/flashinfer/data/aot/mxfp8_gemm_cutlass_sm120"
  99. read_only = true
  100. # Node-local runtime cache (triton/tilelang/torch-ext/cuda flashinfer workspaces).
  101. [[extra_mounts]]
  102. host = "/home/kilork/exl3-cache"
  103. container = "/cache"
  104. [env]
  105. # DS41 runtime profile (validated against DS41_* envs; kv_cap_mib is
  106. # env-only, not a CLI flag).
  107. DS41_GPU_MEMORY_UTILIZATION = "0.92"
  108. DS41_MAX_MODEL_LEN = "1048576"
  109. DS41_MAX_NUM_SEQS = "2"
  110. DS41_MAX_NUM_BATCHED_TOKENS = "3072"
  111. DS41_LONG_PREFILL_TOKEN_THRESHOLD = "2816"
  112. DS41_KV_CAP_MIB = "0" # display-only candidate: all KV from the 2 GB display pool
  113. # Feature gates (serve.py hard-requires the '1' set; defaults are 1, set
  114. # explicitly so the guard passes).
  115. DS41_ENABLE_COOPERATIVE_MOE = "1"
  116. DS41_ENABLE_DCP2 = "1"
  117. DS41_ENABLE_DSPARK = "1"
  118. DS41_ENABLE_SSD_VOCAB = "1"
  119. DS41_SSD_ENGRAM_SOURCE = "/model/engrams"
  120. DS41_ENGRAM_CACHE_MIB = "64"
  121. DS41_DRAFT_EXL3_PATH = "/draft-exl3"
  122. # Node-local cache directories (/cache mount, persistent between serves).
  123. VLLM_CACHE_ROOT = "/cache/vllm"
  124. TILELANG_CACHE_DIR = "/cache/tilelang"
  125. TRITON_CACHE_DIR = "/cache/triton"
  126. TORCH_EXTENSIONS_DIR = "/cache/torch-extensions"
  127. CUDA_CACHE_PATH = "/cache/cuda"
  128. XDG_CACHE_HOME = "/cache"
  129. FLASHINFER_WORKSPACE_BASE = "/cache/flashinfer"
  130. TMPDIR = "/cache/tmp"
  131. # Engine / offline / threading.
  132. VLLM_PLUGINS = "ds41"
  133. VLLM_USE_V2_MODEL_RUNNER = "1"
  134. VLLM_USE_BREAKABLE_CUDAGRAPH = "0"
  135. VLLM_ENGINE_READY_TIMEOUT_S = "3600"
  136. VLLM_WORKER_MULTIPROC_METHOD = "spawn"
  137. VLLM_NO_USAGE_STATS = "1"
  138. HF_HUB_OFFLINE = "1"
  139. TRANSFORMERS_OFFLINE = "1"
  140. DSV41_IO_THREADS = "96"
  141. TORCH_CUDA_ARCH_LIST = "12.1a"
  142. FLASHINFER_CUDA_ARCH_LIST = "12.1a"
  143. MAX_JOBS = "1"
  144. MKL_NUM_THREADS = "4"
  145. OPENBLAS_NUM_THREADS = "4"
  146. TORCH_NCCL_ASYNC_ERROR_HANDLING = "1"
  147. MALLOC_ARENA_MAX = "2"
  148. MALLOC_TRIM_THRESHOLD_ = "131072"
  149. VLLM_SPARSE_INDEXER_MAX_LOGITS_MB = "128"
  150. # NCCL pins (on top of the launcher's cluster NCCL env).
  151. NCCL_NVLS_ENABLE = "0"
  152. NCCL_CROSS_NIC = "0"
  153. NCCL_IB_MERGE_NICS = "0"
  154. NCCL_CUMEM_ENABLE = "0"
  155. NCCL_MAX_CTAS = "8"
  156. NCCL_BUFFSIZE = "1048576"
  157. NCCL_LL128_BUFFSIZE = "262144"
  158. NCCL_PROTO = "^LL128"
  159. NCCL_MAX_NCHANNELS = "8"
  160. NCCL_IB_ROCE_VERSION_NUM = "2"