前言

分布式深度学习训练中,梯度同步是决定扩展效率的关键瓶颈。当模型参数量达到数十亿级别时,多设备之间的集合通信开销往往成为制约训练吞吐量的核心因素。CANN(Compute Architecture for Neural Networks)是华为昇腾AI处理器的基础软件栈,而HCCL(Huawei Collective Communication Library)作为CANN的重要组成部分,承担着昇腾NPU之间高速数据传输的职责。2025年11月30日,华为正式开源了HCCL仓库,为研究者和工程师提供了深入理解昇腾通信机制的窗口。HCCL不仅实现了AllReduce、Broadcast、AllGather、ReduceScatter、AlltoAll等标准的集合通信原语,还提供了Ring、Mesh、Recursive Halving-Doubling等多种通信算法选项,支持HCCS、RoCE、PCIe等物理链路,并同时兼容单算子执行模式和图模式两种运行方式。本文以AllReduce为核心标尺,系统对比Ring AllReduce和Recursive Halving-Doubling两种算法在昇腾NPU多卡拓扑上的实现差异,深入分析不同物理链路特性对算法效能的影响,并探讨HCCL与HCOMM之间的控制面与数据面分离设计。

AllReduce的数学抽象与问题定义

AllReduce是分布式训练中最常用的集合通信操作之一,其数学定义为:给定N个参与节点,每个节点i持有一个长度为L的向量Xi,AllReduce的目标是让所有节点最终获得同一个归约结果,该结果是所有节点输入向量的逐元素归约。以求和为例,最终每个节点得到的结果向量Y满足Y[j] = sum_{i=1}^{N} Xi[j]对所有元素位置j均成立。这个操作在深度学习训练中的典型使用场景是梯度平均:每个计算设备计算出一份本地梯度向量,所有设备通过AllReduce将梯度求和后再取平均值,作为下一轮迭代的模型更新依据。

从通信复杂度的角度来看,AllReduce的时间成本由两个主要因素决定:数据量和通信拓扑结构。假设每个节点需要传输的数据量为D,节点之间的带宽为B,通信延迟为L,那么一个朴素的两阶段AllReduce实现(先归约到根节点,再广播到所有节点)在P个节点的系统中需要约2(P-1)乘以(D/B + L)的时间。更高效的算法通过重叠计算与通信、合理安排数据分片来降低通信瓶颈。HCCL仓库中重点实现的Ring AllReduce和Recursive Halving-Doubling两种算法,分别代表了针对不同数据规模和硬件拓扑的最优选择策略。

在昇腾NPU的硬件环境中,P个NPU通常通过HCCS(Huawei Cache Coherent System)或RoCE(RDMA over Converged Ethernet)高速互联。以Ascend 910为代表的昇腾AI处理器单芯片包含多个AI Core,通过HCCS总线可以构建8卡或16卡的紧耦合拓扑。在多机场景下,跨服务器的RoCE网络成为节点间通信的主要通路。物理链路的带宽和延迟特性差异,直接影响算法选择:HCCS链路的带宽远高于RoCE,且延迟极低,因此适合大批量数据的长距离传输;RoCE链路的带宽相对较低但覆盖面广,适合跨机通信或者小数据量的广播操作。理解这些物理约束,是深入掌握HCCL算法实现的前提。

Ring AllReduce:带宽最优的环形流水线

Ring AllReduce算法的核心思想是将P个参与节点组织成一个逻辑环,每个节点只与环上的两个邻居直接通信。数据被切分为P个块,每个节点负责归约一个数据块,并将该块沿着环传递,直到所有数据块都完成归约并传播到所有节点。这个算法的通信步骤数与节点数量P成正比,但关键在于每个步骤中所有P个节点同时参与传输,形成了流水线式的并行数据传输,使得总通信时间与节点数量解耦,主要由数据总量和单链路带宽决定。

具体而言,假设P个节点形成一个编号为0到P-1的环,数据向量被划分为P个等长的块。在reduce-scatter阶段,每个节点i将自己的第i块数据发送给节点(i+1) mod P,同时从节点(i-1) mod P接收数据并与本地块进行归约。这个过程循环P-1次后,每个节点持有了所有节点对应块的归约结果。在all-gather阶段,每个节点将自己的归约结果块发送给(i+1) mod P,同时从(i-1) mod P接收其他节点的数据。这个过程同样循环P-1次后,所有节点都拥有了完整的归约结果。两个阶段加起来,每个节点发送和接收的数据总量均为2D(P-1)/P。

