请添加图片描述
个人主页:ujainu

前言

昇腾 NPU 上跑一个大模型推理,背后要调多少个算子库?ops-nn 做矩阵乘,ops-transformer 做 FlashAttention,catlass 做模板化 GEMM,还有第三方算子……每个加速库要对接每一个算子库,M 个算子库 × N 个加速库,光适配代码就够喝一壶。CANN 的 ascend-boost-comm 就是干这件事的——它不是通信库,而是算子公共平台中间件,把 M×N 的对接变成 M+N。

先纠正一个高频误解:很多人看到 ascend-boost-comm 里有"comm",就以为是通信组件,跟 hccl 扯上关系。完全不是一回事。hccl 是集合通信库,管的是多卡之间 AllReduce、Broadcast 这些事;ascend-boost-comm 是算子平台的中间件,管的是算子库和加速库之间的标准化对接。一个管"卡间说话",一个管"库间握手"。hixl 是单边通信库,同样和 ascend-boost-comm 没有任何交集。

M×N 复用问题:ascend-boost-comm 的设计动机

先用一个具体场景说清楚为什么这东西必须存在。

假设你维护 ATB(ascend-transformer-boost)加速库,要支持昇腾 NPU 上的大模型推理。ATB 底层用到了 MatMul、LayerNorm、FlashAttention 等算子,这些算子在昇腾上的实现来源分散:

  • MatMul 可能来自 ops-nn,也可能来自 catlass(catlass 有针对特定 shape 的硬件特化实现,性能更好)
  • FlashAttention 来自 ops-transformer
  • LayerNorm 来自 ops-nn
  • 未来某天,catlass 新增了 Ascend 910B 的特化 GEMM 模板,ATB 要不要接?

现在问题来了:如果 ATB 直接硬编码依赖这些算子库,就形成了一个 M×N 的适配网格。M 个算子库(N ops-nn + ops-transformer + catlass + 第三方……)× N 个消费方(ATB + cann-recipes-infer + cann-recipes-train + asnumpy + 第三方推理框架……)。当任何一个算子库升级接口、改变构建方式、迁移到新硬件,每个消费方都要跟着改适配代码。这就是经典的"N+1问题"变体——改动点散落在 N×M 条对接线上。

ascend-boost-comm 的设计哲学,就是在这个网格中间插入一个标准化层,把 M×N 变成 M + N:

// 算子库只需要"上架"一次
// 之后所有加速库都从公共平台获取,不再需要单独对接
BoostComm::RegisterOpLibrary("ops_nn",      ops_nn_interface);
BoostComm::RegisterOpLibrary("ops_transformer", ops_transformer_interface);
BoostComm::RegisterOpLibrary("catlass",     catlass_interface);

// 加速库也只需要"下单"一次
// 底层算子来自哪个库,由平台根据硬件和版本自动选择
auto matmul_op   = BoostComm::GetOperation("MatMul");
auto flash_attn  = BoostComm::GetOperation("FlashAttention");

当 catlass 发布支持 Ascend 950 的新模板时,只需在公共平台注册一份,ATB 下次调用 GetOperation("MatMul") 时平台自动路由到最新最优的实现。ATB 自己的代码一行不用动。

算子库和加速库之间缺了什么

打个比方:算子库是供应商,加速库是渠道商。没有中间件的时候,每个渠道商要跟每个供应商单独签合同、对接口、验货。3 个供应商、4 个渠道商,就是 12 条对接线。供应商换了包装规格,12 条线全部要改。

ascend-boost-comm 就是那个"标准化采购平台"。供应商往平台上架,渠道商从平台下单,接口统一、版本对齐、变更只改一处。

M×N 变成 M+N,这才是 ascend-boost-comm 存在的核心理由。

南向对接:把算子库"上架"

ascend-boost-comm 南向对接的算子库来源很广,每一类都有不同的接入逻辑:

ops-nn:神经网络基础算子库

ops-nn 提供神经网络中最通用的基础算子,包括 MatMul、Conv2D、LayerNorm、Softmax、ReLU 等。这些算子覆盖了大多数深度学习模型的计算图,是昇腾 NPU 上跑 AI workloads 的算力底座。

ascend-boost-comm 与 ops-nn 的对接方式是:ops-nn 遵循 opbase 定义的算子描述规范,将所有基础算子以统一格式注册到公共平台。每个算子包含名称、类型、接口签名和版本号,ascend-boost-comm 根据这些元数据生成稳定的调度入口。

ops-transformer:大模型进阶算子库

ops-transformer 提供大模型场景下特有的算子,如 FlashAttention(多头注意力加速实现)、MoE(混合专家)相关算子、Grouped Query Attention、Rotary Position Embedding 等。这类算子更新频繁,往往伴随新模型架构的发布而快速迭代。

ascend-boost-comm 在这里的关键价值是"版本隔离":ops-transformer 的激进更新节奏不需要传导到上层。加速库拿到的始终是平台标准化后的接口句柄,具体用 ops-transformer 的哪个 commit,由平台在运行时决定。

