-
Notifications
You must be signed in to change notification settings - Fork 227
[DSv4] Refresh GB200 dynamo-vLLM 1k1k sweep #2190
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,136 @@ | ||
| name: "dsv4-vllm-disagg-gb200-1p1d-dep8-dep16" | ||
|
|
||
| # 1k/1k mid-to-high throughput topology. Extrapolated from | ||
| # kimi-k2.5/1k1k/disagg-gb200-1p1d-dep4-dep16.yaml adjusted for DSV4-Pro's | ||
| # DP>=8 minimum. Single prefill worker feeding a wide DP=16 decode handles | ||
| # conc 256-4096 cleanly for 1k prompts (prefill throughput per rank is high | ||
| # enough at this prompt length; see kimi precedent). | ||
| # | ||
| # Differences from our 8k1k 7p1d-dep8-dep16: | ||
| # * prefill_workers: 1 (vs 7) — 1k prompts don't need 14 prefill nodes | ||
| # * max-model-len: 3072 instead of auto | ||
| # * prefill max-num-seqs: 16 (fills 16384-token budget at 1k per seq) | ||
| # * decode max-num-seqs: 512 instead of 256 (shorter KV, more parallelism) | ||
| # * max-cudagraph-capture-size / max-num-batched-tokens (decode): 512 | ||
| # | ||
| # Restored 2026-07 for the GB200 dsv4 1k1k refresh: these day-0 recipes | ||
| # (#1129) were dropped by the deepseek-v4-pro-sa curation (5b0347f43, | ||
| # "only 8k/1k in scope"), which froze the site's GB200 1k1k rows at the | ||
| # 2026-04-25 day-0 run. Container/dynamo/infra fields updated to match | ||
| # the current 8k1k -sa set (v0.20.0-ubuntu2404, dynamo wheel | ||
| # 1.2.0.dev20260426, dedicated NATS/etcd infra node); topology and engine | ||
| # tuning unchanged from day-0. | ||
|
|
||
| model: | ||
| path: "deepseek-v4-pro" | ||
| container: "vllm/vllm-openai:v0.20.0-ubuntu2404" | ||
| precision: "fp4" | ||
|
|
||
| dynamo: | ||
| install: true | ||
| wheel: "1.2.0.dev20260426" | ||
|
|
||
| setup_script: vllm-container-deps.sh | ||
|
|
||
| # Also set slurm.time_limit explicitly (above srtslurm.yaml's 6h default) so | ||
| # a slow first-time Lustre load + cudagraph capture can't get cut off by the | ||
| # SLURM wall clock. | ||
| slurm: | ||
| time_limit: "8:00:00" | ||
|
|
||
| # Bumped from the 1800s default to 4 hours. DSV4-Pro weights load slowly from | ||
| # Lustre with multiple workers contending for the same OSTs — previous 1k/1k | ||
| # run hit the default 1800s. Make this *very* generous since the cost of an | ||
| # over-long deadline is just sitting idle, not wasted compute. | ||
| health_check: | ||
| max_attempts: 1440 | ||
| interval_seconds: 10 | ||
|
|
||
| resources: | ||
| gpu_type: "gb200" | ||
| gpus_per_node: 4 | ||
| prefill_nodes: 2 | ||
| decode_nodes: 4 | ||
| prefill_workers: 1 | ||
| decode_workers: 1 | ||
| gpus_per_prefill: 8 | ||
| gpus_per_decode: 16 | ||
|
|
||
| infra: | ||
| etcd_nats_dedicated_node: true | ||
|
|
||
| frontend: | ||
| type: dynamo | ||
| enable_multiple_frontends: false | ||
|
|
||
| backend: | ||
| type: vllm | ||
| connector: null | ||
|
|
||
| prefill_environment: | ||
| TILELANG_CLEANUP_TEMP_FILES: "1" | ||
| VLLM_USE_NCCL_SYMM_MEM: "1" | ||
| NCCL_CUMEM_ENABLE: "1" | ||
| NCCL_MNNVL_ENABLE: "1" | ||
| NCCL_NVLS_ENABLE: "1" | ||
| VLLM_SERVER_DEV_MODE: "1" | ||
|
|
||
| decode_environment: | ||
| TILELANG_CLEANUP_TEMP_FILES: "1" | ||
| VLLM_USE_NCCL_SYMM_MEM: "1" | ||
| NCCL_CUMEM_ENABLE: "1" | ||
| NCCL_MNNVL_ENABLE: "1" | ||
| NCCL_NVLS_ENABLE: "1" | ||
| VLLM_SERVER_DEV_MODE: "1" | ||
|
|
||
| vllm_config: | ||
| prefill: | ||
| kv-transfer-config: '{"kv_connector": "NixlConnector", "kv_role": "kv_both"}' | ||
| served-model-name: "deepseek-ai/DeepSeek-V4-Pro" | ||
| kv-cache-dtype: "fp8" | ||
| tensor-parallel-size: 1 | ||
| pipeline-parallel-size: 1 | ||
| data-parallel-size: 8 | ||
| data-parallel-rpc-port: 13345 | ||
| enable-expert-parallel: true | ||
| enforce-eager: true | ||
| max-model-len: 3072 | ||
| max-num-seqs: 16 | ||
| max-num-batched-tokens: 16384 | ||
| trust-remote-code: true | ||
| no-enable-prefix-caching: true | ||
| no-enable-flashinfer-autotune: true | ||
| block-size: 256 | ||
| gpu-memory-utilization: 0.88 | ||
| no-disable-hybrid-kv-cache-manager: true | ||
| enable-sleep-mode: true | ||
|
|
||
| decode: | ||
| kv-transfer-config: '{"kv_connector": "NixlConnector", "kv_role": "kv_both"}' | ||
| served-model-name: "deepseek-ai/DeepSeek-V4-Pro" | ||
| kv-cache-dtype: "fp8" | ||
| tensor-parallel-size: 1 | ||
| pipeline-parallel-size: 1 | ||
| data-parallel-size: 16 | ||
| data-parallel-rpc-port: 13345 | ||
| enable-expert-parallel: true | ||
| max-model-len: 3072 | ||
| max-num-seqs: 512 | ||
| max-cudagraph-capture-size: 512 | ||
| max-num-batched-tokens: 512 | ||
| trust-remote-code: true | ||
| no-enable-prefix-caching: true | ||
| block-size: 256 | ||
| compilation-config: '{"cudagraph_mode":"FULL_DECODE_ONLY","mode":0}' | ||
| gpu-memory-utilization: 0.9 | ||
| stream-interval: 50 | ||
| no-disable-hybrid-kv-cache-manager: true | ||
| enable-sleep-mode: true | ||
|
|
||
| benchmark: | ||
| type: "sa-bench" | ||
| isl: 1024 | ||
| osl: 1024 | ||
| concurrencies: "128x256x1024x2048x4096" | ||
| req_rate: "inf" | ||
| use_chat_template: false | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 The three new 1k1k vLLM DSv4-Pro recipes set Extended reasoning...All three new 1k1k recipes ( I verified the client-side code path in A verifier raised a solid refutation that I confirmed by grepping the repo: On impact: since Proof walkthrough: For Recommend the author confirm whether this was intentional (e.g., because these are day-0-derived recipes predating the |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,155 @@ | ||
| name: "dsv4-vllm-disagg-gb200-1p1d-dep8-tep8" | ||
|
|
||
| # 1k/1k variant of NVIDIA's 8k/1k 1p1d-dep8-tep8 recipe (mirrored from | ||
| # aflowers/gb200-dsv4-recipes branch). Same topology and tuning; only | ||
| # max-model-len shrinks from 9280 (8k+1k+pad) to 3072 (1k+1k+pad). No | ||
| # upstream NVIDIA reference for DSV4-Pro 1k/1k vLLM disagg yet. | ||
| # | ||
| # Topology: 1 prefill (DP=8) + 1 decode (TP=8). 4 nodes total. Targets | ||
| # very low concurrency (1-64). | ||
| # | ||
| # Local deltas vs upstream 8k/1k sibling: same as the 8k/1k recipe — see | ||
| # ../8k1k/disagg-gb200-1p1d-dep8-tep8.yaml for the full deviation list. | ||
|
Comment on lines
+10
to
+12
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 Two header-comment path references in the restored 1k1k recipes point to nonexistent files. In disagg-gb200-1p1d-dep8-tep8.yaml (lines 10-12), the comment points to '../8k1k/disagg-gb200-1p1d-dep8-tep8.yaml' but the actual GB200 8k1k low-latency sibling is named disagg-gb200-low-latency.yaml. In disagg-gb200-1p1d-dep8-dep16.yaml (lines 2-4), the comment references 'kimi-k2.5/1k1k/disagg-gb200-1p1d-dep4-dep16.yaml' but the actual directory is kimi-k2.5-fp4/1k1k/ (missing the -fp4 suffix). Both are comment-only with no runtime impact; worth a quick fix so future readers can actually follow the references. Extended reasoning...What the bug is: Two of the three newly-restored 1k1k recipe YAMLs contain header comments that cross-reference sibling/precedent files using paths that do not exist in this repository.
Code path / why nothing catches this: These are plain YAML comments (lines starting with Impact: Zero runtime impact — the sweep, config generation, and benchmark execution are all unaffected. The only cost is to a future engineer who reads the comment, tries to open the referenced file to check 'the full deviation list' or find the extrapolation precedent, and hits a dead path. For (1) this is a real dead-end since the correct file has a completely different name ( Proof (bug 1): Proof (bug 2): Fix: Repoint the first comment at On the refutation: One verifier argued bug 2 is too trivial to report because the filename is unique and easily grep-able despite the wrong parent directory. That's a fair point for bug 2 in isolation, but bug 1's broken reference is a harder dead-end (the correct file has an entirely different name, not a typo'd path), so the pair together is worth a single combined nit-level note — cheap for the author to fix in the same pass, not worth blocking merge over. |
||
| # | ||
| # Restored 2026-07 for the GB200 dsv4 1k1k refresh: these day-0 recipes | ||
| # (#1129) were dropped by the deepseek-v4-pro-sa curation (5b0347f43, | ||
| # "only 8k/1k in scope"), which froze the site's GB200 1k1k rows at the | ||
| # 2026-04-25 day-0 run. Container/dynamo/infra fields updated to match | ||
| # the current 8k1k -sa set (v0.20.0-ubuntu2404, dynamo wheel | ||
| # 1.2.0.dev20260426, dedicated NATS/etcd infra node); topology and engine | ||
| # tuning unchanged from day-0. | ||
|
|
||
| model: | ||
| path: "deepseek-v4-pro" | ||
| container: "vllm/vllm-openai:v0.20.0-ubuntu2404" | ||
| precision: "fp4" | ||
|
|
||
| dynamo: | ||
| install: true | ||
| wheel: "1.2.0.dev20260426" | ||
|
|
||
| setup_script: vllm-container-deps.sh | ||
|
|
||
| slurm: | ||
| time_limit: "8:00:00" | ||
|
|
||
| health_check: | ||
| max_attempts: 1440 | ||
| interval_seconds: 10 | ||
|
|
||
| resources: | ||
| gpu_type: "gb200" | ||
| gpus_per_node: 4 | ||
| prefill_nodes: 2 | ||
| decode_nodes: 2 | ||
| prefill_workers: 1 | ||
| decode_workers: 1 | ||
| gpus_per_prefill: 8 | ||
| gpus_per_decode: 8 | ||
|
|
||
| infra: | ||
| etcd_nats_dedicated_node: true | ||
|
|
||
| frontend: | ||
| type: dynamo | ||
| enable_multiple_frontends: false | ||
|
|
||
| backend: | ||
| type: vllm | ||
| connector: null | ||
|
|
||
| prefill_environment: | ||
| VLLM_ENGINE_READY_TIMEOUT_S: "3600" | ||
| TILELANG_CLEANUP_TEMP_FILES: "1" | ||
| VLLM_USE_NCCL_SYMM_MEM: "1" | ||
| NCCL_CUMEM_ENABLE: "1" | ||
| NCCL_MNNVL_ENABLE: "1" | ||
| NCCL_NVLS_ENABLE: "1" | ||
| VLLM_SERVER_DEV_MODE: "1" | ||
| VLLM_SPARSE_INDEXER_MAX_LOGITS_MB: "1024" | ||
| VLLM_MAX_TOKENS_PER_EXPERT_FP4_MOE: "2048" | ||
| # VLLM_RANDOMIZE_DP_DUMMY_INPUTS: "1" | ||
| # VLLM_MOE_ROUTING_SIMULATION_STRATEGY: "uniform_random" | ||
| UCX_MEMTYPE_CACHE: "n" | ||
| UCX_MEMTYPE_REG_WHOLE: "n" | ||
| UCX_TLS: "cuda_copy,cuda_ipc,tcp" | ||
| UCX_CUDA_IPC_ENABLE_MNNVL: "y" | ||
| NCCL_P2P_LEVEL: NVL | ||
|
|
||
| decode_environment: | ||
| VLLM_ENGINE_READY_TIMEOUT_S: "3600" | ||
| TILELANG_CLEANUP_TEMP_FILES: "1" | ||
| VLLM_USE_NCCL_SYMM_MEM: "1" | ||
| NCCL_CUMEM_ENABLE: "1" | ||
| NCCL_MNNVL_ENABLE: "1" | ||
| NCCL_NVLS_ENABLE: "1" | ||
| VLLM_SERVER_DEV_MODE: "1" | ||
| # VLLM_RANDOMIZE_DP_DUMMY_INPUTS: "1" | ||
| # VLLM_MOE_ROUTING_SIMULATION_STRATEGY: "uniform_random" | ||
| UCX_MEMTYPE_CACHE: "n" | ||
| UCX_MEMTYPE_REG_WHOLE: "n" | ||
| UCX_TLS: "cuda_copy,cuda_ipc,tcp" | ||
| UCX_CUDA_IPC_ENABLE_MNNVL: "y" | ||
| NCCL_P2P_LEVEL: NVL | ||
|
|
||
| vllm_config: | ||
| prefill: | ||
| kv-transfer-config: '{"kv_connector": "NixlConnector", "kv_role": "kv_both"}' | ||
| served-model-name: "deepseek-ai/DeepSeek-V4-Pro" | ||
| kv-cache-dtype: "fp8" | ||
| tensor-parallel-size: 1 | ||
| pipeline-parallel-size: 1 | ||
| data-parallel-size: 8 | ||
| data-parallel-rpc-port: 13345 | ||
| enable-expert-parallel: true | ||
| enforce-eager: true | ||
| max-model-len: 3072 | ||
| max-num-seqs: 16 | ||
| max-num-batched-tokens: 32768 | ||
| trust-remote-code: true | ||
| no-enable-prefix-caching: true | ||
| no-enable-flashinfer-autotune: true | ||
| no-async-scheduling: true | ||
| block-size: 256 | ||
| gpu-memory-utilization: 0.8 | ||
| no-disable-hybrid-kv-cache-manager: true | ||
| enable-sleep-mode: true | ||
| # CPU/DRAM expert offload — required for fit. Without these the prefill | ||
| # rank reports `Available KV cache memory: -16 GiB` and the engine | ||
| # refuses to start. Numa-bind from upstream is still off because our | ||
| # NVIDIA/srt-slurm@sa-submission-q2-2026 clone doesn't ship the | ||
| # vllm_numa_bind_hash_fix.py patch. | ||
| offload-group-size: 3 | ||
| offload-num-in-group: 1 | ||
| offload-prefetch-step: 2 | ||
| tokenizer-mode: deepseek_v4 | ||
|
|
||
| decode: | ||
| kv-transfer-config: '{"kv_connector": "NixlConnector", "kv_role": "kv_both"}' | ||
| served-model-name: "deepseek-ai/DeepSeek-V4-Pro" | ||
| kv-cache-dtype: "fp8" | ||
| tensor-parallel-size: 8 | ||
| pipeline-parallel-size: 1 | ||
| enable-expert-parallel: true | ||
| max-model-len: 3072 | ||
| max-num-seqs: 64 | ||
| max-cudagraph-capture-size: 64 | ||
| max-num-batched-tokens: 64 | ||
| trust-remote-code: true | ||
| no-enable-prefix-caching: true | ||
| block-size: 256 | ||
| attention-config: '{"use_fp4_indexer_cache":true}' | ||
| compilation-config: '{"mode":0,"cudagraph_mode":"FULL_DECODE_ONLY","pass_config":{"fuse_allreduce_rms":false}}' | ||
| gpu-memory-utilization: 0.9 | ||
| stream-interval: 50 | ||
| no-disable-hybrid-kv-cache-manager: true | ||
| enable-sleep-mode: true | ||
| tokenizer-mode: deepseek_v4 | ||
|
|
||
| benchmark: | ||
|
Comment on lines
+130
to
+149
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 In the restored Extended reasoning...The bug: |
||
| type: "sa-bench" | ||
| isl: 1024 | ||
| osl: 1024 | ||
| concurrencies: "1x4x8x16x32x64" | ||
| req_rate: "inf" | ||
| use_chat_template: false | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔴 Both new dep8-dep16 recipes (1p1d and 3p1d) omit
tokenizer-mode: deepseek_v4in their prefill and decodevllm_configblocks, unlike every other DeepSeek-V4-Pro recipe in the tree (including the tep8 sibling added in this same PR).Extended reasoning...
What's wrong
disagg-gb200-1p1d-dep8-dep16.yamlanddisagg-gb200-3p1d-dep8-dep16.yamlset notokenizer-modeanywhere in theirvllm_config.prefillorvllm_config.decodeblocks. Every other DeepSeek-V4-Pro vLLM recipe inbenchmarks/multi_node/srt-slurm-recipes/vllm/deepseek-v4/— all 8k1k GB200/B200/GB300 recipes, the agentic recipes, and critically thedisagg-gb200-1p1d-dep8-tep8.yamlsibling added in this same PR (lines 125 and 147) — setstokenizer-mode: deepseek_v4in both the prefill and decode sections.Why this happened
The header comment on the affected file states it was "Extrapolated from kimi-k2.5/1k1k/disagg-gb200-1p1d-dep4-dep16.yaml adjusted for DSV4-Pro's DP>=8 minimum." Kimi-K2.5 is a different model that does not require the DeepSeek-specific tokenizer, so the extrapolation carried over everything except this one model-specific field. By contrast, the tep8 sibling recipe in the same PR was mirrored directly from NVIDIA's 8k1k DSV4 reference recipe, which is why it correctly retained
tokenizer-mode: deepseek_v4.Why nothing else catches it
tokenizer-modeis not injected by the config/recipe generation pipeline (generate_sweep_configs.py) — it is a raw pass-through field into the vLLM launch args from the recipe YAML itself. There's no default-injection or validation step downstream that would backfill it, anddeepseek_v4is a genuinely distinct, non-auto-selected tokenizer mode (seeutils/bench_serving/benchmark_serving.pyaround line 1271, where it is listed as a separate choice alongsideauto/slow/mistral/custom, with a comment noting the stock HFAutoTokenizermay not recognizedeepseek_v4and vLLM's own loader must be used instead).Impact
Without this setting, vLLM falls back to its default (
auto) tokenizer resolution for DeepSeek-V4-Pro, which will either fail to load a workable tokenizer at engine startup or silently mis-tokenize inputs/outputs. These two recipes back theconc-list: [128, 256, 1024, 2048, 4096]andconc-list: [4096, 8192]scenarios inconfigs/nvidia-master.yaml— i.e. most of the 1k1k sweep this PR is restoring. The result would either be failed CI runs or (worse) benchmark numbers published for an incorrectly-tokenized model, defeating the stated purpose of the PR.Proof by comparison
tokenizer-mode: deepseek_v4— it appears twice (prefill + decode) in every existing DSv4-Pro recipe, and twice in the newdisagg-gb200-1p1d-dep8-tep8.yaml(lines 125, 147) added in this PR.disagg-gb200-1p1d-dep8-dep16.yaml(lines 87-106 shown, prefill/decodevllm_configblocks) anddisagg-gb200-3p1d-dep8-dep16.yamlreturns zero matches.tokenizer-mode: deepseek_v4to both theprefill:anddecode:entries ofvllm_configin both files, mirroring the tep8 recipe and every 8k1k recipe.