【学习】ParallelKittens(PK)学习与分析

ParallelKittens(PK)学习与分析

论文:ParallelKittens: Systematic and Practical Simplification of Multi-GPU AI Kernels(arXiv:2511.13940v1,Stanford Hazy Research,2025-11-17)


第一部分:学习

1. 背景

1.1 硬件失衡:算力增速远超互连增速

硬件维度(A100 → B200) 提升倍数
BF16 Tensor Core 算力 7.2x
HBM 带宽 5.1x
机内互连(NVLink) 仅 3x
机间互连(PCIe/InfiniBand) 仅 2x

算力与互连的剪刀差持续扩大,使通信成为现代 AI 负载的一级瓶颈 :即便有 NVLink/NVSwitch,LLM 负载中通信仍可占据 50% 以上执行时间,GPU 算力大量空转。

1.2 现有三类方案的缺陷

  • 算子专用内核(Flux、Comet、DeepEP、FlashDMoE、CUTLASS 分布式 GEMM):单算子性能强,但依赖 CUTLASS/NVSHMEM/Linux IPC 等复杂底层原语,不可复用;
  • 编译器方案(Triton Distributed、TileLink):缺少显式工作负载分布控制(warp/SM 特化),难以适配新硬件------Triton Distributed 为 H800 调优,在 H100 上有时比非重叠基线还慢;
  • 现成通信库(NCCL、NVSHMEM、xDiT、YunChang):封装了不利于性能的设计选择,比手工调优慢最多 4.08x。

1.3 趋势与核心问题

NVIDIA 路线图 NVL72 → NVL144(2026)→ NVL576(2027),机内 scale-up 系统持续变大 。核心问题:能否用一小撮简单、可复用的原则系统性指导最优多 GPU kernel 设计,而不是每个算子重新发明一次?

2. 创新

2.1 三个可量化原则(核心贡献)

原则一:传输机制选择。 三种机制各有带宽上限:

机制 H100 利用率 B200 利用率 饱和条件 关键特性
Copy Engine 82% 81% ≥256MB 大消息 主机发起、仅连续内存、不占 SM
TMA 78% 74% 仅 2KB 即近峰值 单线程异步、不增寄存器压力
Register 指令 76% 70% 约 76 个 SM(TMA 的 3.2--5.1 倍) 同步、寄存器级、唯一支持网内归约

功能矩阵:CE 不支持任何归约;TMA 支持 P2P 传输、机内广播、P2P 归约;只有 register 级指令支持 in-fabric reduction (multimem.red/multimem.ld_reduce)。现有系统没捕捉这些权衡:Triton Distributed、Flux、CUTLASS 一律走 copy engine,在中小矩阵上反而慢于非重叠基线。

原则二:调度策略。 两种重叠方式各有取舍:

  • intra-SM 重叠 (SM 内分 warp 池):所有 SM 的 Tensor Core 全忙;同步开销低------SM 内 mbarrier 约 64ns vs 经 HBM 的 SM 间同步约 832ns(13 倍)。适合计算/通信粒度对齐(GEMM+RS 比 inter-SM 好 1.2x)。局限:通信跟随计算模式、无法网内加速、远端 L2 只在源设备缓存。
  • inter-SM 重叠 (整块 SM 专职通信):可用网内归约(GEMM all-reduce 通信量降约 N 倍,实测 3.62x;all-gather GEMM 1.57x)、做远端缓存复用(Ring Attention 由通信 SM 批量拉 KV)。代价是 SM 分区权衡,最优比例随负载变化。

通信隐藏量化条件:GEMM+RS 中当归约维 K ≥ sR/2B(H100 BF16 约 K≥2197)时通信可被完全覆盖;实测 K=4096 时非重叠通信占比降至 1% 以下。

2.2 定位:三个"不是"

PK 不是 算子专用库(不绑定具体算子)、不是 编译器(控制权留给开发者)、不是现成黑盒库(暴露高性能机制、抽象掉不影响性能的复杂度)。它是嵌入 CUDA/C++ 的一层极薄原语层。

3. 实现方案:通信原语

3.1 数据结构(按存储层级建模)

