LLM在昇腾NPU面前为何“失语”?AscendCraft用DSL搭建桥梁,让生成内核成功率飙升至98.1%(1/4)
在AI芯片领域,编写一个高性能的算子内核,如同在一台精密、复杂且文档稀疏的机器上精确舞蹈。大语言模型(LLM)在生成CUDA代码时表现尚可,这得益于NVIDIA长期构建的庞大生态:海量的开源代码、详尽的文档和成熟的社区。然而,当目标转向华为昇腾(Ascend)这类神经网络处理器(NPU)时,情况急转直下。最新研究显示,即使是最先进的LLM,直接生成可用的AscendC内核的正确率也不足5%。
为何存在如此巨大的鸿沟?因为NPU的编程模型是“孤岛”式的。它们是领域特定的,有着严格的硬件约束(如内存对齐、复杂的同步机制)、非主流的API以及稀缺的公开示例。对于主要通过“吞噬”公共语料来学习的LLM而言,这无异于要求它用一门几乎没学过的语言撰写博士论文。

面对这一困境,来自南京大学和华为的联合研究团队提出了一个新颖的解决方案——AscendCraft。他们的核心思想并非试图让LLM变得更“聪明”,而是为它搭建一座桥梁。这座桥梁,便是一个精心设计的领域特定语言(DSL)。

通过将核心算法逻辑与硬件复杂性解耦,他们将生成内核的编译成功率提升至98.1%,功能性正确率高达90.4%,甚至让近半数生成的内核性能超越PyTorch。这不仅是代码生成的突破,更是对大模型理解硬件抽象能力的一次深刻探索。
本文将解读AscendCraft这篇论文,探索其如何通过DSL引导和结构化降级,让LLM在陌生的NPU疆域中,成功生成既正确又高效的算子内核。
本文目录
- 一、困境:为什么LLM写不好NPU内核?
- 1.1 硬件架构的“异质性”
- 1.2 编程模型的“复杂性”
- 二、破局:AscendCraft的设计思想与核心方法
- 2.1 第一阶段:DSL生成——为LLM搭建“乐高世界”
- 2.2 第二阶段:降级编译——DSL到AscendC的结构化“翻译”
- 三、实验验证:从“5%的绝望”到“90%的惊喜”
- 3.1 RQ1:正确性——从“几乎不可用”到“基本可靠”
- 3.2 RQ2:性能——不仅仅是“能用”,更是“好用”
- 3.3 RQ3:泛化性——应对“未知”的挑战
- 四、相关工作:站在巨人的肩膀上
- 五、未来展望与总结
一、困境:为什么LLM写不好NPU内核?
要理解AscendCraft的价值,首先需要深刻理解它所面对的挑战。直接让LLM生成NPU内核,就像要求一个从未见过汽车引擎的学徒去修理它,而他手里只有一本关于内燃机原理的大学教材。
1.1 硬件架构的“异质性”
与通用的GPU不同,NPU是为特定计算模式而生的。以华为昇腾(Ascend)NPU为例,其核心计算单元分为三类:
- 标量单元(Scalar Unit):处理控制流和标量数据。
- 向量单元(Vector Unit):执行SIMD(单指令多数据流)操作,如元素级加法和激活函数。
- 立方体单元(Cube Unit):这是NPU的“杀手锏”,专门用于矩阵乘加运算,可以在一个指令周期内完成一个MxK与KxN的矩阵乘法。
此外,它的内存层次结构也非常复杂,包括全局内存(GM)、L1缓冲区、统一缓冲区(UB)和L0缓冲区。开发者需要显式地控制数据在这些层级间的移动。

1.2 编程模型的“复杂性”
AscendC,这个为昇腾NPU设计的编程模型,正是基于这种硬件复杂性而构建的。它是一个基于C++的流水线式编程模型。
- 显式流水线:内核执行被明确划分为
CopyIn(数据搬入)、Compute(计算)和CopyOut(数据搬出)三个阶段。开发者需要手动管理这些阶段的重叠与同步,以最大化硬件利用率。 - 内存管理:
GlobalTensor(全局张量)与LocalTensor(本地张量)的区分,以及内存对齐、访问粒度等硬件约束,要求开发者必须精确管理内存布局。 - 队列与依赖:为协调不同计算单元与内存传输引擎(MTE)的操作,Ascend C 引入了队列(Queue)机制。数据在不同单元间流动时,必须通过“入队/出队”操作来显式管理依赖关系。
对于大语言模型(LLM)而言,要求其一次性生成同时满足上述复杂语义约束的代码,极具挑战。任何细微的错误——例如内存地址未对齐或队列顺序混乱——都可能导致编译失败或运行时错误。这正是直接生成方式成功率极低的核心原因。
二、 破局:AscendCraft 的设计思想与核心方法
面对直接生成所面临的“不可能三角”(复杂性、约束性、稀缺性),AscendCraft 采用了一种分而治之的策略:抽象先行,降级编译。其核心思想是让 LLM 在抽象层完成其擅长的逻辑描述,而将具体实现交由一个结构化的、可控的降级流程完成。
整个流程分为两大阶段,如图3所示:

