Intel Meteor Lake NPU를 Proxmox 컨테이너에 패스스루하여 사용해 본 결과
요약
본 기사는 Intel Meteor Lake NPU를 Proxmox의 비특권 LXC 컨테이너에 패스스루하여 실제 AI 워크로드를 테스트한 결과를 공유합니다. 그 결과, NPU는 embeddings 및 음성 인식(Whisper) 작업에서 CPU 대비 높은 성능을 보였으나, LLM 토큰 생성에서는 내장 GPU에 크게 뒤처지는 것으로 분석되었습니다. 또한, Proxmox 환경에서 NPU를 성공적으로 패스스루하기 위한 기술적인 설정 방법도 제시합니다.
핵심 포인트
- NPU는 embeddings 및 음성 인식 작업에 실용적이며, 저전력 AI 상시 구동에 적합하다.
- LLM 토큰 생성 같은 고부하 작업은 내장 GPU가 NPU보다 월등히 성능이 좋다.
- Proxmox에서 비특권 LXC로 장치를 패스스루하려면 `dev[n]:` 단축키를 사용하는 것이 가장 효율적이다.
‘AI PC’ 세대의 CPU에는 NPU (Neural Processing Unit)가 탑재되어 있습니다. 제가 사용하는 미니 PC(Beelink GTi14 Ultra / Intel Core Ultra 7 155H = Meteor Lake)에도 Intel AI Boost NPU가 장착되어 있지만, Proxmox 상의 컨테이너에서는 인식되지 않았습니다.
본 기사에서는 NPU를 비특권 LXC 컨테이너에 패스스루하여 다음 용도로 실제로 측정한 결과를 공유합니다.
A. embeddings (RAG 벡터화)
B. 음성 인식 (Whisper)
C. NPU와 내장 GPU 동시 실행
- (참고) LLM 생성
결론부터 말씀드리자면, Meteor Lake의 NPU는 ‘embeddings’와 ‘음성 인식’에서는 CPU보다 명확하게 빠르지만, LLM의 토큰 생성에서는 내장 GPU에 크게 뒤처진다는 결과였습니다.
관련 기사: 같은 머신의 내장 GPU로 Ollama / llama.cpp(Vulkan・SYCL・OpenVINO) / OVMS를 비교한 글도 작성했습니다. 본 기사는 그 ‘NPU 편’입니다.
| 용도 | NPU 결과 | CPU 대비 | :--- |
| embeddings (bge-small) | 126.9 texts/s (7.9 ms/text) | 약 2.4 배 |
| Whisper (base, 20초 음성) | 0.42s (RTF 0.021) | 약 1.5 배 |
| LLM 생성 (1.2B) | 9.5 tok/s | GPU의 1/4~1/5 |
| NPU + GPU 동시 | 합계 +10% (경합)
| — |
NPU의 실용적인 사용처는 embeddings와 음성 인식이었습니다.
| 항목 | 내용 |
|---|---|
| 머신 | Beelink GTi14 Ultra (DMI: AZW GTi14 ) |
| SoC | Intel Core Ultra 7 155H (Meteor Lake, 6P+8E+2LP-E = 16C/22T) |
| NPU | Intel AI Boost (NPU 3720, PCI 8086:7d1d ) |
| 내장 GPU | Intel Arc Graphics (8 Xe코어) |
| ... | 비특권 LXC (Ubuntu 24.04.4 LTS, 20GB RAM, 22 vCPU) |
| 컨테이너 | Docker (LXC 내에서 중첩 실행) |
| 유닛 | 개략 성능 |
|---|---|
| NPU (AI Boost) | 약 11 TOPS |
| ... | |
| NPU는 순수 처리량(raw throughput) 면에서는 내장 GPU보다 부족합니다. 장점은 저전력 소비(Intel 자료에 따르면 GPU의 절반 이하 전력 소모)이며, ‘GPU가 다른 작업을 수행하는 동안 상시 AI’ 작업에 적합합니다. |
처음에는 일반적인 순서대로 lxc.cgroup2.devices.allow와 lxc.mount.entry를 수동으로 작성했을 때, 장치 노드는 보이지만 root 권한으로도 열 수 없는 (Permission denied) 상태가 되었습니다. 이는 장치의 소유자가 nobody:nogroup이 되어 장치 cgroup에 반영되지 않았기 때문입니다.
정답은 Proxmox의 **dev[n]: 단축키(shortcut)**를 사용하는 것입니다.
/dev/dri 패스스루와 같은 원리로, 노드 생성과 cgroup 허용을 한 번에 처리해 줍니다.
# /etc/pve/lxc/<CTID>.conf
dev0: /dev/dri/renderD128
dev1: /dev/dri/card0
...
비특권 LXC에서는 mknod가 Operation not permitted로 거부됩니다. 장치 노드를 직접 만들 수 없기 때문에, 반드시 호스트 측의 설정 변경이 필요합니다.
# 호스트(Proxmox)에서
ls -l /dev/accel/accel0 # 존재 확인 (261:0)
# /etc/pve/lxc/<CTID>.conf 에 dev2: /dev/accel/accel0 를 추가
...
재부팅 후, 게스트에서 /dev/accel/accel0가 root:root로 보이고 열 수 있게 됩니다.
커널 측에서는 intel_vpu가 로드되어 있어도, 사용자 공간의 Level Zero NPU 드라이버 (libze_intel_npu.so) 가 없으면 사용할 수 없습니다. 이번에는 OpenVINO 포함 이미지(후술)에 드라이버가 들어있었기 때문에 그것을 이용했습니다.
# 예: 이미지에서 드라이버를 추출
ls /usr/lib/x86_64-linux-gnu/libze_intel_npu.so*
모델의 OpenVINO IR 변환과 추론을 위해 Python 환경을 준비합니다. 함정이 많았기 때문에, 버전 고정이 중요합니다.
python3 -m venv /opt/ov-venv
/opt/ov-venv/bin/pip install torch --index-url https://download.pytorch.org/whl/cpu
/opt/ov-venv/bin/pip install openvino openvino-genai "optimum-intel[openvino]" \
...
주의사항:
torch와 torchvision의 버전이 어긋나면 operator torchvision::nms does not exist 오류로 인해 transformers의 import가 깨집니다. CPU 버전을 세트로 다시 설치해야 합니다. 또한, transformers는 5.4 이상 5.6 미만으로 고정합니다(후술).
bge-small-en-v1.5를 IR로 내보냅니다.
/opt/ov-venv/bin/optimum-cli export openvino \
--model BAAI/bge-small-en-v1.5 --task feature-extraction \
/opt/ov-models/bge-small-ov
내보낸 직후의 모델은 동적 쉐이프([?,?])로 되어 있어 NPU 컴파일러에 의해 거부됩니다 (INT64_MAX 차원 오류). 입력 길이를 고정하여 reshape 합니다.
import openvino as ov
core = ov.Core()
m = core.read_model("/opt/ov-models/bge-small-ov/openvino_model.xml")
...
측정 결과:
| 실행 위치 | 처리량 (Throughput) | 지연 시간 (Latency) |
|---|---|---|
| NPU | 126.9 texts/s | 7.9 ms/text |
| CPU | 52.4 texts/s | 19.1 ms/text |
NPU는 CPU의 약 2.4배입니다. 임베딩 일치도(cosine) 역시 0.99994로 실질적으로 동일한 출력을 얻었습니다. RAG의 벡터화 작업을 NPU에 맡기면, 내장 GPU를 LLM 용도로 비울 수 있습니다.
whisper-base를 내보냅니다. 여기가 가장 어려웠습니다.
/opt/ov-venv/bin/optimum-cli export openvino \
--model openai/whisper-base \
--task automatic-speech-recognition-with-past \
...
--task automatic-speech-recognition (without past)로 내보내면, decoder에 beam_idx가 포함되지 않아 WhisperPipeline이 Port for tensor name beam_idx was not found 오류로 실패합니다. -with-past를 붙이면 decoder에 beam_idx가 들어가 작동하게 됩니다. Whisper의 NPU 실행은, 내보낼 때 transformers >= 5.4가 사실상 필수입니다 (오래된 4.x로 내보낸 IR에는 NPU에서 invalid unordered_map key 오류를 일으키는 알려진 버그가 있습니다). transformers>=5.4,<5.6
에(に) 고정합시다. 실행 및 결과 (20.06초 음성, 3회 측정 최속값):
| 실행처 | 처리 시간 | RTF | 문자 기록 |
|---|---|---|---|
| NPU | 0.42s | 0.021 | CPU와 완벽 일치 |
| CPU | 0.65s | 0.033 | — |
NPU는 CPU의 약 1.5배 속도(20초 음성을 0.42초로 문자 기록). RTF 0.02는 '실시간의 1/50'으로, 상시 문자 기록에는 충분합니다.
import openvino_genai as ov_genai
pipe = ov_genai.WhisperPipeline("/opt/ov-models/whisper-past", "NPU", NPU_PLATFORM="3720")
print(pipe.generate(wav).texts[0])
'GPU로 LLM을 구동하면서, NPU로 다른 소형 모델을 구동하는' 구성을 검증했습니다. NPU에 1.2B, GPU에 4B를 올리고 동시에 요청을 보냅니다.
| 구성 | 처리량 (Throughput) |
|---|---|
| NPU 단독 (1.2B) | 8.7 tok/s |
| GPU 단독 (4B) | 13.9 tok/s |
| 동시 실행 합계 | 15.3 tok/s (NPU 6.5 + GPU 8.8) |
동시에 사용하면 각 스트림은 25~37% 저하하며, 총합도 GPU 단독 대비 +10% 정도에 그쳤습니다. 내장 GPU와 NPU가 메모리 대역폭이나 CPU를 공유하기 때문에, 경쟁(Contention)이 발생하고 있습니다.
→ 처리량을 높이는 목적보다는, 'GPU는 대화용으로 점유하고, NPU로 백그라운드 처리(embeddings・ASR)를 구동하는' 분리 용도가 현실적입니다.
같은 방식으로 1.2B의 LLM을 NPU에서 실행하면 9.5 tok/s였습니다. 내장 GPU의 Vulkan 실행 (같은 1.2B로 45.9 tok/s)의 약 1/5 수준이었습니다. 4B급은 NPU 그래프에 올라가지 않아 Compute error
으로 실패합니다.
NPU는 LLM 생성 속도 목적으로는 가치가 떨어집니다. 모델 대응 범위도 제한적입니다 (대칭 INT4 중심, 컨텍스트 상한이 작음).
| 용도 | NPU 평가 | 근거 |
|---|---|
| Embeddings / RAG | ◎ | CPU 대비 2.4배, 저전력 |
| ASR (Whisper) | ○ | CPU 대비 1.5배, 상시 처리 적합 |
| LLM 생성 | △ | GPU의 1/5 수준, 모델 대응도 제한적 |
| GPU와 동시 | △ | 총합 증가폭이 제한적 |
Meteor Lake의 NPU는 '임베딩'과 '음성 인식(ASR)'에 사용하는 것이 결론입니다. 둘 다 GPU에서 분리할 수 있기 때문에, 'GPU는 LLM, NPU는 RAG 벡터화와 문자 기록'이라는 역할 분담이 유효합니다.
-
패스스루는 Proxmox의
으로 (수동dev[n]:
방식lxc.*
은 효과가 없음) -
NPU는 정적 셰이프 필수(동적 셰이프는 컴파일 불가) -를 명시NPU_PLATFORM=3720 -
Whisper는
+--task ...-with-past
transformers>=5.4 -
사용자 공간의
Level Zero NPU 드라이버가 필요 - NPU 실행은 OpenVINO 포함 이미지 내에서 진행하는 것이 확실합니다. -
Intel NPU / OpenVINO 설정: https://docs.openvino.ai/2026/get-started/install-openvino/configurations/configurations-intel-npu.html
-
OpenVINO GenAI on NPU: https://docs.openvino.ai/2025/openvino-workflow-generative/inference-with-genai/inference-with-genai-on-npu.html
-
Whisper on NPU의 알려진 버그(#4222): https://github.com/openvinotoolkit/openvino.genai/issues/4222
-
OpenVINO Model Server (NPU 배포): https://docs.openvino.ai/2026/model-server/ovms_demos_llm_npu.html
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기