层级 容量/带宽 PK 抽象
寄存器 64KB,130TB/s rt<M,N> Register Tile(最小 16x16)
共享内存 227KB,33TB/s st<M,N> Shared Tile
本机 HBM 80GB,3TB/s g1 Global Layout
peer HBM(NVLink/NVSwitch) 80xN GB,450GB/s pg1 Parallel Global Layout(PGL)

PGL = 跨所有设备同形状同尺寸的内存区域,是全部异步 P2P、广播、多播与归约的中心数据结构;索引用 int4 坐标(tile 级)。所有原语设备发起,强制 Tensor Core 友好布局与连贯互连访问。

3.2 八个核心原语

类别 原语 作用
P2P(异步、单线程) store_async(dst, src, coord) TMA 异步存共享 tile 到多播内存
store_add_async(dst, src, coord) 同上,原子加(TMA 原子归约写)
网内加速(集体) reduce(dst, src, OP) 从多播内存网内归约到本机 HBM
all_reduce(dst_and_src, OP) 就地全归约(多播内存上)
同步 signal(bar, coord, dev_idx, val) 原子加特定设备 barrier 计数
signal_all(bar, coord, val) 多播原子加,一次信号所有设备
wait(bar, coord, dev_idx, expected) 宽松序轮询
barrier(bar, coord, dev_idx) 全设备屏障

设计要点:P2P 原语异步+单线程(可与其他 warp 计算并行 = intra-SM 重叠);网内归约集体发起(= inter-SM 重叠 + 网内加速);同步原语让用户自定义任意调度图。

3.3 LCSC 统一编程模板

四 worker 组件:loader(TMA 加载)、storer(写回)、consumer(Tensor/CUDA Core 计算)、communicator(专职通信 SM)。lcsc::launch_kernel<config, globals, lcsc_template>(G, stream) 自动处理 kernel 配置、SMEM/TMA 设置、barrier 管理、SM/warp 分区运行时搜索。

示例(Figure 18,GEMM+AllReduce) :loader 双缓冲 TMA 加载 A/B → consumer warpgroup::mma_AB 累加 → storer 写回 C 并 device<NUM_DEVICES>::signal 各设备 → communicator 等全部到达后一行 all_reduce。通信相关设备代码仅约 10 行。

3.4 底层复杂度抽象

  • UVA:仅限单进程,不适用 torchrun 多进程生产模型;
  • CUDA IPC :64B stub 跨进程共享------简单但无法用 NVSwitch 加速器;
  • VMM + Multicast :cuMemCreate→FD 导出→Unix Socket 传→cuMemImportFromShareableHandle→cuMemMap,配 cuMulticastCreate/AddDevice/BindMem------启用网内归约的唯一路径,PK 主路径(代价:2MB 粒度对齐,需自定义 tensor 类)。

对用户:launch_kernel 封装全部 OS 驱动交互与预分配,实现"无中间 staging 直连 P2P"。

4. 值得借鉴点(概要)

  1. "先建成本模型,再定 API"的方法论;
  2. 传输机制按功能分层(TMA 管 P2P、register 管网内归约、CE 管主机大块搬运);
  3. intra-SM 与 inter-SM 是互补而非替代,动态选择/混合调度是设计空缺;
  4. 消除"为易用付费"的封装开销;

第二部分:进一步分析------设计开销三件套、统一编程模板

主题一:双向同步、中间缓冲、peer 地址全局读取("为易用付费"的三重剖析)

这是 PK 论文"设计开销"原则的三根支柱。三者分别来自 NCCL(前两项)与 NVSHMEM(第三项),是主流通信库为了通用性/易用性而付出的性能税。逐项建模如下。

1.1 双向同步(two-way synchronization)

机制 :NCCL 对每次数据传输强制"双向握手"------发送方必须确认接收方已就绪、接收方也必须确认发送方已开始,双方交换就绪/确认(flag/ack)后才允许数据进入缓冲区。设计目的是让库在任意调用时序下都安全(不知道对方进程何时到达、缓冲区是否可用)。

代价建模 :设一次握手的往返延迟为 T_handshake、数据量为 S、传输带宽为 B,则单条消息的通信时间为

复制代码
T_msg = T_handshake + S/B + T_staging

当 S 大时 S/B 主导,握手被掩盖;当 S 小(fine-grained 集合,如 MoE dispatch、MLA 投影的中间量),T_handshake + T_staging 主导,延迟而非带宽决定性能。这就是论文观测到 NCCL all-reduce 在纯通信 kernel 上最高 1.79x 性能损失、通信延迟最高 4.5x 的来源。

