跳到正文
北京时间
原文
Hacker News 热门(buzzing.cc 中文翻译)· zhoutong·· 2026-08-04精选AI 评分76

在单颗 AMD MI300X 上运行 DeepSeek V4 Flash

AI 导读

一个开源仓库提供了在单颗 AMD MI300X 上生产运行 DeepSeek-V4-Flash-0731 的完整配置与补丁,无需额外量化或权重卸载。该 304B 参数模型在 192 GB HBM 上实现单流 168.6 tok/s 解码、8 并发流 542 tok/s 聚合吞吐,并验证了 256K 上下文。

推荐理由

为 MI300X 提供了可部署的生产栈,包含 FP8 格式修复、推测解码优化和混合 KV 缓存策略,单卡就能服务 256K 上下文。

正文 · AI 翻译

在单块 AMD MI300X 上运行 DeepSeek V4 Flash

本仓库包含我用于运行以下内容的配置和补丁deepseek-ai/DeepSeek-V4-Flash-0731在一块 AMD MI300X生产环境中的配置和补丁。其中包括 Docker Compose 栈、以 SHA-256 固定校验的文件覆盖层、与上游的参考差异对比,以及调优参数表。该 checkpoint 按发布原样运行,未做额外的权重量化或卸载。

固定技术栈(vLLM ROCm nightly 0.26.1rc1.dev229+g124154a88.rocm723、AITER 0.1.19)的结果:

指标 结果
单流解码(每流中位数,DSpark-7) 168.6 tok/s
使用调优内核进行 Prefill ≈ 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 同步以及若干未调优的 kernel 形状进行修复。本仓库汇集了这些修复,并锁定了生产环境中所使用的版本。


为什么选择 MI300X

MI300X 拥有 192 GB 的 HBM3 和 5.3 TB/s 的内存带宽,其 HBM 容量是 H100 SXM5 的 2.4 倍(AMD)。Doubleword 的分析估计,其标价大约只有后者的一半。对于这个 304B 参数的 checkpoint,这样的内存容量使得简单的单 GPU 部署成为可能:

  • 整个模型可完全放入 HBM,无需 PCIe 权重流式传输或层卸载。
  • 还有空间容纳一个 20 GB 的 GPU KV 池,以及一个 96 GiB 的 CPU 层级,用于存放被逐出的前缀缓存条目。
  • 单张卡可处理 2–8 路典型并发流,并可突发支持多达 64 路流。

MI300X(CDNA3)实现的是 AMD/Graphcore fnuz 变体的 E4M3,而 MI325X 及更新型号使用 OCP 标准的 FP8(背景)。在 MI300X 上假设采用 OCP 语义的 kernel 在 scale 域上可能偏差两倍。在这个 FP8 实现上,正确性是第一优先级;性能调优随后进行。

已有工作,以及本仓库新增的内容

Fergus Finn 的 MI300X 工作日志以及配套的 Doubleword 仓库识别出了 FP8 不兼容、gfx942 上缺失的 AITER 快速路径、稀疏 MLA 解码中的 HIP-graph 隐患,以及 MoE 路由 bug。官方 vLLM recipe覆盖了 NVIDIA 硬件和较新的 AMD GPU(4K 上下文下的 MI325X 以及 MI355X),但没有覆盖针对 0731 checkpoint 的单 MI300X 生产配置。

本仓库新增了:

  1. 针对固定版本 ROCm nightly 的正确性 overlay,包括尚未进入上游 vLLM 的修复。
  2. 一套经过验证的服务配置,采用概率性 DSpark 草稿、块拒绝和静态 K=7。它使用 2,048 token 的调度器预算和 1,024 token 的长 prefill 上限,以防止冷启动提示词阻塞其他流。
  3. AITER GEMM 调优表,针对打包表中缺失的重复出现的 gfx942 形状,外加针对 MXFP4 专家的 gfx942 OGS 几何覆盖。
  4. 混合 KV 策略:20 GB 的 fp8_ds_mla GPU 缓存 + 96 GiB 原生 CPU 卸载,并附带一个加载路径围栏修复,上游 issue #47282 有文档记录,但 PR #47291 从未合并。

仓库结构