在HCCL的实现中,Ring AllReduce充分利用了昇腾NPU的HCCS高速链路特性。HCCS总线提供了节点之间点对点的DMA(Direct Memory Access)能力,支持大块数据的零拷贝传输。在Ascend 910的8卡拓扑中,HCCS环形连接的每跳带宽几乎无损耗,使得Ring AllReduce的流水线能够以接近物理链路极限的速率运行。对于大梯度张量(如百GB级别的模型参数梯度),Ring AllReduce的分块策略能够有效避免单节点的带宽瓶颈,将通信压力分散到环上的所有链路。

从代码实现的角度,HCCL中的Ring AllReduce涉及几个关键的数据结构和函数路径。通信域的初始化建立了节点之间的邻居关系映射,这一步通过HCCL的通信域管理接口完成。算法选择模块会根据通信域的拓扑信息和数据大小,自动决定是否采用Ring算法。以下是HCCL中Ring AllReduce核心执行路径的伪代码展示,展示了reduce-scatter和all-gather两个阶段的流水线结构:

// hccl_algo_ring.cpp - Ring AllReduce核心循环
void RingAllReduce(const RankInfo& self,
                   const RankInfo ring[],
                   const void* send_buf,
                   void* recv_buf,
                   size_t elem_count,
                   HcclDataType dtype,
                   HcclReduceOp op,
                   HcclComm comm) {
    size_t blk = elem_count / rank_num;
    size_t idx = self.id;

    // reduce-scatter阶段:P-1轮归约
    for (size_t step = 0; step < rank_num - 1; ++step) {
        size_t src = (idx - step - 1 + rank_num) % rank_num;
        size_t dst = (idx + 1) % rank_num;
        size_t seg = (idx - step + rank_num) % rank_num;
        // 从上游邻居接收数据到临时缓冲区
        HCOMM_SendRecv(hcomm, send_ptr, blk * sizeof(T),
                       ring[dst], recv_ptr, blk * sizeof(T), ring[src]);
        // 将接收到的数据与本地对应段归约
        for (size_t i = 0; i < blk; ++i) {
            recv_ptr[i] = reduce_op(recv_ptr[i], local_ptr[i]);
        }
    }
    // all-gather阶段:P-1轮广播
    for (size_t step = 0; step < rank_num - 1; ++step) {
        size_t src = (idx - step - 1 + rank_num) % rank_num;
        size_t dst = (idx + 1) % rank_num;
        // 将本地的完整归约结果发送给下游邻居
        HCOMM_Send(hcomm, local_ptr, elem_count / rank_num * sizeof(T), ring[dst]);
        if (step > 0) {
            size_t rcv_seg = (idx - step + rank_num) % rank_num;
            HCOMM_Recv(hcomm, seg_ptr, blk * sizeof(T), ring[src]);
        }
    }
}

这段代码展示的是Ring AllReduce的经典两阶段执行模型,reduce-scatter通过P-1轮环形传递让每个节点获得一个完整分片的归约结果,all-gather再通过P-1轮反向传递将所有分片聚合为完整向量。关键在于每轮通信中所有P个节点同时收发,实现了带宽的完全利用。

Ring AllReduce的优势在昇腾NPU上体现得尤为明显。当使用HCCS链路连接的多块NPU进行通信时,环形拓扑天然适配了HCCS的交换式互联结构。以8卡服务器为例,每块NPU同时通过HCCS与相邻的两块NPU通信,8条HCCS链路全部参与数据传输,总有效带宽接近单链路带宽的8倍。这种带宽线性扩展的特性,使得Ring AllReduce成为昇腾NPU大模型训练场景的首选方案。

然而,Ring AllReduce也存在固有的局限性。每轮通信中所有节点必须同步等待数据到达才能推进,这种同步特性在节点数量较多时会导致流水线停顿的概率增加。此外,Ring AllReduce的通信步骤数为2(P-1),在节点数量P较小时可以忽略不计,但当P扩展到数十甚至上百个节点时,通信延迟的累积会变得显著。更重要的是,Ring AllReduce的reduce-scatter阶段需要每个节点同时作为发送方和接收方,这种对称的双向通信在某些硬件拓扑下可能导致路由冲突。