PK 的解法 :预分配目标缓冲(PGL)+ 一-way 直传。store_async 由发送方单线程发起 ,直接写 peer 的多播内存,不需要接收方先就绪 。同步从"传输前握手"后移到"消费前 barrier":接收方只需在真正消费数据时 wait 计数。语义等价于把 TCP 的 per-packet 确认换成窗口式信用制。

如何借鉴:

  • 自研通信层时,把"同步点"从数据传输前 挪到数据消费前,用显式 barrier/semaphore 而非每消息握手;
  • 前提是双方提前约定好内存布局与生命周期(PGL 式窗口),这是"一-way 化"的工程代价;
  • 对照现实:NCCL 2.31.2 新增的 CFT 设备侧 Put/Get、GIN 的 device-side timeout、Matters 的 barrier-free LL/sentinel 同步,都是同一方向的官方演进------"握手式集合通信 → 窗口式一-way 通信"是行业趋势。

1.2 中间缓冲(intermediate staging buffers)

机制:NCCL 每个 channel 持有小块预分配内存(communication channel buffer)作为中转:数据先由源写到本地 staging,再由 staging 发往目标(或在 ring 拓扑中逐跳搬运)。设计目的是避免每次传输都做 peer 内存句柄交换、简化任意地址对之间的传输、让 ring/tree 算法有统一落脚点。

代价建模:一次传输变成"本地写 + 远端读"两跳:

复制代码
T_comm = S/B_nvlink + 2*S/B_hbm + T_sync

多一次本地 HBM 往返(2*S/B_hbm)。大消息下 HBM 带宽够,损失被掩盖;小消息下这一跳与同步共同放大延迟。

PK 的解法 :直接写入目标 PGL 地址(store_async),零 staging。论文将该设计带来的纯通信 kernel 提升归因于"预分配目标缓冲 + 直接一-way 传输"的组合。

如何借鉴:

  • 评估现有栈时先问:数据是否走了多余的本地 HBM 往返?用 Nsight 看 staging 拷贝占比;
  • 库设计上优先"预分配窗口 + 直达地址",只在地址对高度动态时才退回 staging;
  • 与 1.1 是同一个硬币的两面:都需要"提前约定窗口",换来的是少一跳、少一次握手。

1.3 peer 地址全局读取(__ldg 地址解析 + 组同步)

机制 :NVSHMEM 的每次远程访问,API 内部先执行一次全局内存读(__ldg)取 peer 地址,再发起实际访问;同时 API 强制 __syncthreads 组同步。前者的地址解析是额外的一次全局内存往返(数百 ns 级),后者把 warp 级执行串行化、阻塞了可并行性。

代价建模:单次 element-wise 远程访问延迟

复制代码
T_element = T_addr_load(全局内存读地址) + T_transfer + T_sync_group(组屏障)

论文实测:PK 把 peer 地址在 PGL 初始化时解析并缓存进寄存器 、去掉 __syncthreads 后,element-wise NVLink 访问延迟低 4.5x、带宽高约 20 GB/s。

如何借鉴:

  • "地址翻译一次化"(resolve-once,use-many):把会重复使用的元数据(peer 地址、window 描述符)下沉到寄存器/常量,而不是每次访问都查内存;
  • 检查库 API 内部是否有隐式全局屏障(__syncthreads/barrier),在不需要全组一致时用轻量信号量替代;
  • 这是通用优化模式:每次重复计算/读取的成本,都应前移为一次初始化(类似 cuBLAS workspace 预分配、NCCL communicator 预解析)。

1.4 三者共性

开销 来源库 根因 消除手段 量级
双向同步 NCCL 任意时序安全 一-way + 消费前 barrier all-reduce 最高 1.79x 性能、4.5x 延迟
中间缓冲 NCCL 通用地址对 预分配窗口直达 每消息多一跳 HBM 往返
peer 地址全局读取 NVSHMEM 每次访问解析 寄存器缓存 + 去隐式屏障 延迟低 4.5x、带宽 +20GB/s

方法论归纳 :库的通用性设计(安全、解耦、易用)与性能最优(直达、少同步、少拷贝)存在系统性的张力。设计取舍的关键是区分"影响性能的复杂度"与"不影响性能的复杂度" :IPC/VMM/multicast 设置这类一次性复杂度可以封装;缓冲、同步、地址解析这类每次操作都发生的开销必须暴露控制权。


