Prhub

#32832 [AMD] [sgl-kernel] Bypass caches for peer traffic in ROCm custom all-reduce

原始 PR 作者 wenkaidu 合并时间 2026-08-21 06:24 文件变更 2 提交数 2 评论 10 代码增减 +206 / -0

执行摘要

ROCm 自定义 all-reduce 缓存绕过,延迟降 14-33%

PR 作者指出:custom all-reduce 每次通过 xGMI 读取所有 peer 的 buffer,写出的结果也只会被消费一次,将其放入 L2 只会造成单次数据的缓存污染。同时,hubertlu-tw 评论说明 SGLang CAR v1 在 deterministic inference + SGLANG_USE_1STAGE_ALLREDUCE=1 + SGLANG_USE_AITER_AR=false 且无 AITER 时启用,本 PR 可直接帮助 Miles 用户在使用 AMD GPU 时提升确定性推理下的通信性能。

值得精读。该 PR 展示了如何把 RCCL 的缓存绕过策略(op128.h)移植到 SGLang 自定义 all-reduce,并给出完整的编译器能力检测与回退方案。关注点:GEMM 之外 AMDGPU 全局内存访问优化、b128 builtins 的 syncscope 语义、nontemporal 回退的正确性,以及作者"先基准定位、再按消息大小分层报告收益"的验证方法。注意没有自动化测试是主要短板。

讨论亮点

HaiShaw 最初 review 认为 custom_all_reduce_hip.cuh 的更新不需要;hubertlu-tw 澄清:SGLang 的 CAR v1 不依赖 hipification,必须同步改 hip.cuh,并给出 CAR v1 的启用条件(deterministic inference、SGLANG_USE_1STAGE_ALLREDUCE=1、SGLANG_USE_AITER_AR=false 且无 AITER),该 PR 可帮助 Miles 的 AMD 用户。HaiShaw 随后回复 'HIP specific changes' 并最终批准。另外 hubertlu-tw 在本地复测 test_amd_deterministic_custom_allreduce.py 与 microbenchmark 一致后 approve;HaiShaw 还请求提供完整运行命令示例(评论被截断),该请求没有在评论区得到完整回应。

实现拆解

变更入口为两个文件:python/sglang/kernels/aot/csrc/allreduce/custom_all_reduce.cuh 与 custom_all_reduce_hip.cuh,均为纯新增代码(+103/-0)。实现分四步:

  1. 编译器能力检测:在 USE_ROCM 分支中定义 ROCM_HAVE_GLOBAL_DWORDX4_BUILTINS,通过 __has_builtin 同时检测 __builtin_amdgcn_global_load_b128 与 __builtin_amdgcn_global_store_b128,并定义 sgl_v4u(unsigned int x4 扩展向量类型)与 sgl_v4u_gptr(address_space(1) 指针),为后续 128 位访问做准备。
  2. 新增缓存绕过访问器:load_bypass/store_bypass 模板用于 16 字节 packed 类型。主路径调用 b128 builtins 并传入空 syncscope 字符串(系统内存域),编译为 global_{load,store}_dwordx4 且置 sc0/sc1 位;回退路径用两条 64 位 nontemporal load/store(SLC 位),与 RCCL op128.h 的 builtin-free 方案一致。两种路径都通过 union 在 packed 类型与向量/u64 数组间复用内存。
  3. 改造 packed_reduce 数据通路:在 packed_reduce 的 peer 元素读取处,USE_ROCM 下改走 load_bypass,结果写入改走 store_bypass,使 xGMI 上的远程读写绕过 L2 直达 HBM。所有分支都由 USE_ROCM 保护,CUDA 路径保持原样。
  4. 验证配套:PR 未新增自动化测试;作者在 gfx950(MI35x)上通过 ISA 反汇编确认 sc0/sc1 位,并用 test_amd_deterministic_custom_allreduce.py 及 microbenchmark(TP=8、hidden=16384、bf16、10 trials)验证正确性与性能;hubertlu-tw 在本地复测通过。
文件 模块 状态 重要度
python/sglang/kernels/aot/csrc/allreduce/custom_all_reduce.cuh 归约内核 modified 4.91
python/sglang/kernels/aot/csrc/allreduce/custom_all_reduce_hip.cuh 归约内核 modified 4.91

关键符号

load_bypass store_bypass packed_reduce

关键源码片段

python/sglang/kernels/aot/csrc/allreduce/custom_all_reduce.cuh core-logic

CAR 主实现文件,新增缓存绕过访问器并改造 packed_reduce 的 peer 读写路径。

