1. 深度学习编译器概述:为什么需要深度学习编译器?

大家好,我是老张。做深度学习编译器这块也有些年头了。今天咱们聊聊最基础的问题——为什么我们需要深度学习编译器

说实话,我刚入行那会儿也觉得奇怪。深度学习框架不是挺多的吗?PyTorch、TensorFlow,直接用不就行了?干嘛还要搞个编译器出来?

嗯,后来我在一个落地项目里被狠狠教育了一回。那次要在嵌入式设备上跑一个BERT模型,PyTorch导出的模型直接跑,推理延迟200多毫秒。客户要求50毫秒以内。我折腾了整整两周,各种算子优化、手工调优,最后勉强压到80毫秒。后来用TVM重新编译了一遍,你猜怎么着?直接干到45毫秒。

从那以后,我就明白了——深度学习编译器不是锦上添花,而是刚需

1.1 为什么需要深度学习编译器?

说白了,深度学习编译器要解决的核心问题就一个:让模型在不同硬件上跑得又快又好

你想想看,现在的深度学习模型越来越复杂。几年前还是几层的CNN,现在动不动就是上百层的Transformer。硬件平台更是五花八门——NVIDIA的GPU、AMD的GPU、华为的昇腾、寒武纪的NPU、各种ARM的CPU、甚至还有RISC-V的AI加速器。

每个硬件都有自己的"脾气":

  • GPU喜欢并行计算,但不同架构的GPU对算子支持不一样
  • NPU通常只支持有限的算子集合,需要把复杂算子拆解
  • CPU上跑模型,内存带宽往往是瓶颈

我在一个项目里遇到过这种情况:同一个卷积算子,在NVIDIA V100上跑得飞快,换到华为昇腾310上就慢得像蜗牛。为什么?因为昇腾对某些卷积配置没有硬件加速,需要拆成多个小算子来执行。手工做这件事?累死你。

核心观点:深度学习编译器的本质,是把"写一次模型,到处都能高效运行"这个理想变成现实。

1.2 深度学习编译器与传统编译器的区别

很多人第一次接触深度学习编译器,会拿它和GCC、LLVM这些传统编译器做对比。我建议你换个角度想——它们解决的问题域完全不同

传统编译器,比如GCC,输入的是C/C++代码,输出的是机器码。它的优化目标很明确:让程序跑得更快,或者让代码体积更小。优化手段也相对固定:常量折叠、循环展开、指令调度、寄存器分配等等。

但深度学习编译器呢?输入的是一个计算图,输出的是针对特定硬件的可执行代码。它的优化目标要复杂得多:

对比维度 传统编译器 深度学习编译器
输入 高级语言源码 计算图(DAG)
输出 机器码/汇编 硬件可执行代码
优化目标 执行速度、代码体积 推理延迟、吞吐量、内存占用、功耗
优化粒度 指令级别 算子级别 + 图级别 + 指令级别
硬件适配 相对通用 高度定制化
典型代表 GCC, LLVM, MSVC TVM, XLA, Glow, nGraph

你看,区别还是挺明显的。我个人的理解是:传统编译器做的是"翻译+优化",深度学习编译器做的是"理解+重构+优化"

为什么会这样?因为深度学习模型的计算图有很强的语义信息。比如一个卷积算子,编译器知道它是在做特征提取,可以尝试各种等价变换——Winograd算法、FFT变换、Im2Col+GEMM等等。传统编译器面对的是通用代码,它不知道这段代码到底在干什么,所以不敢做太激进的变换。

一个小技巧:如果你之前做过传统编译器,转来做深度学习编译器,记得把思维从"指令优化"切换到"图优化"上来。我刚开始就犯过这个错,花了很多时间在底层指令优化上,结果发现图级别的融合和重排带来的收益更大。

1.3 深度学习编译器的核心价值

总结一下,深度学习编译器到底能给我们带来什么?

  1. 硬件抽象:你不需要为每个硬件平台手写算子。写一次模型,编译器帮你适配。
  2. 自动优化:算子融合、内存规划、并行调度,这些脏活累活编译器替你干了。
  3. 性能可移植:同一个模型在不同硬件上都能获得接近最优的性能。
  4. 降低开发成本:不用再养一个"算子优化团队"了。

我记得有一次跟一个做芯片的朋友聊天,他说他们公司之前每个新芯片出来,都要花三个月时间适配主流框架的算子。后来用了TVM,这个时间缩短到了两周。这就是深度学习编译器的价值。

注意:深度学习编译器不是万能的。对于某些极端场景(比如要在特定硬件上榨干每一分性能),手工优化的算子可能还是比编译器生成的代码快10%-20%。但编译器胜在通用性和开发效率。我的建议是:80%的场景用编译器,剩下20%的关键路径再手工调优。

1.4 知识体系总览

下面这张图是我自己整理的深度学习编译器知识体系,你可以把它当作整个课程的地图:

深度学习编译器知识体系 输入:计算图 前端优化(图级别) 算子融合 · 常量折叠 · 死代码消除 · 形状推断 中端优化(算子级别) 自动调度 · 内存规划 · 数据布局转换 · 并行策略 后端优化(硬件级别) 指令选择 · 寄存器分配 · 循环优化 · 硬件特化 输出:可执行代码 IR表示:Graph IR IR表示:Tensor IR IR表示:硬件IR

这张图展示了深度学习编译器的完整工作流程。从输入的计算图开始,经过前端、中端、后端三层优化,最终生成可执行代码。每一层都有自己独特的优化技术和中间表示(IR)。

后面的课程,我们会一层一层地深入进去。前端优化讲算子融合和形状推断,中端优化讲自动调度和内存规划,后端优化讲硬件特化和指令生成。每一层都有很多坑,我会把我在项目中踩过的坑都告诉你。

好了,这一章就到这里。记住一句话:深度学习编译器,本质上是在"计算图"和"硬件"之间搭一座自动化的桥。理解了这一点,后面的内容就好办了。


公众号:蓝海资料掘金营,微信deep3321