在AMD MI300X上部署DeepSeek-V4-Flash的工程挑战与解决方案
本文记录了在AMD MI300X上运行DeepSeek-V4-Flash推理时遇到的FP8方言不兼容、注意力内核缺失、HIP图支持等软件问题及修复过程,揭示了AMD旧款加速器在AI软件生态上的短板。
在AMD MI 300 X上推出DeepSeek-V4-Flash在Doubleword,我们正在构建一个专为体积设计的推理云。要做到这一点,我们必须考虑到计算短缺的问题。
AMD的MI 300 X于2023年12月在2023年12月6日的AMD“Advancing AI”活动上推出。作为AMD对英伟达H100的回应,与H200一起推出同一代产品。在高端人工智能加速器领域,它是一只奇怪的鸭子。
虽然H100价格正在攀升(一年期租金在五个月内上涨了40%,英伟达各主要部件的按需容量均已售罄SemiAnalysis,《严重的图形处理器短缺:租赁容量》,2026年4月。),MI 300 X可能仍然没有得到充分的重视。
每张卡192 GB HBM 3,而H100的80 GB、相当的FP 8计算,标价约为一半。然而,您今天可以按需租用一台(例如从Hotaisle),价格明显低于同等的NVIDIA容量。原因是软件。
在AMD上运行人工智能工作负载的问题已在其他地方得到了详尽的描述,并且有迹象表明AMD新芯片上的差距正在缩小SemiAnalyses的InferceX仪表板跟踪最新的AMD部件(MI 350 X、MI 355 X)与当前几代NVIDIA。
.对软件的新关注并没有扩展到旧部件。截至2026年5月初,在MI 300 X上使用DeepSeek-V4-Flash运行vLLM根本不起作用。理论上,MI 300 X是一款出色的加速器。我们希望它发挥作用。
这篇文章是我们在试图让它工作时发现的所有尖锐边缘和蜿蜒路径的工作日志。
FP 8方言MI 300 X是加速器一代的一部分,开启了更低比特宽度的进程。LLM权重,以及在较小程度上激活和KV缓存,对数字不精确性的敏感性低于典型的高性能计算工作负载,因此Hopper一代的英伟达芯片和第一款Instinct芯片首次添加了对低于16位精度的硬件支持。
结果是,对相应传输一半数据的工作负载应用了两倍的FLOP。问题在于,对于构建FP 8数据类型的最佳方法存在分歧。Graphcore和AMD在2022年预印本中提出了一项标准,并得到了高通的支持。
Arm、英特尔和英伟达通过开放计算项目提出了另一个方案。回顾了导致IEEE 754的一些岔路口,这篇对William Kahan的采访是一本很好的读物,了解算术标准实际上是如何制定的,包括哪些论点获胜,哪些被遗忘。
不同的提供商建立在不同且不兼容的行为中。考虑到双方的支持者名单,也许并不奇怪,AMD / Graphcore标准未能成功。AMD较新的MI 325、MI 350和MI 355 X芯片全部迁移到OCP标准的FP 8。
但MI 300 X仍然只在fnuz工作方言意思是“有限的,nans,无符号零”,i. e.没有-0也没有INF.
对于人工智能工作负载来说,这些似乎是明智的选择小浮点范围,每个比特都很重要,但方言从未完全起飞,后来的AMD几代又回到了更多外观正常的FP 8。,因此最初的vLLM工作在AMD上提出DeepSeek实际上并不适合提出DeepSeek在MI 300 X上。
很多vLLM的FP 8路径都知道e4 m3与e5 m2but not of弗努兹与OCP。
这两种方法共享其位布局,但指数不同偏置1,因此读取错误方言的相同字节将返回是原来的两倍MI 300 X是唯一一款主要的加速器,这种区别在实践中很重要自始至终,我们将在本文中提出的公共vLLM仓库中注意到来自演示PR的相关提交。
236de4e64使DeepSeek v4压缩器和融合的压缩/量化/缓存写入使用平台FP 8 d类型,以便扩展和缓存字节一致,并且bd 06 e5 d87路由通过感知fnuz-awaware的融合量化和插入助手来滑动窗口K-缓存。
.错过注意力的捷径DeepSeek v4的注意力很少。每个查询都处理由学习的索引器选择的KV缓存的前k子集,滑动窗口上下文单独处理。它有很多移动的部分:KV压缩、索引器、滑动窗口路径、为每个部分提供信息的FP 8缓存。
在为了获得最大性能而进行的生产部署中,每一个部分都需要以已调好的内核的形式进行特别关注(没有双关语)。
AMD上快速调整的内核的来源是AITER。AITER是AMD的调优内核库,大致类似于NVIDIA用户从cuBLAS、cuDNN、FlashAttention和Transformer Engine中获得的内容。
当AITER没有针对给定形状的路径时,vLLM会退回到通用Triton,并且通用Triton注意力比已调好的内核慢好几倍。
AITER对DSA 4的覆盖范围不均衡,并且现有的覆盖范围往往针对后期的AMD部件(CDNA4),而不是MI300 X中的CDNA3(gfx 942)核心。这件事的后果有两种不同的形式。
部分片段缺少AITER路径完全基于gfx942:分页MQA logits、稀疏MLA预填充、稀疏MLA解码。对于每个人,我们需要放入一个特定于ROCM的助手来调用AITER它存在并延伸到Triton实现,在那里它不。
有些作品具有AITER路径,该路径存在,但专门在gfx942:AITER预填充MQA对数和AITER稀疏预填充对数落在这里。
解决办法是拒绝派遣到他们时,海流台报告gfx 942并让Triton后备处理替代电话请参阅cb 8a18556:页面化MQA和稀疏MLA后备、AITER保护gfx 942以及正确性覆盖。
.臀部压图HIPP图是AMD的CUDA图的模拟,具有实际上相同的语义:在热身时记录一次操作流,在后续的每个步骤中重播记录的图。
好处是从解码循环中消除了每次启动的Python负担,当您每个令牌启动数百个小内核时,这一点非常重要。由于DeepSeek v4有如此多的活动部分,如果我们不利用图形,将会有很多内核发布。代价是捕获的区域必须纯粹取决于其设备输入。
任何从主机读取的内容、分配形状取决于实时批次的粗糙张量或在捕获区域内同步的内容都会被记录为热身时的任何值,并在之后永远重播。AITER调优的内核通过构造与此组成。AITER内核是C++需要设备指针和大小的启动;
它们不分配Python的粗糙划痕,并且它们不会在中途读取主机Scalar。编写一个工作不好的Triton内核很容易,我们这样做过几次22 cc 02230将稀疏MLA解码元数据重建为静态、捕获安全张量:没有动态不均匀的分配,捕获下没有主机到设备的纯量写入。
.松散的结束我们遇到了一些小问题:- MoE路由错误,专家面具形状取决于是否ROCm AITER是全局启用的,而不是关于matmul是否要实际上是ATER的。随着AITER在全球范围内的发展,深入到仿真后台,内核出错了面具和代币被发送给错误的专家。
8b5f7aa 2c.
- Triton内核,根据全局张量掩盖填充通道边界而不是逻辑块大小。在高并发时,在MoE路由位矩阵上潦草地绘制了填充的通道。c32932bb9.调整一下通过正确性排序,我们可以进行一些基本的优化。
在MI 300 X上工作的DSV 4-Flash的第一个配置文件显示,昂贵的层是稀疏MLA路径和MXFP 4 MoE路径。这很好-如果不是这样,我们真的会被搞砸。
然而,在第一次提出之后,有一段有意义的时间不在摇篮里它们本身,但在簿记和围绕它们调整稀疏MLA解码的每一步都重建了粗糙的元数据。解码核心写入临时张量,然后复制到调用者的输出缓冲区中。的bf 16投影权重在每个解码步骤中都被实现,而不是被缓存。
一种静态Triton发射形状涵盖小批量坡道和饱和坡道S