Recursive Halving-Doubling:短消息场景的延迟优势

Recursive Halving-Doubling算法(简称RHD)是一种基于递归二分思想的AllReduce实现,其设计目标是在消息长度较短时最小化端到端通信延迟。与Ring AllReduce的线性流水线不同,RHD算法通过log2§轮通信完成所有节点的归约,每轮的通信数据量逐轮减半,通信伙伴的数量逐轮翻倍。这种对数级别的通信步骤数,使得RHD在小消息场景下具有显著的延迟优势。

RHD算法的执行分为halving阶段和doubling阶段两个部分。假设有P个节点,编号为0到P-1,数据向量被划分为P个等长块。在halving阶段,节点i将自己的数据发送给节点i XOR 2^k(第k轮的幂次),同时从同一个伙伴节点接收数据并进行归约。经过log2§轮halving后,每个节点持有了所有节点数据的归约结果,但由于每轮只传输数据的一半,所以halving阶段结束后每个节点只持有完整的归约结果的一半。在doubling阶段,节点将结果数据逐次翻倍地发送给伙伴节点并接收对方的数据进行拼接,同样经过log2§轮后,所有节点都获得了完整的归约结果。

RHD算法的通信延迟分析揭示了其核心优势。在每轮通信中,节点传输的数据量为D/2^k(第k轮),通信步骤数为log2§。因此总通信时间为log2§乘以(D/B + L),其中D为数据总量,L为链路延迟。与Ring AllReduce的总通信时间相比,RHD的总通信量约为Ring的一半,但在延迟主导的场景下(消息长度D较小时),log2§步骤远少于2(P-1)步骤,使得RHD的总延迟远低于Ring AllReduce。具体的数值对比可以帮助理解:当P=8时,Ring AllReduce需要14个通信步骤,而RHD仅需要6个通信步骤(3轮halving加3轮doubling)。当消息长度较小使得链路延迟L成为主要因素时,RHD的对数级步骤优势会转化为显著的性能优势。

HCCL中RHD算法的实现需要仔细处理节点编号与通信伙伴的映射关系。在昇腾NPU的实际部署中,节点编号并非总是从0到P-1的连续整数,可能存在复杂的映射关系,这要求算法实现必须正确计算每轮的伙伴节点ID。以下代码展示了RHD算法的核心通信逻辑:

// hccl_algo_rhd.cpp - Recursive Halving-Doubling实现
void RecursiveHalvingDoubling(const RankInfo& self,
                               const void* send_buf,
                               void* recv_buf,
                               size_t elem_count,
                               HcclDataType dtype,
                               HcclReduceOp op,
                               HcclComm comm) {
    size_t n = rank_num;
    size_t cnt = elem_count;
    size_t rank = self.id;
    void* tmp = work_buf;

    // halving阶段:log2(n)轮,每轮传输数据量减半
    for (size_t k = 1; k < n; k <<= 1) {
        size_t partner = rank ^ k;
        size_t offset = (rank / k) * k % (n / k == 1 ? n : n);
        size_t seg_off = (rank & (k - 1)) * cnt;
        size_t seg_cnt = cnt / k;

        if (rank < k) {
            // 低编号节点发送低位数据
            HCOMM_Send(hcomm,
                       (char*)send_buf + seg_off,
                       seg_cnt * type_size,
                       rank_tbl[partner]);
            // 接收高位数据并归约
            HCOMM_Recv(hcomm,
                       tmp,
                       seg_cnt * type_size,
                       rank_tbl[partner]);
            reduce_kernel(tmp, send_buf + seg_off, seg_cnt);
            cnt /= 2;
        } else {
            // 高编号节点发送高位数据
            HCOMM_Send(hcomm,
                       (char*)send_buf + seg_off,
                       seg_cnt * type_size,
                       rank_tbl[partner]);
            HCOMM_Recv(hcomm,
                       tmp,
                       seg_cnt * type_size,
                       rank_tbl[partner]);
            reduce_kernel(tmp, send_buf + seg_off, seg_cnt);
            cnt /= 2;
        }
    }

    // doubling阶段:log2(n)轮,每轮传输数据量翻倍
    for (size_t k = n / 2; k >= 1; k >>= 1) {
        size_t partner = rank ^ k;
        size_t seg_off = (rank / k) * k % (n / k == 1 ? n : n);
        size_t seg_cnt = cnt;

        HCOMM_Send(hcomm,
                   (char*)send_buf + seg_off,
                   seg_cnt * type_size,
                   rank_tbl[partner]);
        HCOMM_Recv(hcomm,
                   tmp,
                   seg_cnt * type_size,
                   rank_tbl[partner]);
        memcpy((char*)send_buf + seg_off, tmp, seg_cnt * type_size);
        cnt *= 2;
    }
}

