首页
/ SGLang 中的 MSCCL++ All-Reduce 基准测试与推理集成指南

SGLang 中的 MSCCL++ All-Reduce 基准测试与推理集成指南

2026-09-09 15:02:26作者:舒璇辛Bertina

本篇指南聚焦 SGLang 仓库中 benchmark/kernels/all_reduce/README.md 所介绍的 MSCCL++ All-Reduce 基准测试方案,覆盖 MSCCL++ 的安装前置条件、TP=8/TP=16 场景下的 benchmark 运行命令、以及在 CUDA Graph 捕获推理中通过 --enable-mscclpp 启用该后端的完整流程,并结合仓库内基准脚本与通信实现源码,说明其底层调优机制与使用限制。读完本文,你将掌握如何在多卡环境中对 MSCCL++、NCCL、PyNccl 三种 all-reduce 实现做延迟对比,并理解 SGLang 选择 MSCCL++ 的适用场景与取舍。

一、为什么需要在 SGLang 中关注 MSCCL++

All-reduce 是张量并行(Tensor Parallelism, TP)推理中最频繁发生的集合通信操作。在 SGLang 的 TP 场景下,每一层的 attention 输出与 MLP 输出都需要跨全部 TP rank 做一次 all-reduce 求和,通信延迟直接进入每 token 的生成延迟。

MSCCL++ 是一个 GPU 驱动的通信库(GPU-driven communication library),可以作为 NCCL 的替代实现来完成 all-reduce。根据 benchmark/kernels/all_reduce/README.md,它的两个核心卖点是:

  • 支持 CUDA Graph 捕获:其 kernel 可以直接被录制进 CUDA Graph,避免 eager 模式下 kernel launch 开销,这对 SGLang 依赖 CUDA Graph 加速 decode 阶段至关重要;
  • 针对中小消息大小优化:TP 推理中 all-reduce 的数据量通常不大(例如激活张量的中间维度),MSCCL++ 在小消息场景下相对 NCCL 有更低延迟。

从仓库源码看,SGLang 已将其接入通信栈:实现了 PyMscclppCommunicator(见 python/sglang/srt/distributed/device_communicators/pymscclpp.py),并在 bootstrap.py 启动阶段根据命令行参数设置全局开关(见 python/sglang/srt/distributed/bootstrap.py)。

二、支持配置与安装前置条件

2.1 当前支持的配置

根据原文档,MSCCL++ all-reduce 目前支持两种典型配置:

配置 节点数 TP 大小
单节点 1 TP=8
两节点 2 TP=16

pymscclpp.py 的实现看,PyMscclppCommunicator 声明支持的 world size 为 [8, 16, 32],超出该范围时会打印 warning 并自动禁用("PyMscclpp is disabled due to an unsupported world size")。同时要求组内 rank 连续(不允许 stride 分布),否则同样会禁用。

2.2 安装方式一:使用 SGLang 官方 Docker 镜像(默认已装)

如果直接使用仓库 docker/Dockerfile 构建的默认 SGLang 镜像,MSCCL++ 已默认安装,无需任何额外操作。在 Dockerfile 中可以确认其安装逻辑:镜像会根据 CUDA_VERSION 选择对应依赖分支执行 python3 -m pip install "/tmp/mscclpp[cuda12]""/tmp/mscclpp[cuda13]",并通过 CMAKE_ARGS 指定 GPU 架构(80,90,100,100a,103,103a),最终由 pip 触发 CMake 构建扩展。

2.3 安装方式二:手动从源码安装

若不使用上述 Docker 镜像(或希望手动安装),需要 CMake 与 CUDA Toolkit,然后:

git clone https://github.com/microsoft/mscclpp.git
cd mscclpp && mkdir build && cd build
cmake .. && make -j && pip install ..

注意:原文档链接指向 mscclpp 上游仓库,安装请以你本地实际可达的仓库地址为准。

2.4 验证安装

在运行 benchmark 或启用 MSCCL++ 推理之前,请确认 Python 环境中可以正常导入 mscclpp

python -c "import mscclpp; print(mscclpp.__version__)"

如果导入失败,PyMscclppCommunicator 在初始化时会捕获 ImportError 并将 available 置为 False,SGLang 会静默回退到 NCCL,不会报错中断,但 --enable-mscclpp 也就不会生效。

三、运行 All-Reduce 基准测试

3.1 单节点 TP=8

基准脚本位于 benchmark/kernels/all_reduce/benchmark_mscclpp.py,单节点直接使用 torchrun