catlass:高性能矩阵乘模板库

catlass 是昇腾上做 GEMM(通用矩阵乘)的高性能模板库,针对不同硬件(Ascend 910A/910B/950 等)和不同数据形状做了大量手工优化。当矩阵乘的 shape 满足特定条件时,catlass 的实现可以比通用 ops-nn 实现快数倍。

ascend-boost-comm 对 catlass 的处理比较特殊:catlass 提供的不是单一算子,而是一组按 shape 分发的模板变体。平台层会根据输入 tensor 的 shape、dtype、stride 等属性,自动选择最合适的 catlass 实现,或者回退到 ops-nn 的通用实现。这个路由逻辑在公共平台内部完成,上层加速库无感知。

// 算子库侧:统一用 opbase 规范注册,catlass 可以注册多个 shape-specific 变体
struct OpVariant {
    std::string variant_name;   // 如 "gemm_128x256_skinny", "gemm_512x512_wide"
    std::vector<TensorShape> preferred_shapes;  // 该变体偏好的 shape 范围
    OpInterface impl;          // 具体实现
};

// catlass 注册时携带多个变体,平台自动路由
BoostComm::RegisterOpLibraryVariants("catlass", {
    {"gemm_avx2_128", {...}},   // 针对 Ascend 910A 128xN shape
    {"gemm_avx3_256", {...}},   // 针对 Ascend 910B 256xN shape
    {"gemm_c2x_512",  {...}},   // 针对 Ascend 950 512xN shape
});

第三方算子

ascend-boost-comm 也对社区或第三方贡献的算子开放注册接口。第三方只需实现 opbase 定义的算子接口规范,就能接入公共平台,被所有上层的加速库发现。这个机制让昇腾生态具备了良好的可扩展性——不需要修改 ATB 或 cann-recipes,第三方算子就能进入昇腾 NPU 的算子调度体系。

// 第三方算子接入示例
BoostComm::RegisterOpLibrary("custom_quant", {
    .name = "W8A16Quant",
    .type = OpType::QUANTIZATION,
    .interface = CustomQuantImpl,
    .version = "1.2.0",
    .priority = 2  // 优先级低于 catlass 和 ops-nn
});

这些算子库各自有独立的接口风格、版本节奏和构建方式。ascend-boost-comm 定义了一套统一的算子描述和调用规范,让上游不管怎么变化,下游看到的接口是稳定的。

// 统一的算子描述规范——不管底层是 ops-nn 还是 catlass
struct OpDescriptor {
    std::string op_name;       // 算子标识(全局唯一)
    std::string op_type;       // 算子分类(MatMul/Attention/LayerNorm...)
    OpInterface interface;     // 统一调用接口
    OpVersion version;         // 版本管理,用于兼容性判断
    int priority;              // 多实现时的调度优先级
};

// 算子接口规范(opbase 定义)
class OpInterface {
public:
    virtual ~OpInterface() = default;
    virtual OpResult Execute(const OpContext& ctx, Stream stream) = 0;
    virtual bool Verify(const TensorDesc& input, const TensorDesc& output) = 0;
    virtual std::vector<DeviceArch> SupportedArch() const = 0;
};

opbase 在这里扮演基础设施的角色——它提供公共头文件、结构体和调度框架,ascend-boost-comm 和所有 ops-* 仓库都依赖它。可以理解为 opbase 是建材标准,ascend-boost-comm 是施工平台,算子库是按标准生产的预制件。

北向支撑:让加速库"下单"

北向的消费者主要是 ATB(ascend-transformer-boost),还有 cann-recipes-infer、cann-recipes-train、asnumpy 等。

ATB(ascend-transformer-boost)

ATB 的三层架构——基础原生算子 → 图算子机制 → 插件机制——最底层那层原生算子,就是从 ascend-boost-comm 拿的。ATB 不需要知道 MatMul 的实现来自 ops-nn 还是 catlass,它只管向公共平台请求"给我一个 MatMul"。

ATB 内部有一个算子选择策略器,当请求某个算子时,平台会综合考虑硬件型号、tensor shape、dtype、用户指定的偏好等因素,从多个已注册的候选实现中选出一个最合适的。如果 catlass 有针对当前 shape 的特化实现且优先级更高,就选 catlass;如果没有,就回退到 ops-nn。

// ATB 构建图算子时,通过公共平台获取底层算子
atb::Operation *matmul = BoostComm::CreateOperation({
    .name = "MatMul",
    .backend = "auto"  // 平台自动根据硬件和 shape 选择最优后端
});

