npunlock は Intel Core Ultra NPU でカスタム C カーネルを可能にする

TL;DR

npunlock は、Intel の SHAVE コア内に存在する Core Ultra NPU3720 に対して、任意の C コードをマシンコードにコンパイルし、標準的な OpenVINO 風のグラフ内でそのカーネルを実行するワークフローを提供します。これにより、Intel が公式にサポートする操作セットを超えた NPU の利用が可能になります。


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 ソフトウェアは、プロプライエタリコンパイラが認識している演算から構成されたグラフしか受け入れません。新しい演算の手書き C 実装を提供するための公開 API は存在しないため、開発者は SHAVE コアにアクセスできなくなっています。npunlock はこのロックを解除し、以下を可能にします:

  • Intel が公式にサポートしていない(または将来サポートしない)新しい演算の研究。
  • 手動で最適化されたカーネルを書くことによる細かいパフォーマンスチューニング。
  • 1 つのグラフ内で 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}")

Windows x64 マシン(Meteor Lake CPU および NPU3720 搭載)でスクリプトを実行すると、非常に小さな最大絶対誤差が報告され、機能の正しさが確認されます。

対応機能(最新リリース時点)

  • カスタムカーネルコンパイル:MoviTools を通じて C → ACT-SHAVE マシンコード。
  • グラフ統合:Intel が提供する演算とカスタムノードを併用可能。
  • データ型:静的密度 FP16 の単項/二項カーネルと検証済みの FP32 単項パス。
  • ミックスド・プレシジョングラフ:1 つのグラフに独立した FP32 単項と FP16 二項のカスタムブランチを含められる。
  • 数学ライブラリ:mlibm.a にバンドルされたシンボルインベントリを通じて、tanhf などの非線形関数が利用可能。
  • API:Python、CLI、ネイティブ C インターフェースを提供。

現在の制限

  • プラットフォーム:Windows x64 のみ。Linux 対応は未検証。
  • ハードウェア:Meteor Lake / Intel NPU3720 でのみ検証済み。他の世代は検証されていない。
  • 静的形状:静的テンソル形状のみサポート。動的形状は未対応。
  • ACT キャリア:カスタムカーネルをホストできるのは、Abs のような互換性のある ACT キャリアのみ。
  • ミックスド・プレシジョン変換グループ:自動検出は不可。ミックスド・プレシジョンの例では別々のブランチを使用。

"サポートは実験的であり、現在は Windows x64、Meteor Lake / NPU3720、静的形状、互換性のある ACT キャリア、既知のテンソルレイアウトに限定されています。" – npunlock README

はじめ方

前提条件

  1. ハードウェア:Meteor Lake CPU と Intel NPU3720 を搭載した Windows x64 マシン。
  2. ドライバ:デバイス用の公式 Intel NPU ドライバをインストール。
  3. ツールチェーン: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 は実用的なユースケースについて質問。プロジェクトの作者は、Intel が公式にサポートしていない推論タスク向けに「ベアメタル NPU プログラミング」を可能にすると回答。
  • @Bayard_ne は、カスタムで非伝統的な推論ワークロードに直接アクセスできる点に興奮を示した。
  • @alex7o は、Qualcomm Hexagon へのアプローチの拡張を提案し、より広範な適用性への関心を示した。

これらのコメントは、低レベル NPU ハッキングへの熱意と、クロスプラットフォーム対応への期待を浮き彫りにしています。

Linux 対応および新しい NPU への貢献

リポジトリは以下の貢献を歓迎しています:

  1. Linux ポート – Windows で生成された SHAVE イメージが Linux でそのまま動作するかの検証、および Linux 向け MoviTools ラッパーの構築。
  2. 新しいハードウェア – 既存の 3720xx SHAVE イメージが後続の Intel NPU で動作するか、OEM ドライバパックに一致するツールチェーンが提供されているかの確認。

両方の取り組みにはハードウェア検証、ドライバ/ファームウェアバージョンの追跡、ホストオラクルとの数値比較が必要です。詳細なガイドは Linux および新しい NPU への移植 ウィキページにあります。

ドキュメント概要

  • MoviTools の入手方法 – レガシー ドライバをインストールせずにコンパイラを取得する方法。
  • Python API – グラフの構築、コンパイル、実行。
  • カスタムカーネルの書き方 – エントリポイントの規則、テンソルの扱い、例題カーネル。
  • npunlock の仕組み – グラフコンパイルとカーネル挿入の内部構造。
  • 逆エンジニアリングのブレークスルー – カスタムカーネルを可能にした実験。
  • 現在の制限 – 完全な互換性マトリクス。
  • 開発およびネイティブ API – ビルドシステム、テスト、C インターフェース。

すべてのドキュメントはリポジトリの wiki フォルダ内にあり、README からリンクされています。

ライセンス

npunlock は Apache License 2.0 の下でリリースされています。MoviTools や Intel/Movidius ライブラリなどのプロプライエタリ依存関係は再配布されず、それぞれの元のライセンスの下に残ります。

Sources

関連

  • プロジェクト
  • Dispatch
  • プロジェクト
  • プロジェクト
  • プロジェクト