AI/ML Compiler & Runtime:從硬體 Mismatch 開始的 AI/ML Stack 重構之旅

January 18, 2026

記錄在邊緣裝置上打造客製化 AI Compiler 與 Runtime 的實務經驗,從硬體限制到系統設計的完整歷程。

AI/ML Compiler and Runtime

AI/ML Compiler and Runtime

我原以為只是把模型轉過去跑,現實是 Compiler 與 Runtime 與硬體規格上的假設互相打架。只好從零把假設拆開,再一個個拼回去。

前言:當「業界標準」不再是標準答案

想像一下,你拿到一顆晶片。規格書上寫著不錯的算力數字,老闆期待你讓 AI 模型在上面飛起來。

你打開 TensorFlow,照著官方文件一步步走,模型順利跑起來了。

然後你看了一眼效能數字,沉默了。

這顆晶片的算力,連一半都沒展現出來。

▉ 當「標準流程」變成成本

這不是假設情境。這是我在開發公司內部神經網路 SDK UPDL CompilerUPDL Runtime 時的親身經歷。

問題的根源很簡單,也很殘酷:硬體與主流 Toolchain 之間,存在本質的不適配。

我們的晶片是一顆以 RISC-V 為核心的 CPU,搭配專為 CNN 優化的 NPU。理論上,這是邊緣 AI 的標準組合。


傳統路線:看起來很美的標準答案

一開始,我們選的是業界的標準路線:

  • TensorFlow 訓練模型 (Model Authoring)
  • TFLite Converter (Program Preparation)
  • LiteRT / TFLite Micro 部署 (Runtime Execution)

這條路的好處是生態成熟、踩坑有社群陪。

但問題也來得很快。


硬體 Mismatch:魔鬼藏在每一層的邊界

▉ 一開始,我們也想省事

專案初期,我們很務實地選擇借助 ARM 生態:LiteRT 當 Runtime,CMSIS-NN 當 Kernel library,NPU 負責加速部分運算。

軟體吃成熟生態的紅利,硬體專心榨算力。

但當整條 Pipeline 串起來,問題開始浮現。效能不是被計算吃掉的是被那些「看起來合理的假設」一點一點侵蝕掉的。


Mismatch #1:Int8 的世界觀,撞上 Int16 的現實

CMSIS-NN 是為 Int8、Cortex-M、極度受限的記憶體環境設計的。

但我們的 NPU 原生支援 Int16。

這個 Mismatch 的後果很直接:

  1. Casting overhead:Int8 → Int16 的擴展無法避免
  2. 精度優勢吃不到:明明硬體能做更精確的運算,卻被軟體框架拖回 Int8 的世界觀

我們付出了額外成本,卻沒換到對等的回報。這筆帳怎麼算都不划算。

模型確實「能跑」。但這跟「跑得好」是兩回事。

能跑不等於能用。這是我在邊緣 AI 學到的第一課。


Mismatch #2:Tensor Layout,真正的大魔王

如果說 Precision mismatch 是慢性病,Tensor layout 就是急性發作。

CHW 還是 HWC? 這從來不是對錯問題,而是軟硬體怎麼搭配的問題。

我們的硬體為 CHW 優化。TensorFlow 整路的 Toolchain 預設 HWC。

結果?同一份 Tensor 在每一層 Kernel 的邊界被反覆重排:

  • Pre-kernel: HWC → CHW
  • Dispatch to NPU
  • Post-kernel: CHW → HWC

效能不是輸在計算核心,是輸在資料搬來轉去。這是我在邊緣 AI 學到的第二課


轉折點:當你發現標準答案是錯的

意識到這件事之後,選擇其實很清楚。

如果想讓硬體發揮真正的能力,就不能繼續依賴為別人設計的工具。

於是我們走上了艱辛的路:專為公司硬體設計的客製化 Compiler + Runtime Stack

這個任務,落到了我頭上。


從零開始寫 Compiler:一段沒有地圖的旅程

老實說,寫 Compiler 這件事一點都不浪漫。

專案開始時,公司沒人做過這個。每踏出一步,對公司是新技能;對我來說,是持續走進未知。

沒有前人經驗可以參考,沒有內部文件可以查。很多時候我只能反覆問自己:

這個選擇,能不能讓系統往前走一步?

能,就做。不確定,就先試。


為什麼不用 ONNX / MLIR / TFLite Convertor?

這是我被問最多的問題。

