npunlock는 Intel Core Ultra NPU에서 사용자 정의 C 커널을 가능하게 합니다
TL;DR
npunlock은 Intel의 SHAVE 코어를 포함한 Core Ultra NPU3720에 임의의 C 코드를 머신코드로 컴파일하고, 표준 OpenVINO 스타일 그래프 내에서 해당 커널을 실행하는 워크플로우를 제공합니다. 이는 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이 공식적으로 지원하지 않거나 지원할 계획이 없는 새로운 연산에 대한 연구.
- 수작업 최적화된 커널을 작성함으로써 세밀한 성능 튜닝.
- 단일 그래프 내에서 FP32 유니어리 연산과 FP16 바이너리 사용자 정의 브랜치를 혼합하는 혼합 정밀도 파이프라인 탐색 (2026-09-23에 발표된 돌파구).
빠른 시작 예제 (FP32 GELU)
다음 파이썬 스크립트는 완전한 엔드투엔드 흐름을 보여줍니다:
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 유니어리 경로.
- 혼합 정밀도 그래프: 하나의 그래프 내에서 독립적인 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는 실용적인 사용 사례에 대해 질문했고, 프로젝트 작성자는 "Intel이 공식적으로 지원하지 않는 추론 작업을 위한 베어메탈 NPU 프로그래밍"을 가능하게 한다고 답변했습니다.
- @Bayard_ne는 사용자 정의, 비정형 추론 워크로드에 직접 접근할 수 있다는 점에서 큰 기대감을 드러냈습니다.
- @alex7o는 Qualcomm Hexagon으로 이 접근법을 확장할 수 있음을 제안하며, 더 넓은 적용 가능성에 관심을 보였습니다.
이러한 댓글들은 저수준 NPU 해킹에 대한 열정과 다중 플랫폼 지원에 대한 갈망을 강조합니다.
Linux 지원 및 최신 NPU에 대한 기여
이 리포지토리는 다음과 같은 기여를 환영합니다:
- Linux 포트 – Windows에서 생성된 SHAVE 이미지가 Linux에서 변경 없이 실행되는지 테스트하고, Linux 호환 MoviTools 래퍼 구축.
- 새로운 하드웨어 – 기존
3720xxSHAVE 이미지가 이후 Intel NPU에서 작동하는지 확인하거나, OEM 드라이버 팩이 동일한 툴체인을 제공하는지 확인.
이 두 작업 모두 하드웨어 검증, 드라이버/펌웨어 버전 추적, 호스트 오라클과의 수치 비교가 필요합니다. 자세한 안내는 Linux 및 최신 NPU로 포팅하기 위키 페이지에서 확인할 수 있습니다.
문서 개요
- MoviTools 확보 방법 – 구형 드라이버 설치 없이 컴파일러를 얻는 방법.
- Python API – 그래프 생성, 컴파일, 실행.
- 사용자 정의 커널 작성 – 엔트리 포인트 규칙, 텐서 처리, 예제 커널.
- npunlock 작동 방식 – 그래프 컴파일 및 커널 삽입 내부 구조.
- 역공학적 돌파구 – 사용자 정의 커널을 가능하게 한 실험들.
- 현재 제한 사항 – 완전한 호환성 매트릭스.
- 개발 및 네이티브 API – 빌드 시스템, 테스트, C 인터페이스.
모든 문서는 리포지토리의 wiki 폴더에 있으며, README에서 링크되어 있습니다.
라이선스
npunlock는 Apache License 2.0 하에 배포됩니다. MoviTools 및 Intel/Movidius 라이브러리와 같은 기업용 종속성은 재배포되지 않으며 원래 라이선스에 따라 유지됩니다.
Sources
관련
- 프로젝트
- Dispatch
- 프로젝트
- 프로젝트
- 프로젝트