Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 33 additions & 7 deletions models/deepseek-ai/DeepSeek-V4.1-Flash.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ meta:
provider: "DeepSeek"
description: "DeepSeek V4.1 Flash vision-language MoE (552B backbone; 8B active per prompt token, 16B per output token) combining sliding-window plus compressed sparse attention with a two-level indexer, engram n-gram memory, hyper-connections, and a DSpark multi-token draft head."
date_added: 2026-09-09
date_updated: 2026-09-12
date_updated: 2026-09-13
difficulty: advanced
tasks:
- text
Expand All @@ -20,14 +20,18 @@ meta:
gb200: verified
gb300: verified
mi350x: verified
mi355x: verified

model:
model_id: "deepseek-ai/DeepSeek-V4.1-Flash"
min_vllm_version: "0.30.0"
default_frontend: rust
docker_image:
nvidia: "vllm/vllm-openai:deepseekv41-flash-0909"
amd: "vllm/vllm-openai-rocm:deepseekv41-flash-0909"
# ROCm nightly rather than the 0909 tag: 0909 predates
# vllm-project/vllm#56503, which moves the mHC delayed pre block off the
# eager Torch reference and onto AITER.
amd: "vllm/vllm-openai-rocm:nightly-eed1f3d0c6043bd494424a22443ee198dd56f657"
architecture: moe
parameter_count: "552B"
active_parameters: "8-16B"
Expand All @@ -39,7 +43,7 @@ model:
VLLM_ENGINE_READY_TIMEOUT_S: "3600"
install:
docker:
note: "Serve from the dedicated vllm/vllm-openai:deepseekv41-flash-0909 image — no pip wheel carries the DeepSeek-V4.1 architecture."
note: "Serve from the pinned image for your GPU vendor — no pip wheel carries the DeepSeek-V4.1 architecture. NVIDIA pins the 0909 release tag; AMD pins a ROCm nightly (see Prerequisites)."
pip: false

dependencies: []
Expand Down Expand Up @@ -111,20 +115,36 @@ hardware_overrides:
extra_args:
- "--gpu-memory-utilization"
- "0.9"
# Plain "aiter" opens vLLM's full MoE priority list, whose head is the
# Composable Kernel backend, giving the a8w4 experts. Naming
# aiter_triton_mxfp4_bf16 instead pins the Triton W4A16 _moe_gemm_a16w4.
- "--moe-backend"
- "aiter_triton_mxfp4_bf16"
- "aiter"
Comment on lines 115 to +122

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The hardware_overrides.amd.extra_args block is missing critical ROCm execution and optimization arguments that are used in the verified MI355X validation command in the guide (lines 956-971) and are standard across other ROCm recipes (like DeepSeek-V4-Flash.yaml). Specifically, it should include --distributed-executor-backend mp (required for stable multi-GPU execution on ROCm) and --compilation-config '{"mode": 3, "cudagraph_mode": "FULL_DECODE_ONLY"}' (critical for compilation and decode performance), as well as --max-num-batched-tokens 8192.

Without these, the synthesized command generated by the UI/API for AMD users will be unoptimized and may fail or hang during multi-GPU execution.

    extra_args:
      - "--distributed-executor-backend"
      - "mp"
      - "--gpu-memory-utilization"
      - "0.9"
      - "--max-num-batched-tokens"
      - "8192"
      # Plain "aiter" opens vLLM's full MoE priority list, whose head is the
      # Composable Kernel backend, giving the a8w4 experts. Naming
      # aiter_triton_mxfp4_bf16 instead pins the Triton W4A16 _moe_gemm_a16w4.
      - "--moe-backend"
      - "aiter"
      - "--compilation-config"
      - '{"mode": 3, "cudagraph_mode": "FULL_DECODE_ONLY"}'

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checked all three against the run this recipe is verified against and against vLLM at the pinned commit (eed1f3d0c6). Declining them.

--compilation-config '{"mode": 3, "cudagraph_mode": "FULL_DECODE_ONLY"}' — mode 3 is CompilationMode.VLLM_COMPILE, the Inductor-based piecewise-compilation path. DeepseekV41ForCausalLM is not torch-compiled upstream, which is precisely why this block sets VLLM_USE_BREAKABLE_CUDAGRAPH=1 a few lines below, and why the ROCm sparse SWA backend reporting UNIFORM_BATCH forced the feature-level DSpark override merged in #963. Adding this would abort at engine init, not improve decode.