.
├── compose.yaml         # The production stack (vLLM ROCm + Caddy), digest-pinned
├── Caddyfile.example    # Copy to Caddyfile; set hostname, email, and source CIDR
├── vllm-entrypoint.sh   # Removes stale CPU-KV mmaps from /dev/shm before start
├── SHA256SUMS           # SHA-256 pins for every runtime artifact
├── patches/
│   ├── *.py            # Byte-for-byte production overlays (mounted read-only)
│   ├── diffs/*.patch   # Unified diffs vs. the upstream base revision
│   └── README.md       # Provenance and regeneration instructions
└── tuning/
    └── *.csv           # AITER A8W8 blockscale tuning tables for gfx942

运行时配置

该技术栈使用摘要固定的官方 vLLM ROCm nightly 版本,包含:

  • --trust-remote-code 以及 DeepSeek V4 tokenizer、推理和工具解析器
  • fp8_ds_mla KV 缓存(UE8M0 块缩放 FP8,而非通用的非缩放 FP8),使用 256-token 块
  • VLLM_ROCM_USE_AITER=1 和 --moe-backend triton;Triton OGS 处理分组 MXFP4 专家,而 AITER 处理注意力和稠密线性层
  • DSpark-7 投机解码,采用概率性草稿和块拒绝
  • 完整/可断 CUDA graph 捕获,在稳定解码期间每个 token 只需一次 graph 启动
  • Caddy 作为 IP 白名单 HTTPS 代理

部署它

1. 主机前提条件

一块 MI300X(gfx942,304 个 CU,约 192 GiB HBM)、一个可正常工作的 AMD 内核驱动、较新的 Docker Compose、用于 CPU KV 层约 235 GiB 内存,以及约 500 GB 磁盘(仅模型缓存就约 156 GB)。

2. 拉取固定版本的运行时和模型

VLLM_IMAGE='vllm/vllm-openai-rocm@sha256:e68d18b2ba50298661bfc49baf01158fbf036645c2362cccf3e8a7a79fe6c69a'
MODEL='deepseek-ai/DeepSeek-V4-Flash-0731'
REVISION='7872f01b1d1fe23eabc4c98b48bffcef5a386062'

docker pull "$VLLM_IMAGE"
docker run --rm --entrypoint hf \
  -v /root/.cache/huggingface:/root/.cache/huggingface \
  "$VLLM_IMAGE" download "$MODEL" --revision "$REVISION"

3. 准备文件

cp Caddyfile.example Caddyfile   # then set your hostname, email, and remote_ip CIDR
mkdir -p aiter-cache crash-dumps
chmod +x vllm-entrypoint.sh
sha256sum -c SHA256SUMS        # verify the overlays before first start

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 bitmatrix 填充通道 + 融合 SiLU 分组专家 + 快速 DeepSeek 路由 MXFP4 Triton 路径必需;掩码修复尚未上游合并
mxfp4.fused-silu.py vllm/.../fused_moe/oracle/mxfp4.py 融合 SiLU 内核的 Gate/up 交错布局 与融合 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 tile 几何配置(最多 1,536 路由行) 性能在 gfx942 上;默认几何配置在超过 768 路由行后急剧变慢
fused_compress_quant_cache.fnuz-shuffle.py vllm/models/deepseek_v4/common/ops/fused_compress_quant_cache.py FNUZ FP8 + 16×16 预混洗,用于 Lightning Indexer 缓存写入器 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 head-512 稀疏预填充 可复现的工具调用需要确定性;BLOCK_H=64 关乎性能
rocm_aiter_mla.dspark-causal.py vllm/v1/attention/backends/mla/rocm_aiter_mla.py 因果多 token 投机验证 ROCm 上 DSpark small-head MLA 所需——现已上游;overlay 就是上游文件的原样副本
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 bitmatrix 内核会将其块列填充到 Triton 块大小,但填充通道却是针对全局张量边界进行掩码,而非逻辑块大小。在高负载下,填充通道会破坏路由矩阵,导致长提示词下出现近似匹配的工具名称和被遗忘的 schema。一行修复方案是 mask = (offs_local < BLOCK_SIZE) & (offs_global < nonzero_indx_size),取自 Doubleword 提交 c32932bb9。该 overlay 还包含针对分组 MXFP4 专家的 fused-SiLU 和快速路由改动。

FP8 格式。 DeepSeek V4 的 Lightning Indexer 缓存使用 FP8。原版写入器以行主序输出 OCP E4M3 字节,而 MI300X 上的 AITER 则以预混洗的 16×16 tile 布局消费 AMD FNUZ E4M3 字节。在最坏情况下,将一种格式误读为另一种会产生两倍的缩放误差。该 overlay 在 ROCm 上选择 float8e4b8 配合 FP8_MAX=224.0 以及混洗写入偏移,而在其他地方保持 OCP 路径不变。

投机解码

该技术栈采用带块拒绝的概率性起草。两个 Gumbel overlay 使起草提议噪声与拒绝和恢复噪声保持独立。

性能

生产配置中的关键优化:

改动 效果
为 304-CU 调优 21 种重复出现的 A8W8 GEMM 形状 gfx942 单流/双流解码提升 42–62%;在 8–64 并发流下提升 10–35%
融合 SiLU、快速 DeepSeek 路由、对批次敏感的专家分块 原生 C1 解码从 34.5 → 56.6 tok/s(+64%);路由 kernel 从 42.6 → 11.9 µs/层
BLOCK_H=64 稀疏预填充分块 预填充达到 7.9–8.5K tok/s;稀疏注意力追踪从 317 → 142 ms/请求
静态 K=7,概率 + 块拒绝,因果验证 单流 119.5 tok/s,且输出正确
2,048-token 预算 + 1,024-token 长预填充上限 52K 预填充之后的迟到短请求 TTFT:8.2 s → 0.5 s
20 GB GPU KV + 96 GiB CPU 层级 1.93M-token 长度等效容量;可接纳七个 256K 请求

最终并发扫描

各不相同的约 400 词提示词,流式,temperature=1.0, top_p=0.95;C1–C8 为 512 输出 token,C64 为 256:

流 聚合 tok/s 每流解码中位数 TTFT p50
1 126.2 168.6 tok/s 1.026 s
2 145.4 152.7 0.939 s
4 316.8 108.6 0.369 s
8 542.3 90.3 1.027 s
64 830.2 16.4 2.190 s

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 s 降至 0.5 s。在 120–125 s 的冷预填充之后,对 380K 缓存 token 的热召回耗时 0.64–2.65 s。

生产注意事项

  • HBM 余量有限。预热后的高水位为 205.8 GB 中的 204.5 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 容量。
  • 重启后先预热内核。 首次 prefill 会初始化内核,处理 8.9K token 需要 5.3 秒;后续运行只需 1.7 秒。在接入流量之前,先运行一次未缓存的 prefill。
  • 既要测试吞吐量,也要测试正确性。 验证套件包括两轮工具调用测试用例、BFCL 子集(74–76/90 精确调用)、OpenCode 工具 schema 检查,以及在原生和 DSpark 两条路径上的 380K-token 大海捞针召回。冷 prefill 和缓存 prefill 可能走不同的浮点路径,因此两者都要测试。

许可与来源

该技术栈、文档以及源自 vLLM 的叠加层采用 Apache-2.0 许可(见 LICENSE);源自 AITER 的叠加层保留其 MIT 头部声明。每个 diff 的上游基础版本都记录在 patches/README.md 中。模型本身采用 MIT 许可。

参考资料

所有链接均于 2026-08-04 验证。

  • 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、block size 256、deepseek_v4 解析器;面向 MI325X/MI355X 的 AMD 指南
  • 在 AMD MI300X 上启动 DeepSeek-V4-Flash(Fergus Finn,Doubleword,2026 年 6 月)— 本仓库所基于的启动工作日志:FNUZ 与 OCP FP8 对比、gfx942 上的 AITER 缺口、HIP-graph 隐患、路由 bug
  • doublewordai/vllm-amd-blog-doubleword — 上述内容的演示 PR,包括 commit c32932bb9(“按逻辑块大小屏蔽 MXFP4 bitmatrix padding lanes”)
  • vLLM commit 77469c9 — “[ROCm][MLA] Mask the AITER MLA small-head verify flatten causally (#50476)”
  • vLLM issue #47282 — CPU-KV 加载路径缺少与计算之间的跨流同步(WAR 缺口)
  • vLLM PR #47291 — 提议的 WAR 修复,尚未合并;此处以 overlay 形式携带
  • AMD Instinct MI300X — 192 GB HBM3,5.3 TB/s 峰值带宽,2.61 PFLOPS 峰值 FP8
  • ROCm/AITER — 用于 ROCm 注意力和稠密线性层的 AMD 调优内核库
  • vLLM —— 服务运行时(ROCm 每日构建版位于 vllm/vllm-openai-rocm 下)

来源:Hacker News 热门(buzzing.cc 中文翻译) · github.com

相关事件