Prhub

#29479 [AMD] fix dsv4 indexer dtype dispatch on gfx950

原始 PR 作者 billishyahao 合并时间 2026-07-09 17:54 文件变更 2 提交数 4 评论 3 代码增减 +10 / -8

执行摘要

修复 gfx950 上 FP8 dtype 错误分发

DeepSeek-V4 的 indexer 和 unified-KV paged-decode kernel 原先使用 is_hip() 对所有 AMD GPU 硬编码 torch.float8_e4m3fnuz,该格式只适用于 CDNA3 (gfx942)。在 gfx950 (MI355) 上需要使用 torch.float8_e4m3fn,否则会导致 FP8 KV cache 精度错误。

本 PR 为平台特异性 bugfix,改动清晰简洁,值得快速合并。建议后续增加单元测试,验证 is_fp8_fnuz() 在不同 GPU 平台上的返回值及对应的 dtype 选择,防止回归。

讨论亮点

HaiShaw 在 review 中指出,跨仓库环境下 e4m3fnuz 的 FP8_MAX 应为 224.0 而非 240.0,建议修正。作者 billishyahao 回复确认,并说明重新检查后发现 FP8_MAX 在 indexer.py 中未实际使用,因此将其整体移除,改为直接通过 torch.finfo 推断。该讨论已解决。

实现拆解

  1. python/sglang/srt/layers/attention/dsv4/indexer.py

    • 将导入 is_hip 替换为从 sglang.srt.layers.quantization.fp8_kernel 导入 is_fp8_fnuz
    • 将顶层的 if is_hip(): ... else: ... 分支替换为单行 FP8_DTYPE = torch.float8_e4m3fnuz if is_fp8_fnuz() else torch.float8_e4m3fn,并移除 FP8_MAX(因其在模块内未被使用)。
  2. python/sglang/srt/layers/attention/dsv4/unified_kv_kernels/paged_decode.py

    • 添加 from sglang.srt.layers.quantization.fp8_kernel import is_fp8_fnuz
    • 将原硬编码的 _FP8_DTYPE = torch.float8_e4m3fnuz 改为 _FP8_DTYPE = torch.float8_e4m3fnuz if is_fp8_fnuz() else torch.float8_e4m3fn
    • 更新了存储注释,说明格式差异。

本 PR 无测试配套,也没有配置或部署变更。

文件 模块 状态 重要度
python/sglang/srt/layers/attention/dsv4/indexer.py 注意力 modified 6.05
python/sglang/srt/layers/attention/dsv4/unified_kv_kernels/paged_decode.py 注意力 modified 6.05

关键源码片段

python/sglang/srt/layers/attention/dsv4/indexer.py dependency-wiring

核心 fix 文件之一,将硬编码的 is_hip() 条件改为 is_fp8_fnuz(),修正 FP8 数据类型选择逻辑。

# 变更后:使用 is_fp8_fnuz() 判断,而非 is_hip()
# 新引入:from sglang.srt.layers.quantization.fp8_kernel import is_fp8_fnuz
# 移除:from sglang.srt.utils import is_hip(该导入保留但不再用于此处)# 模块级 FP8 数据类型选择
# torch.float8_e4m3fnuz 仅用于 AMD gfx942 (CDNA3)
# gfx950 及其他平台应使用 torch.float8_e4m3fn
FP8_DTYPE = torch.float8_e4m3fnuz if is_fp8_fnuz() else torch.float8_e4m3fn
# FP8_MAX 因未被外部引用而移除(不依赖模块级常量,调用方自行使用 torch.finfo)

评论区精华

FP8_MAX 值及是否保留 正确性

HaiShaw 指出 e4m3fnuz 的 FP8_MAX 应为 224.0 而非 240.0。

结论:作者检查后认为 FP8_MAX 在 indexer.py 中未使用,将其移除。 · 已解决

风险与影响

本 PR 改动极小(仅两文件共 10 行),风险较低。但需注意:

  • is_fp8_fnuz() 在非 AMD 或未正确初始化的环境中表现异常,可能导致 dtype 选择错误。由于该函数来自 sglang.srt.layers.quantization.fp8_kernel,应已覆盖常见场景。
  • 移除 FP8_MAX 不影响模块功能,因其未被引用。
  • 无相应测试覆盖,建议增加针对不同 GPU 类型的 dtype 选择测试。

影响范围仅限于在 gfx950 (MI355) 上运行 DeepSeek-V4 并使用 FP8 KV cache 的场景。修复后,FP8 数据类型从错误的 e4m3fnuz 变为正确的 e4m3fn,从而保证 KV cache 精度。对其他平台(NVIDIA、gfx942)无影响,行为保持不变。

缺少测试覆盖

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论