这段代码的核心在于异或运算XOR用于计算通信伙伴节点ID,这在RHD算法中是标准做法。halving阶段从最低位开始逐位翻转,每次翻倍传输数据量减半;doubling阶段则反向进行,每次减半传输数据量翻倍,最终拼接出完整的归约结果。两阶段各需要log2(n)轮通信,总共2乘log2(n)轮。

在昇腾NPU的硬件环境中,RHD算法对物理链路的利用率与Ring AllReduce有着本质区别。由于RHD在每轮通信中只涉及一半的节点对(每对节点互为通信伙伴),因此单轮的并发度低于Ring AllReduce。但RHD的总传输数据量更小(halving阶段总共传输约D/2 + D/4 + D/8 + …约等于D,doubling阶段同样总共约D),而Ring AllReduce的总传输数据量约为2D。这意味着在小数据量场景下,RHD的总传输量优势足以抵消其并发度不足的劣势。

RHD算法在昇腾NPU上的一个重要约束来自网络拓扑适配。当节点通过RoCE网络跨机互联时,RHD的递归二分模式可能导致某些通信步骤跨越多跳路由。例如在两机各8卡的16卡场景下,如果RoCE交换机的拓扑不完全对称,RHD中的某些节点对可能经过较长的网络路径。HCCL的算法选择器在做出路由决策时,会综合考虑节点间的物理距离、链路类型和跳数,选择最适合当前拓扑的通信算法。

Ascend950的AIV&AICPU通信引擎与图模式

Ascend950是华为推出的面向大规模训练场景的AI处理器集群方案,其通信架构引入了AIV(AI Vector Engine)和AICPU(AI Control Processor)的双引擎设计,为集合通信提供了更为灵活的硬件支持。2026年4月,Ascend950的通信算子正式支持图模式,这一更新对HCCL的整体执行效率产生了深远影响。理解AIV和AICPU在通信中的角色分工,以及图模式对通信流水线的优化机制,是掌握昇腾通信栈演进的必要环节。

AIV是昇腾AI处理器中的向量计算单元,专门负责大规模张量数据的并行运算。在集合通信的场景中,AIV承担了数据归约(Reduce)操作的核心计算任务:当多块NPU的数据汇聚到某一节点时,AIV负责执行逐元素的加法、乘法、最大值等归约运算。AIV的优势在于其SIMD(Single Instruction Multiple Data)向量化能力,可以在一个指令周期内完成多个数据元素的归约计算,这使得软件层面的归约操作几乎不构成性能瓶颈。

AICPU则负责通信的控制平面工作,包括通信原语的调度、内存地址的管理、传输请求的发起和完成事件的处理。在传统模式下,集合通信的操作由主控CPU逐条下发指令,每次通信操作都伴随着控制指令的往返开销。这种模式在通信量较大时影响可控,但在短消息通信或高频率通信场景下,控制开销可能远超实际数据传输的时间。AICPU通过预取通信指令、批量提交传输请求、异步处理完成事件等方式,有效降低了控制平面的开销。

图模式是昇腾通信算子在2026年4月引入的重要特性,其核心思想是将多个通信操作组合为一个计算图统一调度执行。在传统的单算子模式下,每个集合通信操作(如AllReduce)都是独立的执行单元,驱动层需要分别发起和管理每个操作的通信流程。图模式则允许用户将一连串通信操作预先编排为有向无环图(DAG),系统根据数据依赖关系和硬件拓扑自动安排执行顺序,实现跨算子的通信与计算重叠。

