在 Intel 设备上运行本地 LLM:llama.cpp + OpenVINO Docker 实战

无需 NVIDIA 显卡,用已有的 Intel CPU/GPU 即可运行大语言模型。

本文适合没有 NVIDIA 显卡的 Intel 用户(含集成显卡)。你会学到:llama.cpp + OpenVINO 的 Docker 镜像如何开箱即用地跑 LLM,CPU/GPU/API 服务器三种启动方式,以及 GPU 驱动栈、上下文溢出等常见坑的排查方法。

背景

本地运行 LLM 的好处很明显:数据隐私、零网络依赖、无限次调用不花钱。但主流方案多依赖 NVIDIA CUDA,Intel 用户(尤其是集成显卡用户)往往被排除在外。

OpenVINO 是 Intel 的 AI 推理加速工具包,能让 LLM 推理充分发挥 Intel 硬件的潜力。配合 llama.cpp(C++ 实现的高性能推理引擎),Intel 设备上也能获得不错的推理体验。

但该组合的编译配置较为繁琐,涉及 OpenVINO SDK 安装、CMake 参数调整以及 GPU 驱动栈配置。于是便有了这个项目:llama-openvino-docker,将整个过程封装为 Docker 多阶段构建,开箱即用。

技术架构

Docker 多阶段构建

Build Stage (Ubuntu 24.04)
  ├── 安装编译工具链
  ├── 下载 OpenVINO 2026.2 归档
  ├── 编译 llama.cpp(DGGML_OPENVINO=ON)
  └── 导出 .so 库和二进制
       ↓
Base Runtime Stage
  ├── 最小 Ubuntu 24.04 运行时
  ├── Intel GPU 驱动(IGC + Compute Runtime + Level Zero)
  └── OpenVINO 运行时库
       ↓
Target Stages
  ├── light    →  仅 llama-cli(默认)
  ├── full     →  全部二进制 + Python 工具
  └── server   →  仅 llama-server + health check

设计思路:

  • build 阶段搭建完整的编译环境,用完即弃
  • base 阶段只保留运行时所需的最小依赖,镜像仅 ~300MB
  • 多目标输出,按需选择:CLI 推理、API 服务、全工具链

GPU 驱动栈

要让 OpenVINO GPU 插件正常工作,关键在于完整的 GPU 驱动栈:

llama-cli / llama-server
    ↓
OpenVINO GPU Plugin (libopenvino_intel_gpu_plugin.so)
    ↓
Level Zero API + OpenCL API
    ↓
Intel Compute Runtime (libze_intel_gpu.so)
    ↓
Intel Graphics Compiler (IGC)
    ↓
Intel GPU 硬件

最初踩了个坑:只在 Docker 中安装了 intel-opencl-icd,以为这样就够了。结果 OpenVINO GPU 插件一直报 device GPU is not available, fallback to CPU。后来才发现还需 Level Zero GPU 驱动 (libze-intel-gpu1) 和 Intel Graphics Compiler。参照官方 llama.cpp OpenVINO Dockerfile,从 Intel GitHub Releases 下载精确版本的驱动 deb 包才解决问题。

快速上手

拉取镜像

项目配置了 GitHub Actions 自动构建,推送到 GitHub Container Registry:

docker pull ghcr.io/heihei0299/llama-openvino-docker:light

下载模型

mkdir -p ~/models
wget https://huggingface.co/bartowski/Llama-3.2-1B-Instruct-GGUF/resolve/main/\
Llama-3.2-1B-Instruct-Q4_K_M.gguf -O ~/models/Llama-3.2-1B-Instruct-Q4_K_M.gguf

CPU 模式

开箱即用,无需额外配置:

docker run --rm -it -v ~/models:/models \
    ghcr.io/heihei0299/llama-openvino-docker:light \
    --no-warmup -c 1024 -m /models/Llama-3.2-1B-Instruct-Q4_K_M.gguf

GPU 模式

需要透传 Intel GPU 设备到容器:

docker run --rm -it -v ~/models:/models \
    --device=/dev/dri \
    --group-add=$(stat -c "%g" /dev/dri/render* | head -n 1) \
    -u $(id -u):$(id -g) \
    --env=GGML_OPENVINO_DEVICE=GPU \
    --env=GGML_OPENVINO_STATEFUL_EXECUTION=1 \
    ghcr.io/heihei0299/llama-openvino-docker:light \
    --no-warmup -c 1024 -m /models/Llama-3.2-1B-Instruct-Q4_K_M.gguf