// custom_all_reduce.cuh / custom_all_reduce_hip.cuh 中新增的缓存绕过辅助函数
// 整个新增块由 USE_ROCM 保护,CUDA 构建不受影响。template <typename P>
DINLINE P load_bypass(const P* ptr) {
    // 只支持 16 字节 packed 类型,例如 float4、int4 等
    static_assert(sizeof(P) == 16, "load_bypass expects a 16-byte packed type");
#if ROCM_HAVE_GLOBAL_DWORDX4_BUILTINS
    // 主路径:b128 builtins + 空 syncscope(系统内存域),置 sc0/sc1 绕过位
    union {
        P p;
        sgl_v4u v; // unsigned int x4 扩展向量类型
    } u;
    u.v = __builtin_amdgcn_global_load_b128((sgl_v4u_gptr)ptr, SGL_SYSTEM_SYNCSCOPE);
    return u.p;
#else
    // 回退路径:两条 64 位 nontemporal 访问,置 SLC 位,与 RCCL op128.h 一致
    union {
        P p;
        uint64_t u64[2];
    } u;
    const uint64_t* addr = reinterpret_cast<const uint64_t*>(ptr);
    u.u64[0] = __builtin_nontemporal_load(addr);
    u.u64[1] = __builtin_nontemporal_load(addr + 1);
    return u.p;
#endif
}template <typename P>
DINLINE void store_bypass(P* ptr, const P& val) {
    static_assert(sizeof(P) == 16, "store_bypass expects a 16-byte packed type");
#if ROCM_HAVE_GLOBAL_DWORDX4_BUILTINS
    union {
        P p;
        sgl_v4u v;
    } u;
    u.p = val;
    __builtin_amdgcn_global_store_b128((sgl_v4u_gptr)ptr, u.v, SGL_SYSTEM_SYNCSCOPE);
#else
    union {
        P p;
        uint64_t u64[2];
    } u;
    u.p = val;
    uint64_t* addr = reinterpret_cast<uint64_t*>(ptr);
    __builtin_nontemporal_store(u.u64[0], addr);
    __builtin_nontemporal_store(u.u64[1], addr + 1);
#endif
}

评论区精华

custom_all_reduce_hip.cuh 是否也需要修改 设计

HaiShaw 在 review 中认为 custom_all_reduce_hip.cuh 的更新不需要;hubertlu-tw 澄清 SGLang CAR v1 不依赖 hipification,因此 hip.cuh 版本必须同步修改,并给出 CAR v1 的启用条件。

结论:保留 hip.cuh 修改;HaiShaw 最终批准。 · 已解决

性能与正确性验证 测试

hubertlu-tw 在本地运行 test_amd_deterministic_custom_allreduce.py 和 microbenchmark,确认 gfx950 上的性能数据;作者验证 TP=2/4/8 位级确定性。

结论:验证通过,reviewer approve。 · 已解决

CAR v1 使用场景说明与运行示例 question

HaiShaw 请求提供运行 CAR v1 的完整命令示例(评论截断),并指出 CAR v1 选择条件;hubertlu-tw 说明适用于 Miles 用户。

结论:未在评论中给出完整命令,属于可改进的文档缺口。 · unresolved

风险与影响

  • 影响面:改动完全被 USE_ROCM 包住,CUDA 编译与运行路径不受影响。但两个 .cuh(通用与 hip 版本)需要同步维护,未来如有改动存在漏改风险。
  • 兼容性:主路径依赖 clang/AMD 工具链的 b128 builtins;不支持时走 64 位 nontemporal 回退,回退路径在部分架构上可能无法获得相同的绕过效果,且 64 位拆分访问不如 128 位原子请求高效。
  • 性能风险:基准显示 >8 MB 后收益降至 1%-7%,但无回归;32 MB+ 依然不差。不过基准只在 gfx950 单机验证,未覆盖 MI200 等旧架构或跨节点。
  • 测试缺口:没有新增自动化单元测试,只有手工/本地验证;PR 展示的 CI 状态显示 pr-test 与 pr-test-extra 均为失败(原因未在材料中说明),合并前需确认失败原因是否与本次改动相关。

对用户:使用 AMD gfx942/gfx950(MI300/MI35x)并启用确定性推理 + 1-stage all-reduce 的用户可观察到 TP=2/4/8 下 all-reduce 延迟下降 14-33%,尤其是 256 KB-8 MB 的典型消息区间;Miles 平台的 AMD 用户直接受益。对系统:peer 读写绕过 L2 可降低 L2 污染,进而可能改善同卡其他 kernel 的缓存命中。对团队:纯新增代码、无行为变更开关,风险低;但 hip.cuh 与 cuh 双份维护需要留意。对 CI:AMD 相关 CI 标签 run-ci 已触发,但状态显示失败。

仅 ROCm 路径变更 无新增自动化测试 依赖编译器 builtin 支持 CI 状态失败待确认 双文件同步维护成本

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论