--distributed-executor-backend mp and --max-num-batched-tokens 8192 — neither appears in the verified MI355X launch line (benchmarks/single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh in SemiAnalysisAI/InferenceX#3058). That script passes --max-num-batched-tokens 16384, which is also vLLM's own default for UsageContext.OPENAI_API_SERVER on a GPU reporting ≥160 GiB (EngineArgs.get_batch_defaults), so 8192 would halve the verified value rather than match it.

On the cited precedent: DeepSeek-V4-Flash.yaml is a different architecture, and its AMD block carries those flags legitimately. V4.1-Flash is the one without torch.compile support. None of the three are in V4.1-Flash's AMD block on main today either, so adding them would be outside this PR's scope — aligning the existing recipe with #3058.

extra_env:
VLLM_ROCM_USE_AITER: "1"
VLLM_ROCM_USE_AITER_MOE: "1"
# aiter.ops.triton warns on every call that Gluon is unavailable and it is
# falling back to Triton. Gluon is gfx1250-only, so on gfx950 that is a
# fixed property, and it was 98% of the lines in a gsm8k server log.
AITER_TRITON_LOG_LEVEL: "ERROR"
# DeepseekV41ForCausalLM does not support torch.compile. The ROCm sparse
# SWA backend only reports UNIFORM_BATCH, so default FULL_AND_PIECEWISE
# cannot start unless breakable CUDA graphs are on.
VLLM_USE_BREAKABLE_CUDAGRAPH: "1"

strategy_overrides:
single_node_tp:
# Verified at TP4 (one GB200 NVL4 tray; 4 of 8 GPUs on an MI350X node).
# Verified at TP4 (one GB200 NVL4 tray; 4 of 8 GPUs on an MI350X or
# MI355X node).
tp: 4
hardware_overrides:
mi355x:
# vllm serve defaults max_num_seqs to 1024 on >=160 GiB GPUs, but the
# MI355X run this recipe is verified against served 128. Pinned so the
# published command reproduces that run, and only for this pairing.
extra_args:
- "--max-num-seqs"
- "128"
Comment on lines +146 to +147

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: maybe we can also add --max-cudagraph-capture-size 1024 for dspark 6 for better perf. Not a blocker for merging this PR though.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @ivanium, for the suggestion! The current recipe is to align with the sweep run SemiAnalysisAI/InferenceX#3058. We will test --max-cudagraph-capture-size 1024
cc: @Fangzhou-Ai

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dig into it a little bit, I think this setting is for benchmarking purposes only. In general we don't need the cap on max-num-seqs and max-cudagraph-capture-size. Mayabe we should revise this PR into a benchmark-only recipe? @ivanium @AndreasKaratzas

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But we do want to pin the image to the latest nightly now, DSV4.1 has been enabled since this Saturday.

@ivanium ivanium Sep 13, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about we add a perf tuning section in the overview on how to set these parameters and potentially link to the InferenceX submission?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep that's what I'm (my codex) planning to do now.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please check #968

pd_cluster:
# Verified 1P1D on GB200 NVL4: one tray per role, TP4 each, NIXL transfer.
env:
Expand Down Expand Up @@ -303,12 +323,18 @@ guide: |

## Prerequisites

- The `vllm/vllm-openai:deepseekv41-flash-0909` image (vLLM 0.30.0+). No pip wheel serves
this architecture, so the Install block only offers Docker.
- An image (vLLM 0.30.0+); no pip wheel serves this architecture, so the Install block
only offers Docker. On NVIDIA that is `vllm/vllm-openai:deepseekv41-flash-0909`. On AMD
it is `vllm/vllm-openai-rocm:nightly-eed1f3d0c6043bd494424a22443ee198dd56f657` — a ROCm
nightly rather than the 0909 tag, because 0909 predates
[vllm-project/vllm#56503](https://github.com/vllm-project/vllm/pull/56503), which moves
the mHC delayed pre block off the eager Torch reference and onto AITER.
- The Rust OpenAI frontend is selected by default in the command builder. Switch
to Python if you encounter unsupported features or compatibility issues.
- Expect a long first load: `VLLM_ENGINE_READY_TIMEOUT_S=3600` is set for that reason.
- On AMD, the generated command sets `VLLM_USE_BREAKABLE_CUDAGRAPH=1`. DeepSeek-V4.1-Flash does not support `torch.compile`, and the ROCm sparse SWA backend only supports uniform-batch CUDA graphs. Without breakable CUDA graphs, default `FULL_AND_PIECEWISE` dies at capture.
- On AMD, the generated command passes `--moe-backend aiter` rather than naming a kernel. Naming `aiter_triton_mxfp4_bf16` pins the Triton W4A16 `_moe_gemm_a16w4` kernel; the plain name lets vLLM select the Composable Kernel a8w4 experts, which measured 4–9% faster per decode step at 131k context on MI355X, with larger gains at higher concurrency. It also sets `AITER_TRITON_LOG_LEVEL=ERROR` to drop AITER's per-call "Gluon unavailable" warning, which is constant on gfx950 and dominated the server log.
- On MI355X, **Tensor Parallel** additionally pins `--max-num-seqs 128`, the value the verified run served. Left unset, `vllm serve` defaults to 1024 on GPUs with at least 160 GiB. Raise it if your traffic needs more scheduler capacity than the verified configuration.
- On AMD, ticking **Speculative decoding** also sets `enable_adaptive_verification:false`. vLLM currently refuses the true flag: `DeepseekV41IndexerBackend.supports_device_cpu_query_lens_mismatch()` is False, and `DeepseekV41ROCMAiterSparseSWABackend` reports `UNIFORM_BATCH` rather than `ALWAYS`. DSpark still drafts 5 tokens per round.

## Verifying
Expand Down