Prhub

#49843 [Bugfix][ROCm] Use batch DMA for CPU KV cache loads

原始 PR 作者 AndreasKaratzas 合并时间 2026-07-27 17:18 文件变更 2 提交数 2 评论 2 代码增减 +16 / -2

执行摘要

修复 ROCm 平台 CPU->GPU KV 缓存 Triton 路径的内存错误

该 PR 源于一个 bug:在 ROCm 上,Triton 路径直接加载共享内存映射的主机指针,导致内存错误。复现的故障地址与 mmap 基址加上选中的块偏移匹配。PR 描述明确指出需要为 ROCm 添加已有的 XPU batch-DMA 回退逻辑,同时保持其他平台路径不变。

该 PR 是一个针对特定硬件平台的简洁 bugfix,变更量小且逻辑清晰。值得精读以理解在异构平台上 Triton 内核的局限性和回退策略。

讨论亮点

审阅者 tjtanaa 在测试文件的第 38 行评论道:“should we guard this test to only run on ROCm?” 作者 AndreasKaratzas 回复:“oh yeah, completely missed the skip there.” 随后在第二次提交中增加了 @pytest.mark.skipif(not current_platform.is_rocm(), ...) 守卫。

实现拆解

  1. 修改核心调度函数 _select_swap_blocks_fn(文件 vllm/v1/kv_offload/cpu/gpu_worker.py):在现有的回退条件中加入 current_platform.is_rocm(),使得 ROCm 平台即使 HAS_TRITON 为 True,也使用 ops.swap_blocks_batch(C++ batch DMA)而非 Triton 内核。更新了注释,将原先的“ROCm builds without Triton”调整为“ROCm host mappings”以更准确地描述问题根源。
  2. 新增测试函数 test_rocm_cpu_to_gpu_uses_dma(文件 tests/v1/kv_offload/cpu/test_gpu_worker.py):添加了 from vllm import _custom_ops as opsfrom vllm.v1.kv_offload.cpu import gpu_worker 导入。新测试使用 monkeypatch 设置 gpu_worker.HAS_TRITON = Trueis_xpu 返回 False、is_rocm 返回 True,然后断言 _select_swap_blocks_fn 返回 ops.swap_blocks_batch,确保 ROCm 走 DMA 路径。
  3. 添加平台守卫:在新增测试函数上添加 @pytest.mark.skipif(not current_platform.is_rocm(), reason="ROCm-specific test"),确保该测试仅在 ROCm 环境下运行。该守卫是在 review 评论中由审阅者 tjtanaa 提出、作者 AndreasKaratzas 确认后添加的(提交历史显示在第二次提交中实现)。
文件 模块 状态 重要度
vllm/v1/kv_offload/cpu/gpu_worker.py KV 卸载 modified 5.75
tests/v1/kv_offload/cpu/test_gpu_worker.py 测试 modified 5.17

关键符号

_select_swap_blocks_fn test_rocm_cpu_to_gpu_uses_dma

关键源码片段

vllm/v1/kv_offload/cpu/gpu_worker.py core-logic

核心逻辑修改:在 `_select_swap_blocks_fn` 中为 ROCm 添加 DMA 回退路径,修复 Triton 加载主机指针的内存错误。

# vllm/v1/kv_offload/cpu/gpu_worker.py
def _select_swap_blocks_fn(
    kv_cache_groups_data_refs: list[list[CanonicalKVCacheRef]],
    gpu_to_cpu: bool,
):
    # GPU->CPU is bandwidth-bound; the dedicated copy engine beats Triton.
    if gpu_to_cpu:
        return ops.swap_blocks_batch
    # Fall back to the C++ DMA path on platforms where Triton isn't usable
    # (e.g. ROCm host mappings) or where GPU kernels cannot directly
    # dereference CPU pointers (XPU lacks CUDA's unified virtual address space,
    # so the Triton kernel's tl.load(cpu_ptr) is invalid on XPU).
    # 现在 ROCm 也使用 DMA 路径,因为 Triton 直接加载共享内存映射的主机指针会导致错误
    if not HAS_TRITON or current_platform.is_xpu() or current_platform.is_rocm():
        return ops.swap_blocks_batch
    page_sizes = [r.page_size_bytes for g in kv_cache_groups_data_refs for r in g]
    # Triton wins only on small, 8-byte-aligned payloads.
    if (
        not page_sizes
        or max(page_sizes) >= THRESHOLD_BYTES
        or any(s % 8 for s in page_sizes)
    ):
        return ops.swap_blocks_batch
    chunk = min(triton.next_power_of_2(max(page_sizes)), 8192)
    return functools.partial(swap_blocks_batch, bytes_per_chunk=chunk)
tests/v1/kv_offload/cpu/test_gpu_worker.py test-coverage

新增 ROCm 专用测试,验证 `_select_swap_blocks_fn` 在模拟 ROCm 环境下正确返回 `ops.swap_blocks_batch`。

# tests/v1/kv_offload/cpu/test_gpu_worker.py
# 仅在 ROCm 平台运行该测试
@pytest.mark.skipif(not current_platform.is_rocm(), reason="ROCm-specific test")
def test_rocm_cpu_to_gpu_uses_dma(monkeypatch: pytest.MonkeyPatch) -> None:
    # 模拟 ROCm 环境:有 Triton,非 XPU,是 ROCm
    monkeypatch.setattr(gpu_worker, "HAS_TRITON", True)
    monkeypatch.setattr(gpu_worker.current_platform, "is_xpu", lambda: False)
    monkeypatch.setattr(gpu_worker.current_platform, "is_rocm", lambda: True)
​
    refs = [[CanonicalKVCacheRef(tensor_idx=0, page_size_bytes=512)]]
    # 验证即使 HAS_TRITON=True,也选择 batch DMA 而非 Triton
    assert gpu_worker._select_swap_blocks_fn(refs, gpu_to_cpu=False) is (
        ops.swap_blocks_batch
    )

评论区精华

平台守卫缺失 测试

tjtanaa 建议为新增测试添加 @pytest.mark.skipif 仅允许在 ROCm 上运行,作者承认遗漏后立即修复。

结论:在第二次提交中补充了 `@pytest.mark.skipif(not current_platform.is_rocm(), reason="ROCm-specific test")`。 · 已解决

风险与影响

风险较低:变更仅涉及一个条件判断,不影响 CUDA、XPU 或其他平台路径。新增测试验证了正确的函数选择,但未测试实际数据传输的正确性。可能存在将非 ROCm 的 Triton 路径误判为 DMA 路径的风险,但当前条件只针对 ROCm 添加,不会误伤。

影响范围较小:仅影响 ROCm 平台上 CPU->GPU 的 KV 缓存 offload 操作。修复后 ROCm 将使用 C++ batch DMA 取代 Triton 内核,避免了内存错误。性能和正确性预计得到恢复。

特定硬件平台风险 核心路径变更

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论