单块 AMD MI300X 运行 DeepSeek V4 Flash 实战指南
deepseek-ai/DeepSeek-V4-Flash-0731 所需的配置与补丁。内容包括 Docker Compose 堆栈、SHA-256 固定的文件覆盖层、与上游的参考差异对比,以及调优参数表。检查点按原样运行,无需额外的权重量化或卸载。
以下为固定堆栈(vLLM ROCm 夜间版 0.26.1rc1.dev229+g124154a88.rocm723,AITER 0.1.19)的测试结果:
| 指标 | 结果 |
|------|------|
| 单流解码(每流中位数,DSpark-7) | **168.6 tok/s** |
| 使用调优内核的预填充 | **≈ 7.9–8.5K tok/s**(默认配置下新提示词为 6,988–7,019 tok/s) |
| 8 个并发流 | 总计 542 tok/s,每流中位数 90.3 tok/s |
| 64 流突发 | 总计 830 tok/s,无 OOM,无引擎错误 |
| 上下文长度 | 已验证 256K(架构支持 1M) |
| HBM 中的权重 | 156.67 GiB — **无需额外量化或权重卸载** |
官方 vLLM 方案主要面向 NVIDIA 及更新的 AMD 硬件。要在 MI300X 上稳定运行该模型,需要修复其 FP8 格式、高并发下的 MoE 路由、因果推测验证、CPU-KV 同步,以及多个未调优的内核形状。本仓库收集了这些修复,并固定了生产环境中使用的版本。
为什么选择 MI300X
MI300X 拥有 **192 GB HBM3** 和 5.3 TB/s 的内存带宽,HBM 容量是 H100 SXM5 的 2.4 倍(AMD)。Doubleword 的分析估计其标价大约只有一半。对于这个 304B 参数的检查点,内存容量足以实现简单的单 GPU 部署:- 整个模型可放入 HBM,无需 PCIe 权重流式传输或层卸载。
- 留有 20 GB 的 GPU KV 池空间,以及 96 GiB 的 CPU 层用于存储被驱逐的前缀缓存条目。
- 单卡可处理 2–8 个典型并发流,以及最多 64 个流的突发请求。
MI300X(CDNA3)使用的是 AMD/Graphcore 的 E4M3 fnuz 变体,而 MI325X 及更新型号则采用 OCP 标准的 FP8(背景介绍)。如果在 MI300X 上使用 OCP 语义的内核,缩放域的结果可能会偏差两倍。因此,首要任务是确保 FP8 实现的正确性,性能优化则放在其后。
已有成果与本仓库的补充
Fergus Finn 的 MI300X 工作日志及其配套的 Doubleword 仓库已发现 FP8 不兼容、gfx942 上缺少 AITER 快速路径、稀疏 MLA 解码中的 HIP-graph 隐患以及 MoE 路由错误。官方 vLLM 配方覆盖了 NVIDIA 硬件和更新的 AMD GPU(MI325X 在 4K 上下文、MI355X),但未提供针对 0731 检查点的单 MI300X 生产配置。
本仓库新增了以下内容:
- 正确性覆盖层:针对固定版本的 ROCm 每日构建,包含上游 vLLM 尚未合并的修复。
- 经过验证的服务配置:采用概率性 DSpark 草稿生成、块拒绝机制和静态 K=7。该配置使用 2,048 token 的调度预算和 1,024 token 的长预填上限,防止冷启动提示阻塞其他流。
- AITER GEMM 调优表:补充了打包表缺失的常见
gfx942形状,以及针对 MXFP4 专家的gfx942OGS 几何覆盖。 - 混合 KV 策略:20 GB 的
fp8_ds_mlaGPU 缓存 + 96 GiB 原生 CPU 卸载,并修复了加载路径的同步问题(上游 issue #47282 有记录,但 PR #47291 从未合并)。
仓库结构
.
├── compose.yaml # 生产环境堆栈(vLLM ROCm + Caddy),使用摘要固定版本
├── Caddyfile.example # 复制为 Caddyfile;设置主机名、邮箱和来源 CIDR
├── vllm-entrypoint.sh # 启动前清理 /dev/shm 中过时的 CPU-KV 内存映射
├── SHA256SUMS # 所有运行时工件的 SHA-256 校验值
├── patches/
│ ├── *.py # 逐字节的生产环境覆盖层(以只读方式挂载)
│ ├── diffs/*.patch # 与上游基础版本之间的统一差异文件
│ └── README.md # 来源说明和重新生成指南
└── tuning/
└── *.csv # gfx942 的 AITER A8W8 块缩放调优表
运行时配置
该堆栈使用摘要固定的官方 vLLM ROCm 每日构建版本,并包含以下特性:
--trust-remote-code以及 DeepSeek V4 分词器、推理和工具解析器fp8_ds_mlaKV 缓存(UE8M0 块缩放 FP8,非通用无缩放 FP8),块大小为 256 个 tokenVLLM_ROCM_USE_AITER=1和--moe-backend triton;Triton OGS 处理分组的 MXFP4 专家模块,而 AITER 处理注意力机制和密集线性层- DSpark-7 推测解码,采用概率草稿和块拒绝机制
- 完整/可中断的 CUDA 图捕获,在稳定解码阶段每个 token 仅触发一次图启动
- Caddy 作为基于 IP 白名单的 HTTPS 代理
部署步骤
1. 主机前置条件
需要一块 MI300X(gfx942,304 个计算单元,约 192 GiB HBM)、可用的 AMD 内核驱动、最新版 Docker Compose、约 235 GiB 内存用于 CPU KV 层,以及约 500 GB 磁盘空间(仅模型缓存就约 156 GB)。
2. 拉取固定版本的运行时和模型
3. 准备文件
cp Caddyfile.example Caddyfile # 然后设置你的主机名、邮箱和 remote_ip CIDR mkdir -p aiter-cache crash-dumps chmod +x vllm-entrypoint.sh sha256sum -c SHA256SUMS # 首次启动前验证覆盖层文件
4. 启动
docker compose config -q docker compose up -d docker compose logs -f inference
正常启动约需 5 分钟,且必须显示以下所有内容:
Model loading took 156.67 GiB
DSpark draft model loaded: 96 params
GPU KV cache size: 1,927,444 tokens
Maximum concurrency for 262,144 tokens per request: 7.35x
Created mmap file /dev/shm/vllm_offload_...mmap (103.08 GB)
Capturing CUDA graphs (FULL)
Application startup complete
图捕获完成后,运行 rocm-smi --showmeminfo vram。预热后的高水位线约为 205.8 GB 中的 204.5 GB。如果仅剩几百 MB,服务器可能启动成功,但首次请求会失败。
5. 冒烟测试
HOST='your-host.example.com'
curl -fsS "https://$HOST/v1/models"
curl -sS "https://$HOST/v1/completions" \
-H 'Content-Type: application/json' \
-d "{\"model\": \"deepseek-ai/DeepSeek-V4-Flash-0731\",
\"prompt\": \"Calculate 17 * 23. Answer with the number only.\",
\"temperature\": 0, \"max_tokens\": 32}"
补丁说明
每个 patches/*.py 文件都是一个完整文件覆盖层,以只读方式挂载到容器中对应文件之上;compose.yaml 中包含了目标路径。对应的 diffs/*.patch 记录了与上游基线的差异。基础镜像保持摘要锁定,因此升级时需要更改镜像引用并重新验证整个堆栈。
| 覆盖层 | 挂载目标 | 修复内容 | 何时需要 |
|---|---|---|---|
gpt_oss_triton_kernels_moe.pack128-fused-silu-fast-routing.py |
vllm/.../fused_moe/experts/gpt_oss_triton_kernels_moe.py |
MXFP4 位矩阵填充通道 + fused-SiLU 分组专家 + 快速 DeepSeek 路由 | 必需:MXFP4 Triton 路径必须使用;掩码修复尚未合并到上游(参见提交) |
mxfp4.fused-silu.py |
vllm/.../fused_moe/oracle/mxfp4.py |
fused-SiLU 核的 Gate/up 交错布局 | 使用 fused-SiLU 覆盖层时必须;若保留标准 SiLU 路径则可同时跳过两者 |
triton-kernels-matmul-ogs-opt-flags.dsv4-mi300x.py |
vllm/third_party/triton_kernels/matmul_ogs_details/opt_flags.py |
gfx942 MXFP4 OGS 瓦片几何(最多 1,536 路由行) |
性能优化于 gfx942;默认几何在路由行超过 768 时性能急剧下降 |
fused_compress_quant_cache.fnuz-shuffle.py |
vllm/models/deepseek_v4/common/ops/fused_compress_quant_cache.py |
Lightning Indexer 缓存写入器中的 FNUZ FP8 + 16×16 预混洗 | MI300X 上必须;MI325X/MI355X 使用 OCP FP8,需保留原始字节 |
aiter_pa_mqa_logits.i64.py |
aiter/ops/triton/gluon/pa_mqa_logits.py |
ChunkK=256 分页 MQA 核中的 64 位偏移量 |
当 KV 偏移量可能超过 4 GiB 时必须;小 KV 池可跳过 |
rocm_aiter_mla_sparse.prefill-bh64.py |
vllm/v1/attention/ops/rocm_aiter_mla_sparse.py |
确定性 torch.topk 预填充 + BLOCK_H=64 头-512 稀疏预填充 |
确定性对于可复现的工具调用是必需的;BLOCK_H=64 为性能优化 |
rocm_aiter_mla.dspark-causal.py |
vllm/v1/attention/backends/mla/rocm_aiter_mla.py |
因果多令牌推测验证 | ROCm 小头 MLA 上的 DSpark 必需——现已上游;覆盖层即为上游文件原样 |
dspark-speculator.independent-draft-gumbel.py + spec-decode-utils.independent-draft-gumbel.py |
vllm/v1/worker/gpu/spec_decode/dspark/speculator.py + .../spec_decode/utils.py |
草稿提议的 Gumbel 噪声与拒绝/恢复噪声隔离 | 仅在使用 draft_sample_method=probabilistic 时需要(本方案的贪婪路径不需要) |
kv_offload_cpu_gpu_worker.load-war.py |
vllm/v1/kv_offload/cpu/gpu_worker.py |
将 CPU→GPU 的 KV 恢复操作与正在进行的计算进行栅栏同步(#47282,PR #47291) | 仅在使用 --kv-offloading-backend native 时需要 |
两个重要的正确性修复
MXFP4 路由。 MoE 位矩阵内核将其块列填充到 Triton 块大小,但填充通道的掩码是针对全局张量边界而非逻辑块大小。在负载下,填充通道会破坏路由矩阵,导致长提示词中出现近似匹配的工具名称和遗忘的模式。一行修复代码为 mask = (offs_local < BLOCK_SIZE) & (offs_global < nonzero_indx_size),取自 Doubleword 提交 c32932bb9。该覆盖层还包含针对分组 MXFP4 专家的融合 SiLU 和快速路由更改。
FP8 格式。 DeepSeek V4 的 Lightning Indexer 缓存使用 FP8。标准写入器按行主序输出 OCP E4M3 字节,而 MI300X 上的 AITER 则按预混洗的 16×16 瓦片布局消费 AMD FNUZ E4M3 字节。在最坏情况下,将一种格式解释为另一种格式会产生两倍的缩放误差。该覆盖层在 ROCm 上选择 float8e4b8,设置 FP8_MAX=224.0 并使用混洗写入偏移量,同时在其他地方保持 OCP 路径不变。
推测解码
此技术栈使用带块拒绝的概率草稿生成。两个 Gumbel 覆盖层确保草稿提议噪声独立于拒绝和恢复噪声。
性能
生产配置中的关键优化:
| 变更 | 效果 |
|---|---|
针对 304-CU gfx942 调优 21 个重复出现的 A8W8 GEMM 形状 |
单/双流解码提升 +42–62%;8–64 流时提升 +10–35% |
| 融合 SiLU、快速 DeepSeek 路由、批量敏感的专家瓦片 | 原生 C1 解码从 34.5 提升至 56.6 tok/s(+64%);路由内核从 42.6 降至 11.9 µs/层 |
BLOCK_H=64 稀疏预填充瓦片 |
预填充阶段达到7.9–8.5K tok/s;稀疏注意力追踪从每请求317毫秒降至142毫秒 |
| 静态K=7,概率+块拒绝,因果验证 | 单流119.5 tok/s,输出正确 |
| 2,048 token预算 + 1,024 token长预填充上限 | 52K预填充后的短请求TTFT:从8.2秒降至0.5秒 |
| 20 GB GPU KV缓存 + 96 GiB CPU层 | 等效193万token容量;接纳7个256K请求 |
最终并发测试
使用约400词的独立提示词,流式输出,temperature=1.0, top_p=0.95;C1–C8输出512 token,C64输出256 token:
| 流数 | 总tok/s | 单流解码中位数 | TTFT p50 |
|---|---|---|---|
| 1 | 126.2 | 168.6 tok/s | 1.026秒 |
| 2 | 145.4 | 152.7 | 0.939秒 |
| 4 | 316.8 | 108.6 | 0.369秒 |
| 8 | 542.3 | 90.3 | 1.027秒 |
| 64 | 830.2 | 16.4 | 2.190秒 |
DSpark的接受率取决于提示词;这些数据仅针对当前图像,并非通用模型基准。
预填充
使用优化后的内核,无缓存预填充达到7.9–8.5K tok/s,具体取决于调度器预算:C1下8,192 token预算时为7.90–7.99K,C4下为8.46–8.51K。生产配置采用2,048 token预算以隔离延迟,新提示词下为6,988–7,019 tok/s。启用1,024 token长预填充上限后,8.9K token提示词在C1下达到5.20–5.29K tok/s。作为交换,排在52K冷预填充后的短请求TTFT从8.2秒降至0.5秒。380K缓存token的热召回在120–125秒冷预填充后仅需0.64–2.65秒。
生产注意事项
- HBM余量有限。预热后的高水位线为204.5 GB(总容量205.8 GB)。30 GB的KV缓存池虽能加载,但在图捕获阶段会因
HSA_STATUS_ERROR_OUT_OF_RESOURCES错误而失败。请勿提高--kv-cache-memory-bytes参数;需持续监控HBM使用量是否增长。 - CPU KV 层存储的是缓存条目,而非权重。
--kv-offloading-size 96 --kv-offloading-backend native会在/dev/shm中映射约 103 GB 空间,用于存放被驱逐的前缀缓存条目。入口点在崩溃后会清除过时的映射。 - 1,664 token 的调度器警告属于正常现象。 DSpark-7 会从 2,048 token 的预算中预留草稿槽位。提高预算会保留更多运行中的滑动窗口状态,从而减少可用的 KV 容量。
- 重启后需要预热内核。 首次预填充会初始化内核,处理 8.9K token 耗时 5.3 秒;后续运行只需 1.7 秒。在接收流量前,先执行一次无缓存的预填充。
- 既要测试吞吐量,也要测试正确性。 验证套件包含两轮工具调用测试用例、BFCL 子集(74–76/90 次精确调用)、OpenCode 工具模式检查,以及在原生和 DSpark 两条路径上进行的 380K token 针眼召回测试。冷预填充和缓存预填充可能走不同的浮点路径,因此两者都需要测试。
许可与来源
本技术栈、文档以及基于 vLLM 的覆盖层均采用 Apache-2.0 许可(见 LICENSE 文件);基于 AITER 的覆盖层保留其 MIT 许可头。每个补丁的上游基础版本记录在 patches/README.md 中。模型本身采用 MIT 许可。
参考资料
所有链接已于 2026 年 8 月 4 日验证。
- DeepSeek-V4-Flash-0731 模型卡片 — 官方发布;304B 参数;集成 DSpark 模块;推荐参数
temperature=1.0, top_p=0.95;MIT 许可 - 官方 vLLM DeepSeek V4 Flash 配方 — 参考启动配置,DSpark(
num_speculative_tokens=7),FP8 KV,块大小 256,deepseek_v4解析器;针对 MI325X/MI355X 的 AMD 指南 - 在 AMD MI300X 上部署 DeepSeek-V4-Flash(Fergus Finn, Doubleword, 2026 年 6 月)— 本仓库所基于的部署工作日志:FNUZ 与 OCP FP8 对比、
gfx942上的 AITER 差距、HIP 图风险、路由错误 - doublewordai/vllm-amd-blog-doubleword — 上述内容的演示 PR,包括 提交
c32932bb9("按逻辑块大小屏蔽 MXFP4 位矩阵填充通道") - vLLM 提交
77469c9— "[ROCm][MLA] 按因果顺序屏蔽 AITER MLA 小头验证的扁平化操作 (#50476)" - vLLM 问题 #47282 — CPU-KV 加载路径缺少与计算流的跨流同步(WAR 缺口)
- vLLM PR #47291 — 提议的 WAR 修复方案,尚未合并,此处作为覆盖层使用
- AMD Instinct MI300X — 192 GB HBM3 显存,5.3 TB/s 峰值带宽,2.61 PFLOPS 峰值 FP8 性能
- ROCm/AITER — AMD 调优内核库,用于 ROCm 注意力机制和密集线性层
- vLLM — 服务运行时(在
vllm/vllm-openai-rocm下使用 ROCm 每日构建版本)