// ATB 也可以指定偏好策略
atb::Operation *fast_matmul = BoostComm::CreateOperation({
    .name = "MatMul",
    .backend = "catlass",  // 强制走 catlass,哪怕 shape 不是最优
    .enable_fusion = true  // 开启算子融合
});
// ATB 图构建层示例:融合算子从公共平台获取
atb::Graph graph;
graph.AddNode("flash_attention", BoostComm::CreateOperation({
    .name = "FlashAttention",
    .backend = "auto",
    .options = {
        {"head_dim", 128},
        {"is_causal", true}
    }
}));
graph.AddNode("linear", BoostComm::CreateOperation({
    .name = "MatMul",
    .backend = "catlass"  // 大 shape 矩阵乘走 catlass
}));

这意味着:catlass v1.5 新增了 Ascend 950 的硬件特化模板,ATB 不用改一行代码就能用上——公共平台负责把新能力"上架",加速库下次请求自动拿到最新版本。

asnumpy

asnumpy 是昇腾的 NumPy 兼容层,让用户可以用类似 NumPy 的 API 操作 NPU 上的数据。当你写 npu_array.matmul(other) 时,底层走的正是通过 ascend-boost-comm 拿到的算子实现——是 ops-nn 还是 catlass,用户完全无感知。

import ascnasnumpy as npu

# 用户代码:标准的 NumPy 风格
a = npu.random.randn(1024, 512).astype(npu.float16)
b = npu.random.randn(512, 256).astype(npu.float16)

# 底层:ascend-boost-comm 自动路由到最优 GEMM 实现
# shape 合适走 catlass,否则走 ops-nn
c = npu.matmul(a, b)

cann-recipes-infer / cann-recipes-train

cann-recipes 系列仓库提供昇腾推理和训练场景的最佳实践配方。它们在构建算子图时,同样通过 ascend-boost-comm 获取所需算子,而不是直接依赖具体的 ops-* 仓库。这种解耦让 cann-recipes 能够独立于算子库进行版本迭代,降低了昇腾 CANN 整体的耦合度。

在 CANN 五层架构中的位置

ascend-boost-comm 横跨第 2 层(算子服务层)和第 3 层(编译层)之间。说它是桥梁有点虚,更准确地说,它是算子层和应用链的接缝

没有这层接缝,每个上层应用都要自己对接算子库的构建系统、头文件路径、版本兼容性。有了它,上层只看一个接口,底层随便换。

┌─────────────────────────────────────────────────┐
│  第1层:GE / AIR / MindX(应用框架层)           │
├─────────────────────────────────────────────────┤
│  第2层:ops-nn / ops-transformer / catlass /   │
│         opbase(算子供应层)                     │
│           ↑ 南向注册                             │
│  ascend-boost-comm                               │
│           ↓ 北向查询                             │
│  第3层:ATB / cann-recipes-* / asnumpy(算子消费)│
├─────────────────────────────────────────────────┤
│  第4层:CCE / TIBA(编译层)                    │
│  第5层:CCE Kernel(算子实现层)                │
└─────────────────────────────────────────────────┘

ascend-boost-comm 本身不实现任何算子逻辑,它只负责:注册(南向接收算子库的能力)、发现(北向响应加速库的请求)和路由(根据硬件和 shape 选择最优实现)。

和 hccl/hixl 到底有什么区别

再强调一次,因为这俩太容易搞混了:

维度 ascend-boost-comm hccl hixl
定位 算子公共平台中间件 集合通信库 单边通信库
解决的问题 M×N 算子对接 多卡数据同步 单卡跨设备 DMA
数据流向 库与库之间(单卡内) 卡与卡之间 设备与设备之间
典型操作 RegisterOpLibrary、GetOperation AllReduce、Broadcast、AllGather Put、Get、Sendrecv
作用层级 算子层(第2-3层之间) 通信层(多卡互连) 通信层(单设备)

hccl 管的是"多张 NPU 卡之间怎么同步数据",hixl 管的是"单张卡上 Host 和 Device 或者 Device 和 Device 之间怎么搬数据",ascend-boost-comm 管的是"算子库和加速库之间怎么握手"。三件事,三个库,别搞混。

// hccl:多卡通信——所有卡的数据汇总到同一个值
hcclResult_t ret = HcclAllReduce(send_buf, recv_buf, count,
                                  hcclFloat, hcclSum, comm, stream);

// ascend-boost-comm:算子调度——从公共平台获取一个算子实例
auto op = BoostComm::GetOperation("FlashAttention");
op->Execute(ctx, stream);

写在最后

如果你在做 ATB 插件开发、或者在给昇腾 NPU 适配一个新的算子库,ascend-boost-comm 是你必须理解的中间层。它不生产算子,也不消费算子——它让算子的生产者和消费者不必直接见面。

理解 ascend-boost-comm 的关键是记住一个公式:M×N → M+N。每当你看到昇腾生态里有新的算子库加入,或者新的加速库出现,只需要两件事:往公共平台上架一次,从公共平台下单一次。就够了。

仓库地址:https://atomgit.com/cann/ascend-boost-comm

下一步:如果你是算子库开发者,关注 opbase 的公共规范和 ascend-boost-comm 的注册接口;如果你是加速库开发者,直接看 ATB 的 Operation 构建方式,底层算子怎么来的不用你操心。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