关键参数说明:

  • --device=/dev/dri — 将宿主机的 Intel GPU 设备节点透传至容器
  • --group-add=$(stat -c "%g" /dev/dri/render*) — 赋予容器访问 GPU 的权限组
  • GGML_OPENVINO_DEVICE=GPU — 指定使用 GPU 后端
  • GGML_OPENVINO_STATEFUL_EXECUTION=1 — 启用状态化 KV 缓存,减少重复计算

API 服务器

启动 OpenAI 兼容的 API:

docker run --rm -it -p 8080:8080 -v ~/models:/models \
    ghcr.io/heihei0299/llama-openvino-docker:server \
    --no-warmup -c 8192 -m /models/model.gguf --host 0.0.0.0

# 测试
curl http://localhost:8080/v1/chat/completions \
    -H "Content-Type: application/json" \
    -d '{"messages":[{"role":"user","content":"Hello!"}],"max_tokens":50}'

踩坑记录

1. GPU 驱动不全导致回退 CPU

症状:日志中输出 device GPU is not available, fallback to CPU

排查过程:

  1. 确认 /dev/dri/ 设备已透传 — ✅
  2. 确认 intel-opencl-icd 已安装 — ✅
  3. 检查 libze_intel_gpu.so — ❌ 不存在

解决方案:从 Intel GitHub Releases 下载并安装 libze-intel-gpu1intel-igc-coreintel-igc-opencl 等 6 个 deb 包。

2. Context size exceeded

症状:服务器日志大量出现 Context size has been exceeded,所有请求均失败

原因:llama-server 默认 -np -1(auto)会根据 CPU 核数创建多个 slot(如 4 核 → 4 slots)。每个 slot 的可用上下文为 -c / -np。若 -c 1024 配合 4 slots → 每 slot 仅 256 tokens,请求稍大即溢出。

解决:设置 -c 8192(4 slots 下每 slot 2048 tokens)或限制 -np 2

3. 本地安装 vs Docker

起初项目同时提供了一键安装脚本 install-arch.sh(支持 Arch Linux 本地编译)。但维护两条路线工作量翻倍,且 Docker 化的优势更为明显:

  • 可重复性:同一套环境在所有机器上一致
  • 隔离性:GPU 驱动版本不会与宿主机冲突
  • 分发便利:GitHub Actions 自动构建,用户直接 docker pull

最终决定砍掉本地安装路线,专注 Docker。

4. GitHub Actions 分支名问题

第一次配置 CI 时,工作流中写的是 branches: [main],但本地仓库的默认分支名为 master。push 了半天 Actions 就是不触发,排查才发现分支名不匹配。重命名分支后才恢复正常。

GitHub Actions CI/CD

项目配置了完整的 CI 流水线:

on:
  push:
    branches: [main]
    tags: ["v*"]
  pull_request:
    branches: [main]

三个目标并行构建(base / light / server),利用 GitHub Actions cache 加速。构建成功后自动推送到 ghcr.io,生成标签:

  • :light / :server / :base — 按目标区分
  • :latest → 指向 :light
  • :v* — 语义化版本标签

性能参考

使用 llama-bench 在 Intel i7-13700H 上的测试结果:

设备模型Prompt 速度生成速度
CPU (OpenVINO)Llama-3.2-1B Q4_K_M~45 t/s~25 t/s
GPU Iris XeLlama-3.2-1B Q4_K_M~1450 t/s~27 t/s
GPU (Flash Attn)Llama-3.2-1B Q4_K_M~1500 t/s~30 t/s

GPU 的 prompt 处理速度(1450 t/s)远快于 CPU(45 t/s),但生成速度差异不大。这是因为小模型的生成阶段是存储带宽瓶颈,而非算力瓶颈。

验证与自查

  1. CPU 模式运行镜像,能正常输出生成文本
  2. GPU 模式运行,日志中无 fallback to CPU,且 prompt 速度明显高于 CPU(可用 llama-bench 对比)
  3. curl http://localhost:8080/v1/chat/completions 返回正常 JSON 响应
  4. docker run 指定 -c 8192 后,大请求不再报 Context size has been exceeded

参考