Graph Optimization(圖最佳化)
3 秒看懂
圖最佳化 = 把 AI 模型的”計算藍圖”(計算圖)自動重寫,合併冗餘步驟、刪掉廢操作、調整執行順序,讓同一模型跑得更快、佔更少記憶體、耗更少算力——AI 編譯器的核心引擎。
類比:就像一份菜譜的”精簡版”——把”先切蔥,再切蔥”合併為”一次切蔥”,把”加熱→冷卻→再加熱”最佳化為直接用溫的食材,步驟少了,出菜速度翻倍,廚房空間也省了。
3 分鐘產業解釋
什麼是計算圖
深度學習架構(PyTorch、TensorFlow)會把使用者寫的 Python 模型程式碼轉換成一張有向無環圖(DAG):
- 節點:運算元(Conv2d、MatMul、ReLU、Softmax…)
- 邊:張量資料流(tensor)的依賴關係
這張圖就是模型的”執行藍圖”。架構 runtime 按圖逐節點執行。
為什麼需要圖最佳化
原始計算圖是”教科書式”的:忠於使用者程式碼,但不考慮硬體特性。常見問題:
| 原始圖的問題 | 最佳化手段 | 效果 |
|---|---|---|
| 兩個小運算元序列,各讀寫一次視訊記憶體 | 運算元融合(Operator Fusion) 合為一個 kernel | 減少視訊記憶體頻寬壓力 |
| 計算中產生大量中間張量 | 記憶體規劃/複用(Memory Planning) | 降低峰值視訊記憶體佔用 |
| 死程式碼、冗餘計算 | 死程式碼消除(DCE)、常量摺疊(Constant Folding) | 減少無效計算 |
| 資料版面配置不適合硬體 | 版面配置轉換(Layout Optimization) 如 NCHW↔NHWC | 匹配硬體偏好 |
| 某些 pattern 可被硬體特化指令加速 | Pattern Matching + 替換 | 利用專用指令集 |
誰在做圖最佳化
- 推論側:NVIDIA TensorRT、Intel OpenVINO、Qualcomm QNN、Apple Core ML、華為 MindSpore Lite
- 訓練/通用編譯:Google XLA(TPU 生態)、PyTorch 2.0 的
torch.compile(TorchInductor/TorchDynamo)、Apache TVM、微軟 ONNX Runtime - 學術/開源:MLIR(LLVM 子專案)提供統一 IR,成為新一代編譯基礎設施
產業定位:圖最佳化是 AI 編譯器的”中端(middle-end)“——前端把架構模型轉為 IR,中端做圖級最佳化,後端生成硬體指令。它是連線”模型”和”晶片”的關鍵中間層。
15 分鐘專家深入
圖最佳化的技術分層
圖最佳化並非單一 pass,而是一個多層級的最佳化流水線:
┌─────────────────────────────────────────────────────────────┐
│ 圖最佳化流水線 │
├─────────────────────────────────────────────────────────────┤
│ Level 0: 通用圖變換 │
│ - 常量摺疊(Constant Folding) │
│ - 死程式碼消除(Dead Code Elimination) │
│ - 公共子表示式消除(CSE) │
│ - 冗餘轉置消除(Transpose Elimination) │
├─────────────────────────────────────────────────────────────┤
│ Level 1: 數學等價變換 │
│ - 運算元代數簡化(如 Conv+BN 融合) │
│ - MatMul + Bias + Activation → Fused GEMM │
│ - Softmax 數值穩定化改寫 │
├─────────────────────────────────────────────────────────────┤
│ Level 2: 硬體感知最佳化(需後端反饋) │
│ - 運算元融合(Operator Fusion / Kernel Fusion) │
│ - 記憶體規劃(Memory Planning / Liveness Analysis) │
│ - 資料版面配置最佳化(Layout Transform) │
│ - 並行策略(如 Tensor Parallelism 切分點選擇) │
├─────────────────────────────────────────────────────────────┤
│ Level 3: 代數化/Tile 級最佳化 │
│ - Loop Tiling / Blocking │
│ - 向量化 / Tensorization │
│ - Prefetch / Pipeline 排程 │
└─────────────────────────────────────────────────────────────┘
關鍵 Pass 詳解
1. 運算元融合(Operator Fusion)
核心思想:多個運算元合為一個 kernel launch,減少 kernel 啟動開銷和中間張量的視訊記憶體讀寫。
常見融合 pattern:
| 融合型別 | 示例 | 機制 |
|---|---|---|
| 水平融合 | 多個相同 shape 的 elementwise op | 並行執行,共享一次視訊記憶體讀寫 |
| 垂直融合 | Conv → BN → ReLU | 後者消費前者的輸出,直接在暫存器/共享記憶體中傳遞 |
| Reduction 融合 | MatMul → Softmax → MatMul | 中間結果保留在片上,避免回寫 |
工程難點:
- 融合不是無限的——GPU 每個 kernel 的暫存器/共享記憶體有限,融合過度會導致 occupancy 下降
- 不同硬體(NVIDIA GPU / CPU / NPU)的融合規則不同,需要 cost model 或 profile 指導
2. 常量摺疊(Constant Folding)
編譯期將純常量子圖計算出結果,直接替換為常量張量。
# 最佳化前
x = tf.constant([1, 2, 3])
y = tf.constant([4, 5, 6])
z = x + y # 執行時才計算
# 最佳化後(常量摺疊)
z = tf.constant([5, 7, 9]) # 編譯期直接算好
對量化模型特別重要:量化引數的 scale/zero_point 計算往往是純常量圖。
3. 死程式碼消除(DCE)
移除不影響最終輸出的節點。常見於:
- 模型剪枝後殘留的未連線運算元
- 條件分支中不可達的子圖
- 除錯/日誌運算元在生產環境的移除
4. 記憶體規劃(Memory Planning)
問題:計算圖執行過程中,各張量的生命週期(live range)不同,如何分配視訊記憶體使峰值最小?
方法:
- 圖著色演算法:對 interference graph 做著色,同色張量可共享記憶體
- Greedy by size:按張量大小貪心分配
- 更先進的方法:考慮碎片化、對齊約束、多 stream 併發
實際影響:對大型模型推論尤其關鍵——相同硬體,最佳化前可能 OOM,最佳化後可跑。
5. 資料版面配置最佳化(Layout Optimization)
不同硬體對 tensor 記憶體版面配置的偏好不同:
- NVIDIA Tensor Core:對 NHWC、特定 tiling 格式有硬體加速
- Intel VNNI 指令:要求特定的資料排列
- NPU/TPU:通常有固定的 layout 要求
圖最佳化器需要在圖中插入最少的 layout transform 節點,同時滿足各運算元的 layout 約束——這是一個約束滿足問題。
技術原理(最深)
計算圖的 IR 表示
圖最佳化操作的是 中間表示(Intermediate Representation, IR)。不同架構的 IR 各有特點:
| IR | 所屬 | 特點 |
|---|---|---|
| ONNX | ONNX 社群(微軟/Facebook 主導) | 標準化交換格式,靜態圖,運算元集版本化 |
| HLO | Google XLA | XLA 的高層 IR,保留高階運算語義,迴圈以控制流(如 while)或 reduce 形式存在,強型別 |
| StableHLO | MLIR 生態(Google 貢獻) | HLO 的 MLIR dialect 版本 |
| TorchScript IR | PyTorch | 基於 SSA 的靜態子圖表示 |
| FX Graph | PyTorch Dynamo | 基於 Python bytecode 的輕量 IR |
| Relay / TIR | Apache TVM | Relay 做高層圖最佳化,TIR 做低層程式碼生成 |
| MLIR Dialects | LLVM 子專案 | 多層級 dialect(linalg, tensor, scf…),可混合不同抽象層 |
MLIR 的特殊地位:它不是一個 IR,而是一個 IR 架構(IR Framework)——允許定義不同抽象層級的 dialect,用統一 pass infrastructure 做變換。當前業界趨勢是向 MLIR 收斂。
Pass Infrastructure
圖最佳化的執行依賴於 Pass Manager:
PassManager
├── GraphPass 1 (常量摺疊)
├── GraphPass 2 (DCE)
├── GraphPass 3 (運算元融合 - pattern matching)
├── GraphPass 4 (版面配置最佳化)
├── GraphPass 5 (記憶體規劃)
└── GraphPass 6 (目的碼生成 - delegation to backend)
每個 Pass:
- 輸入:一個 IR(計算圖)
- 輸出:變換後的 IR
- 可配置:是否依賴後端、是否需要 profile 資料
Pass 排序問題:不同 Pass 之間可能有依賴關係(如 DCE 需要在融合之後再跑一次)。Pass Manager 需要處理這些依賴。
運算元融合的形式化
運算元融合的本質是 子圖替換(Subgraph Replacement):
Pattern: [A] → [B] → [C] (A、B、C 為運算元型別)
Replace: [FusedABC] (如果 A,B,C 的 shape/型別滿足條件)
實現方式:
- 基於規則:人工定義可融合的 pattern 白名單(TensorRT 主要方式)
- 基於搜尋:TVM 的 AutoTVM/Ansor,搜尋最優的運算元組合和 tiling 策略
- 基於 Cost Model:訓練一個 ML 模型預測融合後的效能,指導是否融合
圖示——垂直融合的記憶體效果:
未融合:
Conv2D: 讀 input[224×224×3] → 計算 → 寫 output[112×112×64]
BatchNorm: 讀 output[112×112×64] → 計算 → 寫 output'[112×112×64]
ReLU: 讀 output'[112×112×64] → 計算 → 寫 output''[112×112×64]
視訊記憶體頻寬: 3次讀 + 3次寫 (中間張量各讀寫一次)
融合後:
Conv2D_BN_ReLU: 讀 input → 計算(在暫存器/共享記憶體中完成BN和ReLU) → 寫 output
視訊記憶體頻寬: 1次讀 + 1次寫
節省: ~67% 視訊記憶體頻寬 (此例)
記憶體規劃演算法詳解
核心問題是 區間圖著色(Interval Graph Coloring):
張量生命週期(live range):
t0: ████████ (張量 A)
t1: ████████████ (張量 B)
t2: ████████ (張量 C)
t3: ████████████(張量 D)
時刻: 0 1 2 3 4 5 6 7 8
Interference Graph: (生命週期重疊的張量連邊)
A-B, A-C, B-C, B-D, C-D
圖著色(最少顏色 = 最少記憶體塊):
A→色1, D→色1 (不重疊,可複用)
B→色2
C→色3
結果: 3塊記憶體,峰值 = max(|A|+|B|+|C|, |B|+|D|, ...)
實際工程中還需考慮:張量對齊要求、多 stream 併發、動態 shape 的不確定性。
動態 Shape 的圖最佳化挑戰
許多模型有動態維度(如序列長度可變):
- 靜態圖最佳化假設 shape 固定,可做更激進的最佳化
- 動態 shape 下,融合規則可能因 shape 變化而失效
- 解決方案:Shape-specialized compilation(為不同 shape 範圍編譯不同版本)、Trace-and-specialize
技術演進史
2015 TensorFlow 1.x 引入靜態計算圖(Graph Mode)
└─ 開啟"先定義圖,再執行"的範式
2016 TensorRT 1.0 釋出
└─ 業界首個商業化圖最佳化推論引擎(NVIDIA)
2017 TVM 論文發表(陳天奇等,華盛頓大學)
└─ 提出端到端編譯棧,引入 AutoTVM 自動調優
2018 ONNX 標準逐漸成型
└─ 計算圖的跨架構交換成為可能
2018 PyTorch 1.0 引入 TorchScript / JIT
└─ 嘗試在 eager mode 架構上建靜態圖最佳化能力
2019 MLIR 專案啟動(Chris Lattner,LLVM 之父)
└─ 統一編譯基礎設施的願景
2022 XLA 在 TPU 上預設使用,但在 TensorFlow 2.9 中 CPU/GPU 尚未預設啟用(需手動開啟)
└─ 端到端圖最佳化 + 程式碼生成
2023 PyTorch 2.0 釋出 torch.compile
└─ TorchDynamo (圖捕獲) + TorchInductor (後端) 架構
└─ 標誌著 eager mode 架構全面擁抱圖最佳化
2023 StableHLO 成為 MLIR 生態的穩定 HLO dialect
└─ JAX/XLA 生態向 MLIR 收斂
2024 圖最佳化與大型模型訓練/推論深度結合
└─ MoE routing 的圖級最佳化、投機解碼的圖變換、
KV-cache 管理的圖級推論等成為熱點
2025 圖最佳化走向"編譯時-執行時協同"
└─ 線上 profiling → 圖重編譯(如 PyTorch 的
profile-guided optimization in Inductor)
關鍵轉折點:
- 2022 年 torch.compile 是分水嶺——證明了”易用性(eager mode)+ 高效能(圖最佳化)“可以兼得
- MLIR 的崛起改變了圖最佳化的基礎設施層
技術路線對比
| 維度 | TensorRT | XLA | TVM | TorchInductor | ONNX Runtime |
|---|---|---|---|---|---|
| 所屬 | NVIDIA | Apache(學術主導) | Meta PyTorch | 微軟 | |
| 主要場景 | NVIDIA GPU 推論 | TPU/GPU 訓練+推論 | 多硬體(學術+工業) | PyTorch 生態訓練+推論 | 跨架構推論 |
| 圖捕獲方式 | ONNX/自有 parser | JAX jit / TF function | Relay IR import | TorchDynamo bytecode trace | ONNX model load |
| 融合策略 | 規則 + profiling | HLO pass(規則為主) | Relay FuseOps(規則) | Triton codegen(規則+模板) | 規則 + 執行提供者 |
| 程式碼生成 | CUDA kernel 庫 | LLVM → PTX/機器碼 | LLVM/自定義後端 | Triton → CUDA | 各執行提供者 |
| 動態 Shape | 有限支援(profile 多種 shape) | 部分支援 | 支援(需額外配置) | 通過 recompilation 支援 | 有限支援 |
| 硬體覆蓋 | NVIDIA GPU 專精 | TPU 專精,GPU 通用 | 廣泛(GPU/CPU/FPGA/NPU) | GPU(CUDA)、CPU | 廣泛(通過 EP) |
| 開源程度 | 閉源(runtime 開源) | 開源(部分) | 完全開源 | 完全開源 | 開源 |
| 成熟度 | 生產級 | 生產級(TPU 生態) | 生產級(需調優) | 快速成熟中 | 生產級 |
| 學習曲線 | 中等 | 高(需理解 XLA/JAX) | 高 | 中等 | 低 |
趨勢判斷:
- 推論側:TensorRT 在 NVIDIA 生態仍佔主導,但 TensorRT-LLM 等專用最佳化器在崛起
- 訓練側:PyTorch + torch.compile 逐步成為主流
- 編譯基礎設施:MLIR 方向是共識
上下游
上游(圖最佳化的輸入來源)
| 層級 | 環節 | 代表 |
|---|---|---|
| 模型定義 | 架構 API | PyTorch、TensorFlow、JAX、PaddlePaddle |
| 圖捕獲 | 靜態圖/Tracing/JIT | TorchDynamo、JAX jit、TF function |
| 模型交換 | 標準化格式 | ONNX、StableHLO、TorchScript |
| 運算元定義 | 標準運算元集 | ONNX Opset、HLO ops、MLIR linalg |
下游(圖最佳化的輸出去向)
| 層級 | 環節 | 代表 |
|---|---|---|
| 程式碼生成 | 後端編譯器 | LLVM、Triton、CUDA codegen、TVM TIR |
| 運算元庫 | 高度最佳化的 kernel | cuDNN、cuBLAS、MIOpen、oneDNN |
| Runtime | 架構執行時 | TensorRT Runtime、TVM Runtime、PyTorch eager |
| 硬體 | 目標加速器 | NVIDIA GPU、Google TPU、各種 NPU、CPU(x86/ARM) |
產業鏈位置
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ 模型訓練 │ → │ 模型匯出 │ → │ 圖最佳化 │ → │ 程式碼生成 │ → 硬體執行
│(PyTorch) │ │(ONNX等) │ │(編譯中端) │ │(編譯後端) │
└──────────┘ └──────────┘ └──────────┘ └──────────┘
↑
我們討論的是這裡
"AI編譯器的心臟"
關鍵指標
效能指標
| 指標 | 含義 | 典型量級(估算) |
|---|---|---|
| 推論延遲(Latency) | 單次推論耗時 | 圖最佳化通常可帶來 1.5x~5x 加速(vs 未最佳化 eager) |
| 吞吐量(Throughput) | 單位時間處理樣本數 | 提升幅度與延遲類似 |
| 峰值記憶體(Peak Memory) | 視訊記憶體/記憶體佔用峰值 | 記憶體規劃通常可降 20%~50% [估算] |
| Kernel Launch 次數 | GPU kernel 啟動次數 | 融合後可大幅減少(數量級級別降低) |
| 視訊記憶體頻寬利用率 | 實際頻寬 vs 理論頻寬 | 最佳化後更接近 roofline |
編譯指標
| 指標 | 含義 | 關注點 |
|---|---|---|
| 編譯時間 | 圖最佳化 + 程式碼生成耗時 | 首次編譯可能數秒到數分鐘;需考慮是否影響使用者體驗 |
| 編譯記憶體 | 編譯器本身記憶體佔用 | 大型模型編譯時可能成為瓶頸 |
| Pass 正確性 | 最佳化後模型精度是否變化 | 數值誤差需在可接受範圍內 |
最佳化覆蓋率指標
| 指標 | 含義 |
|---|---|
| 運算元覆蓋率 | 圖最佳化器支援的運算元佔模型總運算元的比例 |
| 融合覆蓋率 | 被融合的運算元佔可融合運算元的比例 |
| fallback 比例 | 無法最佳化、回退到預設實現的子圖佔比 |
供需與市場資料
需求側驅動力
- 大型模型推論成本:LLM 推論成本佔 AI 部署總成本的大頭(估算 >60%),圖最佳化是降本核心手段
- 端側 AI:手機/IoT/車載晶片算力有限,圖最佳化是”免費”獲取效能的關鍵
- 多硬體生態:雲端端 GPU/TPU、邊緣 NPU、端側 DSP,每個都需要圖最佳化適配
- 訓練效率:大型模型訓練成本極高(單次 GPT-4 級訓練估算數千萬美元),訓練側圖最佳化也有顯著經濟價值
供給側格局
| 型別 | 代表 | 商業模式 |
|---|---|---|
| 晶片廠商自有編譯器 | NVIDIA TensorRT, Intel OpenVINO, Qualcomm QNN | 繫結自家硬體生態 |
| 雲端廠商/架構內建 | Google XLA, Meta TorchInductor | 支撐自家雲端服務和架構競爭力 |
| 獨立編譯器/工具鏈 | Apache TVM(商業公司 OctoML), ONNX Runtime | 提供跨平台編譯服務 |
| AI 編譯創業公司 | Modular (Mojo), Centml, 壁仞(部分) | AI 編譯器即服務 |
市場規模(估算)
- AI 編譯器/最佳化工具作為獨立市場尚無權威統計口徑——它嵌入在推論架構、晶片 SDK、雲端服務中
- 間接參考:全球 AI 推論市場(包含硬體+軟體)規模在數百億美元量級 [多家行研估算],圖最佳化是推論軟體棧的核心價值環節
- Modular(Chris Lattner 創辦)2022 年融資估值超過 $1B [公開報道],反映資本市場對 AI 編譯基礎設施的重視
代表公司與資本對映
| 公司/組織 | 圖最佳化產品/技術 | 資本/上市資訊 |
|---|---|---|
| NVIDIA | TensorRT, TensorRT-LLM | NASDAQ: NVDA |
| XLA, MLIR 貢獻, JAX | Alphabet (NASDAQ: GOOGL) | |
| Meta | TorchDynamo, TorchInductor | NASDAQ: META |
| Microsoft | ONNX Runtime, Olive | NASDAQ: MSFT |
| Modular | Mojo 語言, MAX 引擎 | 私有(融資估值 >$1B [公開報道]) |
| OctoML | TVM 商業化, OctoAI | 私有 |
| Centml | 基於 TVM 的編譯最佳化平台 | 私有 |
| 華為 | MindSpore 圖最佳化, Ascend 編譯器 | 未上市(海思半導體) |
| 寒武紀 | Neuware 編譯器 | 688256.SH |
| 壁仞科技 | BIRENSUPA 編譯棧 | 私有 |
| 百度 | PaddlePaddle 圖最佳化, XPU 編譯器 | NASDAQ: BIDU / 9888.HK |
資本對映邏輯:
- 純做 AI 編譯器的上市公司極少——它主要是巨頭的基礎設施投入
- 間接受益標的:NVIDIA(TensorRT 強化 CUDA 生態護城河)、AI 編譯器創業公司(一級市場)
- 國內關注:華為昇騰生態的編譯器成熟度、國產 GPU 廠商的編譯器能力
投資邏輯
核心投資主題
-
“編譯器即護城河”
- NVIDIA 的 CUDA + TensorRT 生態是其 AI 晶片霸主地位的核心護城河
- 圖最佳化器的運算元覆蓋、融合質量、硬體適配是多年工程積累,難以快速複製
-
“編譯器決定硬體可用性”
- 同一款晶片,有無成熟的圖最佳化工具鏈,效能可能差 2~10 倍 [估算]
- 這直接決定晶片是否能進入實際部署
-
“AI 編譯器創業視窗”
- Modular 的 Mojo 語言試圖從程式語言層面重新定義 AI 編譯
- 中國 AI 編譯器人才稀缺,創業公司有機會
風險點
| 風險 | 說明 |
|---|---|
| 巨頭擠壓 | NVIDIA/Google/Meta 持續投入,獨立編譯器公司空間被壓縮 |
| 架構繫結 | PyTorch torch.compile 成熟後,第三方編譯器的價值降低 |
| 硬體碎片化 | 適配大量硬體的成本極高,初創公司難以覆蓋 |
| 評估困難 | 圖最佳化效果高度依賴具體模型+硬體,難以通用化評估 |
常見誤讀糾偏
誤讀 1:“圖最佳化 = 量化”
糾偏:量化(INT8/FP16 量化)是圖最佳化可應用的一個場景,但圖最佳化的範圍遠大於量化。量化是資料型別變換,圖最佳化是圖結構變換(融合、消除、重排、記憶體規劃等)。兩者是正交維度,可疊加使用。
誤讀 2:“圖最佳化能無限加速,XX 倍提升”
糾偏:圖最佳化的加速受限於硬體 roofline 和原始圖的最佳化空間:
- 如果模型已經是 compute-bound(計算瓶頸),減少視訊記憶體頻寬的融合收益有限
- 如果原始架構已經做了基本最佳化,進一步提升空間更小
- 實際加速倍數因模型、硬體、baseline 對比不同而差異巨大——宣傳中的”10x”往往是以未最佳化 eager mode 為 baseline,參考價值有限
誤讀 3:“torch.compile 能替代 TensorRT”
糾偏:兩者定位不同:
torch.compile是 PyTorch 訓練+推論的通用編譯最佳化,覆蓋多種硬體- TensorRT 是 NVIDIA GPU 推論專用的深度最佳化引擎,包含圖最佳化 + 運算元自動調優 + 精度校準
- 在 NVIDIA GPU 推論場景,TensorRT 的最佳化深度通常優於 torch.compile
- torch.compile 的優勢在於易用性和訓練支援
誤讀 4:“圖最佳化是一次性編譯,不需要執行時資訊”
糾偏:現代圖最佳化正走向 編譯時-執行時協同:
- Profile-Guided Optimization (PGO):先用執行時 profile 資料指導編譯最佳化
- Speculation + Recompilation:如 PyTorch 2.0 會先假設靜態 shape 編譯,遇到新 shape 時重新編譯
- Continuous Profiling:執行時持續監測,必要時觸發重最佳化
學習路徑
入門(~2 周)
- 理解計算圖:用 PyTorch 畫一個簡單模型的計算圖(
torch.jit.trace或torch.fx) - 跑一遍 ONNX:匯出模型為 ONNX,用 Netron 視覺化,感受”圖長什麼樣”
- 體驗 torch.compile:對同一個模型,對比 eager mode vs
torch.compile的速度
進階(~1-2 月)
- 讀 TVM 教程:TVM 官方教程 的 Relay pass 部分
- 讀 TensorRT 開發者指南:瞭解 fusion rules、layer fusion 的實操
- 學 MLIR 基礎:MLIR 官方教程——理解 dialect、pass、pattern rewrite
深入(~3-6 月)
- 讀論文:
- “TVM: An Automated End-to-End Optimizing Compiler for Deep Learning” (OSDI 2018)
- “Glow: Graph Lowering Compiler Techniques for Neural Networks” (arXiv 2018)
- “MLIR: Scaling Compiler Infrastructure for Domain Specific Computation” (CGO 2021)
- 讀原始碼:PyTorch `to