图3:AscendCraft 框架图。该图展示了 AscendCraft 分两阶段生成 Ascend C 内核的完整流程。第一阶段,LLM 基于类别专属示例生成领域特定语言(DSL),聚焦核心计算与分块策略;第二阶段,通过多轮 LLM 引导的降级转译,逐步将 DSL 转换为 Ascend C 代码,并结合编译反馈进行修正。该框架旨在解决直接生成正确率低的问题,通过结构化拆分与 DSL 抽象约束生成空间,显著提升成功率。
2.1 第一阶段:DSL 生成——为 LLM 构建抽象接口
AscendCraft 的核心创新之一是引入了一套轻量级领域特定语言(DSL)。该 DSL 被设计为 LLM 与复杂硬件细节之间的“缓冲区”,遵循以下设计原则:
- 简洁结构化语法:DSL 语法紧凑,去除了 C++ 的繁复细节,使 LLM 能够专注于算法逻辑(如分块策略和数据流)。
- 适度抽象:DSL 有意隐藏了 Ascend C 中繁琐但非核心的底层细节(例如处理非对齐内存访问的复杂配置),提供更简洁的操作原语。
- 硬件语义建模:DSL 显式地建模了昇腾硬件的关键执行语义,例如通过特定指令显式分配片上缓冲区,并通过明确的代码块划分流水线阶段。

图2:基于昇腾 DSL 编写的 Softmax 内核示例。该示例展示了主机端执行规划与设备端内核计算的分离,以及 CopyIn、Compute、CopyOut 的分阶段执行模式。体现了该 DSL 在抽象底层细节的同时,有效表达分块计算、片上缓冲区使用及核间数据流逻辑的能力。
在生成阶段,LLM 会获得 DSL 规范及针对特定算子类别(如“规约”)的专家示例。这使得 LLM 能够学习高级优化模式,而非陷入具体的底层 API 细节。
2.2 第二阶段:降级编译——从 DSL 到 Ascend C 的结构化转换
这是 AscendCraft 工程化实现的关键。该框架并未尝试让 LLM 一次性完成从 DSL 到 Ascend C 的转换,而是将此过程分解为四个有序的、由 LLM 引导的降级阶段。每个阶段仅专注于一项特定的转换任务,并配有精心设计的提示模板。
这四个阶段依次为:
阶段 1:主机端代码生成
- 任务:将 DSL 中的主机端函数转换为 Ascend C 的宿主代码,包括定义数据结构、计算分块参数及配置内核启动参数。
- 关键:确保主机侧计算的所有参数能正确传递给内核。
阶段 2:内核初始化代码生成
- 任务:生成内核初始化逻辑,包括参数赋值、计算核心数据偏移量以及初始化片上内存资源。
- 关键映射:将 DSL 中的缓冲区分配指令映射为 Ascend C 中的传输队列(
TQue)或临时缓冲区(TBuf)。
阶段 3:内核计算代码生成(核心)
- 任务:将 DSL 内核中的
copyin、compute、copyout代码块,分别翻译为 Ascend C 中对应的函数。 - 关键映射:
copyin:将数据从全局内存搬运至片上队列。compute:从队列中取出数据,并将 DSL 计算原语映射为 Ascend C 的向量/矩阵运算 API。copyout:将结果从队列搬回全局内存。
- 结构约束:强制划分为三个独立函数,从结构上避免了数据搬运与计算指令的错误交织。
阶段 4(可选):对齐与填充优化
- 任务:处理硬件对齐要求。当分块大小不满足对齐约束时,将普通数据拷贝操作替换为支持填充的
DataCopyPad,并自动计算填充参数。
每个阶段完成后,生成的代码会尝试编译。若编译失败,错误信息将反馈给 LLM 用于修正代码,然后进入下一阶段。这种带反馈的渐进式降级机制,显著提升了生成过程的鲁棒性。
三、 实验验证:效果评估
AscendCraft 在 MultiKernelBench 基准测试上进行了全面评估。该基准包含 52 个不同类别的算子内核,其数据规模经过设计,使内核执行时间足够长,以排除启动开销的干扰,确保性能比较的有效性。
3.1 RQ1:生成正确性——从极低到实用化的提升
最显著的改进体现在编译成功率和功能正确率上。
3.2 RQ2:性能评估——从“能用”到“好用”
在确保功能正确的基础上,内核性能是衡量其实际应用价值的关键。表2展示了AscendCraft生成的AscendC内核在不同性能阈值下,与PyTorch Eager模式参考实现的对比结果。