torchrun --nproc_per_node 8 \
    --nnodes 1 \
    --node_rank 0 \
    benchmark/kernels/all_reduce/benchmark_mscclpp.py

3.2 两节点 TP=16

多节点需要先导出分布式环境变量,再在每个节点上以对应 RANK(0 或 1)分别启动:

export WORLD_SIZE=2
export MASTER_ADDR=<master-ip>
export MASTER_PORT=12345

# 在每个节点上以对应的 RANK(0 或 1)运行:
torchrun --nproc_per_node 8 \
    --nnodes $WORLD_SIZE \
    --node_rank $RANK \
    --master_addr $MASTER_ADDR \
    --master_port $MASTER_PORT \
    benchmark/kernels/all_reduce/benchmark_mscclpp.py

脚本开头的 docstring(benchmark_mscclpp.py)也给出了同样的环境变量示例(WORLD_SIZE=1, RANK=0, MASTER_ADDR=127.0.0.1, MASTER_PORT=12345),单机调试时可以直接复用。

3.3 基准测试对比什么

根据 benchmark_mscclpp.py__main__ 逻辑,该脚本会依次对多种 all-reduce 后端测量延迟并输出对比:

后端 执行模式 对应代码路径
torch / NCCL eager torch_allreducedist.all_reduce
MSCCL++ eager msccl_allreducePyMscclppCommunicator.all_reduce
MSCCL++ CUDA Graph 同上,但包在 graph_capture 上下文内录制并 replay
PyNccl CUDA Graph pynccl_allreducePyNcclCommunicator.all_reduce

测试细节:

  • 消息大小:遍历 sz = 2**i(i 从 10 到 19),即从 1 KiB 到 512 KiB 的 2 的幂次消息;当 sz * dtype.itemsize > 2**20 时提前 break(见 benchmark_mscclpp.py),测试张量统一使用 torch.bfloat16
  • Graph 测时:在 graph_capture() 上下文内把 graph_loop=10 次 all-reduce 录制进单个 torch.cuda.CUDAGraph,warmup 2 次后 replay 10 轮,用 CUDA Event 计时并除以 graph_loop 得到单次延迟(见 _bench_graph_timebenchmark_mscclpp.py);
  • Eager 测时:warmup 2 次后连续执行 10 次取平均(见 _bench_eager_timebenchmark_mscclpp.py);
  • 正确性校验:每个消息大小下都用 torch.testing.assert_close 对比 torch eager 与 msccl(eager 与 graph 两个版本)的输出,通过后 rank 0 打印 correctness check PASS!(见 benchmark_mscclpp.py);
  • 结果输出:优先使用 tabulate 输出 GitHub 风格 Markdown 表格(列:msg_sizetorch eager timemsccl eager timemsccl graph timepynccl graph time),未安装 tabulate 时回退到手写 Markdown 表格(见 print_markdown_tablebenchmark_mscclpp.py)。

脚本还内置了可选的 torch.profilerprofile = False 默认关闭),开启后会把 Chrome trace 导出到 prof/msccl/trace_rank{rank}.json.gz,便于进一步分析 kernel 级耗时。

四、在推理中启用 MSCCL++:--enable-mscclpp

4.1 启动命令

在 CUDA Graph 捕获的推理过程中,通过 --enable-mscclpp 将 all-reduce 后端切换为 MSCCL++:

python -m sglang.launch_server \
    --model-path Qwen/Qwen3-8B \
    --tp-size 8 \
    --enable-mscclpp

4.2 参数定义与启动链路

该参数定义在 python/sglang/srt/arg_groups/fields/exec_.py,其语义为:

"Enable using mscclpp for small messages for all-reduce kernel and fall back to NCCL."

即 MSCCL++ 仅接管小消息的 all-reduce,超出其适用范围的请求仍回退到 NCCL。

启动时,bootstrap.py 中的 _set_all_reduce_flags() 会执行:

set_mscclpp_all_reduce(get_exec().comm.enable_mscclpp)

该函数修改 parallel_state.py 中的全局标志 _ENABLE_MSCCLPP_ALL_REDUCE(默认 False),随后在 initialize_model_parallel 时决定是否创建 PyMscclppCommunicator 实例并挂载到张量并行组的 pymscclpp_comm 属性上(见 parallel_state.py)。

4.3 何时真正走 MSCCL++:运行时守卫条件