我們當然也研究過。直接改 TFLite Convertor 原始碼或是借助 ONNX 生態性的完整,又或是導入 MLIR 優雅的架構。

但當時的判斷是:現在導入,風險大於收益。

原因很現實:

  • 沒人能確定我們真的吃得到它們的好處
  • 對自家硬體的理解還在建立中
  • 一旦架構選錯,要回頭會非常痛苦

所以我們選了一條看起來很土但很實際的路:先做 MVP,跑通再說。


MVP 的錨點:MLPerf Tiny Golden Models

我們用 MLPerf Tiny 的 Golden model 們當第一個目標。

  • 技術面:打通 Compiler → Runtime → Hardware 整條路
  • 組織面:產出能對外報告的 Benchmark 數字

這不是最完美的選擇。但它是當下能走得動的選擇。


Model Compiler:不只是轉模型,是重建執行邏輯

Model compiler 的工作遠比「把模型轉成另一種格式」複雜:

  • TensorFlow graph re-writing
  • Topological sorting
  • Memory planning
  • Operator lowering / mapping
  • Batchnorm folding
  • Quantization calibration
  • Hardware-specific pattern matching
  • Kernel fusion
  • Dialect/Code generation
  • Tensor layout transformation

這些事情如果丟給 Runtime 做,代價太高了。

Compiler 的價值不在於它能做什麼,在於它讓 Runtime 不必做什麼。


Int16 量化:一個牽一髮動全身的系統問題

Int16 量化不只是把浮點數 Float 轉成整數 int 這麼簡單。

Symmetric 還是 Asymmetric ? Scale 怎麼選? Zero-point 怎麼算? 要不要限制成 Power-of-2 Scaling ? Overflow 發生時怎麼處理 ?誤差怎麼傳播?

每一個選擇都會影響模型能不能跑、跑得準不準。

這不是單一模組的問題,是整個系統的問題。


Runtime:結構簡單,驗證困難

Runtime 的架構其實不複雜:Parser、Interpreter、Dispatcher、CPU Fallback、NPU Hook。

真正困難的是驗證。

你要確保:Python 寫的 Compiler 產出的東西,能在 C 寫的 Micro-controller Runtime 上正確執行。你要確保:FP32 世界的數學,轉到 Int16 世界還是對的。

這中間的鴻溝,比想像中寬得多。


數值驗證:確保系統是「對的」,不只是「能跑」

我建了一套驗證三個準則:

  1. CPU Fallback Kernel 與 NPU Kernel 結果必須一致
  2. 每一層 Kernel 的量化誤差必須可解釋
  3. 全模型的誤差傳播必須在可接受範圍

Golden Model 的價值在這裡體現,它讓我在早期就發現了 Graph execution model 的設計漏洞。

Debug 最怕的不是 Bug 很多,是 Bug 藏得很深。早期發現的 Bug 是禮物,上線後發現的 Bug 是災難。


一個 Add,推翻整個假設

原本的設計假設很簡單:Sequential execution,利用 Ping-pong Buffer 就夠了。

然後我遇到了 Residual network 的 Add operator。

這個 Operator 需要同時讀取兩個不相鄰 Layer 的輸出。原本的 Buffer 管理策略瞬間崩潰。

我被迫回頭研究業界的做法跟設計:

  • Node lifetime analysis
  • DAG-based graph execution model
  • Memory planning algorithms

一個看起來最簡單的 Operator,推翻了整個記憶體管理的假設。

系統設計最危險的時刻,就是你以為自己已經想清楚的時候。** **但過早的引入無法掌握的複雜算法系統,更是一件危險的事。


結語:從做模型到做系統

回頭看這段經歷,我才真正理解一件事:

AI/ML 系統的瓶頸,往往不在模型本身,而是在我們如何假設它會被執行。

碩士期間我做的是自動駕駛演算法研究,關心的是模型、理論。

而在這個專案中,開始關心完全不同的議題:

  • 計算怎麼映射到硬體
  • 記憶體怎麼被使用
  • Latency、Throughput、Power 怎麼預測跟優化
  • 工具鏈的每一個設計怎麼影響最終行為

這讓我從「做模型的人」慢慢變成「設計系統的人」。

當 AI 走向 Edge、走向實體世界,Compiler 和 Runtime 不再只是工具。它們是系統設計的一部分,是決定產品能不能用的關鍵環節。

這是我想持續深耕的方向。

因為真正的挑戰,是當演算法落地到系統時的每一個細節中。

Tags