表 2:各算子类别下的性能评估。AscendCraft生成的AscendC内核与PyTorch Eager模式的性能对比。Fast0.8表示性能达到PyTorch基准的80%,Fast1.0表示性能持平或超越PyTorch。
评估数据显示:
* 82.7% 的生成内核达到了PyTorch基准性能的 20% 以上。这表明绝大多数生成代码已具备基本的硬件优化能力,例如向量化或多核并行,脱离了“玩具”代码的范畴。
* 57.7% 的生成内核达到了PyTorch基准性能的 80% 以上。这些内核已具备相当程度的优化水平,能够满足实际应用场景的性能需求。
* 46.2% 的生成内核性能 持平或超越了PyTorch基准。这一结果证明,通过DSL引导的生成方案能够有效学习并传递硬件优化策略,从而产出高度优化的代码。
从算子类别来看,激活、损失、优化器等类别的算子性能表现优异。而归约、池化等类别由于涉及更复杂的底层指令优化,生成的代码性能尚有提升空间。总体而言,结果表明AscendCraft能够在无需手动调优的情况下,为多数算子生成高性能内核,同时为复杂算子的进一步优化指明了方向。
3.3 RQ3:泛化性测试——应对“未知”算子
为了验证方法对全新、未见过的算子的泛化能力,研究团队将AscendCraft应用于一个新型神经网络结构——mHC(Manifold-Constrained Hyper-Connections)的核心算子生成。该模型结构不在训练基准中,因此测试完全基于模型的泛化能力。
测试结果令人振奋:AscendCraft在单次生成中,即为mHC的两个核心算子生成了功能完全正确的AscendC内核,其性能分别是PyTorch Eager模式的 6.6倍 和 3.0倍。
更进一步的案例显示,由于生成的代码结构清晰、可读性强,一位经验丰富的开发人员以这些代码为起点,在LLM的辅助下,仅用一天时间就将两个算子的性能进一步优化至PyTorch基准的 15.9倍 和 7.2倍。
这一案例充分展现了AscendCraft的实用价值:它不仅能够自动生成高质量、可用的基础内核,更能为后续的专家级深度优化提供一个坚实且高效的起点,显著降低开发门槛与周期。
四、 相关工作
AscendCraft的研究建立在多个领域的前沿工作基础上,并针对NPU编程的独特挑战进行了创新性融合。
- LLM驱动的代码生成:诸如KernelBench、Astra等工作探索了利用LLM生成GPU(如CUDA)内核。AscendCraft的独特性在于,它将这一方向拓展至编程约束更严格、生态工具更少的NPU领域。
- GPU内核自动生成与DSL:以Triton为代表的DSL通过高级抽象简化了GPU内核开发。AscendCraft的设计思想受此启发,但其DSL专门为NPU独特的执行语义(如显式流水线、内存层级)量身定制。
- 中间表示与降级:传统编译器通过多层中间表示将高级语言逐步转换为机器码。AscendCraft创造性地将LLM作为“智能降级器”,融入这一经典流程,负责将高层次的DSL逐步、可靠地翻译成低层次的AscendC代码。
AscendCraft的核心创新在于,它通过设计一个承上启下的DSL,将复杂的NPU内核生成问题进行了有效拆分:LLM专注于高层算法逻辑表达,而结构化的编译流程则负责处理底层的硬件约束与优化,使两者各司其职,从而在极具挑战性的领域取得了突破。
五、 未来展望与总结
AscendCraft的工作展示了DSL结合结构化生成在NPU编程领域的巨大潜力,同时也指出了未来的探索方向:
- 性能瓶颈突破:针对归约、规范化等算子性能尚有差距的问题,未来可在DSL中引入更细粒度的硬件原语描述,或在降级阶段集成自动化的性能调优策略。
- DSL表达力扩展:当前DSL主要覆盖单算子。未来可扩展其表达范围,以支持更复杂的融合算子(如Attention)的自动生成与优化。
- 构建生成-优化闭环:可探索构建自动化闭环系统,使LLM能够根据性能剖析(Profiling)反馈,自动迭代优化DSL描述或生成的底层代码。
总结
AscendCraft展示了一种通过系统设计弥补大模型在特定领域能力短板的优雅路径。它并非试图让LLM通晓一切,而是为其构建了一个得力的“工作台”——一个既能抽象核心计算意图、又能屏蔽底层硬件复杂性的领域特定语言(DSL)。
通过多阶段、结构化的降级流程,该方法成功地将LLM的算法能力安全、可靠地转化为能在昇腾NPU上高效执行的代码。这项工作的启示在于,面对未来异构计算硬件多样化的趋势,“DSL + 结构化代码生成” 可能成为连接高级算法与底层硬件的有效“翻译器”。AscendCraft的实践,为“如何让AI高效驾驭AI硬件”这一关键问题,提供了一个极具前景的解决方案。
- SGEMM-cube:昇腾910A使用FP16 Cube单元模拟FP32 GEMM,实现了22位尾数精度恢复,性能达到理论峰值的77%。
- NPUEval:评估AMD硬件上的LLM向量化NPU Kernel——涵盖102个机器学习算子、提供编译器反馈,并实现超过50%的向量化峰值效率。
- Act:首个从张量加速器ISA描述自动生成编译器后端的工具,其性能超越手工优化库1.77倍,并能完成311ms超大内核的编译。
关注“鲸栖”小程序,掌握最新AI资讯
本文来自网络搜集,不代表鲸林向海立场,如有侵权,联系删除。转载请注明出处:http://www.itsolotime.com/archives/26913


