ascend-boost-comm:一次写完,到处复用——算子公共平台的 M×N 哲学

发布时间:2026/5/23 10:18:22

ascend-boost-comm:一次写完,到处复用——算子公共平台的 M×N 哲学 如果有 M 个算子和 N 个框架/模型你需要写 M×N 次集成代码。但如果把共性抽象出一层公共平台就只需要写 MN 次。这就是 ascend-boost-comm 在解决的问题。去年帮一个同事调分布式推理的代码他在 PyTorch 上写了一套算子集成逻辑跑得好好的。后来领导要求兼容 MindSpore他又照着 PyTorch 那套重写了一遍——同样的通信逻辑只是框架接口不同。当时我跟他说你能不能用中间层抽象一把框架层只做薄薄的一层适配真正的算子通信逻辑放在公共层他说「我也想但哪来的公共层」现在答案是ascend-boost-comm。一、ascend-boost-comm 是什么ascend-boost-comm 是 CANN 生态中的算子公共平台中间件定位是实现 M 个算子与 N 个上层应用之间的复用。从 CANN 五层架构来看ascend-boost-comm 位于编译层和执行层之间。它不直接编译代码也不直接执行算子而是在两者之间提供一套标准化的算子集成接口。这套接口对上层PyTorch、MindSpore、Paddle 等框架适配器暴露统一的调用方式对下层算子实现提供标准化的调度和通信能力。链接https://atomgit.com/cann/ascend-boost-comm二、M×N 问题的本质假设你有 10 个算子FlashAttention、MoE、KV Cache 管理等要在 3 个框架PyTorch、MindSpore、Paddle上都能用。如果不做抽象你需要写的代码量10 个算子 × 3 个框架 30 套集成代码每套集成代码至少包含框架适配层、内存管理、通信接口、错误处理。这些东西的逻辑是相近的但因为每个框架的接口不同你被迫重写。ascend-boost-comm 的做法是把共性的部分抽取出来做成一个公共平台。10 个算子 → 对接公共平台1 套标准接口 3 个框架 → 各对接公共平台3 套薄适配层 总代码量 ≈ 10 3 13 套从 30 套到 13 套省的是维护成本。而且后续加一个新算子第 11 个只需要写算子到平台的一层对接所有框架自动可用。加一个新框架第 4 个只需要写一个薄适配层所有算子自动可用。三、核心技术算子模板化与参数化ascend-boost-comm 的核心设计是算子模板化。一个典型的通信密集型算子比如 FlashAttention在不同框架中调用时的核心逻辑是一样的把输入张量切成 blocks、在 blocks 之间做 softmax 规约、合并输出。变化的只是——怎么从 PyTorch 的 Tensor 转到 NPU 的 Buffer或者怎么从 MindSpore 的 Parameter 转成一样的格式。ascend-boost-comm 的做法是把算子逻辑做成参数化模板// ascend-boost-comm 中的算子模板伪代码核心结构示意templatetypename InputTensor,typename OutputTensorclass FlashAttentionOp{public:// 框架适配器只需要实现这两个接口voidSetInput(constInputTensorq,constInputTensork,constInputTensorv);OutputTensorGetOutput();private:// 真正的算子逻辑——不需要框架适配层关心voidtiling_kernel();voidsoftmax_reduce();voidoutput_merge();// 内部使用统一的 Buffer 格式跟框架无关boost::Buffer*q_buf_;boost::Buffer*k_buf_;boost::Buffer*v_buf_;};注释解释WHYboost::Buffer是 ascend-boost-comm 内部的统一数据类型它屏蔽了 PyTorch Tensor、MindSpore Parameter、Paddle Tensor 之间的差异。上层适配层的工作就是「把框架自己的类型转成 boost::Buffer」仅此而已。四、通信抽象统一收发语义ascend-boost-comm 的另一个关键能力是统一通信接口。不同的通信库hccl、hixl、hcomm有各自独立的 API直接调用的话算子代码里会出现大量的 if-else 分支——根据场景选 hccl 还是 hixl根据拓扑选 Ring 还是 Tree。ascend-boost-comm 在通信库之上再做一层抽象// 统一的通信接口boost::CommResultSend(constboost::Bufferdata,conststd::vectorintdest_ranks,boost::CommBackend backend);boost::CommResultRecv(boost::Buffer*data,conststd::vectorintsrc_ranks,boost::CommBackend backend);CommBackend可以选 HCCL、HIXL 或 HCOMM但算子代码不需要知道底层是哪个——只需要告诉公共平台「我需要把这块数据发到 rank 3 和 rank 5」平台自动选最优通道。这个抽象的好处在于通信策略的变化不影响算子代码。比如你从单机训练全部用 HCCL迁移到 PD 分离推理KV Cache 传输用 hixl算子代码不需要改——只需要在配置里把对应的通信后端从 HCCL 换成 HIXL。五、实战案例FlashAttention 的三框架适配对比用一个具体例子展示 ascend-boost-comm 的价值。在没有公共平台的时候你要在 PyTorch、MindSpore、Paddle 三个框架中支持 FlashAttention 算子PyTorch 版本没有平台之前# 直接调用 CANN ACL 接口代码跟框架深度耦合fromtorch_npu.npuimportflash_attention outputflash_attention(q,k,v,dropout_p0.0,is_causalTrue)使用 ascend-boost-comm 之后PyTorch 侧只需要写一个薄薄的 wrapperclassFlashAttention(torch.autograd.Function):staticmethoddefforward(ctx,q,k,v):# 只需一步转成 boost::Buffer交给平台boost_bufboost.from_torch(q,k,v)result_bufboost.flash_attention(boost_buf,causalTrue)returnboost.to_torch(result_buf)MindSpore 侧同理classFlashAttention(nn.Cell):defconstruct(self,q,k,v):boost_bufboost.from_mindspore(q,k,v)result_bufboost.flash_attention(boost_buf,causalTrue)returnboost.to_mindspore(result_buf)两个框架的 wrapper 逻辑几乎一模一样差异只在入口和出口的类型转换。真正的算子逻辑在boost.flash_attention里只写一次。这种模式对运维的收益很明显——算子升级时更新 ascend-boost-comm 的包版本就行不需要改框架侧的代码。框架升级时只需要更新薄适配层算子逻辑不变。六、与 ATB 的关系ascend-boost-comm 和 ATBascend-transformer-boost在概念上容易混淆但它们的分工清晰ATB专注 Transformer 类模型的加速——提供融合算子、KV Cache 管理、分布式推理调度等能力。它是「垂直领域加速库」。ascend-boost-comm专注算子与上层应用的连接——提供统一的算子集成接口和通信抽象。它是「横向公共平台」。在技术栈上的关系PyTorch → [框架适配器] → ascend-boost-comm → ATB 算子 → NPU MindSpore → [框架适配器] → ascend-boost-comm → ATB 算子 → NPU Paddle → [框架适配器] → ascend-boost-comm → ATB 算子 → NPU可以看到加了 ascend-boost-comm 之后ATB 只需要对接一个公共平台而不是三个框架。这解决了双重的 M×N 问题。七、使用建议如果你是算子开发者新算子的集成逻辑优先按 ascend-boost-comm 的模板接口实现。这样一来算子一写完三个框架就自动可用。不要像以前那样先写一个框架的版本再逐个适配。如果你是框架适配层维护者在框架侧把类型转换封装成工具函数boost.from_torch、boost.to_torch等后续添加新算子只需要一行调用。如果你是分布式训练用户关注通信后端的选择。在 ascend-boost-comm 的配置中可以按场景切换 HCCL / hixl / hcomm不用在代码里硬编码。这对跨平台迁移训练→推理、单机→多机很有帮助。链接https://atomgit.com/cann/ascend-boost-comm

相关新闻