Show HN: Npunlock – 为英特尔 NPU 运行自定义 C 内核
Show HN: Npunlock – Run custom C kernels for Intel NPUs

原始链接: https://github.com/hsfzxjy/npunlock

**npunlock** 是一个实验性工具包,旨在实现英特尔 NPU SHAVE 核心的自定义 C 语言编程,从而绕过英特尔官方仅限于图(graph)级别的软件栈限制。英特尔的标准工具将用户限制在预定义的算子内,而 npunlock 则允许开发者编译自定义 C 内核,并将其直接集成到 NPU 计算图中。 主要功能包括: * **自定义执行:** 在 NPU 计算图中运行用户定义的内核(例如 GELU、`tanhf`),同时利用英特尔原生编译器和驱动程序来处理外围基础架构。 * **兼容性:** 目前已在搭载 Meteor Lake (NPU3720) 的 Windows x64 系统上验证,支持 FP32 和 FP16 操作,包括混合精度计算图。 * **工作流程:** 该库处理从 C 源代码到可运行 NPU 机器码的复杂路径,编译过程需要 MoviTools 工具链。 * **开源:** 采用 Apache 2.0 许可证,该项目旨在为性能关键型或非标准操作提供桥梁。 项目目前处于开发阶段,现阶段局限于 Windows 系统、静态形状以及特定硬件。项目欢迎社区贡献,以支持 Linux 及更新一代的英特尔 NPU。

Hacker News 最新 | 过往 | 评论 | 提问 | 展示 | 招聘 | 提交 登录 Show HN: Npunlock – 在英特尔 NPU 上运行自定义 C 内核 ( github.com/hsfzxjy ) 4 点 由 hsfzxjy 提交 1 小时前 | 隐藏 | 过往 | 收藏 | 1 条评论 help Gigachad 4 分钟前 [–] 这有什么用处? 回复 指南 | 常见问题 | 列表 | API | 安全 | 法律 | 申请 YC | 联系方式 搜索:
相关文章

原文

Intel ships programmable SHAVE cores inside its NPUs, but the public stack exposes only graph-level programming. npunlock reconstructs the missing path from custom C code to a runnable NPU kernel.

How npunlock adds custom C kernels to an Intel NPU graph

The current implementation has been verified on Windows x64 with Meteor Lake / NPU3720.

Latest breakthrough — 2026-09-23: One native graph can execute independent FP32-unary and FP16-binary custom branches; explicit ACT-group preflight handles the compiler's branch reordering. Evidence and limits.

This complete FP32 GELU example embeds the C kernel in Python, places it in an NPU graph, and checks the result against NumPy. The bundled npunlock/npu3720_kernel.h target header supplies the NPU3720 invocation and tensor-address helpers. The tested MoviTools toolchain makes most conventional libm functions available to kernels without including <math.h>; this example calls tanhf directly. See the mlibm.a symbol inventory for the observed candidates.

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({"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}")

The same code is available as the runnable FP32 GELU example. See also the FP16 GELU and multi-layer two-input examples, plus a mixed-precision graph with unary and binary custom branches.

Intel's normal NPU software accepts graphs made from operations its compiler supports; it does not expose a public workflow for supplying a C implementation for an operation. The NPU's ACT-SHAVE processors are programmable and run software kernels. npunlock makes those processors usable for compatible custom graph operations while retaining Intel's compiler and driver for the surrounding graph and hardware execution.

  • Windows x64
  • Meteor Lake / Intel NPU3720
  • an installed Intel NPU driver for the device
  • Python 3.10 or newer
  • CMake 3.24 or newer and an installed MSVC toolchain for source installation
  • the extracted MoviTools MVC_DEPEND toolchain for custom C compilation

OpenVINO is not required as a runtime, Python package, or compiler frontend. npunlock does emit OpenVINO-format IR for the installed Intel driver.

npunlock is currently installed from a source checkout:

The build bundles npunlock.dll and npunlock_worker.exe inside the Python package, so normal Python use does not require a separate native path.

Custom C compilation uses Intel/Movidius MoviTools, which npunlock does not redistribute or download.

A MoviTools package verified to work was found in a legacy Lenovo driver pack. See Getting MoviTools for the official download, hash, extraction command, and expected layout.

Extract the MVC_DEPEND payload from Lenovo's older Intel NPU driver package 31.0.100.1688, but remember, DO NOT install or downgrade to that driver. All we need is the bundled MoviTools.

Point npunlock at the extracted MVC_DEPEND root and run GELU:

$env:NPUNLOCK_MOVITOOLS_DIR = 'C:\path\to\MVC_DEPEND'
python examples\example_gelu.py

The example runs on the NPU and reports its maximum error against a NumPy reference.

  • compile user-written C into ACT-SHAVE machine code
  • run custom kernels inside Intel NPU graphs
  • static dense FP16 unary and two-input custom kernels
  • a verified unary FP32 path
  • one graph containing independent FP32-unary and FP16-binary custom branches
  • nonlinear math such as GELU and tanhf
  • Python, CLI, and native C APIs

Support is experimental and currently limited to Windows x64, Meteor Lake / NPU3720, static shapes, compatible ACT carriers, and known tensor layouts. Connected mixed-precision conversion groups are not yet patch-discoverable; the verified mixed-precision example uses independent branches. Other NPU generations have not been verified. See Current limitations for the full compatibility boundary.

Help test Linux and newer NPUs

Have an NPU3720 Linux system or a newer Intel NPU? Contributions are welcome. Two routes look especially promising but remain untested:

  • a patched NPU3720 graph produced on Windows may run on Linux because the NPU firmware executes the custom machine code; building SHAVE code on Linux would additionally require a way to load the Windows MoviTools DLLs;
  • newer NPUs may execute the existing 3720xx SHAVE image, or an older OEM driver package for that generation may provide matching MoviTools components.

Both need hardware validation, driver/firmware version records, and output comparison against a host oracle. If you can test either path, feedback, failure reports, and code contributions are welcome. See Porting to Linux and newer NPUs for the hypotheses, caveats, and a suggested test plan.

Warning

A note on AI use: I did use AI while building this project--for scaffolding, repetitive implementation work, converting my reverse-engineered results into organized documentation, and fixing my English. The reverse engineering, experiments, debugging, and technical conclusions came from hands-on work. If that doesn’t bother you, there’s a pretty deep and surprisingly satisfying rabbit hole ahead.

npunlock is licensed under the Apache License 2.0. MoviTools and the Intel/Movidius libraries are external proprietary dependencies and are not covered or redistributed by this repository.

联系我们 contact @ memedata.com