Show HN: Npunlock – Intel NPUでカスタムCカーネルを実行する
Show HN: Npunlock – Run custom C kernels for Intel NPUs (github.com)
要約
Npunlockは、Intel NPUのプログラマブルなSHAVEコア上でカスタムCコードをカーネルとして実行できるようにするツールです。Intelの公式スタックではグラフレベルのプログラミングしか公開されていませんが、Npunlockはこのギャップを埋め、カスタムCコードから実行可能なNPUカーネルへのパスを再構築します。現在はWindows x64のMeteor Lake / NPU3720で検証されており、FP32およびFP16のカスタムカーネル実行をサポートしています。
全文翻訳
IntelはNPU内にプログラム可能なSHAVEコアを搭載していますが、公開されているスタックではグラフレベルのプログラミングしか利用できません。npunlockは、カスタムCコードから実行可能なNPUカーネルへの、失われたパスを再構築します。
現在の実装は、Windows x64 (Meteor Lake / NPU3720) で検証済みです。
最新のブレークスルー — 2026-10-20: マルチタイルACTグループの出力が、タイルごとのユニークなDPU入力セットへの正確なDMAファンインを通じて追跡できるようになりました。タイル変換はグラフ自体から導出されます。証拠と制限。
このプロジェクトが初めての方へ:カスタムカーネルチュートリアルに従って、最初のFP16ループからキャリア選択、マルチ入力カーネル、変換、再利用可能なデプロイメント成果物までを学習してください。
クイック例
この完全なFP32 GELUの例では、CカーネルをPythonに埋め込み、NPUグラフに配置し、NumPyとの結果を比較します。バンドルされているnpunlock/npu3720_kernel.hターゲットヘッダーは、NPU3720の呼び出しとテンソルアドレスヘルパーを提供します。MoviToolsのmathアーカイブは、<math.h>を必要とせずに馴染みのある名前を公開します。この例では、実行テスト済みのtanhfパスを使用しています。他のアーカイブエントリは、ハードウェアでテストされるまで候補のままです。観測された候補については、mlibm.aシンボルインベントリを参照してください。
import numpy as np
import npunlock as npu
npu.configure(movi_dll_dir=r"C:\path\to\MVC_DEPEND")
gelu_c: bytes = 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_one(input_value)
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}")
同じコードが、実行可能なFP32 GELUの例として利用可能です。以下も参照してください。
なぜnpunlockか?
Intelの通常のNPUソフトウェアは、コンパイラがサポートするオペレーションから作られたグラフを受け入れますが、オペレーションに対するC実装を提供する公開ワークフローは提供していません。NPUのACT-SHAVEプロセッサはプログラム可能で、ソフトウェアカーネルを実行します。npunlockは、これらのプロセッサを互換性のあるカスタムグラフオペレーションに使用可能にし、周囲のグラフとハードウェア実行のためにIntelのコンパイラとドライバを維持します。
要件
- Windows x64
- Meteor Lake / Intel NPU3720
- デバイス用のインストール済みIntel NPUドライバ
- Python 3.10以降
- CMake 3.24以降と、ソースインストール用のインストール済みMSVCツールチェーン
- カスタムCコンパイル用の抽出済みMoviTools
MVC_DEPENDツールチェーン
OpenVINOは、ランタイム、Pythonパッケージ、またはコンパイラフロントエンドとして必要ありません。npunlockは、インストール済みのIntelドライバ用にOpenVINO形式のIRを出力します。
インストール
npunlockは現在、ソースチェックアウトからインストールされます。
python -m pip install .
ビルドは、Pythonパッケージ内にnpunlock.dllとnpunlock_worker.exeをバンドルするため、通常のPython使用では個別のネイティブパスは必要ありません。
MoviToolsの入手
カスタムCコンパイルはIntel/Movidius MoviToolsを使用しますが、これはnpunlockでは再配布またはダウンロードされません。
検証済みのMoviToolsパッケージは、レガシーLenovoドライバパック内で見つかりました。MoviToolsの入手を参照して、公式ダウンロード、ハッシュ、抽出コマンド、および期待されるレイアウトを確認してください。
Lenovoの古いIntel NPUドライバパッケージ 31.0.100.1688 から MVC_DEPEND ペイロードを抽出しますが、そのドライバをインストールしたりダウングレードしたりしないでください。必要なのはバンドルされたMoviToolsのみです。
セットアップの確認
NPUNLOCK_MOVITOOLS_DIRを設定した後、両方のランタイム機能を検査します。
python -m npunlock doctor
レポートは、既にコンパイルされたプログラムの実行と、カスタムCのコンパイルを区別します。後者は追加でMoviToolsを必要とします。JSONおよびオフラインオプションについては、Python APIガイドを参照してください。エンドツーエンドのカスタムカーネルコンパイル、実行、および正確なホストオラクルチェックを明示的に行いたい場合は、python -m npunlock doctor --fullを使用してください。
例の実行
抽出したMVC_DEPENDのルートをnpunlockに指定し、GELUを実行します。
$env:NPUNLOCK_MOVITOOLS_DIR = 'C:\path\to\MVC_DEPEND'
python examples\example_gelu.py
例はNPU上で実行され、NumPyリファレンスに対する最大誤差を報告します。
現在動作するもの
Cカーネルを記述し、ACT-SHAVEマシンコードにコンパイルし、互換性のあるIntel NPUグラフに配置し、PythonまたはネイティブC APIから実行できます。ハードウェアでテストされた例には、単項およびマルチ入力カーネル、選択されたFP16、FP32、整数および変換パス、非線形数学、ローカル削減、および境界付き制御フローが含まれます。
カスタムカーネルは、通常のグラフオペレーションやDPUワークと共存できます。プログラムは元のCソースなしで保存およびロードでき、テンソルI/Oは通常のコピーまたは再利用可能なNumPy互換共有バッファを使用できます。
カスタムカーネルチュートリアルから始め、次にカスタムカーネルの記述でプログラミングモデルを、現在の制限事項で正確にテストされたキャリア、dtype、形状、およびグラフオペレーションを参照してください。
現在の制限事項
npunlockは実験的なものであり、Windows x64 (Meteor Lake / NPU3720) およびグラフコンパイラ8.3で検証されています。カスタムカーネルは現在、静的形状と、既知の互換性のあるキャリアおよびテンソルレイアウトのいずれかを必要とします。見た目が似ているグラフオペレーションが自動的に互換性があるわけではありません。
Linuxおよび新しいIntel NPUは、サポート対象プラットフォームではなく、テスト対象のままです。正確なハードウェア、dtype、形状、キャリア、およびグラフオペレーションの互換性マトリックスについては、現在の制限事項を参照してください。
Linuxおよび新しいNPUのテストにご協力ください
NPU3720 Linuxシステムまたは新しいIntel NPUをお持ちですか?貢献を歓迎します。特に有望な2つのルートがありますが、まだテストされていません。
- Windowsで生成されたパッチ適用済みのNPU3720グラフは、NPUファームウェアがカスタムマシンコードを実行するため、Linuxで実行できる可能性があります。LinuxでのSHAVEコードのビルドには、Windows MoviTools DLLをロードする方法も追加で必要になります。
- 新しいNPUは、既存の
3720xxSHAVEイメージを実行する可能性があります。または、その世代の古いOEMドライバパッケージが一致するMoviToolsコンポーネントを提供する可能性があります。
どちらのパスもハードウェア検証、ドライバ/ファームウェアバージョン記録、およびホストオラクルとの出力比較が必要です。どちらかのパスをテストできる場合は、フィードバック、障害レポート、およびコード貢献を歓迎します。仮説、注意点、および段階的なテスト計画については、Linuxおよび新しいNPUへの移植を参照してください。Linuxビルドは、構造レポート用のnpunlock-inspectと、ステージごとの診断および正確なホストオラクルを備えた明示的なインプロセス実行試行用のnpunlock-linux-probeを提供します。後者はハードウェアテストの準備ができていますが、NPUパススルーを備えたLinuxシステムではまだ実行されていないため、Linux実行はまだサポートされている構成ではありません。
ドキュメント
- カスタムカーネルチュートリアル — 最初のカーネルを記述し、互換性のあるキャリアを選択し、マルチ入力および混合精度グラフに拡張します
- MoviToolsの入手 — レガシードライバをインストールせずにコンパイラツールチェーンを入手します
- Python API — Pythonからグラフを構築、コンパイル、実行します
- カスタムカーネルの記述 — Cエントリポイント、テンソル契約、および例
- npunlockの仕組み — グラフコンパイルとカスタムカーネルの統合
- リバースエンジニアリングのブレークスルー — カスタムカーネルを可能にした実験と発見
- モデルからマシンコードへ — ステップバイステップのローリングダウンと関連コンポーネント
- Intel NPUアーキテクチャ — DPUとACT-SHAVEの概要
- 現在の制限事項 — 検証済みのハードウェアとABIスコープ
- Linuxおよび新しいNPUへの移植 — 実験的なルートと貢献ガイド
- 移植プローブバンドル — 再現可能なグラフ、テンソル、プロビナンス、およびオラクルパッケージ
- 開発とネイティブAPI — CMake、テスト、パッケージング、CLI、およびCインターフェース
- 完全なドキュメントインデックス
警告
AIの使用に関する注意: このプロジェクトの構築中にAIを使用しました。スキャフォールディング、反復的な実装作業、リバースエンジニアリングの結果を有益なドキュメントに整理する作業、および英語の修正に使用しました。リバースエンジニアリング、実験、デバッグ、および技術的な結論は、実践的な作業から得られました。それが気にならないのであれば、非常に深く、驚くほど満足のいくウサギの穴が待っています。
ライセンス
npunlockはApache License 2.0の下でライセンスされています。MoviToolsおよびIntel/Movidiusライブラリは、外部のプロプライエタリな依存関係であり、このリポジトリではカバーまたは再配布されません。