图模式对Ring AllReduce和RHD两种算法的影响各有不同。对于Ring AllReduce而言,reduce-scatter和all-gather两个阶段之间存在数据依赖关系,但在图模式下可以将这两个阶段之间的数据传递操作与前一阶段的收尾计算重叠执行,从而减少空闲等待时间。对于RHD算法,图模式的优势体现在多组RHD通信之间的流水线编排上:当一组RHD的doubling阶段与下一组RHD的halving阶段不存在数据依赖时,两者可以并行执行,充分利用硬件的并发通信能力。

HCCL在图模式下的执行路径涉及算子图的构建和调度。以下代码片段展示了HCCL图模式下的通信原语注册过程:

// hccl_graph_api.cpp - 图模式通信原语注册
HcclResult HcclGraphAddAllReduce(HcclGraphHandle graph,
                                 const void* send_buf,
                                 void* recv_buf,
                                 size_t elem_count,
                                 HcclDataType dtype,
                                 HcclReduceOp op,
                                 const char* tag,
                                 HcclComm comm,
                                 HcclGraphNode* node) {
    HcclGraphNodeDesc desc = {};
    desc.op_type = HCCL_OP_ALLREDUCE;
    desc.send_buf = send_buf;
    desc.recv_buf = recv_buf;
    desc.count = elem_count;
    desc.dtype = dtype;
    desc.op = op;
    desc.comm = comm;
    desc.alg_tag = tag;  // 算法标签,影响调度优先级

    // 将原语描述加入计算图
    return GraphAddNode(graph, &desc, node);
}

HcclResult HcclGraphBuild(HcclGraphHandle graph) {
    // 分析节点间的依赖关系,构建DAG
    GraphAnalyzeDeps(graph);
    // 根据拓扑信息进行通信调度优化
    GraphScheduleOptimize(graph, topo_info);
    // 生成底层通信任务列表
    GraphCodegen(graph, &task_list);
    return HCCL_SUCCESS;
}

这段代码展示了图模式的核心API设计:用户通过HcclGraphAddAllReduce将通信原语添加到计算图中,通过tag字段可以指定算法偏好或关联标签,图构建阶段由GraphAnalyzeDeps分析数据依赖、GraphScheduleOptimize根据拓扑优化调度、GraphCodegen生成底层任务序列。三步分离的设计使得图模式具有良好的扩展性和可配置性。

2026年5月,HCCL进一步支持了静态库的链接方式,这意味着用户可以将HCCL的通信能力静态嵌入到训练框架中,省去了运行时动态加载的开销。静态库方式对于容器化部署和嵌入式场景尤为重要,它消除了对动态链接库的依赖,提升了库的加载速度,并使得通信库的版本与训练框架的版本可以独立管理和升级。结合图模式的静态库构建,用户可以获得一个零依赖、高性能、可预测的通信运行时环境。

HCCL与HCOMM的关系:控制面与数据面分离

深入理解HCCL的技术架构,不能不提及HCCL与HCOMM之间的关系。HCCL和HCOMM并非两个独立运作的通信库,而是构成了昇腾集合通信栈的两个层次,分别负责算法策略和底层传输。这种控制面与数据面的分离设计,是HCCL能够在多种硬件拓扑和通信场景下保持高效性和可扩展性的关键所在。

HCCL层位于整个通信栈的上部,主要职责包括集合通信算法的实现与选择、集合操作的端到端流程管理、以及与上层深度学习框架的对接。当用户在PyTorch或MindSpore等框架中调用分布式训练接口时,框架底层通过HCCL的API发起AllReduce等集合通信请求。HCCL层接收请求后,根据当前通信域的拓扑信息、硬件能力描述符和数据大小,通过内部的算法选择器决定使用Ring、Mesh还是RHD等算法。这个决策过程涉及对网络带宽、延迟、节点数量和消息长度的综合评估。

HCOMM层则位于通信栈的底部,负责最底层的点对点数据传输。HCOMM的全称是Huawei Communication基础库,它封装了对HCCS、RoCE和PCIe等物理链路的统一访问接口。在Ring AllReduce中,HCCL计算出的reduce-scatter步骤需要调用HCOMM的点对点Send/Recv接口来完成实际的数据传输;在RHD中,每轮的伙伴节点间通信同样通过HCOMM完成。HCOMM提供了DMA传输能力,允许数据直接从GPU或NPU的设备内存传输到网络,无需经过主机内存中转,这种零拷贝路径对于大块数据的传输效率至关重要。