TensorParallelGroup.all_reduce 在每次调用时通过 pymscclpp_comm.should_mscclpp_allreduce(input_) 决定是否走 MSCCL++(见 parallel_state.py)。从 pymscclpp.py 的实现看,必须同时满足以下条件:

  1. 通信器未被禁用,且 world_size 属于支持集合(8/16/32);
  2. 输入张量 dtype 属于 [torch.float, torch.float16, torch.bfloat16]
  3. 输入张量满足弱连续(weakly contiguous)要求;
  4. 归约操作是 ReduceOp.SUMPyMscclppCommunicator.all_reduce 内部也断言 op == ReduceOp.SUM);
  5. 当前消息字节数存在已调优的配置(_get_tuned_config 命中 best_configs);
  6. 不在 piecewise CUDA graph / torch.compile 捕获或 warmup 阶段——注释明确说明在这些阶段使用 mscclpp 会改变 all-reduce 分发路径并触发重新编译,因此会被显式绕过。

任何一条不满足,都会自动回退到 NCCL,保证功能正确性优先。

4.4 首次启动的自动调优(Auto-tuning)

原文档特别提示:MSCCL++ 在首次初始化时会执行自动调优(auto-tuning),可能给启动增加数秒时间;调优结果在进程生命周期内缓存best_configs 字典)。

从源码看,调优过程在 PyMscclppCommunicator.__init__ 中由 _create_algorithms() 触发(pymscclpp.py):

  • TP=8(单节点):使用 native 算法集合(default_allreduce_nvls_packetdefault_allreduce_packetdefault_allreduce_rsag_zero_copy,若启用对称内存还包含 default_allreduce_nvls_zero_copy),每种算法按消息大小范围匹配,并对 nblocks / nthreads_per_block 的候选组合逐一测时(见 _create_native_algorithms);
  • TP=16 / TP=32(跨节点):改用 DSL 算法(allreduce_{n_nodes}node_{tbg}TBG_{num_threads_per_block}TPB),通过 mscclpp.compile 编译,线程块组大小与每块线程数组合测时(见 _create_dsl_algorithms)。

_tune[1<<9, 1<<24) 共 15 个 2 的幂大小逐一做 graph 内计时(warmup 5 次、graph 内 10 次 launch、20 次 ops),并在各 rank 间广播时间取平均以保证所有 rank 选择一致的配置(见 pymscclpp.py)。每个已调优大小在 _get_tuned_config 中按向上取整的 2 的幂(最小 512 B、最大 256 MiB)映射到最近配置(pymscclpp.py)。

五、使用边界与回退行为总结

综合原文档与源码,使用 MSCCL++ 时需注意以下边界:

  • world size 限制:仅 8 / 16 / 32 受支持,且要求组内 rank 连续;--enable-mscclpp 与不支持的 world size 组合时,通信器会被静默禁用并回退 NCCL(仅打 warning);
  • dtype 限制:仅支持 float / float16 / bfloat16,其他 dtype 直接回退;
  • 仅限 SUM 归约:其他 ReduceOp 不支持;
  • 对称内存:若同时启用 enable_symm_mem(见 exec_.py),native 算法集会额外包含 zero-copy 的 NVLS 算法,all_reduce 调用时也会传入 symmetric_memory 标志;
  • 与自定义 all-reduce 的关系enable_mscclppdisable_custom_all_reduce 是独立开关,二者同时存在时通过 should_mscclpp_allreduce 的运行时守卫协调优先级,需要逐条满足上述 6 项条件才会真正走 MSCCL++;
  • 启动延迟:首次初始化包含约 15 个消息大小 × 多组算法配置的 graph 计时,因此启动阶段会有数秒额外开销,属预期行为。

六、快速上手核对清单

  1. 确认 GPU 数量满足 TP=8(单节点)或 TP=16(两节点),且组内 rank 连续;
  2. 使用默认 docker/Dockerfile 镜像,或手动从源码编译安装 mscclpp,并验证 import mscclpp 成功;
  3. 运行基准测试对比 eager / graph 下 torch-NCCL、MSCCL++、PyNccl 的延迟,确认正确性校验输出 correctness check PASS!
  4. 推理服务加上 --enable-mscclpp,观察首次启动的 auto-tuning 日志与延迟收益;
  5. 如遇异常回退,检查 dtype、ReduceOp、消息大小是否命中调优缓存等守卫条件(见 pymscclpp.py)。
登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.76 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
860
1.35 K
docsdocs
暂无描述
Markdown
899
5.83 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
925
1.85 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.84 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
533
601
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.03 K
525
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.37 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
395