openTPU:AI 現已能自行開發推理硬體
AI is now capable of developing its own inference hardware
openTPU 是一個開源 AI 加速器,允許 AI 代理直接設計並執行推理晶片。
- 系統構成:使用 SystemVerilog、指令集、模擬器、編譯器及 PCIe 主機軟體,全部集中於單一 monorepo。
開源硬體可讓 AI 代理直接設計推理晶片,本文提供實際效能與開發流程,對硬體工程師與 AI 研究者皆具參考價值。
一個由 AI 開發的開源 AI 加速器。
openTPU 將 auto-arch-tournament 的教訓帶入 AI 加速器。它提出兩個問題:AI 代理在硬體設計上能走多遠?以及它們能否建造執行自己推論的晶片?
otpu-chat 在 FPGA 卡(左側)上執行 LFM2.5-230M,otpu-smi 顯示卡的使用率和 DRAM 頻寬(右側)。
學習場所
openTPU 也是一個學習專案。整個加速器都放在一個小型 monorepo,您可以從頭到尾閱讀:硬體設計(SystemVerilog)、指令集、位準模擬器、核心語言及其編譯器,以及驅動實體 PCIe 卡的主機軟體。如果您想了解 AI 加速器的工作原理,從 Python 的矩陣乘法到電路線,這是個不錯的起點。
結果
此設計在 Inspur YPCB-00338 卡(Xilinx Kintex-7 xc7k480t,兩條 DDR3 通道)上執行十個現代模型及其真實權重,卡片產出的 tokens 與模擬器完全一致,逐位相同。
| 模型 | 權重 | 解碼,裝置 | 解碼,牆鐘時間 | 預填,裝置 | 解碼時的 DRAM |
|---|---|---|---|---|---|
| LFM2-2.6B | int8 | 59.0 tok/s | 52.3 tok/s | 295.6 tok/s | 14.5 GB/s (85% of peak) |
| LFM2-2.6B | 4-bit, int8 head | 85.8 tok/s | 82.1 tok/s | 335.4 tok/s | 14.1 GB/s (82%) |
| Qwen3-0.6B | int8 | 21.6 tok/s | 21.3 tok/s | 92.1 tok/s | 14.4 GB/s (84%) |
| Qwen3-0.6B | 4-bit, int8 head | 31.3 tok/s | 30.7 tok/s | 103.4 tok/s | 13.9 GB/s (82%) |
| Qwen3-0.8B | int8 | 17.6 tok/s | 16.3 tok/s | 61.4 tok/s | 14.5 GB/s (85%) |
| Qwen3-0.8B | 4-bit, int8 head | 24.5 tok/s | 23.3 tok/s | 66.7 tok/s | 14.1 GB/s (83%) |
| Gemma 4 E2B | 4-bit, int8 head | 10.57 tok/s | 10.53 tok/s | 32.1 tok/s | 15.6 GB/s (92%) |
| Gemma 4 E2B | 4-bit, 4-bit head | 12.14 tok/s | 12.09 tok/s | 29.9 tok/s | 15.5 GB/s (91%) |
| LFM2-2.6B | int8 | 6.05 tok/s | 6.03 tok/s | 21.4 tok/s | 16.1 GB/s (94%) |
| LFM2-2.6B | 4 位元,int8 頭 | 10.96 tok/s | 10.93 tok/s | 20.6 tok/s | 15.8 GB/s (93%) |
| SmolLM3-3B | int8 | 5.00 tok/s | 4.99 tok/s | 21.1 tok/s | 16.0 GB/s (94%) |
| SmolLM3-3B | 4 位元,int8 頭 | 8.74 tok/s | 8.72 tok/s | 22.8 tok/s | 15.7 GB/s (92%) |
| Phi-4-mini (3.8B) | int8 | 3.99 tok/s | 3.98 tok/s | 13.8 tok/s | 16.0 GB/s (94%) |
| Phi-4-mini (3.8B) | 4 位元,int8 頭 | 6.56 tok/s | 6.55 tok/s | 15.0 tok/s | 15.8 GB/s (92%) |
| Qwen3.5-2B | int8 | 8.02 tok/s | 8.00 tok/s | 38.2 tok/s | 16.0 GB/s (94%) |
| Qwen3.5-2B | 4 位元,int8 頭 | 12.09 tok/s | 12.03 tok/s | 41.7 tok/s | 15.8 GB/s (92%) |
| Qwen3.5-4B | 4 位元,int8 頭 | 5.88 tok/s | 5.87 tok/s | 12.9 tok/s | 15.7 GB/s (92%) |
| Gemma 4 E4B | int8, 4 位元頭及降至 0-23 | 3.78 tok/s | 3.75 tok/s | 14.8 tok/s | 16.0 GB/s (94%) |
測試於卡片:前三個模型於 2026-09-29 使用生產映像
deploy_champ_e698dcd7。LFM2-2.6B、SmolLM3-3B 與 Phi-4-mini 於 2026-09-30,Qwen3.5-2B、4B 與 Gemma 4 於 2026-10-01,使用 Build B,deploy_fused133c_79c5707a,自此以後為生產版。
Build B 使 LFM2-2.6B、SmolLM3 與 Phi-4-mini 以 8-9% 的速度比 e698dcd7 更快(Gemma 4 E2B 10%),
達到 91-94% 的 DRAM 峰值而非 82-87%。Qwen3.5-4B 的 int8 映像超過 4 GiB。
- 映像:主 e698dcd 於 133.33 MHz,所有模型共用一個位流。它擁有由小型 CPU 在記憶體核心內校準的 LiteDRAM 控制器、一個四列同步矩陣單元以及串流引擎 (docs/stream.md)。DDR3-1066,峰值 17.1 GB/s。
- 主機:卡片安裝於 opentpu(Intel Core i7-4790)中。
- 方法,
tools/qual/perf.py:解碼為 64 個貪婪 token,緊接 512 token 提示,使用主機的 argmax 在迴圈中(未串流)。"Device" 僅計算加速器執行的週期;"wall" 加上主機。Prefill 為 512 token 提示,位於裝置上。 - DRAM 流量來自卡片自身的計數器,於執行時產生。
- Gemma 4 E2B 將每層嵌入表格保留在卡片上(3.5-3.6 GiB 的映像;docs/gemma4.md);以 int8 時不符合。它在三個提示中與 Hugging Face 的貪婪 tokens 匹配,無論哪個頭部。E4B 的表格(2.95 GB)保留在主機上,主機每個 token 會把一行 11 KB 複製到卡片;其映像為 3.96 GiB,int8 版帶頭部以及前 24 層的下行投影以 4-bit (docs/gemma4_e4b.md)。在卡片自己的解碼迴圈(卡片挑選每個 token)中,Gemma 4 解碼速度更快:E2B 11.01 / 12.73 tok/s(int8 / 4-bit head),E4B 3.83 tok/s,執行於裝置上。
- 每個配置都與模擬器逐 token、逐位置匹配,並使用在地解碼程式。更多細節見 docs/board.md。
在卡片執行時將 logits 回傳(tools/decode_profile.py,96 tokens),4-bit 解碼更快,裝置 / 實際 tok/s:
- LFM2: 89.5 / 84.5;
- Qwen3: 33.7 / 33.3;
- Qwen3.5: 24.6 / 24.2;
- LFM2-2.6B: 11.07 / 11.02 (build B);
- SmolLM3-3B: 8.92 / 8.89 (build B);
- Phi-4-mini: 6.69 / 6.67 (build B).
先前的正式映像 se-cand3 是用 Xilinx MIG、雙列矩陣單元和 120.755 MHz 時鐘構建的。以相同方式測量,新映像:
- decode: 在每個配置中與 se-cand3 相差 2.3% 以內。解碼受限於 DRAM,LiteDRAM 的讀取速率為 DDR3 峰值的 82-85%,與 MIG 一致。
- prefill: 1.3 倍(Qwen3.5)到 2.0 倍(LFM2 4-bit)更快。
- calibration: 映像啟動時,核心 CPU 在 12 秒內校準兩個 DDR3 通道,無需主機參與。
早期映像及其數字見 docs/board.md,第 5 節。
Mixture-of-experts 模型若大於卡片的 4 GiB,將其專家從主機儲存(docs/offload.md,第 10 節)串流進來。卡片為每個 token 路由並計算每個專家,並將專家儲存在其 DRAM 的每層槽位中。主機僅將缺失的專家從池檔案複製到這些槽位,速率與鏈路相同(第 10.1 節)。於 2026-10-01 以 build B (79c5707a) 測試,卡片自己的解碼迴圈挑選每個 token,4-bit 專家,int8 頭部:
- LFM2.5-8B-A1B(8.5B 引數,1.7B 活躍):在 160 tokens 上 10.6 tok/s。98.5% 的專家使用命中槽位,每 token 串流 5.2 MB。
- Qwen3.5-35B-A3B(34.7B 引數,3.0B 活躍):3.95 tok/s,配合 Hugging Face 的 16 個貪婪 tokens。62% 的專家使用命中,並以 1.41 GB/s 透過 PCIe(第 10.3 節)每 token 串流 153 MB。
- 兩者與模擬器完全一致。
4-bit 權重(docs/quant.md)使用 FP4 值,採用兩層區塊比例,4.25 bits/權重,並為了精度將 LM 頭保留為 int8。它們將每 token 的位元組數減少約三分之一,並提升解碼速度 40%(Qwen3.5)至 45%(Qwen3、LFM2),但在困惑度上有可測量的成本,docs/quant.md 按模型報告。
主機幾乎不再參與。對於 LFM2 和 Qwen3,卡片只執行一次編譯好的解碼程式,該程式從暫存器讀取位置並查詢自己的嵌入與 RoPE 行,並在卡片仍在執行時將 logits 回傳:主機在 omarchy 上每 token 增加 0.17~0.30 ms(opentpu 上 0.45~1.3 ms)。Qwen3.5 以相同方式進行解碼;其 prefill 仍在卡片之前於主機上編譯每個區塊的程式。
工作原理
Kernels in ol mlp, attention, full model layers
| @ol.jit
Language + compiler layouts, affine loop addressing, fusion
|
ISA 8 x 32-bit words per instruction
|
ISA simulator <======> RTL same bits, checked by the tests
(Python) (SystemVerilog)
| Vivado bitstream
FPGA card Kintex-7 xc7k480t
| PCIe
Host otpu-chat, otpu-smi, otpu-lens
機器被設計得故意簡單。序列器每個週期發出一條指令給幾個單元:DMA 移動資料,矩陣單元乘以從 DRAM 串流的 int8 權重,向量單元執行 fp32 計算,量化器將結果轉回 int8。沒有快取也沒有隱藏排程:每一次資料移動都是一條指令,因此追蹤能準確顯示週期的去向。docs/isa.md 描述整個指令集。
核函式看起來像這樣:
from opentpu import language as ol @ol.jit def mlp(h, gamma, w_gate, w_up, w_down, out, eps): # simplified; see kernels/mlp.py x = ol.load(h) xs = ol.quantize(rmsnorm(x, ol.load(gamma), eps)) g = ol.dot(xs, w_gate) u = ol.dot(xs, w_up) a = ol.all_gather(silu(g) * u) y = ol.all_gather(ol.dot(a, w_down)) if ol.program_id() == 0: ol.store(out, x + y)
因為每一次資料移動都是一條指令,執行的追蹤能說明其速度。Lens,這個分析器,會從 RTL、模擬器或卡片記錄執行並在瀏覽器中開啟,提供屋頂線圖、時間線以及每條指令的表格 (docs/lens.md)。
Lens 重新播放 Qwen3 解碼步驟的一部分。顏色顯示每個單元在每個週期的狀態:忙碌、等待 DRAM 或等待另一條指令。
試試看
除了卡片之外,所有程式都能在筆記型電腦上執行。
pip install -e . pip install pytest torch transformers python3 -m pytest -q # RTL tests also need Verilator 5 hf download LiquidAI/LFM2.5-230M --local-dir models/LFM2.5-230M otpu-chat --model lfm2 --backend isa # chat on the simulator
有卡片時,先在 boards/ypcb-00338 中建置位流 (make bit),再透過 JTAG 載入,接著執行 sudo otpu-setup 與 otpu-chat --backend board。docs/board.md 會帶你完成啟動流程。
| 指令 | 功能說明 |
|---|---|
otpu-chat |
與 Qwen3-0.6B、LFM2.5-230M (--model lfm2)、Qwen3.5-0.8B (--model qwen35)、LFM2-2.6B (lfm2-2.6b)、SmolLM3-3B (smollm3)、Phi-4-mini (phi4-mini) 或 Qwen3.5-2B / 4B (qwen35-2b, qwen35-4b) 聊天 |
otpu-smi |
溫度、功率、DRAM 頻寬以及各單元使用率 |
otpu-lens |
記錄一次執行並在分析器中開啟 |
otpu-selftest, otpu-diag |
檢查卡片是否正常工作 |
從哪裡開始閱讀
- docs/isa.md:指令集。其他所有內容都是基於它構建的。
opentpu/kernels與 docs/compiler.md:核函式如何轉成指令。opentpu/isasim.py:模擬器,亦即規格。rtl/:硬體,從rtl/top/otpu_top.sv開始。- docs/lfm2.md、docs/qwen35.md、docs/llama.md、docs/benchmarks.md:完整模型及其週期分佈。
- docs/board.md:實體卡片,從時鐘到 PCIe。
接下來
- DRAM 的最後幾個百分比。 解碼受限於 DRAM 效率:它讀取 DDR3-1066 峰值的 82%~85%。LiteDRAM 路徑的效率工作正在進行中。
- 時序裕度與面積。 設計在 133.33 MHz 下閉合,這是 128 byte 埠與兩條 DDR3 通道相匹配的時鐘,但僅剛好(WNS +0.032 ns)。Vivado 競賽持續最佳化其裕度與面積。解碼受 DRAM 限制,較快的時鐘主要有助於預填。
- 更快的預填。 四列同步矩陣單元已在量產影像中;預填仍受限於矩陣單元的乘法速率。
貢獻
歡迎提出問題與拉取請求,且大多數工作僅需 Python 與 Verilator,無需 FPGA。對 ISA、模擬器或 RTL 的更改必須保持 python3 -m pytest -q 通過,且效能宣告應說明測量方式。
授權
Apache License 2.0。請參閱 LICENSE。
來源:hackernews100 · github.com