主题二:统一编程模板(LCSC)

2.1 模板的四角色抽象:生产者-消费者在 SM/warp 层的实例化

复制代码
struct lcsc_template {
    static void loader(...);        // 生产:TMA 从本地/peer HBM 加载 tile
    static void consumer(...);      // 消费:Tensor/CUDA Core 计算
    static void storer(...);        // 生产:把结果写本地/peer HBM
    static void communicator(...);  // 专职:网内归约 / 批量 peer 搬运
};

本质是把单 GPU kernel 里成熟的 warp specialization (FlashAttention 式的 producer/consumer 流水线)推广到跨 GPU:loader/storer 是数据生产端,consumer 是计算端,communicator 是通信执行端------通信第一次成为与计算、加载、存储平级的"第一公民"角色。

2.2 一个模板如何同时表达两种重叠策略

  • intra-SM 重叠:loader/storer 访问 peer HBM 时,与同 SM 内 consumer 的 Tensor Core 计算并发(TMA 单线程异步发起,不占寄存器);
  • inter-SM 重叠 :communicator 独占一个或多个 SM 专职通信,其余 SM 专职计算------SM 分配由 num_comm_sms 控制。

模板的价值在于:两种策略不是两套代码,而是同一模板的两个配置。开发者只需决定"通信放哪个角色",SM 分区由框架自动搜索。

2.3 模板如何建模

关键超参 :num_comm_sms(专职通信的 SM 数)。设总 SM 数为 N_SM、计算 SM 数为 N_comp = N_SM - N_comm,则

复制代码
T = max( T_comp(N_comp), T_comm(N_comm) ) + T_non-overlap + T_sync

最优分区在 T_comp(N_comp) ≈ T_comm(N_comm) 处。论文指出该最优值随负载(输入尺寸、消息粒度)变化:大负载偏计算(多 N_comp),小负载需更多通信 SM。PK 的做法是运行时自动搜索(模板封装 autotune),而非静态定死。

信号量与 phasebit :模板内用 comp_sem/comm_sem 信号量 + 阶段位(phasebit)实现多级流水线(loader 双缓冲、consumer 消费、storer 写回、communicator 归约),把"跨设备屏障"降为"跨生产者-消费者握手",避免全设备 barrier。这是 FlashAttention 双缓冲流水线的跨 GPU 扩展------同步从"全局屏障"细化为"按 tile 依赖握手"。

成本权衡:inter-SM 同步 832ns vs intra-SM 64ns、网内归约把 AR 通信量降 N 倍 vs 少 N 个 SM 计算力------模板把这三项权衡固化为可调参数,用户/自动搜索在此参数空间取最优点。

2.4 模板的借鉴价值

  1. 结构即文档:四角色模板让多 GPU kernel 的可读性逼近单 GPU kernel,通信代码从"库调用点缀"变成"结构化组件"------<50 行设备代码的根因不是原语多强大,而是模板把 90% 的样板(配置、SMEM、TMA、barrier、分区)吸收掉了;
  2. 可组合性:把通信、加载、存储、计算解耦为独立函数,意味着同一模板可复用于 GEMM、Attention、MoE(论文已验证四种并行策略全用同一模板);
  3. 对库设计者的启示:提供"模板 + 原语"而不是"全自动编译器"或"裸 API"------前者保证控制力(专家可手调),又大幅降低普通开发者的上手成本;这是 CUTLASS 的 CuTe DSL、ThunderKittens、PK 一脉相承的设计哲学;
  4. 对框架的启示 :num_comm_sms 自动搜索可以进一步模型化(用 roofline 预估最优分区),未来可接入调度器做全局感知。

主题三:如何建模

  1. 测量:在本机复现论文三张微观基准------三种机制的带宽-消息粒度曲线、SM 数-带宽曲线、intra/inter SM 同步延迟(64ns/832ns);
  2. 定位:用总成本模型找出目标 kernel 的瓶颈项(comp/mem/comm/launch/sync 哪个最大);
  3. 选型:按决策矩阵选传输机制,按隐藏判据选重叠策略(能 intra 则 intra,需要网内加速/远端复用则 inter);
  4. 消税 :逐项检查双向同步、中间缓冲、peer 地址解析、隐式屏障是否存在,按主题一的手段消除,最后 autotune num_comm_sms。

