编译与图优化正文
页面目标
这页把图优化、融合、lowering、调度和 codegen 串成一条后端链路,而不是只停留在概念说明。
适用人群
- 想理解图优化、执行模型和 backend 差异的人。
- 正在排查“图看着没问题,但跑起来慢”的人。
- 想把编译视角和项目 benchmark 联系起来的人。
不适用人群
- 只关心上层业务逻辑,不关心执行链路的人。
- 还没建立图级 / 执行级基本概念的人。
- 只想看一个编译名词,不想看约束和代价的人。
你应该如何开始读
- 先读
1E-09 -> 1E-19,把图优化和融合的直觉立住。 - 再读
1E-32 -> 1E-33 -> 1D-08 -> 1D-29,看 lowering、调度和执行成本。 - 如果你关心 backend 差异,再看
09 -> 32 -> 33。 - 最后回到
2.2 -> 2.6 -> 2.7A -> 2.9,把后端视角接回项目。
故事线
一个典型的编译故事,是“图上看起来没问题,但跑起来就是慢”。最开始大家往往会以为是某个算子没有写好,或者模型结构本身不合理;但把链路往下走以后,问题常常出在图级融合没做好、lowering 没收敛、backend 约束没算进去。
第一步先看 1E-09 -> 1E-19,确认图里哪些地方真的贵。 第二步再看 1E-32 -> 1E-33,确认 lowering 和成本模型有没有把问题讲清楚。 第三步再看 1D-08 -> 1D-15 -> 1D-18 -> 1D-29,确认执行模型和调度是不是才是真正的瓶颈。 最后回到 2.2 -> 2.6 -> 2.7A -> 2.9,看 backend 视角是否真的能把项目结果拉起来。
这个故事的重点不是“编译器会自动变快”,而是图级、执行级和 backend 级必须分层看,才能找到真正该动手的地方。
具体案例
案例 1:图看着干净,但跑起来就是慢
现象是:图结构没有明显异常,算子数量也不夸张,但实际运行时就是慢。
判断链路是:先看 09 -> 19 -> 32,确认是不是中间张量和融合没做好;再看 1D-08 -> 1D-15 -> 1D-18 -> 1D-29,确认是不是执行模型和调度才是问题根源。
常见结论是:
- 图级上看起来合理,不代表执行级就合理。
- 如果 backend 侧仍然需要频繁搬运,中间张量省不下来,速度就很难起来。
这个案例的重点是:图优化不是只看“看起来漂亮”,而是看它最终有没有减少执行成本。
案例 2:lowering 和 codegen 看起来都过了,但性能没涨
现象是:pass pipeline 跑通了,代码也生成了,但 benchmark 没有明显改善。
判断链路是:先看 1E-32 -> 1E-33,确认 lowering 和成本模型是不是只停留在语义正确;再看 1D-08 -> 1D-18 -> 1D-29,确认 kernel 组织和调度是否真的把问题解决。
常见结论是:
- lowering 的正确,不等于性能上的划算。
- 如果 schedule 没跟上,codegen 只能把“可执行”变成“能跑”,不一定变成“跑得好”。
这个案例的重点是:编译链路里最容易被误判的,就是“已经翻译出来了”不代表“已经优化好了”。
案例 3:同一张图在不同 backend 上差距很大
现象是:同一份模型结构,在不同 backend 上跑出来的结果差异明显。
判断链路是:先看 09 -> 32 -> 33,确认是否是目标硬件和成本模型不同;再看 2.2 -> 2.6 -> 2.7A -> 2.9,确认 backend 视角是否真的回到了项目指标。
常见结论是:
- backend 差异不是异常,而是约束不同。
- 如果只盯一个 backend 的经验,很容易误判其他平台。
这个案例的重点是:编译优化必须和目标后端绑定,否则“优化结论”很容易失效。
图级
图级关心的是“哪些算子可以被看成同一组问题”。这一层先处理结构和成本向量,而不是立即下沉到 kernel。
| 问题 | 先看什么 | 你要确认什么 |
|---|---|---|
| 图里哪里贵 | 09 -> 33 | 成本向量和 TCO 是否匹配 |
| 融合是否值得 | 19 -> 09 -> 32 | 中间张量是否真的减少 |
| 图级判断是否成立 | 1E-09 -> 1E-19 | 图结构和 backend 约束是否冲突 |
执行级
执行级关心的是“高层图被收敛成什么可执行形式”。这一层已经开始处理 lowering、schedule 和执行成本。
| 问题 | 先看什么 | 你要确认什么 |
|---|---|---|
| lowering 为什么不是翻译 | 32 | pass pipeline 是否合法且逐层收敛 |
| 调度怎么影响执行 | 1D-15 -> 1D-29 | 执行顺序是否更合理 |
| 编程模型和执行模型怎么接 | 08 -> 15 -> 18 | kernel 组织是否符合硬件约束 |
backend 级
backend 级关心的是“同一张图在不同目标上为什么会有不同结果”。这一层最容易和具体硬件和编译器实现耦合。
| 问题 | 先看什么 | 你要确认什么 |
|---|---|---|
| 为什么不同 backend 不一样 | 09 -> 32 -> 33 | 目标硬件约束和成本是否不同 |
| 为什么 kernel 视角重要 | 1D-08 -> 1D-18 -> 1D-29 | 图级优化是否已经下沉到可执行实现 |
| 后端结果如何回到项目 | 2.2 -> 2.6 -> 2.7A -> 2.9 | 后端优化是否真的改善项目指标 |
一页速记
| 层级 | 你主要关心什么 | 在本专题里怎么看 |
|---|---|---|
| 图级 | 图里哪些算子可以合并、消掉或重排 | 先看 1E-09 -> 1E-19 |
| 执行级 | lowering 之后怎么排、怎么跑、怎么省开销 | 再看 1E-32 -> 1E-33 -> 1D-08 -> 1D-29 |
| 后端级 | 不同 backend 为什么会有不同结果 | 回看 09 -> 32 -> 33 和 1D-18 |
| 收口层 | 最终怎么回到项目和 benchmark | 最后看 2.2 -> 2.6 -> 2.7A -> 2.9 |
建议阅读顺序
- 先看
1E-09 -> 1E-19,把图优化和融合的直觉立住。 - 再看
1E-32 -> 1E-33,把 lowering 和成本模型补齐。 - 再看
1D-08 -> 1D-15 -> 1D-18 -> 1D-29,把执行模型和调度接起来。 - 最后回到
2.2 -> 2.6 -> 2.7A -> 2.9,看后端视角怎么回到项目结果。
典型阅读链
- 如果你想先理解“图里哪里贵”,先读
09 -> 33。 - 如果你想先理解“为什么融合能省”,先读
19 -> 09 -> 32。 - 如果你想先理解“lowering 为什么不是翻译”,先读
32。 - 如果你想先理解“编译和 kernel 为什么会连在一起”,先读
08 -> 15 -> 18 -> 29。 - 如果你想先理解“同一张图为什么在不同 backend 上不一样”,先读
09 -> 32 -> 33。 - 如果你想先理解“后端优化怎么回到项目”,先读
2.2 -> 2.6 -> 2.7A -> 2.9。
进一步展开
1. 先判断层级
- 如果问题还停留在图结构和依赖关系,优先按图级处理。
- 如果问题已经涉及合法化、执行顺序和调度,优先按执行级处理。
- 如果问题和特定硬件、后端或 kernel 绑定很强,优先按 backend 级处理。
2. 再判断成本
- 看是不是中间张量、布局变化、pass 代价或者执行气泡在吃成本。
- 看是否需要把问题下沉到更靠近硬件的层级。
- 看优化目标是不是已经从“图更漂亮”变成“执行更划算”。
3. 最后判断回收点
- 图级优化最后要回到执行级验证。
- 执行级优化最后要回到 benchmark 验证。
- backend 级优化最后要回到项目指标验证。
对照表
| 场景 | 先看什么 | 重点差异 |
|---|---|---|
| 图级优化 | 1E-09 -> 1E-19 | 看算子合并、消除和重排 |
| 执行级优化 | 1E-32 -> 1E-33 -> 1D-29 | 看 lowering、调度和执行成本 |
| backend 差异 | 09 -> 32 -> 33 | 看不同后端的约束和收益 |
| 回到项目 | 2.2 -> 2.6 -> 2.7A -> 2.9 | 看优化怎么回到实际结果 |
常见错误
- 以为编译器会自动解决所有性能问题。
- 只盯 fusion,不看 lowering 和 codegen。
- 忽略不同 backend 的差异。
- 用图级语言解释所有执行问题,结果层级对不上。
FAQ
Graph Optimization和Fusion是一回事吗?不是,前者是图级结构和成本判断,后者是减少中间结果和搬运的具体手段。- 为什么要把
Lowering单独拿出来?因为它决定了高层表示如何逐层收敛成可执行形式,很多问题不是“能不能翻译”,而是“能不能合法且高效地下沉”。 - 这个专题是不是 Part 3 的替代品?不是,它更像是前后端之间的观察层,帮你理解为什么后端实现会受图和 backend 约束影响。
- 为什么要把
Part 1E和1D一起看?因为一个负责图与编译视角,一个负责执行和 kernel 视角,合在一起才完整。
深入阅读
- 想看完整后端链路故事,去 编译与图优化深入阅读。
- 想快速回顾摘要、图级和清单,继续留在本页即可。
相关专题
- Profiling 专题:当你先要确认图优化是不是确实带来收益时看这里。
- 推理优化专题:当 backend 差异直接影响推理路径和 cache 行为时看这里。
- 通信与并行专题:当执行模型和通信调度、并行切分一起分析时看这里。
判断清单
- 先看问题是“图太贵”还是“执行太慢”。
- 再判断瓶颈是
fusion、layout、lowering还是scheduling。 - 再看优化是应该停留在图级,还是必须下沉到 kernel / backend。
- 再对照
Part 1E / 1D,确认优化是不是和硬件约束一致。 - 最后回到
2.2 / 2.6 / 2.7A / 2.9,看后端视角是否真的改善了项目结果。
小结
编译与图优化专题的价值,是把“为什么某些优化能落地”讲清楚,而不是把编译术语再堆一遍。
