npunlock 允許在 Intel Core Ultra NPU 上使用自訂 C 核心
TL;DR
npunlock 提供了一種工作流程,可將任意 C 程式碼編譯為 Intel SHAVE 核心的機器碼,並在標準 OpenVINO 風格的圖形中執行這些核心,從而將 NPU 的功能擴展至 Intel 官方支援的操作集之外。
npunlock 的功能
npunlock 重建了從使用者撰寫的 C 程式碼到可執行 NPU 核心的缺失路徑。它:
- 使用 Intel/Movidius MoviTools 將 C 程式碼編譯為 ACT-SHAVE 機器碼。
- 將編譯後的核心封裝為自訂運算,可插入 OpenVINO 相容的圖形中。
- 使用 Intel 現有的驅動程式和編譯器處理周圍的圖形,因此僅自訂節點由 npunlock 處理。
- 輸出 OpenVINO 格式的 IR,讓整個流程的其餘部分保持不變。
"Intel 在其 NPU 內建可程式設計的 SHAVE 核心,但公開的堆疊僅提供圖形層級的程式設計。
npunlock重建了從自訂 C 程式碼到可執行 NPU 核心的缺失路徑。" – npunlock README
為何這很重要
Intel 的 NPU 軟體僅接受由專有編譯器所知的操作組成的圖形。沒有公開 API 可以提供手寫的 C 實作來新增運算,這實際上將開發者排除在 SHAVE 核心之外。npunlock 打開了這扇門,使開發者能:
- 研究尚未(或永遠不會)被 Intel 支援的新運算子。
- 透過撰寫手動優化的核心來進行細緻的效能調校。
- 探索混合精度流程,將 FP32 單元和 FP16 二元自訂分支結合於單一圖形中(此突破於 2026-09-23 宣布)。
快速入門範例(FP32 GELU)
以下 Python 程式碼片段示範了完整的端到端流程:
import numpy as np, npunlock as npu
npu.configure(movi_dll_dir=r"C:\path\to\MVC_DEPEND")
gelu_c = b"""
#define MLIBM_DEFINE_LINK_COMPAT 1
#include <npunlock/npu3720_kernel.h>
void controlled_act(unsigned layerParams) {
act_abi_invocation invocation;
ACT_ABI_LOAD_INVOCATION32_OR_RETURN(layerParams, invocation);
const float *in = ACT_ABI_INPUT_PTR32(const float, invocation, 0u);
float *out = ACT_ABI_OUTPUT_PTR32(float, invocation, 1u);
const float SQRT_2_DIV_PI = 0.7978845608028654f;
for (unsigned i = 0; i < invocation.element_count; ++i) {
float x = in[i];
float w = x + 0.044715f * x * x * x;
w = tanhf(w * SQRT_2_DIV_PI);
out[i] = 0.5f * x * (1.0f + w);
}
}
"""
N = 2048
x = npu.input("x", shape=(1, N), dtype="f32")
y = npu.custom(x, source=gelu_c, carrier="Abs", _name="y")
program = npu.compile(npu.Graph(inputs=[x], outputs=[y], name="gelu_f32_example"))
input_value = np.linspace(-4, 4, N, dtype=np.float32).reshape(1, -1)
output = program.run({"x": input_value})["y"]
reference = 0.5 * input_value * (1.0 + np.tanh(np.sqrt(2.0/np.pi) * (input_value + 0.044715 * input_value**3)))
print(f"maximum absolute error: {np.max(np.abs(output - reference)):g}")
在搭載 Meteor Lake CPU 與 NPU3720 的 Windows x64 機器上執行此腳本,報告的絕對誤差極小,確認了功能正確性。
支援功能(截至最新版本)
- 自訂核心編譯:透過 MoviTools 將 C 編譯為 ACT-SHAVE 機器碼。
- 圖形整合:自訂節點可與 Intel 提供的操作共存。
- 資料類型:支援靜態密集 FP16 單元/二元核心,以及已驗證的 FP32 單元路徑。
- 混合精度圖形:單一圖形可包含獨立的 FP32-單元與 FP16-二元自訂分支。
- 數學函數庫:透過內建的
mlibm.a符號清單,可使用tanhf等非線性函數。 - API:提供 Python、CLI 與原生 C 介面。
目前限制
- 平台:僅支援 Windows x64;Linux 支援尚未測試。
- 硬體:僅在 Meteor Lake / Intel NPU3720 上驗證過。其他世代尚未驗證。
- 靜態形狀:僅支援靜態張量形狀;尚未處理動態形狀。
- ACT 載體:僅支援相容的 ACT 載體(例如
Abs)來承載自訂核心。 - 混合精度轉換群組:無法自動發現;混合精度範例使用獨立分支。
"支援為實驗性質,目前僅限於 Windows x64、Meteor Lake / NPU3720、靜態形狀、相容的 ACT 載體與已知的張量佈局。" – npunlock README
開始使用
前置條件
- 硬體:搭載 Meteor Lake CPU 與 Intel NPU3720 的 Windows x64 機器。
- 驅動程式:安裝該裝置的官方 Intel NPU 驅動程式。
- 工具鏈:Python 3.10+、CMake 3.24+、MSVC 工具鏈,以及 MoviTools
MVC_DEPEND套件(從舊版 Lenovo 驅動套件中提取,請勿安裝驅動本身)。
安裝步驟
# 克隆程式碼庫並安裝 Python 套件
git clone https://github.com/hsfzxjy/npunlock.git
cd npunlock
python -m pip install .
該套件內建 npunlock.dll 與 npunlock_worker.exe,因此除了指定 MVC_DEPEND 位置外,無需額外設定原生路徑。
執行 GELU 範例
$env:NPUNLOCK_MOVITOOLS_DIR = 'C:\path\to\MVC_DEPEND'
python examples\example_gelu_f32.py
該腳本會編譯自訂核心,插入圖形中,在 NPU 上執行,並與 NumPy 比較最大絕對誤差。
Hacker News 社群反饋
- @ur-whale 指出僅支援 Windows 是一個障礙。
- @Gigachad 詢問實際應用場景;專案作者回應表示,這讓開發者能進行「裸機 NPU 程式設計」,用於 Intel 官方不支援的推論任務。
- @Bayard_ne 強調能直接存取自訂、非傳統推論工作負載的興奮感。
- @alex7o 建議將此方法延伸至 Qualcomm Hexagon,顯示對更廣泛適用性的興趣。
這些評論凸顯了對底層 NPU 破解的熱情,以及對跨平台支援的渴望。
貢獻:Linux 支援與更新的 NPU
該程式碼庫歡迎貢獻,包括:
- Linux 移植 – 測試 Windows 產生的 SHAVE 映像是否能在 Linux 上無變更執行,並建立 Linux 相容的 MoviTools 包裝。
- 新硬體支援 – 檢查現有的
3720xxSHAVE 映像是否適用於後續 Intel NPU,或 OEM 驅動套件是否提供對應工具鏈。
兩項工作皆需硬體驗證、驅動/韌體版本追蹤,以及與主機基準的數值比對。詳細指引請見 Porting to Linux and newer NPUs 維基頁面。
文件總覽
- 取得 MoviTools – 如何取得編譯器而不安裝舊版驅動程式。
- Python API – 建構、編譯與執行圖形。
- 撰寫自訂核心 – 入口點規範、張量處理與範例核心。
- npunlock 的運作原理 – 圖形編譯與核心注入的內部機制。
- 逆向工程突破 – 讓自訂核心成為可能的實驗。
- 目前限制 – 完整相容性矩陣。
- 開發與原生 API – 建構系統、測試與 C 介面。
所有文件皆存放於程式碼庫的 wiki 資料夾中,並連結至 README。
授權
npunlock 以 Apache License 2.0 釋出。MoviTools 與 Intel/Movidius 庫等專有相依性不被重新分發,並維持其原始授權。
Sources
相關
- 專案
- Dispatch
- 專案
- 專案
- 專案