主题四:如何借鉴

4.1 通信库使用者(训练框架 / 推理引擎)

  • 别只测带宽:小消息场景用延迟基准评估栈(如 vLLM 的 ITL、MoE dispatch 时延),"1.79x 隐藏损失"在大模型细粒度通信里真实存在;
  • 在 NVLink 域优先融合:把 AG+GEMM、GEMM+RS、GEMM+AR 做成融合 kernel(参照 PK Figure 7-9 的收益区间),避免每层一个 NCCL 调用;
  • 细粒度集合别走 NCCL reshape 路线:DeepSpeed-Ulysses 的 4D all-to-all、tensor 维 all-gather 用 PGL 直跑原始 layout,可省掉 reshape+copy。

4.2 算子开发

  • 采用"模板 + 原语"结构:把通信提成 loader/storer/communicator 角色,通信代码控制在 10-50 行内,可读性接近单 GPU kernel;
  • 多播内存是隐藏的大杀器 :multimem.red/ld_reduce 的网内归约让 all-reduce 通信量降 N 倍------需要 VMM+Multicast 内存路径(2MB 对齐、自定义 tensor 类),值得为此改造内存管理;
  • 借鉴其衡量方法:每个新 kernel 报告"非重叠通信占比",以 1%(DP/TP)、9%(SP)、15%(EP)为参考基线。

4.3 通信库设计(对标 NCCL / NVSHMEM 演进)

  • 一-way + 预分配窗口:把双向握手改为消费前 barrier,把 staging 缓冲改为直达目标窗口------这是 NCCL 2.31.2 CFT(device-side Put/Get)、GIN 的演进方向,可加速吸收;
  • 地址解析一次化 :peer 地址/窗口描述符缓存到寄存器,去掉 API 内隐式 __syncthreads;
  • 暴露机制选择而非替你选:按 CE/TMA/Register 功能矩阵提供三档原语,让上层按消息粒度选型;
  • 模板化 :提供 LCSC 式模板 + num_comm_sms 自动搜索,让用户获得手工调优的性能而不必手写全部样板。

附:关键数字速查

项 数值
算力 vs NVLink 增速差 7.2x vs 3x
通信占 LLM 执行时间 >50%
CE/TMA/Reg 带宽利用率(B200) 81% / 74% / 70%
TMA 饱和消息 2KB
CE 饱和消息 256MB
Register 饱和 SM 数 ~76(TMA 的 3.2--5.1 倍)
intra-SM vs inter-SM 同步 64ns vs 832ns
通信隐藏条件(H100 BF16) K ≥ 2197
NCCL 开销(双向同步+缓冲) all-reduce 1.79x 性能、4.5x 延迟
NVSHMEM 开销(地址解析+组同步) 4.5x 延迟、-20GB/s 带宽
网内归约收益 GEMM-AR 3.62x、AG-GEMM 1.57x
PK 通信代码量 10-50 行/ kernel
非重叠通信占比(PK) 1%(DP/TP)/ 9%(SP)/ 15%(EP)
相关推荐
坤坤子吖1 小时前
Python基础语法学习:列表和元组
开发语言·笔记·python·学习
JWASX2 小时前
Java 转 go 学习 - 接口
学习·golang
I Am a robert girl2 小时前
从零读懂世界模型的持续学习:一份组合式基准的源码级拆解
学习·具身智能·持续学习·灾难性遗忘·机器人学习·世界模型·组合式基准
扶风ff2 小时前
练题簿在线免费刷题:刷题、背题、错题复习,一个小程序安排日常备考
学习·小程序
東隅已逝,桑榆非晚2 小时前
数据结构队列
数据结构·笔记·学习
老王爱玩车2 小时前
字符串和字符串函数
c语言·开发语言·数据结构·学习
扶风ff2 小时前
练题簿在线免费刷题:共享题库、学习任务、在线考试,岗位培训更方便
学习·小程序
JWASX2 小时前
Java 转 go 学习 - 并发编程(3)
学习·golang
传奇开心果编程2 小时前
【Compose Multiplatform 跨端开发学与练】第9课 测试与调试
android·学习·macos·ios·kotlin·web·composer