博文

目前显示的是标签为“集合通信”的博文

DeepEP原理分析(二):low latency模式代码详解(更新中)

图片
最近在做基于 DeepEP 和 SGLang 的推理优化。DeepEP 是一个用于取代 MoE 模型中 AlltoAll 操作、非常精妙和细致的点对点通信 kernel,好好研读其实现过程对 CUDA 编程、MoE rank 间通信都有巨大好处(下面的分析基于0625 main版本,详细代码请自行上 github 上搜索) 1 dispatch 1.1 入参详解 1、接收与打包参数:主要用于在目标 GPU 上存储从其他 GPU 接收到的数据 - packed_recv_x:用于存储接收到的已打包好的 token 特征数据,这些数据将直接用于本地专家的计算。这是数据在接收方的最终存储位置 - packed_recv_x_scales:如果使用 FP8 量化传输,这个指针指向用于存储 packed_recv_x 对应 FP8 scale(缩放因子)的缓冲区 - packed_recv_src_info:存储每个接收到的 token 在其来源 GPU 上的原始索引 。这个信息在后续 combine 阶段至关重要,用于将计算结果正确地写回 - packed_recv_layout_range:记录由每个本地专家从各个源 rank 接收到的 token 的布局信息。它通常将来自某个源 rank 的 token 总数和 token 在 packed_recv_x 缓冲区中的起始偏移量打包成一个 64 位整数,其结构可参考下面这个二维数组示意图,这个结构使得 dispatch kernel 能够记录每个本地专家从哪个源 rank 接收了多少 token,以及这些 token 在接收缓冲区中的具体位置。随后 combine kernel 可以利用这些信息,将处理后的 token 结果正确地发送回它们最初的源 rank - packed_recv_count:原子计数器,每个本地专家都有一个属于自己的该计数器,用来追踪该专家已经接收了多少 token,以便为新到达的 token 计算正确的存储偏移量 - cumulative_local_expert_recv_stats:用于累计每个本地专家接收到的 token 总数,作为统计信息 2、RDMA 缓冲区参数:RDMA 通信过程所需的空间和信号 - rdma_recv_x:RDMA 接收缓冲区。从其他节点通过网络发送过来的数据会先被存...

DeepEP原理分析(一):low latency模式特点总结

图片
 一、双缓冲模式 双缓冲模式是一种常见的提升数据发送效率的方法,数据的发送和接收往往有延迟。如果只用一块缓冲区,必须等通信完成后才能复用这块内存。而使用双缓冲则让通信任务和数据准备任务同时进行,有效隐藏通信延迟,提高整体吞吐。该方法涉及两块缓存,第一块缓存用于当前数据收发时,也会对第二块缓存会进行清理以准备下一轮的数据发送。例如下面的 low latency dispatch 代码中第一块缓存为 buffer,第二块为 next_buffer,它们均为 LowLatencyBuffer 结构体,位于显存(rdma_buffer_ptr )上 当 dispatch kernel 利用多个 SM 和 buffer 进行数据收发时,最后一个 warp 中的第一个 SM 也会对 next_buffer 进行清零操作,这样当下一次进行 combine 时可以直接复用刚刚完成的 dispatch 过程中准备好的 next_buffer,而 combine 过程同样也会为下一次的 dispatch 准备好 buffer。buffer 和 next_buffer 见的切换通过“异或”操作进行(^= 1),每进行一次异或操作 low_latency_buffer_idx 的值就会从 0 变为 1 或 1 变成 0,这样每轮 dispatch 和 combine 的过程就能错开利用两块 buffer 二、zero copy 原理 在 test_low_latency 测试脚本中有个叫做 test_func 的函数,该函数允许调用者手动设置是否使用 zero copy 模式来进行 combine。顾名思义 zero copy 指在 combine——也就是各专家将 dispatch 过程中收到的 token 计算完后的结果发回 token 所在的原 rank——该过程中无需将 token 计算结果拷贝至 RDMA 发送缓冲区,而是直接将让 combine 发送缓冲区(combine_rdma_send_buffer_data_start)指向计算后结果(simulated_gemm_x) 其关键作用的便是 get_next_low_latency_combine_buffer 函数,里面会使用 from_blob 方法,该方法会根据传入的原始数据指针创建一个引用(而非复制) 指向...