QiMeng-Xpiler: Transcompiling Tensor Programs for Deep Learning Systems with a Neural-Symbolic Approach
TL;DR 精炼摘要
QiMeng-Xpiler结合大语言模型与符号程序合成,实现深度学习系统张量程序的自动跨平台转编译。通过多阶段AI辅助编译和符号修复,降低人工成本,提高代码正确性和性能,推动“一次编写,到处运行”目标。
摘要
Heterogeneous deep learning systems (DLS) such as GPUs and ASICs have been widely deployed in industrial data centers, which requires to develop multiple low-level tensor programs for different platforms. An attractive solution to relieve the programming burden is to transcompile the legacy code of one platform to others. However, current transcompilation techniques struggle with either tremendous manual efforts or functional incorrectness, rendering "Write Once, Run Anywhere" of tensor programs an open question. We propose a novel transcompiler, i.e., QiMeng-Xpiler, for automatically translating tensor programs across DLS via both large language models (LLMs) and symbolic program synthesis, i.e., neural-symbolic synthesis. The key insight is leveraging the powerful code generation ability of LLM to make costly search-based symbolic synthesis computationally tractable. Concretely, we propose multiple LLM-assisted compilation passes via pre-defined meta-prompts for program transformation. During each program transformation, efficient symbolic program synthesis is employed to repair incorrect code snippets with a limited scale. To attain high performance, we propose a hierarchical auto-tuning approach to systematically explore both the parameters and sequences of transformation passes. Experiments on 4 DLS with distinct programming interfaces, i.e., Intel DL Boost with VNNI, NVIDIA GPU with CUDA, AMD MI with HIP, and Cambricon MLU with BANG, demonstrate that QiMeng-Xpiler correctly translates different tensor programs at the accuracy of 95% on average, and the performance of translated programs achieves up to 2.0x over vendor-provided manually-optimized libraries. As a result, the programming productivity of DLS is improved by up to 96.0x via transcompiling legacy tensor programs.
思维导图
论文精读
中文精读
1. 论文基本信息
1.1. 标题
QiMeng-Xpiler: Transcompiling Tensor Programs for Deep Learning Systems with a Neural-Symbolic Approach (QiMeng-Xpiler:一种基于神经-符号方法的深度学习系统张量程序转编译)
1.2. 作者与机构
作者: Shouyang Dong, Yuanbo Wen, Jun Bi, Di Huang, Jiaming Guo, Jianxing Xu, Ruibai Xu, Xinkai Song, Yifan Hao, Ling Li, Xuehai Zhou, Tianshi Chen, Qi Guo, Yunji Chen 机构:
- 中国科学技术大学 (University of Science and Technology of China)
- 寒武纪技术 (Cambricon Technologies)
- 中国科学院计算技术研究所处理器国家重点实验室 (SKL of Processors, Institute of Computing Technology, Chinese Academy of Sciences)
- 中国科学院软件研究所 (Institute of Software, Chinese Academy of Sciences)
1.3. 发表信息
- 发布时间 (UTC): 2025-05-04T15:14:27.000Z
- 原文链接:
https://arxiv.org/abs/2505.02146 - PDF 链接:
https://arxiv.org/pdf/2505.02146v1.pdf - 发布状态: 预印本 (Preprint),发表在 arXiv 上。
1.4. 摘要概括
随着图形处理器 (GPU) 和专用集成电路 (ASIC) 等异构深度学习系统 (Deep Learning Systems, DLS) 在工业数据中心广泛部署,为不同平台开发低级张量程序 (Tensor Programs) 变得复杂且耗时。转编译 (Transcompilation),即将现有代码从一个平台自动转换到另一个平台,是减轻编程负担的有吸引力的解决方案。然而,当前转编译技术面临巨大的手动工作量或功能不正确的问题,使得张量程序的“一次编写,到处运行 (Write Once, Run Anywhere)”仍未实现。
本文提出了一种新颖的转编译器 QiMeng-Xpiler,它通过结合大语言模型 (Large Language Models, LLMs) 和符号程序合成 (Symbolic Program Synthesis),即神经-符号合成 (Neural-Symbolic Synthesis),自动实现 DLS 间的张量程序翻译。其核心思想是利用 LLM 强大的代码生成能力,使得成本高昂的基于搜索的符号合成在计算上变得可行。具体而言,QiMeng-Xpiler 提出了多个人工智能辅助的编译阶段,通过预定义的元提示 (meta-prompts) 进行程序转换。在每个程序转换过程中,采用高效的符号程序合成来修复有限规模的不正确代码片段。为了实现高性能,本文提出了一种分层自动调优 (hierarchical auto-tuning) 方法,系统地探索转换阶段的参数和顺序。
实验在四种具有不同编程接口的 DLS 上进行:使用 VNNI 的 Intel DL Boost、使用 CUDA 的 NVIDIA GPU、使用 HIP 的 AMD MI 和使用 BANG 的 Cambricon MLU。结果表明,QiMeng-Xpiler 平均以 95% 的准确率正确翻译了不同的张量程序,翻译后的程序性能比供应商提供的手动优化库高出 2.0 倍。因此,通过转编译现有张量程序,DLS 的编程生产力提高了 96.0 倍。
2. 整体概括
2.1. 研究背景与动机
随着神经网络工作负载对计算需求的不断增长,各种深度学习系统 (DLS),如 NVIDIA GPU、Google TPU、GraphCore IPU 和 Cambricon MLU,已广泛部署在云和互联网服务公司的数据中心。为了充分利用这些多样化的 DLS,需要为不同平台开发多种高性能的张量程序 (Tensor Programs)。这些低级张量程序是深度学习中张量算子的实现,其开发极具挑战性,因为 DLS 架构复杂且编程模型各异。理想情况下,“一次编写,到处运行 (Write Once, Run Anywhere)”能够极大缓解在异构 DLS 环境中的编程问题。
论文试图解决的核心问题是:如何自动、准确且高效地将一个 DLS 平台的低级张量程序转编译到另一个 DLS 平台,以实现代码复用和编程效率提升?
这个问题在当前领域的重要性体现在:
-
编程负担重: 为每种 DLS 从头开发和优化张量程序需要大量专业知识和人力。
-
性能瓶颈: 手动优化的程序往往能达到最佳性能,但耗时耗力;自动转换工具若性能不佳则失去意义。
-
异构性挑战: 不同 DLS 之间在并行模型(如
SIMTvs.SIMD)、内存层次结构、专用指令集等方面存在巨大差异,使得代码转换极其复杂。现有研究存在哪些具体的挑战或空白(Gap):
-
规则型转编译 (Rule-based transcompilation):需要专家手动定义转换规则,面对巨大的架构差异和复杂编程模型时,规则定义工作量巨大且难以维护,不具可扩展性。例如,将
CUDA代码转换为FPGA的FCUDA需要定义大量数据通信、计算优化和并行映射规则。 -
符号合成方法 (Symbolic synthesis approaches):虽然能保证语义正确性,但通常依赖于成本高昂的可满足性模理论 (Satisfiability Modulo Theories, SMT) 求解器,搜索空间巨大,难以扩展到大型通用程序。此外,它们难以处理不同平台间的并行语义差异,且需要大量手动工作来精确指定输入约束。
-
数据驱动方法 (Data-driven approaches):通常利用大型语言模型 (LLMs) 进行代码生成。尽管在高级语言(如 C++、Java、Python)之间翻译表现出色,但在张量程序这种专业领域,由于训练数据稀缺,
LLM难以完全保留语义,翻译准确率低(例如,GPT-4 仅为 29.6%),仍需大量手动修正。这些挑战共同导致了“一次编写,到处运行”的张量程序仍是一个悬而未决的问题。
这篇论文的切入点或创新思路是:
论文提出了一种神经-符号 (neural-symbolic) 方法,将 LLM 的灵活性与符号合成 (symbolic synthesis) 的严谨性相结合。核心思路是利用 LLM 强大的代码生成能力来提供高层级的程序骨架和转换方向,从而大幅缩小搜索空间,使原本计算成本高昂的基于搜索的符号合成变得可行,主要用于修复 LLM 生成的低级细节错误。这种协同方法旨在克服现有技术的局限性,实现张量程序在 DLS 间的自动、正确且高性能的转编译。
2.2. 核心贡献/主要发现
论文最主要的贡献可以总结为以下几点:
-
提出神经-符号程序合成方法: 首次提出将 LLM 的代码生成能力与 SMT 求解器的精确修复能力相结合,实现张量程序在 DLS 间的自动转编译。
LLM用于生成高层级的程序草图和进行转换,而小规模的SMT用于修复不正确的代码片段,保证功能正确性。 -
设计多阶段 LLM 辅助编译流程: 将复杂的转编译任务分解为一系列
LLM辅助的转换阶段(如顺序化/并行化、内存转换、张量化/反张量化),每个阶段都通过预定义的元提示 (meta-prompts) 来指导LLM进行程序转换,显著提高了翻译准确性。 -
引入分层性能自动调优机制: 为了最大化翻译后程序的性能,提出了一个分层自动调优方法。包括:
- 传递内自动调优 (Intra-Pass Auto-Tuning):通过穷举搜索探索各个转换阶段的参数(例如,平铺大小 (tiling sizes)),以优化程序性能。
- 传递间自动调优 (Inter-Pass Auto-Tuning):利用 蒙特卡洛树搜索 (Monte Carlo Tree Search, MCTS) 来系统地探索转换阶段的最佳序列,以达到最佳性能。
-
广泛的异构 DLS 实验验证: 在 Intel DL Boost (
VNNI)、NVIDIA GPU (CUDA)、AMD MI (HIP) 和 Cambricon MLU (BANG) 四种具有不同编程模型的 DLS 上进行了广泛实验,验证了QiMeng-Xpiler的通用性和有效性。论文得出的关键结论或发现:
-
高翻译准确率:
QiMeng-Xpiler平均能以 95% 的准确率正确翻译不同张量程序,在大多数情况下编译和计算准确率接近 100%。这显著优于纯LLM或规则型方法。 -
优异的执行性能: 翻译后的程序在性能上最高可达供应商提供的手动优化库的 2.0 倍,平均性能也能达到 。这表明
QiMeng-Xpiler不仅能生成正确代码,还能生成高性能代码。 -
显著提升编程生产力: 通过自动转编译现有张量程序,
QiMeng-Xpiler将 DLS 的编程生产力提高了高达 96.0 倍(例如在 Cambricon MLU 上)。 -
神经-符号方法的必要性: 消融实验表明,缺少
SMT求解器(即纯LLM辅助)无法达到接近 100% 的准确率,强调了神经-符号范式在确保转编译正确性方面的关键作用。这些发现解决了在异构 DLS 环境中高效开发和部署张量程序面临的巨大编程负担和兼容性挑战。
3. 预备知识与相关工作
3.1. 基础概念
为了更好地理解 QiMeng-Xpiler 的工作原理,需要了解以下核心概念:
- 深度学习系统 (Deep Learning Systems, DLS): 指为加速深度学习工作负载而设计的专用硬件平台,如 NVIDIA GPU、AMD MI、Google TPU、Graphcore IPU 和 Cambricon MLU。这些系统通常具有高度并行、复杂内存层次和定制指令集等特点。
- 张量程序 (Tensor Programs): 指用于实现深度学习中基本张量运算(如矩阵乘法、卷积、激活函数等)的低级代码。这些程序通常直接利用硬件的并行能力和内存结构进行高度优化,例如
CUDA C、HIP、BANG C或带有VNNI扩展的 C 语言代码。 - 转编译 (Transcompilation / Source-to-Source Compilation): 是一种将用一种高级编程语言编写的源代码自动转换为另一种高级编程语言(或同一语言的不同方言)的过程。其目标是实现代码的复用,减少为不同平台重写代码的工作量。
- 神经-符号方法 (Neural-Symbolic Approach): 这是一种结合了神经网络(如
LLM)和符号人工智能(如逻辑推理、程序合成)优势的方法。在QiMeng-Xpiler中,LLM负责高层次、灵活的代码生成,而符号合成负责低层次、精确的代码验证和修复。 - 大语言模型 (Large Language Models, LLMs): 基于大规模文本数据训练的深度神经网络模型,能够理解、生成和处理人类语言。在本文中,
LLM主要用于代码生成、理解程序语义和进行程序转换。 - 符号程序合成 (Symbolic Program Synthesis): 一种通过搜索预定义规则或利用逻辑求解器(如
SMT求解器)来自动生成满足给定规范(例如输入/输出示例或语义约束)的程序的方法。其主要优点是能保证生成程序的语义正确性,但通常面临巨大的搜索空间和计算成本。 - 可满足性模理论 (Satisfiability Modulo Theories, SMT) 求解器: 是一种将命题逻辑和一阶逻辑的决策过程扩展到特定理论(如整数算术、数组理论、位向量)的工具。在程序合成中,
SMT求解器可以用来验证程序属性、寻找满足约束的变量值或修复代码中的错误。 - 编程模型 (Programming Models): 指在特定硬件上编写程序所遵循的范式和接口。
- SIMT (Single Instruction, Multiple Threads): 如
CUDA C中的 NVIDIA GPU,多个线程(threads)并行执行同一指令,但每个线程可以有自己的数据和执行路径。 - SIMD (Single Instruction, Multiple Data): 如 Cambricon MLU 中的
BANG C,一个指令同时处理多个数据元素。 - VNNI (Vector Neural Network Instructions): Intel CPU 上的指令集扩展,旨在加速深度学习工作负载,特别是向量乘加运算。
- SIMT (Single Instruction, Multiple Threads): 如
- 内存层次结构 (Memory Hierarchy): DLS 通常具有多级内存,从速度最快、容量最小的寄存器(
registers),到较快但容量有限的共享内存(shared memory/__shared__/NRAM/WRAM),再到速度最慢但容量最大的全局内存(global memory/__global__/__mlu_device__)。高效的内存管理对 DLS 性能至关重要。 - 专用指令集/内联函数 (Specialized Instruction Sets/Intrinsics): DLS 通常包含针对深度学习运算(如矩阵乘法、卷积)优化的定制指令。程序员可以通过内联函数(
intrinsics)直接调用这些指令,以获得最佳性能。例如wmma::mma_sync(NVIDIATensor Core)、__builtin_amdgcn_mfma_f32_16x16x4f32(AMDMatrix Core)、__bang_mlp(Cambricon MLU)。
3.2. 前人工作
文章将现有的转编译方法分为三类,并分析了它们在 DLS 张量程序转编译中的局限性:
-
规则型方法 (Rule-based approaches):
- 原理: 这类方法要求专家手动定义一系列转换规则(通常应用于抽象语法树 (Abstract Syntax Tree, AST)),然后通过模式匹配来解析输入源代码并进行转换。
- 例子:
FCUDA(CUDA到FPGA转换器),C2Rust( 到Rust),CxGo( 到Go),HIPIFY(CUDA到HIP),PPCG(利用多面体模型进行 到CUDA的自动并行化)。 - 局限性:
- 人工工作量巨大: 面对不同平台间巨大的架构差异和编程模型,手动定义高效、全面的转换规则几乎不可行。
- 可扩展性差: 规则通常针对特定场景,难以推广到通用或复杂的张量程序。
- 鲁棒性不足: 难以处理不规则的代码结构,限制了其通用性。
-
符号合成方法 (Symbolic synthesis approaches):
- 原理: 这类方法通过搜索预定义领域特定语言 (Domain-Specific Language, DSL) 或利用 SMT 求解器从输入/输出示例或形式化语义规范生成语义等效的目标代码。
- 例子:
C2TACO( 张量代码到TACO DSL),MetaLift和Tenspiler(通过统一中间表示IR进行合成)。 - 局限性:
- 可扩展性有限: 依赖于成本高昂的基于搜索的
SMT求解器,难以扩展到大型通用程序。 - 难以处理并行语义: 难以处理不同平台间复杂的并行语义差异(如
CUDA C的SIMT与BANG C的SIMD)。 - 手动工作量: 需要大量手动工作来精确指定
SMT求解器的输入约束或目标语言的语义。 - 优化能力不足: 主要处理计算指令,难以满足对分层存储和并行能力的优化要求。
- 可扩展性有限: 依赖于成本高昂的基于搜索的
-
数据驱动方法 (Data-driven approaches):
- 原理: 这类方法通常训练神经网络(特别是
LLMs)从大量源代码中学习代码生成模式,实现代码翻译。 - 例子:
TransCoder(C++、Java、Python 间翻译),StarCoder,GPT-4,OpenAI-o1。 - 局限性:
- 功能不正确: 即使是预训练的
LLMs,在张量程序这种专业领域,也难以完全保留语义,翻译准确率低(例如,GPT-4 仅为 29.6%),需要大量手动修正。 - 缺乏语义理解: 缺乏对程序深层语义的理解,生成的代码可能不完整或不正确。
- 领域特异性数据稀缺: 在特定领域或复杂问题上表现不佳,因为高质量和多样化的训练数据难以获取。
- 功能不正确: 即使是预训练的
- 原理: 这类方法通常训练神经网络(特别是
3.3. 技术演进与差异化分析
技术演进: DLS 张量程序转编译领域的技术演进大致遵循了从“手动规则”到“自动化搜索”,再到“大数据驱动”的路径。
- 早期: 主要依赖专家知识,通过手工编写规则(如
AST转换)进行代码转换。这种方式直观但维护成本高、可扩展性差。 - 中期: 引入了程序合成技术,利用形式化方法(如
SMT求解器)来保证语义正确性。但这受限于搜索空间的巨大性和计算资源的限制,难以应用于大规模、复杂的实际场景。 - 近期: 随着机器学习和深度学习的发展,特别是
LLMs的兴起,数据驱动的方法成为主流,通过学习大量代码库来自动生成和翻译代码。这种方法在通用编程语言转换上表现出色,但在专业性强、数据稀缺的 DLS 张量程序领域遇到了瓶颈,尤其是在功能正确性上难以保证。
差异化分析:
QiMeng-Xpiler 的核心创新在于融合了数据驱动(LLM)和符号合成(SMT)的优势,形成了神经-符号 (neural-symbolic) 方法,以解决现有方法的痛点,具体差异化体现在:
- LLM 的灵活性 + SMT 的严谨性:
- 现有 LLM 局限: 纯
LLM在 DLS 张量程序翻译中准确率低,尤其是在低级细节(如循环边界、索引、特定指令参数)上容易出错。 - 现有符号合成局限: 纯符号合成因搜索空间过大而无法处理大型通用程序。
- QiMeng-Xpiler 创新:
LLM负责生成高层次、大致正确的程序骨架,显著缩小搜索空间。随后,SMT求解器在小规模、局部范围内进行精确修复,确保低级细节的正确性。这使得LLM的灵活性得以利用,同时SMT的严谨性得到保障,解决了LLM准确率不足和SMT扩展性差的问题。
- 现有 LLM 局限: 纯
- 多阶段转换与元提示:
- 现有 LLM 局限: 单次
LLM调用难以处理复杂的跨平台转换。 - QiMeng-Xpiler 创新: 将转编译分解为一系列
LLM辅助的转换阶段(如并行化、内存转换、张量化),每个阶段通过精心设计的元提示 (meta-prompts) 引导LLM进行局部转换,并结合程序注释和编程手册检索,提高了复杂转换的准确性。
- 现有 LLM 局限: 单次
- 性能优化与自动调优:
- 现有方法局限: 多数方法侧重功能正确性,对性能优化考虑不足,或性能优化需要大量手动工作。
- QiMeng-Xpiler 创新: 引入了分层自动调优 (hierarchical auto-tuning) 机制,通过传递内调优 (Intra-Pass Auto-Tuning) (穷举搜索参数) 和传递间调优 (Inter-Pass Auto-Tuning) (基于
MCTS搜索转换序列),系统地探索和优化生成代码的性能,使其能够超越手动优化库。
- DLS 异构性处理:
-
现有方法局限: 难以有效处理 DLS 之间巨大的架构差异(并行语义、内存层次、专用指令)。
-
QiMeng-Xpiler 创新: 通过专门设计的转换阶段(顺序化/并行化、内存转换、张量化/反张量化)和程序注释过程,系统地弥合了 DLS 间的语义鸿沟,使其能够覆盖多种异构 DLS。
通过上述差异化策略,
QiMeng-Xpiler克服了传统规则型、符号合成和数据驱动方法在 DLS 张量程序转编译中面临的“巨大人工投入、有限可扩展性或功能不正确”的挑战,为实现“一次编写,到处运行”提供了切实可行的解决方案。
-
4. 方法论
4.1. 方法原理
QiMeng-Xpiler 的核心思想是利用大语言模型 (LLM) 的强大代码生成能力来为深度学习系统 (DLS) 间的张量程序转编译提供高层次的指导和初步转换,同时结合符号程序合成 (Symbolic Program Synthesis) 的严谨性来确保低层次代码片段的功能正确性。这种神经-符号合成 (Neural-Symbolic Synthesis) 方法旨在克服传统 LLM 准确率不足和传统符号合成可扩展性差的问题。
其背后的理论基础或直觉是:
- LLM 擅长模式识别和高层次语义理解:
LLM经过海量代码训练,能够理解编程语言的结构、模式和高层次意图,并基于这些知识生成代码草图。虽然在细节上可能出错,但其在构建整体逻辑框架和进行语义转换方面表现出色。 - 符号合成擅长形式化验证和精确修复:
SMT求解器等符号合成工具能够基于形式化约束进行逻辑推理和验证,确保代码片段在数学和语义上的完全正确性。但其计算成本高,搜索空间巨大,不适合处理整个复杂程序。 - 协同互补: 将
LLM作为“创意生成者”来提供初始的、大致正确的解决方案,然后将符号合成作为“精确修正者”来局部验证和修复LLM可能产生的细节错误。这样既能利用LLM的效率和广度,又能通过符号合成保证最终代码的正确性,同时将符号合成的计算量限制在可控的小规模范围内。
4.2. 神经-符号程序合成 (Neural-Symbolic Program Synthesis)
QiMeng-Xpiler 将传统的程序转换过程分解为多个转换阶段,每个阶段都包含一个完整的神经-符号程序合成工作流,包括程序注释、基于元提示的转换、错误定位和基于 SMT 的代码修复。
4.2.1. 程序注释 (Program Annotation)
目的: 为特定转换阶段标记代码块的语义,辅助后续的程序转换过程。它通过识别计算操作来抽象出平台无关的功能语义,并通过检索编程手册来获取目标平台的特定实现细节,从而帮助 LLM 生成更准确的程序。
方法步骤与流程: Algorithm 1: Program Annotation Algorithm
Input : A source program P
Output : An annotated program A
Given: LLM, BM25 search engine (SE), programming manual M
1: // Annotate program with identified computation
2: A_semantics <- LLM(P)
3: L <- TraverseComputation(A_semantics) // Get the list of computation information
4: for n in L do
5: // Retrieve the programming manual of each computation
6: Retrieved_Info <- SE.retrieve(n, M) // BM25 search engine retrieves related info from M
7: // Annotate program with memory spaces or tensor intrinsics
8: A_ref <- LLM(A_semantics, Retrieved_Info) // LLM annotates A_semantics with references
9: end for
10: return A
-
语义注释 (Semantics Annotation) (Algorithm 1, Lines 2-3):
LLM接收源程序 作为输入。LLM识别 中的计算操作,并对其进行抽象的语义标记(例如,operation(matmul))。这一步将程序从平台特定的细节中抽象出来,聚焦于功能语义。- 是包含所有识别出的计算操作信息的列表。
-
引用注释 (Reference Annotation) (Algorithm 1, Lines 4-9):
- 对于 中识别出的每个计算操作 :
- 使用 BM25 搜索引擎 (BM25 search engine, SE) 在目标平台的编程手册 (programming manual, M) 中检索与 相关的平台特定信息。
BM25是一种基于词频-逆文档频率 (TF-IDF) 的信息检索算法,用于评估文档与查询之间的相关性。 LLM结合语义注释后的程序 和检索到的平台特定信息 (例如,特定指令的语法、内存约束、计算形状约束)对程序进行进一步注释。这些注释可能包括内存空间(如NRAM,WRAM)或张量内联函数(如intrinsic(__bang_mlp(input[Nram, Wram], output[Nram])))。
- 使用 BM25 搜索引擎 (BM25 search engine, SE) 在目标平台的编程手册 (programming manual, M) 中检索与 相关的平台特定信息。
- 最终输出带有完整注释的程序 。
- 对于 中识别出的每个计算操作 :
4.2.2. 基于元提示的转换 (Meta-Prompts based Transformation)
目的: 使用 LLM 将源程序转换为目标程序,生成一个大致正确的程序骨架。元提示 (Meta-prompt) 是一个高级的提示模板,可根据程序注释的结果和目标平台的特性进行调整。
方法步骤与流程:
-
元提示构成: 每个转换阶段都有其专属的元提示,主要包含三个部分:
- 平台无关描述 (Platform-agnostic description): 描述程序的功能和在实现过程中必须考虑的详细约束。例如,对于张量化 (
Tensorize) 阶段,这部分会提及SIMD的张量化功能,以及在深度学习框架和通用线性代数核心中的应用场景。这部分提示在不同平台之间保持不变。 - 平台特定示例 (Platform-specific examples): 虽然不同平台上的操作符功能语义相似,但其实现细节(如函数名、参数)可能差异很大。为了解决这个问题,
LLM会利用程序注释得到的平台特定信息(从目标平台编程手册中检索),搜索与源程序功能相关的平台特定实现示例。这些示例被整合到元提示中,以指导LLM生成目标程序。例如,将matmul从 转换为BANGC的示例。 - 调优旋钮 (Tuning knobs): 对于像循环拆分 (Loop Split) 和循环重排 (Loop Reorder) 这样的转换阶段,可能需要更多与目标平台相关的约束信息。这些信息作为可选的“调优旋钮”包含在元提示中。例如,循环拆分需要确定目标平台的循环拆分对齐大小,并将其作为最小单元扩展到相应的搜索空间中,供后续的自动调优使用。
- 平台无关描述 (Platform-agnostic description): 描述程序的功能和在实现过程中必须考虑的详细约束。例如,对于张量化 (
-
LLM 生成代码:
LLM结合源程序和调整后的元提示,生成转换后的代码。此时生成的代码通常具有正确的程序骨架,但在具体数值(如循环边界、索引计算)上可能存在错误。
图4:神经符号程序合成在张量化案例中的示例
下图(原文 Figure 4)展示了神经符号程序合成在一个张量化 (Tensorize) 案例中的应用流程:
该图像是论文中的示意图,展示了神经符号程序合成在张量化案例中的应用流程,包括程序注释、基于元提示的程序转换,以及基于SMT的错误定位与修复步骤。
- 程序注释 (Program Annotation):
- 原始
CUDA C代码中,LLM识别出for循环中的计算操作。 BM25搜索引擎在BANG C编程手册中检索matmul相关的__bang_mlp内联函数信息。LLM根据检索信息注释原始代码,例如标记GEMM操作及其参数、内存分配等。
- 原始
- 基于元提示的转换 (Meta-Prompt Based Transformation):
LLM接收包含平台无关描述(张量化的功能、SIMD特性)、平台特定示例(CUDA C到BANG Cmatmul的转换示例)以及调优旋钮(如循环拆分大小)的元提示。LLM生成一个初步的BANG C代码片段,将GEMM操作转换为__bang_mlp内联函数的调用,并包含必要的内存转换和并行结构。
- 单元测试 (Unit Test): 生成的
BANG C代码通过单元测试进行验证。如果测试失败(如图中Result Check Failed),则需要进行修复。 - 错误定位 (Bug Localization): 识别出错误的代码片段,例如图中
__bang_mlp函数的参数len可能不正确。 - 基于 SMT 的代码修复 (SMT-Based Code Repairing):
SMT求解器根据BANG C编程手册中__bang_mlp的约束(例如,len必须是 1024)和原始CUDA C代码中的语义,修复len的值。
4.2.3. 错误定位 (Bug Localization)
目的: 当 LLM 生成的转换代码未能通过单元测试时,准确地定位到引发错误的具体代码片段,以便进行小规模的精确修复。
方法步骤与流程: Algorithm 2: Bug Localization Algorithm
Input : Source program S, Buggy transcompiled program E, Loop index I, Buffer name N, control-flow matching model M
Output : Error Nodes Mt
1: Sn <- AST(S) // Parse source program into AST
2: Ss <- ExtractASTSegment(Sn, I, N) // Extract relevant AST segment from S
3: // Obtain the buffer list
4: Bs <- TraverseBuffers(Ss) // Traverse Ss to get buffer list
5: En <- BinarySearchErrorNodes(Bs, E, S) // Binary search to find error nodes in E based on buffer values and comparison with S
6: Mb <- FindMatchingCodeBlocks(M, Ss, En) // Use control-flow matching model M to find matching code blocks between Ss and En
7: for Ms, Mt in Mb do
8: if Diverse_d_s(Ms, Mt) then // Check for divergence in data flow between Ms and Mt
9: return Mt // Return the buggy code block in the target program E
10: end if
11: end for
- 单元测试验证: 转换后的代码通过提供的单元测试进行验证。如果测试失败,则触发错误定位算法。
- 提取相关代码段: 根据循环索引 或缓冲区名称 识别待转换的代码段 (从源程序的抽象语法树 (Abstract Syntax Tree, AST) 中提取)。
- 二分查找错误节点 (Binary Search Error Nodes):
- 通过在相关内存位置插入打印语句(
printstatements),并使用二分查找策略,比较打印值来缩小错误代码段的范围。 BinarySearchErrorNodes(Bs, E, S)比较 (错误程序)和 (源程序)在缓冲区 中的值,以找到 中开始表现出错误行为的节点 。
- 通过在相关内存位置插入打印语句(
- 匹配控制流代码块 (Find Matching Code Blocks):
- 使用控制流匹配模型 (control-flow matching model, M) 来确定源程序中的代码块 和目标程序中 对应的代码块 之间的对应关系。
- 通过比较源程序和目标程序中控制流语句(如
if,for循环)的映射关系,来识别错误发生的时间和位置。
- 枚举约束并生成 SMT 查询: 一旦找到错误代码片段 ,
QiMeng-Xpiler会枚举该片段中的约束,例如赋值的具体索引变量、循环边界、缓冲区大小或张量语义,并为后续的SMT代码修复过程生成查询。
4.2.4. 基于 SMT 的代码修复 (SMT-based Code Repairing)
目的: 一旦错误被定位,通过 SMT 求解器修复 buggy 代码片段中的低级实现细节,如循环边界、索引和指令参数,这些是 LLM 容易出错的地方。
方法步骤与流程: Algorithm 3: SMT-based Code Repairing Algorithm
Input : A source program P, error program E
Output : A repaired program F
1: Given: Error code snippet S_err
2: Ts <- AST(P) // Parse source program into AST
3: Ss <- extract(Ts, S_err) // Extract source code snippet corresponding to S_err
4: Te <- AST(E) // Parse error program into AST
5: Se <- extract(Te, S_err) // Extract error code snippet S_err from E
6: // Generate the sketch according to the transformation definition.
7: Sk <- GenerateCodeSketch(Ss, Se) // Generate a code sketch (template with holes) based on the transformation applied to Ss -> Se
8: // Generate the smt query
9: Q <- CreateSMTQuery(Ss, Se, Sk) // Create SMT query by formulating constraints from Ss, Se, and filling holes in Sk
10: // Generate the verified code snippet
11: R <- SynthesisCode(Q) // Use SMT solver to synthesize code snippet R by solving Q
12: F <- StitchBack(P, R, S_err) // Stitch the repaired snippet R back into the original program P at the location of S_err
13: return F
-
解析代码片段:
QiMeng-Xpiler首先解析源程序 和错误程序 ,并从中提取出对应的错误代码片段 和 。 -
生成代码草图 (Code Sketch): 根据特定循环转换的定义(例如,循环拆分、缓存读取),生成一个带有“空洞”的程序草图 。这个草图定义了转换后的代码结构,但关键数值或表达式待填充。
-
生成 SMT 查询:
-
枚举约束:
QiMeng-Xpiler明确枚举每个具体的索引变量、循环边界和缓冲区约束。 -
创建查询: 将这些边界约束和缓冲区索引约束,以及代码草图 中的“空洞”公式化为可供
SMT求解器处理的查询 。 -
图5:循环拆分和缓存读取的 SMT 约束示例 下图(原文 Figure 5)展示了循环拆分 (
loop split) 和缓存读取 (cache read) 的SMT约束:
该图像是图5,展示了循环拆分和缓存读取的SMT约束,包括代码示例和对应的符号约束。图中涉及循环拆分的约束 等,以及缓存读取的索引范围和赋值一致性约束。- 循环拆分 (
Loop Split) 的 SMT 约束:- 在循环拆分的情况下,源程序中的一个循环变量 可能会被拆分为两个或更多嵌套循环的变量,例如 和 。
- 目标: 确保拆分后的循环遍历范围与原始循环等效,且新的循环变量能够正确映射回原始变量。
- 约束示例: 和 。这可能意味着在拆分过程中,原始循环变量 和新的循环变量 之间存在一个与拆分因子相关的偏移或范围关系,例如,如果拆分因子是 4,则 和 的差值应该在 -3 到 3 之间,表示它们在原始循环的同一 4 单元块内。
- 变量解释:
- : 原始循环中的一个变量或索引。
- : 拆分后新循环中的一个变量或索引。
- 常数 4: 可能是拆分因子或某个边界值。
- 缓存读取 (
Cache Read) 的 SMT 约束:- 在内存访问优化中,通常需要将数据从全局内存加载到局部缓存(如共享内存)中。
- 目标: 确保数据从全局内存到缓存的加载是正确的,即加载的索引范围和数据内容与原始语义一致。
- 约束示例:
global_index = x + y * width和shared_index = x + y * block_width。global_index: 指向全局内存中的数据位置。shared_index: 指向共享内存中的数据位置。- , : 数据的坐标或维度索引。
width: 全局内存中数据的行宽或步长。block_width: 共享内存中数据的行宽或步长。
- 约束含义: 确保全局内存中的某个
(x, y)元素被正确地映射并加载到共享内存中的对应(x, y)位置,即使它们的步长或布局可能因内存优化而不同。SMT求解器会验证这些索引转换的正确性,以避免数据访问错误。
- 循环拆分 (
-
-
合成代码 (Synthesis Code):
SMT求解器通过解决查询 ,填充草图 中的“空洞”,生成经过验证的、功能正确的代码片段 。 -
缝合代码 (Stitch Back): 将修复后的代码片段 缝合回原始程序 的相应位置,形成最终的修复程序 。
通过这种方式,
QiMeng-Xpiler能够利用SMT求解器精确地校正LLM在低级细节上可能产生的错误,从而保证最终程序的正确性。
4.3. 分层性能自动调优 (Hierarchical Performance Auto-Tuning)
为了实现自动转编译并最大化转换后程序的性能,QiMeng-Xpiler 采用了一种分层自动调优 (hierarchical auto-tuning) 方法。这种方法有效地将高层代码结构(如并行策略、线程绑定)与低层细节(如平铺大小、循环顺序)解耦,从而能够灵活地枚举高层程序草图,并高效地采样低层细节。
转编译探索空间公式化: 整个转编译过程的探索空间 可以形式化为: 其中:
- 表示源张量程序。
- 代表从预定义转换阶段集合 中随机选择的一个阶段。
- 代表从预定义调优旋钮集合 中选择的一个调优选项(即参数)。
- 是转换的次数(即转换阶段序列的长度)。 这意味着,在每一步 ,程序 都会被一个选定的转换阶段 应用,并根据选定的调优选项 进行参数化。
因此,探索空间的大小 遵循以下公式: 这个公式表明,搜索空间的大小与转换阶段的数量以及每个阶段可能的调优参数数量呈指数级关系,因此需要高效的搜索策略。
4.3.1. 传递内自动调优 (Intra-Pass Auto-Tuning)
目的: 在单个转换阶段内部,通过调整参数来优化生成程序的性能。
方法步骤与流程:
-
搜索空间生成:
-
LLM 辅助: 自动调优模块与循环拆分等转换阶段交互,在
LLM的帮助下生成具有不同可调参数的多个程序。 -
可调参数: 主要包括:
- 每个逻辑循环的块数量 (
the number of blocks for each logical loop)。 - 在对上述参数做出决定后的循环顺序 (
the loop order after making decisions on (1))。
- 每个逻辑循环的块数量 (
-
元提示驱动: 这通过专门设计的元提示实现,例如下图(原文 Figure 6)所示的用于循环拆分的元提示,这些提示随后传递给循环拆分和循环重排阶段的
LLM提示。 -
图6:循环拆分的自动调优提示 下图(原文 Figure 6)展示了针对循环拆分 (
loop split) 的自动调优提示:
该图像是图6的示意图,展示了针对循环拆分(loop split)的自动调优提示,包含如何将循环变量i拆分为两个嵌套循环及返回所有可能的循环索引和范围的示例。这个提示要求
LLM将一个循环变量 拆分为两个嵌套循环i_outer和i_inner,并指定i_inner的范围。LLM需要返回所有可能的循环索引及其范围的示例。例如,如果 从 0 到 1024,并且拆分大小为 32,则i_outer可能从 0 到 31,i_inner可能从 0 到 31,并且i = i_outer * 32 + i_inner。 -
多草图生成:
Intra-Pass Auto-Tuning模块还会与其他转换阶段交互,生成不同的程序草图,例如不同的循环绑定策略。
-
-
搜索空间探索:
- 根据目标代码的特性,选择合适的探索方法。
- 穷举搜索 (Brute-Force Search): 对于某些 DLS(例如,
BANG C),由于其指令粒度较大,导致搜索空间相对较小。在这种情况下,直接采用穷举搜索来找到性能最优的程序。 - 搜索空间大小差异: 不同 DLS 的搜索空间大小差异显著。例如,对于
MatMul() 操作,在GPU上的搜索空间(公式中的 )为 150,而在MLU上仅为 10。
4.3.2. 基于 MCTS 的传递间自动调优 (Inter-Pass Auto-Tuning with MCTS)
目的: 自动发现功能正确且性能最优的转换阶段序列。
方法步骤与流程:
-
MCTS 框架:
QiMeng-Xpiler将转编译过程建模为马尔可夫决策过程 (Markov decision process)。- 状态 (State): 每个中间程序都表示为一个状态。
- 动作 (Action): 可以应用的不同的转换阶段。
- 奖励 (Reward): 与程序执行时间改善成正比。
- 目标: 找到导致最优转换阶段序列的动作路径。
-
奖励函数 (Reward function): 为了提高成本模型的准确性并最小化额外开销,
QiMeng-Xpiler在声明新的转换阶段时会进行实际执行时间测量。MCTS与当前程序并行运行,记录最佳实际吞吐量作为当前转换序列的奖励。- 在迭代 时,奖励函数定义为:
其中:
- 表示在迭代 时,经过转换后的程序 ( 索引来自传递内自动调优的搜索空间)。
- 是程序 的吞吐量。
- 如果 是有效程序(即通过了功能正确性检查),则其吞吐量被考虑;否则吞吐量为 0。
- 是在迭代 时,所有传递内自动调优生成的程序中,通过执行获得的最高吞吐量。
-
搜索参数设置:
-
MCTS可能无法在给定迭代中有效达到终止节点,甚至无法生成最终的转编译程序。因此,需要设计空间探索来平衡搜索时间和奖励。 -
最大搜索深度 (Maximum search depth): 考虑到所有 11 个转换阶段都很关键且可能重复,最大搜索深度 应超过 11。经过探索,最终选择 。
-
模拟总次数 (Total number of simulations): 经过探索,选择 512 次模拟。
-
结果: 这种设置在合理的搜索时间(例如数小时)内为转编译程序提供了最佳性能。
通过这种分层自动调优方法,
QiMeng-Xpiler能够高效地探索巨大的搜索空间,不仅生成功能正确的代码,还能确保其达到甚至超越手动优化的性能。
-
5. 实验设置
5.1. 评估平台
QiMeng-Xpiler 的实验在四种不同的深度学习系统 (DLS) 上进行,这些系统具有各自独特的编程接口:
- Intel Gold 6348 CPU with VNNI Extension: 采用支持矢量神经网络指令 (Vector Neural Network Instructions, VNNI) 的特殊指令集,用于加速深度学习任务。编程接口为 C 语言与
VNNI内联函数。 - NVIDIA A100 GPU with CUDA C: 遵循 单指令多线程 (Single Instruction, Multiple Threads, SIMT) 编程模型,使用
CUDA C作为编程接口。 - AMD MI200 with HIP: 提供
CUDA语言的替代方案,使用HIP作为编程接口。 - Cambricon MLU with BANG C: 遵循 单指令多数据 (Single Instruction, Multiple Data, SIMD) 编程模型,使用
BANG C作为编程接口。
5.2. 评估基准 (Benchmarks)
QiMeng-Xpiler 在 21 个广泛使用的深度学习算子(见 Table 5)上进行了评估,这些算子可以分为 6 种类型:
-
MatMul (矩阵乘法):
GEMM(通用矩阵乘法),GEMV(矩阵向量乘法),Batch GEMM(批量矩阵乘法)。 -
Convolution (卷积):
Conv1D(一维卷积),Conv2D NHWC,Conv2D NCHW(二维卷积,不同数据布局),Depthwise Conv(深度可分离卷积)。 -
Activation (激活函数):
ReLU(修正线性单元),Softmax,GeLU(高斯误差线性单元),Sigmoid。 -
Element-wise (逐元素操作):
Add(加法),Sign(符号函数)。 -
Pooling (池化):
MaxPool(最大池化),AvgPool(平均池化),MinPool(最小池化),SumPool(求和池化)。 -
LLM (大语言模型相关操作):
LayerNorm(层归一化),Deformable Attention(可变形注意力),Self Attention(自注意力),RMSNorm(均方根归一化)。每个算子在从真实网络(如 GPT、LLaMA-2、DAT、BERT、ResNet、MobileNet、VGG)中提取的 8 种典型形状上进一步评估。因此,总共有 168 个测试用例。这些测试用例的代码行数范围从 7 行到 214 行,涵盖了各种类型和形状,能够全面评估
QiMeng-Xpiler的能力。
以下是原文 Table 5 的结果:
| Type | Operators | Lines of Code | Cases | |||
| CUDA C | BANG C | Hip | C with VNNI | |||
| MatMul | GEMM, GEMV | 26, 12 | 15, 11 | 25, 12 | 41, 34 | 24 |
| Batch GEMM | 29 | 16 | 28 | 47 | ||
| Convolution | Conv1D | 10 | 14 | 10 | 9 | 32 |
| Conv2D NHWC, NCHW | 32, 30 | 23, 30 | 32, 30 | 83, 85 | ||
| Depthwise Conv | 27 | 24 | 27 | 17 | ||
| Activation | ReLU, Softmax | 7, 24 | 18, 18 | 7, 24 | 14, 28 | 32 |
| GeLU, Sigmoid | 7, 10 | 29, 30 | 7, 10 | 14, 14 | ||
| Elementwise | Add, Sign | 20, 12 | 26, 29 | 18, 12 | 17, 14 | 16 |
| Pooling | MaxPool, AvgPool | 25, 30 | 25, 25 | 25, 30 | 31, 34 | 32 |
| MinPool, SumPool | 23, 29 | 25, 25 | 23, 29 | 33, 30 | ||
| LLM | LayerNorm | 42 | 35 | 42 | 46 | 32 |
| Deformable Attention | 139 | 191 | 139 | 214 | ||
| Self Attention, RMSNorm | 54, 25 | 64, 18 | 54, 25 | 111, 18 | ||
5.3. 评估指标
论文使用三个关键指标来评估 QiMeng-Xpiler 的性能和准确性:
5.3.1. 编译准确率 (Compilation Accuracy)
- 概念定义: 衡量
QiMeng-Xpiler成功通过编译器检查的程序所占的比例。此指标反映了其在处理源代码、生成无错误(语法和基本语义层面)程序方面的能力。通过编译的程序才能进一步运行和测试其功能。 - 数学公式: 论文未提供具体公式,但可推断为:
- 符号解释:
- : 成功通过编译器检查并生成可执行文件的程序数量。
- : 总共进行转编译并评估的程序数量。
5.3.2. 计算准确率 (Computation Accuracy)
- 概念定义: 衡量翻译后的代码在功能上是否正确。如果生成的代码通过了一组单元测试(即其输出与原始程序的输出或预期结果一致),则认为该代码在功能上是正确的。此指标是评估转编译器实用性的关键。
- 数学公式: 论文未提供具体公式,但可推断为:
- 符号解释:
- : 通过单元测试验证功能正确的程序数量。
- : 总共进行转编译并评估的程序数量。
5.3.3. 执行性能 (Execution Performance)
- 概念定义: 评估翻译后的代码在实际硬件平台上的运行速度。此指标通过与供应商提供的手动优化库(如
cuDNN/cuBLAS、oneDNN)进行比较,凸显了QiMeng-Xpiler在实际应用中的价值。性能通常以倍数形式(例如 )表示,表示相对于基线的加速比。 - 数学公式: 论文中以相对倍数表示,可定义为: 或等效地(当执行时间是主要关注点时):
- 符号解释:
- : 翻译程序在单位时间内完成的工作量(例如,每秒浮点运算次数 FLOPS 或每秒处理的图像数量)。
- : 对比基线程序(通常是手动优化库)在单位时间内完成的工作量。
- : 翻译程序的执行时间。
- : 对比基线程序的执行时间。 当比率大于 1 时,表示翻译程序的性能优于基线。
5.4. 对比基线
论文将 QiMeng-Xpiler 的方法与以下两类最先进的方法进行比较:
-
基于 LLM 的方法 (LLM-based approaches):
- GPT-4 Zero-Shot: 使用
GPT-4进行零样本翻译,不提供任何特定示例。 - GPT-4 Few-Shot: 使用
GPT-4进行少样本翻译,在提示中提供少量特定示例。 - OpenAI o1 Zero-Shot: 使用
OpenAI o1模型进行零样本翻译。 - OpenAI o1 Few-Shot: 使用
OpenAI o1模型进行少样本翻译。 这些方法代表了当前LLM在代码生成和翻译方面的最先进水平。
- GPT-4 Zero-Shot: 使用
-
规则型方法 (Rule-based approaches):
- PPCG: 一种利用多面体模型实现 代码到
CUDA自动并行化的工具。 - HIPIFY: AMD 官方提供的一个工具,用于将
CUDA代码迁移到AMD HIP代码。 需要注意的是,规则型方法对于其他转编译方向不可用,这主要是因为开发此类工具所需的复杂性和大量人工努力。
- PPCG: 一种利用多面体模型实现 代码到
-
符号程序合成方法 (Search-based program synthesis approaches):
- 论文指出,这类方法由于面临巨大的搜索空间问题,无法直接在不同
DLS之间进行转编译,因此未直接作为性能基线进行比较。它们主要被用于QiMeng-Xpiler内部的修复环节。
- 论文指出,这类方法由于面临巨大的搜索空间问题,无法直接在不同
6. 实验结果与分析
6.1. 准确率评估
本节展示了编译准确率和计算准确率的评估结果,将 QiMeng-Xpiler 与不同转编译方向上的最新方法进行比较。
以下是原文 Table 6 的结果:
| Source | Method | Compilation Accuracy (%) | Computation Accuracy (%) | ||||||
| CUDA C | BANG C | Hip | C with VNNI | CUDA C | BANG C | Hip | C with VNNI | ||
| CUDA C | GPT-4 Zero-Shot | 0 | 82.7 | 9.5 | 0 | 82.7 | 4.2 | ||
| OpenAI o1 Zero-Shot | 0 | 85.7 | 61.9 | 0 | 82.7 | 60.7 | |||
| GPT-4 Few-Shot | 50.6 | 97.0 | 84.5 | 7.7 | 96.4 | 30.4 | |||
| OpenAI o1 Few-Shot | 51.8 | 98.2 | 85.1 | 48.2 | 98.2 | 55.4 | |||
| QiMeng-Xpiler w/o SMT | 82.7 | 98.2 | 88.1 | 54.2 | 98.2 | 58.3 | |||
| QiMeng-Xpiler w/o SMT + Self-Debugging | 87.5 | 98.8 | 89.3 | 54.8 | 98.2 | 58.9 | |||
| QiMeng-Xpiler | 100 | 100 | 100 | 91.7 | 100 | 95.2 | |||
| BANG C | GPT-4 Zero-Shot | 24.4 | 26.8 | 0 | 0 | 0 | 0 | ||
| OpenAI o1 Zero-Shot | 27.4 | 97.0 | 9.5 | 0 | 0 | 4.2 | |||
| GPT-4 Few-Shot | 69.0 | 66.1 | 23.8 | 6.5 | 6.5 | 13.1 | |||
| OpenAI o1 Few-Shot | 71.4 | 97.0 | 41.7 | 10.1 | 7.7 | 23.2 | |||
| QiMeng-Xpiler w/o SMT | 85.1 | 84.5 | 47.6 | 77.4 | 78.6 | 41.1 | |||
| QiMeng-Xpiler w/o SMT + Self-Debugging | 88.1 | 88.7 | 50.6 | 77.4 | 78.6 | 41.1 | |||
| QiMeng-Xpiler | 100 | 100 | 100 | 95.8 | / | 97.0 | 95.2 | ||
| Hip | GPT-4 Zero-Shot | 97.0 | 0 | 23.8 | 97.0 | 0 | 5.4 | ||
| OpenAI o1 Zero-Shot | 98.2 | 0 | 45.8 | 98.2 | 0 | 4.2 | |||
| GPT-4 Few-Shot | 97.0 | 35.1 | 85.1 | 97.0 | 5.4 | 24.4 | |||
| OpenAI o1 Few-Shot | 98.8 | 42.3 | 88.7 | 98.2 | 9.0 | 30.4 | |||
| QiMeng-Xpiler w/o SMT | 98.2 | 60.7 | 65.5 | 97.6 | 52.4 | 57.1 | |||
| QiMeng-Xpiler w/o SMT + Self-Debugging | 98.8 | 62.5 | 66.1 | 98.2 | 52.4 | 57.1 | |||
| QiMeng-Xpiler | 100 | 100 | 100 | 100 | 86.9 | 96.4 | |||
| C with VNNI | GPT-4 Zero-Shot | 57.1 | 0 | 60.1 | 8.3 | 0 | 8.9 | ||
| OpenAI o1 Zero-Shot | 66.1 | 0 | 97.0 | 10.1 | 0 | 96.4 | |||
| GPT-4 Few-Shot | 81.5 | 41.7 | 74.4 | 14.3 | 6.0 | 12.5 | |||
| OpenAI o1 Few-Shot | 87.5 | 55.4 | 97.0 | 51.2 | 10.7 | 96.4 | |||
| QiMeng-Xpiler w/o SMT | 95.8 | 78.0 | 87.5 | 83.9 | 58.3 | 85.7 | |||
| QiMeng-Xpiler w/o SMT + Self-Debugging | 97.0 | 84.5 | 89.3 | 83.9 | 58.3 | 85.7 | |||
| QiMeng-Xpiler | 100 | 99.4 | 100 | 98.2 | 88.7 | 99.4 | |||
主要发现与分析:
- QiMeng-Xpiler 的卓越性能:
- 在所有转编译方向上,
QiMeng-Xpiler均表现最佳,编译准确率接近 100%,计算准确率在 86.9% 到 100% 之间。这表明QiMeng-Xpiler能够以极少的人工干预处理各种 DLS 上的代码翻译任务,为 DLS 编程领域带来了革命性的进步。
- 在所有转编译方向上,
- LLM-based 方法的局限性:
- 尽管
GPT-4和OpenAI o1等LLM-based方法在某些情况下取得了较高的准确率,但由于LLM的不确定性,它们难以达到 100% 的准确率。例如,CUDA C到BANG C的转换中,GPT-4 Few-Shot的编译准确率仅为 50.6%,计算准确率仅为 7.7%。这意味着纯LLM方法无法满足转编译器对极高准确率的需求。
- 尽管
- 与规则型方法的比较:
-
以下是原文 Table 7 的结果:
Direction Method Compilation(%) Computation(%) CUDA C → HIP Hipify 85.7 85.7 QiMeng-Xpiler 100 100 C → CUDA C PPCG 47.6 47.6 QiMeng-Xpiler 100 98.2 -
QiMeng-Xpiler在准确率上优于最先进的规则型方法。例如,在 到CUDA C的转换中,QiMeng-Xpiler实现了 100% 的编译准确率和 98.2% 的计算准确率,比PPCG高出约 50%。 -
对于相对简单的
CUDA C到HIP任务,QiMeng-Xpiler成功实现了 100% 的准确率,优于HIPIFY的 85.7%。这还表明QiMeng-Xpiler在各种 DLS 上的灵活性,无需太多的适应成本,而规则型方法则难以做到。
-
- 消融实验(有无 SMT)分析:
- 神经-符号合成范式的必要性: 对
QiMeng-Xpiler的SMT求解器进行了消融研究(见 Table 6 中的QiMeng-Xpiler w/o SMT和QiMeng-Xpiler行)。 - 即使没有
SMT求解器,QiMeng-Xpiler仍然比LLM-based方法具有更高的准确率(例如,在HIP到BANG C方向上,QiMeng-Xpiler w/o SMT的计算准确率为 52.4%,而OpenAI o1 Few-Shot为 9.0%)。 - 然而,如果没有
SMT,它无法达到 100% 的准确率,即使结合了最先进的LLM-based代码生成方法Self-Debugging[22] 也是如此。 - 这强调了转编译器对准确率的极高要求。相反,引入
SMT-based代码修复后,程序转编译的计算准确率显著提高到 86.9% 到 100%。这突显了SMT求解器(或更广泛地说,神经-符号合成)对于转编译器的必要性。
- 神经-符号合成范式的必要性: 对
6.2. 执行性能评估
本节展示了 QiMeng-Xpiler 生成的程序与手动优化库(如 PyTorch 与 cuDNN/cuBLAS、CNNL、rocBLAS 和 oneDNN 等后端库)在性能上的比较,涵盖了四种最常见的程序转编译方向。
下图(原文 Figure 7)展示了 QiMeng-Xpiler 在不同平台间转编译张量程序的性能表现及纠正案例数:

主要发现与分析:
-
整体性能表现: 实验结果表明,
QiMeng-Xpiler生成的程序平均性能达到手动优化库的 ,并且最高可达 。这表明QiMeng-Xpiler不仅能够生成功能正确的代码,还能生成高质量、高性能的张量程序。 -
不同转编译方向的性能:
- C with VNNI -> CUDA C: 在这个方向上,
QiMeng-Xpiler表现出显著优势,平均性能达到手动优化库的 ,且在某些算子上(如Conv2D NHWC和Self Attention)实现 的加速。 - CUDA C -> BANG C: 在这个极具挑战的方向上,
QiMeng-Xpiler依然能够达到平均 的性能,并且在某些算子(如GEMM和Conv1D)上接近甚至超过手动优化库。 - CUDA C -> HIP: 性能平均达到手动优化库的 ,在
LayerNorm上甚至略高于手动优化库。 - CUDA C -> C with VNNI: 平均性能为 ,表明在转换为 CPU 平台时也保持了良好的性能。
- C with VNNI -> CUDA C: 在这个方向上,
-
性能超过手动优化库: 在多个算子和转编译方向上,
QiMeng-Xpiler能够生成性能优于甚至高达 2.0 倍于供应商提供的手动优化库的代码。这突显了其自动调优和神经-符号合成策略在发现高性能实现方面的有效性。 -
功能正确案例数: 图中柱状图上方数字表示该算子类型下功能正确的案例数量,这与 Table 6 中的计算准确率相对应。高数量的正确案例是衡量
QiMeng-Xpiler实用性的关键。总结:
QiMeng-Xpiler展现了其在生成高性能张量程序方面的卓越转编译能力,对于多种 DLS 和不同的算子类型,它能够生成与手动优化库相媲美甚至更优的代码,这对于实际应用具有重要意义。
6.3. 案例研究:CUDA C 到 BANG C 的转编译
本文进一步通过 CUDA C 到 BANG C 的转编译方向来展示 QiMeng-Xpiler 的优越性和有效性。选择这个任务是因为它具有挑战性:
- 涉及从
SIMT(CUDA)到SIMD(BANG C)这两种截然不同的编程模型之间的转换。 BANG C是一种不常见的语言,LLM可用的训练数据显著较少。
主要发现与分析:
-
QiMeng-Xpiler的显著改进:QiMeng-Xpiler在CUDA C到BANG C的转编译中取得了比其他方向更大的编译/计算准确率提升。最终实现了 100% 的编译准确率和 91.7% 的计算准确率。 -
OpenAI o1 Zero-Shot的局限性: 尽管OpenAI o1 Zero-Shot在某些转编译方向(例如CUDA C到HIP,编译准确率 85.7%,计算准确率 82.7%)表现出色,但在CUDA C到BANG C的转换中,其表现却非常差,准确率为 0%。这主要是因为BANG C的上述两个挑战超出了OpenAI o1 Zero-Shot的能力。 -
OpenAI o1 Few-Shot的提升与不足:OpenAI o1 Few-Shot通过提供CUDA C到BANG C的翻译示例,显著提高了编译准确率(从 0% 到 50.6%)和计算准确率(从 0% 到 7.7%)。但离完全准确仍有很大差距。 -
QiMeng-Xpiler w/o SMT的优势: 即使没有SMT模块,QiMeng-Xpiler(即QiMeng-Xpiler w/o SMT)也实现了远高于OpenAI o1 Few-Shot的编译准确率(82.7%)和计算准确率(54.2%)。这得益于QiMeng-Xpiler w/o SMT的两个关键方法:- 领域知识获取: 通过文档检索自动注释程序,获得了对目标语言关键字、语法和编程
API的全面理解,弥补了领域特定知识的不足。 - 多阶段转换: 将整个转编译过程分解为一系列基于
LLM的转换阶段,而不是在一个合成步骤中完成复杂的跨语言翻译。这有助于在两种差异巨大的源语言和目标语言之间实现平滑过渡。
- 领域知识获取: 通过文档检索自动注释程序,获得了对目标语言关键字、语法和编程
-
SMT集成的决定性作用: 关键在于,通过集成SMT方法,QiMeng-Xpiler在CUDA C到BANG C的翻译中取得了惊人的准确率,编译准确率达到 100%,计算准确率达到 91.7%。这种准确率主要归功于QiMeng-Xpiler实现了小规模的符号合成,确保了LLM引导下每个转换阶段的功能等价性。结论: 实验证明,
QiMeng-Xpiler能够成功完成跨不同 DLS 的转编译任务,即使对于像BANG C这样新颖且相对不常见的 DLS 也能表现出色。
6.4. 编译时间
下图(原文 Figure 8)展示了 QiMeng-Xpiler 在将 CUDA C 代码转编译为 BANG C 代码时,6 个典型算子的编译时间细分图:

主要发现与分析:
- 总编译时间: 6 个典型算子(
GEMM、Conv2D NHWC、ReLU、LayerNorm、Deformable Attention、Self Attention)的编译时间范围从 1.2 小时到 7.8 小时,平均为 3.7 小时。 - 编译时间细分:
- LLM (大语言模型): 占据了相当一部分时间,这是
LLM进行程序注释和初步转换所需的时间。 - Unit Test (单元测试): 用于验证
LLM转换结果的正确性。 - SMT (符号程序合成): 仅在
LLM无法生成正确转换时触发。对于简单的程序,SMT所占时间比例较小;对于复杂或LLM容易出错的程序,SMT修复时间会增加。例如,Deformable Attention的SMT时间显著高于ReLU。 - Auto-tuning (自动调优): 对于具有更大搜索空间的算子(如
GEMM和Deformable Attention),自动调优所占时间比例显著增加。这是因为它需要系统地探索参数和转换序列以优化性能。 - Evaluation (评估): 评估最终生成程序的性能。
- LLM (大语言模型): 占据了相当一部分时间,这是
- 影响编译时间的因素:
-
SMT仅在LLM失败时触发:这优化了整个流程,避免了不必要的SMT求解成本。 -
搜索空间大小:对于矩阵乘法类等搜索空间较大的算子,自动调优的时间显著增加。
-
特殊内联函数 (
special intrinsics) 的数量:程序中使用的特殊内联函数越多,编译时间越长,这可能与它们的复杂性以及在LLM和SMT阶段处理这些特定约束的难度有关。总结: 尽管总编译时间可能长达数小时,但考虑到其带来的高准确率、高性能和显著的生产力提升,以及自动化程度,这一时间成本在实际工业应用中是可以接受的。
-
6.5. 生产力提升
本节评估了 QiMeng-Xpiler 在真实场景中对编程生产力的提升效果,主要聚焦于 NVIDIA GPU 和 MLU 这两种具有代表性的 DLS。选择了最具挑战性的 Deformable Attention 算子(约 200 行代码)作为基准。
以下是原文 Table 8 的结果:
| Deformable Attention (∼ 200LoCs) | CUDA C-> BANG C | C with VNNI -> CUDA C | |||
| Costs | Performance | Costs | Performance | ||
| Senior Coder | Manual | ∼6 d 4.5 + 0.5 h | 100% | ∼1 d 2.1 h | 100% |
| w/ QiMeng-Xpiler Time Saving | ∼28.8× | 69.20% | ∼11.4× | 132.50 % | |
| Junior Coder | Manual | ∼30 d | 49.85% | ∼3 d | 75.76% |
| w/ QiMeng-Xpiler Time Saving | 4.5 + 3 h ∼96.0× | 65.17% | 2.1 h ∼34.3× | 132.50 % | |
实验设置:
- 邀请了两名计算机科学硕士学生(代表初级程序员)和两名软件工程师(代表高级程序员)。
- 性能数据已根据高级程序员手动实现的程序进行归一化。
- 关注两个转编译方向:
CUDA C到BANG C和C with VNNI到CUDA C。
主要发现与分析:
-
显著的生产力提升:
- GPU (
C with VNNI->CUDA C): 编程生产力提升高达 (对于初级程序员)。高级程序员也可获得 的提升。 - MLU (
CUDA C->BANG C): 编程生产力提升高达 (对于初级程序员)。高级程序员也可获得 的提升。 - 这表明
QiMeng-Xpiler能够将原本需要数天甚至数周的开发工作缩短到几个小时,极大地解放了开发人员。
- GPU (
-
初级程序员获益更大:
- 初级程序员手动实现
Deformable Attention算子所需时间显著长于高级程序员(CUDA C到BANG C方向,初级程序员需 30 天,高级程序员需 6 天)。 QiMeng-Xpiler帮助初级程序员实现了更大的时间节省倍数,因为他们原本的基线时间更长。
- 初级程序员手动实现
-
性能接近甚至超越手动优化:
- 在
C with VNNI到CUDA C方向,QiMeng-Xpiler生成的程序性能甚至达到了手动实现的 132.50% (即 )。 - 在
CUDA C到BANG C方向,生成的程序性能达到了手动实现的 65.17% 到 69.20%,虽然略低于手动优化,但考虑到巨大的生产力提升,这是一个非常可观的权衡。
- 在
-
有限的人工干预:
-
尽管
QiMeng-Xpiler在MLU上的CUDA C到BANG C方向未能自动生成功能完全正确的程序(其计算准确率为 91.7%,意味着部分案例需要调试),但初级程序员仅需额外 3 小时,高级程序员仅需额外 0.5 小时即可调试完成。与原始的数周开发时间相比,这仍然是巨大的时间节省。总结: 实验结果强有力地证明了
QiMeng-Xpiler在实际 DLS 开发中显著提升编程生产力的能力,尤其是在面对复杂算子和异构平台时,其价值更为突出。
-
6.6. 失败案例
尽管 QiMeng-Xpiler 取得了显著成功,但并非所有情况都能实现 100% 的正确翻译。本文分析了一个失败案例,即在 CUDA C 到 BANG C 转编译中的 Deformable Attention 算子。
下图(原文 Figure 9)展示了 Deformable Attention 中复杂的控制流:

失败原因分析:
- 复杂控制流:
Deformable Attention算子包含多层嵌套循环和复杂的条件语句。 - LLM 的局限性:
QiMeng-Xpiler的神经组件(即LLMs)难以处理如此复杂的逻辑结构和条件分支,从而无法准确地将其映射到BANG C所需的SIMD内联函数。LLM在理解和生成涉及复杂数据依赖、分支跳转和多重循环的低级并行代码时仍面临挑战。 - SMT 求解器的局限性: 符号组件(
SMT求解器)也无法从这种高度复杂的控制流中有效提取数学约束并执行代码修复。SMT求解器在处理非线性逻辑、数组索引的复杂条件依赖以及大规模符号推理时,计算成本和复杂性会急剧增加。
未来解决方案:
论文指出,更强大的 LLMs 和更先进的 SMT 分析工具是解决此问题的有希望的方案,有望进一步提高 QiMeng-Xpiler 处理此类复杂案例的能力。这可能包括:
- 提升
LLM对程序深层语义、控制流和数据依赖的理解能力。 - 开发能够更高效地处理复杂约束和更大搜索空间的
SMT求解器或混合验证技术。 - 引入更精细的中间表示,以更好地捕获复杂的程序语义。
6.7. 相关工作
这部分总结了与 QiMeng-Xpiler 相关的现有工作,并进一步强调了 QiMeng-Xpiler 的创新点。
-
规则型方法 (Rule-based approaches):
- 特点: 依赖专家手动定义的规则进行代码转换,如
C2Rust、CxGo、HIPIFY、PPCG。 - 局限性: 劳动密集型,需要对源语言和目标语言有深入了解,限制了其适用性和可扩展性,难以处理不规则代码结构。
- 特点: 依赖专家手动定义的规则进行代码转换,如
-
数据驱动方法 (Data-driven approaches):
- 特点: 利用神经网络(尤其是
LLMs)从大量代码中学习翻译模式,如TransCoder、Codex、StarCoder、GPT-4、OpenAI o1。 - 局限性: 尽管减少了人工工作量,但往往无法保证翻译代码的功能正确性,尤其是在 DLS 这种专业领域。
- 特点: 利用神经网络(尤其是
-
符号合成方法 (Symbolic synthesis approaches):
- 特点: 从输入/输出对或形式化语义规范生成语义等效的代码,如
C2TACO、MetaLift、Tenspiler。 - 局限性: 依赖于成本高昂的基于搜索的
SMT求解器,难以扩展到大型真实世界应用。此外,需要用户手动定义目标语言的语义,这既具挑战性又容易出错。
- 特点: 从输入/输出对或形式化语义规范生成语义等效的代码,如
总结与 QiMeng-Xpiler 的差异化:
现有方法要么需要大量人工工作,要么存在功能正确性问题,要么可扩展性有限,这使得它们无法自动地在具有不同编程模型的 DLS 之间翻译程序。
QiMeng-Xpiler 是首个通过提出新颖的神经-符号合成框架来解决这一挑战的工作。它通过一系列 LLM 辅助的转换来进行翻译,并通过小规模的符号合成确保每个转换的功能等价性。这种混合方法弥合了 LLM 的灵活性与符号合成的严谨性之间的差距,使其能够克服现有方法的局限性,实现 DLS 间张量程序的自动、正确且高性能的转编译。
7. 总结与思考
7.1. 结论总结
本文提出了 QiMeng-Xpiler,一种用于在异构深度学习系统 (DLS) 之间自动转编译张量程序 (Tensor Programs) 的神经-符号合成 (Neural-Symbolic Synthesis) 方法。其核心思想是将大语言模型 (LLMs) 强大的代码生成能力与符号程序合成 (Symbolic Program Synthesis) 的精确修复能力相结合。
QiMeng-Xpiler 将整个转编译过程分解为一系列 LLM 辅助的转换阶段,并利用预定义的元提示 (meta-prompts) 指导程序变换。在每个转换阶段,通过单元测试 (unit tests) 验证 LLM 生成的代码,并使用小规模的 SMT (Satisfiability Modulo Theories) 求解器来精确修复不正确的代码片段,从而确保功能正确性。为了达到高性能,QiMeng-Xpiler 还引入了分层自动调优 (hierarchical auto-tuning) 机制,包括传递内自动调优 (Intra-Pass Auto-Tuning) 探索参数和传递间自动调优 (Inter-Pass Auto-Tuning) 探索转换序列。
在四种具有不同编程接口的 DLS(Intel DL Boost with VNNI、NVIDIA GPU with CUDA、AMD MI with HIP、Cambricon MLU with BANG)上的实验结果表明:
-
QiMeng-Xpiler平均能以 95% 的准确率正确翻译不同的张量程序,并在大多数情况下编译和计算准确率接近 100%。 -
翻译后的程序性能最高可达供应商提供的手动优化库的 2.0 倍,平均性能也达到了 。
-
通过自动转编译现有张量程序,DLS 的编程生产力得到了显著提升,最高可达 96.0 倍。
这些结果证明了
QiMeng-Xpiler在解决异构 DLS 环境中张量程序编程挑战方面的有效性和效率,为实现“一次编写,到处运行”的目标迈出了重要一步。
7.2. 局限性与未来工作
论文指出了 QiMeng-Xpiler 的一个主要局限性,即在处理极端复杂的控制流时可能出现失败:
-
复杂控制流挑战: 例如,在
CUDA C到BANG C转编译Deformable Attention算子时,由于其中包含多层嵌套循环和复杂的条件语句,QiMeng-Xpiler的神经组件 (LLMs) 难以处理这种复杂的逻辑结构和条件分支,无法将其准确映射到BANG C所需的SIMD内联函数。同时,符号组件 (SMT求解器) 也难以从如此复杂的控制流中提取数学约束并进行代码修复。基于此局限性,论文提出了以下未来可能的研究方向:
-
更强大的 LLMs: 开发或利用对程序深层语义、控制流和数据依赖有更强理解能力的
LLMs。 -
更先进的 SMT 分析工具: 探索更高效的
SMT分析工具或混合验证技术,以处理更复杂的约束和更大规模的符号推理。这可能涉及新的算法、更优的启发式搜索或结合其他形式化方法。 -
中间表示 (Intermediate Representation, IR) 的改进: 设计更丰富的中间表示,能够更好地捕获和抽象复杂控制流、数据依赖和并行语义,从而为
LLM和SMT提供更好的输入和更清晰的转换目标。
7.3. 个人启发与批判
7.3.1. 个人启发
QiMeng-Xpiler 的工作提供了以下几点重要启发:
- 神经-符号混合范式的潜力: 这篇论文是神经-符号方法在解决实际工程问题上的一个优秀案例。它证明了
LLM的生成能力和符号方法的严谨性并非互斥,而是可以高度互补,共同解决单一方法难以应对的复杂问题。这种模式在需要创造性(代码生成)和精确性(功能正确性)并存的领域具有广泛应用前景,例如自动驾驶软件开发、智能合约审计、甚至生物信息学中的基因序列设计。 - 问题分解的重要性: 将复杂的转编译任务分解为一系列小的、可管理的转换阶段,并通过
元提示引导LLM,这极大地简化了问题。这种“分而治之”的策略不仅提高了LLM的准确率,也使得SMT的局部修复成为可能。这对于任何大型软件工程任务都具有借鉴意义。 - 领域知识的整合: 通过程序注释和从编程手册中检索信息来为
LLM提供领域特定知识,是提高LLM在专业领域表现的关键。这表明LLM并非万能,但通过与外部知识库和检索增强生成(RAG)等技术结合,可以有效弥补其知识空白。 - 自动调优的价值: 性能优化是 DLS 编程的核心。
QiMeng-Xpiler的分层自动调优机制,尤其是MCTS在搜索转换序列中的应用,展示了在无需专家手动干预的情况下,系统性地探索性能最优解的强大能力。这对于自动化编译器优化、系统配置调优等领域具有普适性。
7.3.2. 批判
尽管 QiMeng-Xpiler 取得了令人印象深刻的成果,但仍有一些潜在的问题、未经验证的假设或可以改进的地方:
- 平均性能的解释: 论文提到“平均性能达到 ”,而“最高可达 ”。这意味着在许多情况下,
QiMeng-Xpiler生成的代码性能实际上低于手动优化库。虽然 仍然是可接受的,并且生产力提升巨大,但对于追求极致性能的场景,这仍然是一个需要权衡的因素。未来的工作可能需要进一步提升平均性能,而不仅仅是关注“最高”性能。 - 编译时间的实用性: 编译时间平均 3.7 小时,对于某些算子甚至高达 7.8 小时。虽然对于生产环境中的一次性转编译是可接受的,但对于开发过程中的迭代和调试周期来说,这个时间可能过长。尤其是在需要快速原型验证和频繁修改代码的场景下,长时间的编译等待会影响开发效率。如何缩短编译时间是一个重要的研究方向。
- LLM 的泛化能力和稳定性:
LLM的输出本质上具有一定的不确定性。虽然SMT修复了错误,但LLM生成代码的“质量”仍然影响着SMT的工作量和修复的成功率。如果LLM的初始生成过于偏离,SMT可能难以修复。随着新的LLM模型不断出现,QiMeng-Xpiler对不同LLM的鲁棒性和泛化能力如何,以及如何应对LLM的“幻觉”现象,都值得深入探讨。 - 规则和提示工程的维护成本: 尽管
QiMeng-Xpiler减少了手动编码,但它依赖于预定义的转换阶段、元提示以及编程手册中的信息。这些“规则”的维护和更新,特别是当新的 DLS 出现或现有 DLS 的编程模型发生变化时,仍然需要一定的工程投入。如何使这些规则和提示更具自适应性,减少人工维护,是进一步自动化面临的挑战。 - SMT 求解器的可扩展性限制: 尽管论文强调
SMT是在“小规模”范围内进行修复,但对于极端复杂的控制流(如失败案例所示),即使是小规模的符号推理也可能变得非常昂贵或无法求解。随着张量程序越来越复杂,SMT求解器在处理复杂数据依赖和非线性约束方面的局限性将进一步显现。 - 适用算子的范围: 论文评估了 21 种算子,覆盖了深度学习的常见操作。然而,DLS 领域不断涌现新的算子和定制化操作。
QiMeng-Xpiler在这些新兴或高度定制化算子上的表现如何,以及是否需要引入新的转换阶段或更复杂的领域知识,仍需进一步验证。
相似论文推荐
基于向量语义检索推荐的相关论文。