HCOMM层的关键设计在于传输抽象的统一性。尽管HCCS、RoCE和PCIe这三种物理链路的特性差异巨大——HCCS提供超低延迟的片间互联,RoCE提供跨机的RDMA能力,PCIe提供异构设备间的直连通信——但HCOMM向上提供的编程接口是统一的。这种抽象使得HCCL的算法层无需关心底层链路的差异,只需调用标准的Send/Recv或RMA(Remote Memory Access)原语。HCOMM在内部负责根据目标地址自动选择最合适的物理链路、处理拥塞控制、管理传输完成事件等底层细节。

从架构分层的角度来看,HCCL与HCOMM的关系类似于TCP/IP协议栈中运输层与应用层的关系。HCOMM类似于运输层,提供可靠的数据传输服务,但不关心数据的语义;HCCL类似于应用层,基于运输层服务构建高层的集合通信语义。这种分层设计的一个直接好处是HCCL可以在不修改算法逻辑的情况下,透明地利用HCOMM新支持的物理链路。例如当昇腾NPU引入新的互联技术时,HCCL无需改动即可直接获益,因为所有的链路适配都在HCOMM层完成。

在实际部署中,这种分层架构也带来了可维护性和调试方面的优势。当通信性能出现问题时,工程师可以分别定位是在HCCL层(算法选择不当、集合操作编排不合理)还是HCOMM层(物理链路故障、传输带宽不足)。HCCL提供了详细的通信剖析接口,用户可以获取每次集合通信的时间分解:算法准备时间、数据分片时间、实际传输时间等子项。当传输时间异常偏高时,问题可能出在HCOMM层的链路质量上;当时间主要消耗在算法准备阶段时,则可能需要调整HCCL的算法选择策略。

效率对比

基于前述章节对Ring AllReduce和Recursive Halving-Doubling两种算法在昇腾NPU多卡拓扑上实现差异的系统分析,以及HCCL与HCOMM分层架构的深入理解,可以将两种算法的效率特性从多个维度进行综合对比。以下表格从通信步骤数、总传输量、延迟特性和物理链路适配四个方面,对两种算法在昇腾NPU场景下的行为特征进行概括性描述。

维度 Ring AllReduce Recursive Halving-Doubling
通信步骤数 2(P-1)步,与节点数P呈线性关系 2乘log2§步,与节点数P呈对数关系
总传输量 约2D(每节点发送和接收各约2D/P) 约2D(halving和doubling各约D)
延迟特性 延迟随P线性增长,大消息传输时带宽利用率高 延迟随P对数增长,小消息传输时总延迟低
物理链路适配 适配HCCS高带宽互联,充分利用多链路并发 适配RoCE跨机通信,最小化跨跳路由次数

在实际的大模型训练场景中,算法选择并非一成不变。HCCL的算法选择器会根据通信域的拓扑信息自动进行权衡:当检测到通信发生在同一服务器内的HCCS互联节点之间且数据量较大时,默认选择Ring AllReduce以充分利用HCCS的高带宽和低延迟特性;当检测到跨服务器的RoCE通信且数据量较小时,自动切换到RHD以最小化通信步骤数和端到端延迟。这种自适应的算法选择机制,使得用户无需手动指定算法即可获得接近最优的通信性能。

对于混合链路拓扑(部分节点通过HCCS互联,部分通过RoCE跨机连接)的场景,HCCL支持分层聚合策略:在HCCS域内通过Ring AllReduce完成本地节点的梯度归约,在RoCE域内通过优化的跨机通信原语完成全局归约。这种两级聚合的设计避免了跨HCCS链路传输大量数据带来的带宽浪费,同时利用RoCE的覆盖范围实现全局同步。

结尾

HCCL作为CANN软件栈中面向集合通信的核心组件,通过对Ring AllReduce和Recursive Halving-Doubling两种算法的精心实现,在昇腾NPU上构建了一套自适应的通信策略体系。Ring AllReduce以其对HCCS高带宽链路的天然适配,成为大规模梯度同步场景下的主力算法;Recursive Halving-Doubling以其对数级别的通信步骤数,在短消息和跨机通信场景下提供了无可替代的延迟优势。HCCL与HCOMM的分离架构,则为这套策略体系提供了坚实的底层基础设施,使得上层算法可以专注于通信效率的优化,而无需关心底层链路的复杂性。


仓库URL:https://atomgit.com/cann/hccl

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