ESC
AI 2 分钟阅读

在单个AMD MI300X上运行DeepSeek V4 Flash

本文详细介绍了如何在单个AMD MI300X GPU上部署DeepSeek V4 Flash AI模型。内容包括硬件规格(192GB HBM3内存、高带宽)、软件配置(vLLM ROCm镜像、Caddy服务器)、针对AMD硬件的优化补丁(如FP8格式兼容性、MoE路由bug修复),以及生产环境部署步骤。文章强调了在AMD GPU上运行大模型的技术挑战和解决方案,对开发者具有实用参考价值。

来源:Hacker News

MI300X拥有192 GB的HBM3和5.3 TB/s的内存带宽,HBM容量是H100 SXM5的2.4倍(AMD)。Doubleword的分析估计其标价成本大约是一半。对于这个3040亿参数的检查点,内存容量允许简单的单GPU部署:

MI300X(CDNA3)实现了AMD/Graphcore的E4M3的fnuz变体,而MI325X及更新型号使用OCP标准的FP8(背景)。在MI300X上假设OCP语义的内核,在缩放域中可能产生两倍的错误。在这个FP8实现上的正确性是首要任务;性能调优在其之后。

Fergus Finn的MI300X工作日志和相关的Doubleword仓库识别了FP8不兼容性、gfx942上缺失的AITER快速路径、稀疏MLA解码中的HIP图风险以及MoE路由错误。官方vLLM配方涵盖了NVIDIA硬件和较新的AMD GPU(MI325X在4K上下文和MI355X),但没有涵盖单MI300X生产配置用于0731检查点。

.
├── compose.yaml # 生产堆栈(vLLM ROCm + Caddy),摘要固定
├── Caddyfile.example # 复制到Caddyfile;设置主机名、电子邮件和来源CIDR
├── vllm-entrypoint.sh # 启动前从/dev/shm移除过时的CPU-KV mmap
├── SHA256SUMS # 每个运行时工件的SHA-256固定值
└── patches/
│ ├── *.py # 逐字节生产覆盖(只读挂载)
│ ├── diffs/*.patch # 与上游基础修订版的统一差异
│ └── README.md # 来源和重新生成说明
└── tuning/
 └── *.csv # gfx942的AITER A8W8块缩放调优表

运行时配置

该堆栈使用摘要固定的官方vLLM ROCm每夜构建:

1. 主机先决条件

一个MI300X(gfx942,304 CUs,约192 GiB HBM),一个工作的AMD内核驱动程序,最新的Docker Compose,约235 GiB RAM用于CPU KV层,以及约500 GB磁盘(仅模型缓存就约156 GB)。

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 # 然后设置您的主机名、电子邮件和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。预热的高水位线约为204.5 GB,总容量205.8 GB。如果仅剩余几百兆字节,服务器可能启动但在第一个请求上失败。

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记录与上游基础版本的更改。基础镜像保持摘要固定,因此升级需要更改镜像引用并重新验证堆栈。

MXFP4路由。 MoE位矩阵内核将其块列填充到Triton块大小,但填充通道是针对全局张量边界而不是逻辑块大小进行掩码的。在负载下,填充通道会破坏路由矩阵,导致长提示下的工具名称近似匹配和架构遗忘。单行修复是mask = (offs_local < BLOCK_SIZE) & (offs_global < nonzero_indx_size),取自Doubleword提交c32932bb9。该覆盖还包括用于分组MXFP4专家的融合SiLU和快速路由更改。

FP8格式。 DeepSeek V4的闪电索引器缓存使用FP8。默认写入器以行优先顺序发出OCP E4M3字节,而MI300X上的AITER消耗AMD FNUZ E4M3字节在预洗的16×16平铺布局中。在最坏的情况下,将一种格式解释为另一种会产生两倍的缩放误差。该覆盖在ROCm上选择float8e4b8,其中FP8_MAX=224.0和洗过的写入偏移量,同时在其他地方保持OCP路径不变。

该堆栈使用带有块拒绝的概率草稿。两个Gumbel覆盖使草稿提案噪声独立于拒绝和恢复噪声。

生产配置中的关键优化: