首页
/ llama.cpp OpenVINO 后端实战指南:在 Intel CPU/GPU/NPU 上加速 GGUF 模型推理

llama.cpp OpenVINO 后端实战指南:在 Intel CPU/GPU/NPU 上加速 GGUF 模型推理

2026-09-06 15:10:19作者:翟江哲Frasier

本篇基于仓库官方文档 docs/backend/OPENVINO.md 整理并深入源码展开,讲解 llama.cpp 的 OpenVINO 后端如何把 GGML 计算图翻译为 OpenVINO 图,从而在 Intel CPU、GPU 与 NPU 上保持 GGUF 模型生态兼容地加速推理。读完你将掌握从环境准备、CMake 构建、Docker 镜像、模型验证清单到全部运行时环境变量调优的完整路径,并能结合源码理解图翻译、权重缓存与 KV cache 管理的关键实现。

后端定位与工作原理

OpenVINO 是 Intel 官方的开源 AI 推理优化工具包,面向云、本地与边缘场景的 Intel CPU、GPU 和 NPU。llama.cpp 中的 OpenVINO 后端实现位于 ggml/src/ggml-openvino,它是一条把核心 GGML 算子翻译为 OpenVINO 图的前端翻译层:后端用 OpenVINO 推理引擎替代标准 GGML 图执行路径,借助图编译、算子融合与设备专属优化提升性能,同时同一份 GGUF 模型文件无需任何改动即可跑在 Intel CPU、集成/独显 GPU 与 NPU 上。

从源码结构看,当一张 ggml_cgraph 被派发到 OpenVINO 后端时,处理流程为四步:

  1. 遍历 GGML 图,识别输入、输出、权重与 KV cache 张量;
  2. 翻译算子:通过 OpenVINO 前端 API 将 GGML 操作转换为 ov::Model,算子注册表与前端转换逻辑集中在 ggml/src/ggml-openvino/openvino/op_table.cppggml/src/ggml-openvino/openvino/frontend.cpp
  3. 编译并缓存模型:针对目标设备编译,缓存逻辑见 ggml/src/ggml-openvino/model-cache.cpp
  4. 绑定内存并推理:把 GGML 张量内存绑定到 OpenVINO 推理张量后执行。

ggml/src/ggml-openvino/ggml-openvino.cpp 顶部的设计注释说明了内存层的混合策略,值得注意:

  • 权重张量:直接存储一个预构建的 ov::op::v0::Constanttensor->extra,避免构图阶段的 memcpy;量化权重在建图时就已转换为 OpenVINO 格式;
  • KV cache / 计算张量:存储 ov::Tensor,可直接传入 infer_request;GPU 场景可升级为 USM(Unified Shared Memory)远程张量,ggml-openvino.cppov::intel_gpu::ocl::USMTensor 的构造即为 GPU 远程缓冲路径。

后端的注册入口为 ggml_backend_openvino_reg(),并带 GGML_BACKEND_DL_IMPL 宏导出(ggml-openvino.cpp),这与 ggml 其他可动态加载后端的机制一致:CMake 层通过 ggml/CMakeLists.txt 中的 GGML_OPENVINO 选项(默认 OFF)决定是否编译该后端,构建时以 -DGGML_OPENVINO=ON 开启(对应 ggml/CMakeLists.txt)。后端的 CMake 会强制 find_package(OpenVINO REQUIRED COMPONENTS Runtime Threading)find_package(OpenCL REQUIRED),并链接 openvino::runtimeopenvino::threadingOpenCL::OpenCL,同时校验平台为 x86-64 或 arm64(见 ggml/src/ggml-openvino/CMakeLists.txt)。

此外,目录下的 openvino/pass/ 包含若干图优化 pass:fuse_to_sdpa(融合为标准缩放点积注意力)、fuse_to_convsqueeze_matmul 等,这是"内核融合"承诺在源码中的落点;openvino/decoder.hggml-decoder.cpp 则对应逐 token 解码阶段的图复用。

性能与内存优化、精度验证、更广的量化覆盖和算子/模型支持均在进行中(work in progress)。

支持的设备

  • Intel CPU
  • Intel GPU(集成与独显)
  • Intel NPU

OpenVINO 本身支持更广泛的 Intel 硬件,但 llama.cpp 的 OpenVINO 后端目前是在类似 Intel® Core™ Ultra Series 1 / Series 2 这类 AI PC 上完成验证的;具体支持面以 OpenVINO 官方系统要求文档为准。

支持的模型精度

  • FP16
  • BF16(Intel Xeon 上)
  • Q8_0
  • Q4_0
  • Q4_1
  • Q4_K
  • Q4_K_M
  • Q5_K(运行时转换为 Q8_0_C
  • Q6_K(运行时转换为 Q8_0_C

CPU / GPU 量化细节: Q5_KQ6_K 张量会被转换为 Q8_0_C

NPU 量化细节:

  • NPU 主推的量化方案是 Q4_0
  • Q6_K 张量一般会重量化为 Q4_0_128;对于 embedding 权重,Q6_K 会重量化为 Q8_0_C,但 token embedding 矩阵本身会被反量化为 fp16。

其他说明:

  • Q4_0Q4_1 模型都会为 token embedding 张量和最终 matmul 权重张量(两者常为同一张量)使用 Q6_K
  • 若在 llama-quantize 量化 Q4_0 时提供了 imatrix,模型中可能出现部分 Q4_1 张量;
  • Q4_K_M 模型可能同时包含 Q6_KQ5_K 张量(在 Phi-3 上观察到);
  • Q5_1 张量采用原生反量化(直接提取 weights、scales、zero-points)。

量化张量的转换/反量化实现集中在 ggml/src/ggml-openvino/ggml-quants.cppggml/src/ggml-openvino/ggml-quants.h

支持的 llama.cpp 工具

以下标准工具可与 OpenVINO 后端集成,但各工具在 CPU/GPU/NPU 上的覆盖并不均匀,完整验证仍在进行:

  • llama-bench
  • llama-cli
  • llama-completion
  • llama-embedding
  • llama-perplexity
  • llama-run
  • llama-server
  • llama-simple

已验证模型

以下模型均在 Intel® Core™ Ultra Series 2(Lunar Lake)上用 llama-cli + Q4_K_M 量化完成测试;后端预期在更广泛的 Intel 硬件、上文列出的精度、工具与模型架构上可用。

图例与测试配置:

  • 状态: ✓ = 通过 | ✗ = 失败或不支持
  • 执行模式:
    • SL = Stateless(无状态,GGML_OPENVINO_STATEFUL_EXECUTION=0
    • SF = Stateful(有状态,GGML_OPENVINO_STATEFUL_EXECUTION=1
    • 注意:NPU 仅以无状态模式运行。
  • 验证系统: Intel® Core™ Ultra 5 238V(Lunar Lake)| 32 GB 内存 | Ubuntu 24.04 | Intel OpenCL GPU 驱动 26.31.39395.13-0 | Intel NPU 驱动 1.35.0。
模型 CPU (SL / SF) GPU (SL / SF) NPU (SL)
bartowski/Llama-3.2-1B-Instruct-Q4_K_M ✓ / ✓ ✓ / ✓
bartowski/Llama-3.2-3B-Instruct-Q4_K_M ✓ / ✓ ✓ / ✓
bartowski/Meta-Llama-3.1-8B-Instruct-Q4_K_M ✓ / ✓ ✓ / ✓
Qwen/qwen2.5-1.5b-instruct-q4_k_m ✓ / ✓ ✓ / ✓
Qwen/qwen2.5-coder-7b-instruct-q4_k_m ✓ / ✓ ✓ / ✓
bartowski/Qwen_Qwen3-0.6B-Q4_K_M ✓ / ✓ ✓ / ✓
bartowski/Qwen_Qwen3-1.7B-Q4_K_M ✓ / ✓ ✓ / ✓
Qwen/Qwen3-4B-Q4_K_M ✓ / ✓ ✓ / ✓
lm-kit/Qwen3-8B-Q4_K_M ✓ / ✓ ✓ / ✓
bartowski/Qwen_Qwen3.5-0.8B-Q4_K_M ✓ / ✗ ✓ / ✗
bartowski/Qwen_Qwen3.5-2B-Q4_K_M ✓ / ✗ ✓ / ✗
bartowski/Qwen_Qwen3.5-4B-Q4_K_M ✓ / ✗ ✓ / ✗
lmstudio-community/Qwen3.5-9B-Q4_K_M ✓ / ✗ ✓ / ✗
unsloth/gemma-3-4b-it-Q4_K_M ✓ / ✓ ✓ / ✓
bartowski/google_gemma-4-E2B-it-Q4_K_M ✓ / ✗ ✓ / ✗
bartowski/google_gemma-4-E4B-it-Q4_K_M ✓ / ✗ ✓ / ✗
bartowski/gemma-4-12B-it-Q4_K_M ✓ / ✗ ✓ / ✗
bartowski/Phi-3-mini-4k-instruct-Q4_K_M ✓ / ✓ ✓ / ✓
bartowski/Phi-3.5-mini-instruct-Q4_K_M ✓ / ✓ ✓ / ✓
bartowski/microsoft_Phi-4-mini-instruct-Q4_K_M ✓ / ✓ ✓ / ✓
bartowski/Mistral-7B-Instruct-v0.3-Q4_K_M ✓ / ✓ ✓ / ✓
QuantFactory/Ministral-3b-instruct.Q4_K_M ✓ / ✓ ✓ / ✓
bartowski/Ministral-8B-Instruct-2410-Q4_K_M ✓ / ✓ ✓ / ✓
bartowski/DeepSeek-R1-Distill-Llama-8B-Q4_K_M ✓ / ✓ ✓ / ✓
bartowski/DeepSeek-R1-Distill-Qwen-7B-Q4_K_M ✓ / ✓ ✓ / ✓
ibm-granite/granite-4.0-350m-Q4_K_M ✓ / ✓ ✗ / ✗
ibm-granite/granite-4.0-micro-Q4_K_M ✓ / ✓ ✓ / ✓
ibm-granite/granite-4.0-1b-Q4_K_M ✓ / ✓ ✗ / ✗
ibm-research/granite-3.2-8b-instruct-Q4_K_M ✓ / ✓ ✓ / ✓
HuggingFaceTB/smollm2-1.7b-instruct-q4_k_m ✓ / ✓ ✓ / ✓
openbmb/MiniCPM-V-2_6-Q4_K_M ✓ / ✓ ✓ / ✓
bartowski/tencent_Hunyuan-7B-Instruct-Q4_K_M ✓ / ✓ ✓ / ✓
LGAI-EXAONE/EXAONE-3.5-7.8B-Instruct-Q4_K_M ✓ / ✓ ✓ / ✓
bartowski/prism-ml_Bonsai-8B-unpacked-Q4_K_M ✓ / ✓ ✓ / ✓
gpustack/bge-m3-Q4_K_M.gguf

构建指南

0. 前置条件

  • 带 Intel 硬件(CPU、GPU 或 NPU)的 Linux 或 Windows 系统;
  • 若使用 Intel GPU 或 NPU:先为 GPU/NPU 安装对应的硬件驱动(详见 OpenVINO 官方"硬件加速附加配置"文档)。

Linux: 需要 Git、CMake、Ninja 等构建工具:

sudo apt-get update
sudo apt-get install -y build-essential libcurl4-openssl-dev libtbb12 cmake ninja-build python3-pip curl wget tar

以及 OpenCL:

sudo apt install ocl-icd-opencl-dev opencl-headers opencl-clhpp-headers intel-opencl-icd

Windows:

  • 安装 Visual Studio 2022 Build Tools(选择 "Desktop development with C++" 工作负载);
  • 安装工具:
# Windows PowerShell
winget install Git.Git
winget install GNU.Wget
winget install Ninja-build.Ninja
  • 通过 vcpkg 安装 OpenCL:
# Windows PowerShell
cd C:\
git clone https://github.com/microsoft/vcpkg
cd vcpkg
.\bootstrap-vcpkg.bat
.\vcpkg install opencl
# 可选但推荐:将 vcpkg 集成到 Visual Studio / CMake
.\vcpkg integrate install

1. 安装 OpenVINO Runtime

按 OpenVINO 官方文档从离线压缩包安装 Runtime(Linux 与 Windows 各有一篇安装指引),然后验证初始化:

echo $OpenVINO_DIR

2. 构建带 OpenVINO 后端的 llama.cpp

克隆 llama.cpp 仓库后进入目录。

Linux:

source /opt/intel/openvino/setupvars.sh
cmake -B build/ReleaseOV -G Ninja -DCMAKE_BUILD_TYPE=Release -DGGML_OPENVINO=ON
cmake --build build/ReleaseOV --parallel

Windows: 打开 x64 Native Tools Command Prompt for VS(确保 MSVC 工具链在 PATH 中),然后执行:

C:\Intel\openvino\setupvars.bat
cmake -B build\ReleaseOV -G Ninja -DCMAKE_BUILD_TYPE=Release -DGGML_OPENVINO=ON -DCMAKE_TOOLCHAIN_FILE=C:\vcpkg\scripts\buildsystems\vcpkg.cmake
cmake --build build\ReleaseOV --parallel

建议 Windows 上把 OpenVINO 装在 C:\Intel\openvino(路径无空格),以避免部分 CMake/Ninja 工具链对 C:\Program Files (x86)\... 的引号问题;安装位置不同则相应调整。cmd 中执行 C:\Intel\openvino\setupvars.bat;PowerShell 中执行 & "C:\Intel\openvino\setupvars.ps1"。构建完成后,在任意 cmd/PowerShell 窗口中 source 对应的 setupvars 脚本即可运行二进制。

Ubuntu 一键构建脚本

对 Ubuntu 24 用户,可用下面的脚本自动完成前置依赖安装(构建工具、OpenCL ICD)、OpenVINO Runtime 的下载/解压/初始化,以及基于 Ninja 的 llama.cpp 构建。将其保存为 build-llamacpp-ov.sh,放在你希望 llama.cpp 目录落地的位置,然后执行:

chmod +x build-llamacpp-ov.sh
./build-llamacpp-ov.sh
#!/usr/bin/env bash
# ============================================
# llama.cpp OpenVINO Build Script (Ninja)
# ============================================
set -euo pipefail

OPENVINO_VERSION_MAJOR="2026.3.1"
OPENVINO_VERSION_FULL="2026.3.1.22476.56d9685302d"

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
OPENVINO_INSTALL_DIR="/opt/intel/openvino_${OPENVINO_VERSION_MAJOR}"
OPENVINO_LINK_DIR="/opt/intel/openvino"
OPENVINO_TGZ="${SCRIPT_DIR}/openvino.tgz"
OPENVINO_URL="https://storage.openvinotoolkit.org/repositories/openvino/packages/${OPENVINO_VERSION_MAJOR}/linux/openvino_toolkit_ubuntu24_${OPENVINO_VERSION_FULL}_x86_64.tgz"

echo "============================================"
echo "Installing prerequisites (apt)..."
echo "============================================"
sudo apt-get update
sudo apt-get install -y \
    build-essential libcurl4-openssl-dev libtbb12 \
    cmake ninja-build python3-pip \
    curl wget tar git

echo "============================================"
echo "Installing OpenCL runtime + headers..."
echo "============================================"
sudo apt-get install -y \
    ocl-icd-opencl-dev opencl-headers opencl-clhpp-headers intel-opencl-icd

cd "${SCRIPT_DIR}"

# ============================================
# Clone llama.cpp if missing
# ============================================
if [[ ! -f "llama.cpp/CMakeLists.txt" ]]; then
    echo "Cloning llama.cpp..."
    git clone https://github.com/ggml-org/llama.cpp
fi

# ============================================
# Setup OpenVINO: download & extract to /opt/intel/openvino_${OPENVINO_VERSION_MAJOR},
# then point /opt/intel/openvino at it via symlink so the active version is swappable.
# ============================================
if [[ -f "${OPENVINO_INSTALL_DIR}/setupvars.sh" ]]; then
    echo "OpenVINO ${OPENVINO_VERSION_MAJOR} already installed at ${OPENVINO_INSTALL_DIR}. Skipping download."
else
    echo "OpenVINO not found at ${OPENVINO_INSTALL_DIR}. Starting download..."
    curl -L -o "${OPENVINO_TGZ}" "${OPENVINO_URL}"

    echo "Extracting OpenVINO to ${OPENVINO_INSTALL_DIR}..."
    sudo mkdir -p "${OPENVINO_INSTALL_DIR}"
    sudo tar -xzf "${OPENVINO_TGZ}" -C "${OPENVINO_INSTALL_DIR}" --strip-components=1
    rm -f "${OPENVINO_TGZ}"
fi

# Refresh symlink: /opt/intel/openvino -> /opt/intel/openvino_${OPENVINO_VERSION_MAJOR}
sudo ln -sfn "${OPENVINO_INSTALL_DIR}" "${OPENVINO_LINK_DIR}"

OPENVINO_ROOT="${OPENVINO_LINK_DIR}"
echo "OpenVINO Ready: ${OPENVINO_ROOT} -> ${OPENVINO_INSTALL_DIR}"

# Install OpenVINO's own runtime dependencies (one-time per system).
if [[ -x "${OPENVINO_ROOT}/install_dependencies/install_openvino_dependencies.sh" ]]; then
    echo "============================================"
    echo "Installing OpenVINO runtime dependencies..."
    echo "============================================"
    echo "Y" | sudo -E "${OPENVINO_ROOT}/install_dependencies/install_openvino_dependencies.sh"
fi

# ============================================
# Clean old build cache
# ============================================
cd "${SCRIPT_DIR}/llama.cpp"
if [[ -d "build/ReleaseOV" ]]; then
    echo "Removing old build directory..."
    rm -rf "build/ReleaseOV"
fi

echo "============================================"
echo "Configuring with CMake..."
echo "============================================"
set +u
source "${OPENVINO_ROOT}/setupvars.sh"
set -u

cmake -B build/ReleaseOV -G Ninja \
    -DCMAKE_BUILD_TYPE=Release \
    -DGGML_OPENVINO=ON

cmake --build build/ReleaseOV --parallel

echo "============================================"
echo "Build completed successfully!"
echo "============================================"
echo "Binaries: $(pwd)/build/ReleaseOV/bin"
echo
echo "NOTE: To run, source setupvars.sh and pick a device:"
echo "  source /opt/intel/openvino/setupvars.sh"
echo "  export GGML_OPENVINO_DEVICE=CPU   # or GPU / NPU"
echo "  ./build/ReleaseOV/bin/llama-cli -m model.gguf"

脚本通过顶部的 OPENVINO_VERSION_MAJOR / OPENVINO_VERSION_FULL 变量固定 OpenVINO 2026.3.1 版本——修改它们即可跟踪其他发行版。

Windows 一键构建脚本

Windows 用户可用下面的 .bat 脚本自动化前置依赖安装(Git、Ninja、CMake、VS 2022 Build Tools、vcpkg + OpenCL)、OpenVINO Runtime 下载/解压与 Ninja 构建。保存为 build-llamacpp-ov.bat 放在 llama.cpp 目标目录同级,从 Command PromptPowerShell 运行:

:: Command Prompt
build-llamacpp-ov.bat
# PowerShell
.\build-llamacpp-ov.bat
@echo off
setlocal enabledelayedexpansion

REM ============================================
REM llama.cpp OpenVINO Build Script (Ninja)
REM ============================================

set "OPENVINO_VERSION_MAJOR=2026.3.1"
set "OPENVINO_VERSION_FULL=2026.3.1.22476.56d9685302d"

set "SCRIPT_DIR=%~dp0"
set "VCPKG_DIR=C:\vcpkg"
set "OPENVINO_INSTALL_DIR=C:\Intel\openvino_%OPENVINO_VERSION_MAJOR%"
set "OPENVINO_LINK_DIR=C:\Intel\openvino"
set "OPENVINO_ZIP=%SCRIPT_DIR%openvino.zip"
set "OPENVINO_EXTRACT_TMP=%SCRIPT_DIR%openvino_extract_tmp"
set "OPENVINO_URL=https://storage.openvinotoolkit.org/repositories/openvino/packages/%OPENVINO_VERSION_MAJOR%/windows/openvino_toolkit_windows_%OPENVINO_VERSION_FULL%_x86_64.zip"

echo ============================================
echo Installing prerequisites...
echo ============================================
winget install --id Git.Git -e --accept-source-agreements --accept-package-agreements 2>nul
winget install --id Ninja-build.Ninja -e --accept-source-agreements --accept-package-agreements 2>nul
winget install --id Kitware.CMake -e --accept-source-agreements --accept-package-agreements 2>nul

REM Ensure Visual Studio Build Tools are installed.
echo Checking for Visual Studio Build Tools...
set "VSWHERE=%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe"
set "VS_INSTALLED="
if exist "%VSWHERE%" (
    for /f "usebackq tokens=*" %%i in (`"%VSWHERE%" -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath 2^>nul`) do (
        set "VS_INSTALLED=%%i"
    )
)
if defined VS_INSTALLED (
    echo Visual Studio with VC++ x86/x64 tools already present at "!VS_INSTALLED!". Skipping winget install.
) else (
    winget install --id Microsoft.VisualStudio.2022.BuildTools -e --override "--wait --passive --add Microsoft.VisualStudio.Workload.VCTools --includeRecommended" --accept-source-agreements --accept-package-agreements
    if errorlevel 1 (
        echo WARNING: winget could not install Visual Studio Build Tools automatically.
        echo Install manually from https://aka.ms/vs/17/release/vs_BuildTools.exe ^(select the "Desktop development with C++" workload^)
        echo and re-run this script from a "Developer Command Prompt for VS 2022".
    )
)

echo ============================================
echo Installing OpenCL via vcpkg...
echo ============================================
if not exist "%VCPKG_DIR%" (
    git clone https://github.com/microsoft/vcpkg "%VCPKG_DIR%"
    cd /d "%VCPKG_DIR%"
    call bootstrap-vcpkg.bat
    call vcpkg integrate install
)
cd /d "%VCPKG_DIR%"
call vcpkg install opencl

cd /d "%SCRIPT_DIR%"

REM ============================================
REM Clone llama.cpp if missing
REM ============================================
if not exist "llama.cpp\CMakeLists.txt" (
    echo Cloning llama.cpp...
    git clone https://github.com/ggml-org/llama.cpp
)

cd /d "llama.cpp"
set "SCRIPT_DIR=%CD%"

REM ============================================
REM Setup OpenVINO: download & extract to C:\Intel\openvino_%OPENVINO_VERSION_MAJOR%,
REM then point C:\Intel\openvino at it via a directory junction (mklink /J).
REM ============================================

if exist "%OPENVINO_INSTALL_DIR%\setupvars.bat" (
    echo OpenVINO %OPENVINO_VERSION_MAJOR% already installed at "%OPENVINO_INSTALL_DIR%". Skipping download.
) else (
    echo OpenVINO not found at "%OPENVINO_INSTALL_DIR%". Starting download...

    curl -L -o "%OPENVINO_ZIP%" "%OPENVINO_URL%"
    if errorlevel 1 (
        echo ERROR: Download failed.
        exit /b 1
    )

    echo Extracting OpenVINO...
    if exist "%OPENVINO_EXTRACT_TMP%" rmdir /s /q "%OPENVINO_EXTRACT_TMP%"
    mkdir "%OPENVINO_EXTRACT_TMP%"
    tar -xf "%OPENVINO_ZIP%" -C "%OPENVINO_EXTRACT_TMP%"
    if errorlevel 1 (
        echo ERROR: Extraction failed.
        exit /b 1
    )

    REM Move the single top-level folder contents into the versioned install dir.
    set "OPENVINO_EXTRACTED="
    for /d %%i in ("%OPENVINO_EXTRACT_TMP%\*") do set "OPENVINO_EXTRACTED=%%i"
    if not defined OPENVINO_EXTRACTED (
        echo ERROR: Could not locate extracted OpenVINO folder under "%OPENVINO_EXTRACT_TMP%".
        exit /b 1
    )
    if not exist "%OPENVINO_INSTALL_DIR%" mkdir "%OPENVINO_INSTALL_DIR%"
    xcopy /e /i /y /q "!OPENVINO_EXTRACTED!\*" "%OPENVINO_INSTALL_DIR%\" >nul
    if errorlevel 1 (
        echo ERROR: Failed to copy OpenVINO from "!OPENVINO_EXTRACTED!" to "%OPENVINO_INSTALL_DIR%".
        echo Re-run this script from an elevated Command Prompt ^(Run as administrator^) if access is denied.
        exit /b 1
    )

    rmdir /s /q "%OPENVINO_EXTRACT_TMP%"
    del "%OPENVINO_ZIP%"
)

REM Refresh junction: C:\Intel\openvino -> C:\Intel\openvino_<version>.
REM `mklink /J` creates a directory junction (no admin / Developer Mode required).
if exist "%OPENVINO_LINK_DIR%" rmdir "%OPENVINO_LINK_DIR%"
mklink /J "%OPENVINO_LINK_DIR%" "%OPENVINO_INSTALL_DIR%" >nul
if errorlevel 1 (
    echo ERROR: Failed to create junction "%OPENVINO_LINK_DIR%" -^> "%OPENVINO_INSTALL_DIR%".
    echo If "%OPENVINO_LINK_DIR%" already exists as a regular non-empty folder, remove it manually and re-run.
    exit /b 1
)

set "OPENVINO_ROOT=%OPENVINO_LINK_DIR%"
echo OpenVINO Ready: %OPENVINO_ROOT% -^> %OPENVINO_INSTALL_DIR%


echo ============================================
echo Setting up compiler environment...
echo ============================================
REM Locate Visual Studio Build Tools vcvars64.bat
set "VSWHERE=%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe"
if exist "%VSWHERE%" (
    for /f "usebackq tokens=*" %%i in (`"%VSWHERE%" -latest -products Microsoft.VisualStudio.Product.BuildTools -property installationPath`) do (
        set "VS_PATH=%%i"
    )
)
if defined VS_PATH (
    call "%VS_PATH%\VC\Auxiliary\Build\vcvars64.bat" >nul
) else (
    echo WARNING: Visual Studio Build Tools not found. Compiler may be missing.
)

REM ============================================
REM Clean old build cache
REM ============================================
if exist "build\ReleaseOV" (
    echo Removing old build directory ...
    rmdir /s /q "build\ReleaseOV"
)

echo ============================================
echo Configuring with CMake...
echo ============================================
call "%OPENVINO_ROOT%\setupvars.bat" >nul 2>nul

cmake -B build\ReleaseOV -G Ninja ^
    -DCMAKE_BUILD_TYPE=Release ^
    -DGGML_OPENVINO=ON ^
    -DCMAKE_TOOLCHAIN_FILE="%VCPKG_DIR%\scripts\buildsystems\vcpkg.cmake"

if errorlevel 1 (
    echo If you continue to face CMAKE errors, make sure to install:
    echo   winget install Microsoft.VisualStudio.2022.BuildTools
    echo   Then run the "Developer Command Prompt for VS 2022" and launch this script from there.
    exit /b 1
)

cmake --build build\ReleaseOV --config Release
if errorlevel 1 exit /b 1

echo ============================================
echo Build completed successfully!
echo ============================================
echo Binaries: %CD%\build\ReleaseOV\bin
echo.
echo NOTE: To run, source setupvars.bat and pick a device:
echo   call "C:\Intel\openvino\setupvars.bat"
echo   set GGML_OPENVINO_DEVICE=CPU   ^&^& REM or GPU / NPU
echo   build\ReleaseOV\bin\llama-cli.exe -m model.gguf
echo.

endlocal

脚本同样通过 OPENVINO_VERSION_MAJOR / OPENVINO_VERSION_FULL 固定 OpenVINO 2026.3.1。新 shell 中通过 junction source 对应脚本——cmdcall "C:\Intel\openvino\setupvars.bat",PowerShell 用 & "C:\Intel\openvino\setupvars.ps1"。若 winget 首次无法注册 VS Build Tools,请手动安装一次后从管理员 Developer Command Prompt for VS 2022 重跑脚本。

3. 下载示例模型

以下载 Llama-3.2-1B(Q4_K_M)为例(Hugging Face 对应仓库地址按上表模型名称检索):

# Linux
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

# Windows PowerShell
mkdir C:\models
Invoke-WebRequest -Uri https://huggingface.co/bartowski/Llama-3.2-1B-Instruct-GGUF/resolve/main/Llama-3.2-1B-Instruct-Q4_K_M.gguf -OutFile C:\models\Llama-3.2-1B-Instruct-Q4_K_M.gguf

# Windows Command Line
mkdir C:\models
curl -L https://huggingface.co/bartowski/Llama-3.2-1B-Instruct-GGUF/resolve/main/Llama-3.2-1B-Instruct-Q4_K_M.gguf -o C:\models\Llama-3.2-1B-Instruct-Q4_K_M.gguf

4. 用 OpenVINO 后端运行推理

首次推理的首 token 可能因"飞式"(on-the-fly)转换为 OpenVINO 图而略有额外延迟,后续 token 与后续运行都会更快(得益于模型缓存,见 ggml/src/ggml-openvino/model-cache.cpp)。

默认上下文取模型训练上下文,可能非常大(例如 Llama 3.2 1B 为 131072),在边缘/笔记本设备上会拉低性能,建议用 -c 限制上下文(如 -c 512)。

# 未设置设备或设备不可用时回退到 CPU。
# 多 GPU 系统可用 GPU.0 或 GPU.1 显式指定具体 GPU。

# Linux
export GGML_OPENVINO_DEVICE=GPU
# 可选:启用有状态执行以提升 GPU 性能(推荐)
export GGML_OPENVINO_STATEFUL_EXECUTION=1
# 运行 llama-simple:
./build/ReleaseOV/bin/llama-simple -m ~/models/Llama-3.2-1B-Instruct-Q4_K_M.gguf -n 50 "The story of AI is "
# 聊天模式:
./build/ReleaseOV/bin/llama-cli -m ~/models/Llama-3.2-1B-Instruct-Q4_K_M.gguf -c 1024
# llama-bench 需要 -fa 1
GGML_OPENVINO_STATEFUL_EXECUTION=1 GGML_OPENVINO_DEVICE=GPU ./build/ReleaseOV/bin/llama-bench -m ~/models/Llama-3.2-1B-Instruct-Q4_K_M.gguf -fa 1

# NPU: 上下文要小,避免超大模型上下文窗口导致失败
export GGML_OPENVINO_DEVICE=NPU
./build/ReleaseOV/bin/llama-cli -m ~/models/Llama-3.2-1B-Instruct-Q4_K_M.gguf -c 512

# Windows Command Line
set GGML_OPENVINO_DEVICE=GPU
# 可选:启用有状态执行(推荐)
set GGML_OPENVINO_STATEFUL_EXECUTION=1
# Windows PowerShell
$env:GGML_OPENVINO_DEVICE = "GPU"
$env:GGML_OPENVINO_STATEFUL_EXECUTION = "1"

# 运行 llama-simple
build\ReleaseOV\bin\llama-simple.exe -m "C:\models\Llama-3.2-1B-Instruct-Q4_K_M.gguf" -n 50 "The story of AI is "
# 聊天模式
build\ReleaseOV\bin\llama-cli.exe -m "C:\models\Llama-3.2-1B-Instruct-Q4_K_M.gguf" -c 1024
# llama-bench 需要 -fa 1
build\ReleaseOV\bin\llama-bench.exe -m "C:\models\Llama-3.2-1B-Instruct-Q4_K_M.gguf" -fa 1

# NPU: 上下文要小
# Windows Command Line
set GGML_OPENVINO_DEVICE=NPU
# Windows PowerShell
$env:GGML_OPENVINO_DEVICE = "NPU"
build\ReleaseOV\bin\llama-cli.exe -m "C:\models\Llama-3.2-1B-Instruct-Q4_K_M.gguf" -c 512

多 GPU 系统用 GPU.0 / GPU.1 指定具体 GPU,更多细节参考 OpenVINO 官方 GPU 设备文档。

5. Docker 构建与运行

仓库自带 ​.devops/openvino.Dockerfile,支持多个构建目标:

# 基础运行时镜像:编译好的共享库 + 最小依赖
docker build -t llama-openvino:base -f .devops/openvino.Dockerfile .

# 完整镜像:全部二进制、Python 工具、gguf-py 库与模型转换工具
docker build --target=full -t llama-openvino:full -f .devops/openvino.Dockerfile .

# 最小 CLI 镜像:仅含 llama-cli 可执行文件
docker build --target=light -t llama-openvino:light -f .devops/openvino.Dockerfile .

# 仅 server 镜像:llama-server 可执行文件、健康检查端点与 REST API
docker build --target=server -t llama-openvino:server -f .devops/openvino.Dockerfile .

# 代理环境下
docker build --build-arg http_proxy=$http_proxy --build-arg https_proxy=$https_proxy --target=server -t llama-openvino:server -f .devops/openvino.Dockerfile .

把示例模型保存在 ~/models(如上一步),在下列示例中挂载进容器:

# 运行容器(CPU)
docker run --rm -it -v ~/models:/models llama-openvino:light --no-warmup -c 1024 -m /models/Llama-3.2-1B-Instruct-Q4_K_M.gguf

# 带 Intel GPU 访问(iGPU 或 dGPU)
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 \
llama-openvino:light --no-warmup -c 1024 -m /models/Llama-3.2-1B-Instruct-Q4_K_M.gguf

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

运行 llama-server(注意:GGML_OPENVINO_STATEFUL_EXECUTION=1 时仅支持单聊天会话/线程):

# CPU
docker run --rm -it -p 8080:8080 -v ~/models:/models llama-openvino:server --no-warmup -m /models/Llama-3.2-1B-Instruct-Q4_K_M.gguf -c 1024 --host 0.0.0.0

# 带 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) \
-p 8080:8080 --env=GGML_OPENVINO_DEVICE=GPU \
llama-openvino:server --no-warmup -c 1024 -m /models/Llama-3.2-1B-Instruct-Q4_K_M.gguf --host 0.0.0.0

# 带 Intel NPU 访问
docker run --rm -it -v ~/models:/models \
--device=/dev/accel --group-add=$(stat -c "%g" /dev/dri/render* | head -n 1) -u $(id -u):$(id -g) \
-p 8080:8080 --env=GGML_OPENVINO_DEVICE=NPU \
llama-openvino:server --no-warmup -c 1024 -m /models/Llama-3.2-1B-Instruct-Q4_K_M.gguf --host 0.0.0.0

# 或直接使用本地构建的 llama-server
./build/ReleaseOV/bin/llama-server -m ~/models/Llama-3.2-1B-Instruct-Q4_K_M.gguf --port 8080 -c 1024

服务起来后,可在浏览器打开 http://localhost:8080 的 Web UI,或在另一个终端用 curl 验证:

# 代理环境下为 localhost 配置 NO_PROXY
export NO_PROXY=localhost,127.0.0.1

# 健康检查
curl -f http://localhost:8080/health

# 简单提问
curl -X POST "http://localhost:8080/v1/chat/completions" -H "Content-Type: application/json" \
 -d '{"messages":[{"role":"user","content":"Write a poem about OpenVINO"}],"max_tokens":100}' | jq .

运行时配置:GGML OpenVINO 后端环境变量

后端通过环境变量控制设备选择、缓存、调试与 profiling。布尔类开关遵循统一约定:设为正整数(如 1)启用;未设置、空、0、负数或非数字均视为禁用。

变量 类型 默认值 说明
GGML_OPENVINO_DEVICE String CPU 目标设备(CPU、GPU、NPU)。多 GPU 系统用 GPU.0/GPU.1 指定具体 GPU。设为 NPU 时启用静态编译模式以获得最佳性能。
GGML_OPENVINO_CACHE_DIR String not set OpenVINO 模型缓存目录(推荐 /tmp/ov_cache),设置后启用模型缓存。NPU 设备不支持。
GGML_OPENVINO_COMPILED_MODEL_CACHE_DIR String not set 前端编译模型缓存目录。设置后 OpenVINO 编译模型导出为 blob,后续运行对匹配的单图模型导入时跳过权重重量化、图转换与编译。
GGML_OPENVINO_PREFILL_CHUNK_SIZE Integer 256 NPU prefill 的 token 块大小(仅 NPU 生效,CPU/GPU 忽略);须为正整数,否则回退默认值。
GGML_OPENVINO_NPU_COMPILE_CONFIG String not set 仅 NPU 的编译器模式参数,以 NPU_COMPILATION_MODE_PARAMS 形式转发给 OpenVINO,例如 optimization-level=3
GGML_OPENVINO_STATEFUL_EXECUTION Boolean 0 启用有状态 KV cache 以提升性能,CPU/GPU 上推荐开启。
GGML_OPENVINO_DISABLE_CACHE Boolean 0 禁用进程内编译模型/解码器缓存(默认开启),设为 1 禁用。
GGML_OPENVINO_DISABLE_KV_SLICE Boolean 0 禁用 KV cache 输入张量切片优化(CPU/GPU 默认开启),设为 1 禁用。
GGML_OPENVINO_MANUAL_GQA_ATTN Boolean device-based 三态。未设置时,GPU 上默认启用手动 GQA 注意力,其他设备默认禁用;设为正整数强制启用,0 强制禁用。
GGML_OPENVINO_MEMORY_OPTIMIZE Boolean 0 编译期内存缩减总开关:启用 GGML_OPENVINO_REDUCE_COMPILE_MEM,GPU 上额外启用 GGML_OPENVINO_RELEASE_WEIGHTS(除非细粒度变量被显式设置)。
GGML_OPENVINO_REDUCE_COMPILE_MEM Boolean 继承自 GGML_OPENVINO_MEMORY_OPTIMIZE 通过流式权重重量化、避免额外权重节点物化来降低编译期宿主内存;显式设置可覆盖总开关。
GGML_OPENVINO_RELEASE_WEIGHTS Boolean GPU 上继承自 GGML_OPENVINO_MEMORY_OPTIMIZE 仅 GPU。当编译模型缓存可复用设备/插件副本后释放宿主权重缓冲;要求图形状稳定,需要重编译的动态工作负载应保持禁用。
GGML_OPENVINO_PROFILING Boolean 0 启用执行期 profiling。
GGML_OPENVINO_DUMP_CGRAPH Boolean 0 将 GGML 计算图转储到 cgraph_ov.txt
GGML_OPENVINO_DUMP_IR Boolean 0 序列化带时间戳的 OpenVINO IR 文件。
GGML_OPENVINO_DEBUG_INPUT Boolean 0 启用输入调试,打印输入张量信息。
GGML_OPENVINO_DEBUG_OUTPUT Boolean 0 启用输出调试,打印输出张量信息。
GGML_OPENVINO_PRINT_CGRAPH_TENSOR_ADDRESS Boolean 0 打印一次张量地址映射。
GGML_OPENVINO_LOG_UNSUPPORTED_OPS Boolean 0 对任何 OpenVINO 后端不支持的算子,打印含张量细节与拒绝原因的警告;以 WARN 级别输出(需 --log-verbosity >= 2,默认已满足)。
  • GGML_OPENVINO_STATEFUL_EXECUTION实验性特性:让 OpenVINO 模型内部托管 KV cache 管理,提升 CPU/GPU 性能。NPU 上无效,且目前并非所有模型都支持;已验证的应用为 llama-simple、llama-cli、llama-bench、llama-run,建议开启以获得最佳性能;llama-server、llama-perplexity 等暂不支持。
  • GGML_OPENVINO_LOG_UNSUPPORTED_OPS 输出 WARN 级别日志(GGML_LOG_WARN),需要 --log-verbosity >= 2(或 -lv 2)。

这些变量在源码中的读取集中在 ggml/src/ggml-openvino/utils.cpp,例如 NPU 静态图判断、KV 切片开关、手动 GQA 三态逻辑与 prefill chunk 解析均可见 ggml_openvino_getenv_int/ggml_openvino_getenv_str 调用;设备名解析则通过 ggml_openvino_get_device_name() 读取 GGML_OPENVINO_DEVICE

示例:GPU 推理 + Profiling

# Linux
export GGML_OPENVINO_CACHE_DIR=/tmp/ov_cache
export GGML_OPENVINO_PROFILING=1
export GGML_OPENVINO_DEVICE=GPU
export GGML_OPENVINO_STATEFUL_EXECUTION=1

./build/ReleaseOV/bin/llama-simple -m ~/models/Llama-3.2-1B-Instruct-Q4_K_M.gguf -n 50 "The story of AI is "

# Windows Command Line
set GGML_OPENVINO_CACHE_DIR=C:\tmp\ov_cache
set GGML_OPENVINO_PROFILING=1
set GGML_OPENVINO_DEVICE=GPU
set GGML_OPENVINO_STATEFUL_EXECUTION=1

# Windows PowerShell
$env:GGML_OPENVINO_CACHE_DIR = "C:\tmp\ov_cache"
$env:GGML_OPENVINO_PROFILING = "1"
$env:GGML_OPENVINO_DEVICE = "GPU"
$env:GGML_OPENVINO_STATEFUL_EXECUTION = "1"

build\ReleaseOV\bin\llama-simple.exe -m "C:\models\Llama-3.2-1B-Instruct-Q4_K_M.gguf" -n 50 "The story of AI is "

源码视角:图翻译与算子支持如何工作

结合 ggml/src/ggml-openvino 的目录结构,可以把运行时管线概括为:

  • 算子注册表openvino/op_table.cpp / op_table.h 建立 GGML 算子到翻译器的映射;openvino/op/ 下每个文件对应一类算子的 ov::Model 构建,如 mulmat.cpprope.cppsoftmax.cpprms_norm.cppflash_attn_ext.cppgated_delta_net.cpp 等;
  • 前端翻译frontend.cpptranslate_session.cpp 组织"遍历图 → 逐算子翻译 → 生成 ov::Model"的会话流程;
  • 图优化 passopenvino/pass/ 中的 fuse_to_sdpa(注意力融合为 SDPA)、squeeze_matmul 等在前端阶段改写图,mark_dequantization_subgraph.h / mark_decompression_convert_constant_folding.h 标记反量化子图与常量折叠;
  • 算子支持检查ggml-openvino.cpp 中的 ggml_backend_openvino_device_supports_op_impl 返回细粒度的支持等级(支持/回退/拒绝),未支持算子可在开启 GGML_OPENVINO_LOG_UNSUPPORTED_OPS 后获得张量级拒绝原因;
  • 权重缓存属性openvino/rt_info/weightless_caching_attributes.hpp 配合编译模型 blob 缓存,对应 GGML_OPENVINO_COMPILED_MODEL_CACHE_DIR 的"跳过重量化/转换/编译"能力;
  • 解码路径ggml-decoder.cppopenvino/decoder.h 复用单 token 解码图,配合进程内缓存(GGML_OPENVINO_DISABLE_CACHE 控制)。

从源码结构看,这一分层使"GGUF 模型不变、仅替换执行引擎"成为可能:llama.cpp 上层(模型图构建、采样、KV cache 语义)照常工作,OpenVINO 后端只接管图的编译与执行。

已知限制

通用(所有设备)

  • 目前仅支持 GGML 算子子集与纯文本模型;不支持的算子(或算子形状/用例)会在 OpenVINO 翻译阶段失败;
  • 多模态(音频/图像/视频)功能为 work in progress;
  • Embedding 与 Reranking 模型支持有限;
  • llama.cpp 各工具在 CPU/GPU/NPU 上的覆盖不均匀。

工具特定

  • llama-bench:需要 -fa 1(flash-attention);
  • llama-cli --context-shift:仅无状态模式(GGML_OPENVINO_STATEFUL_EXECUTION=0);有状态模式下 KV cache 由 OpenVINO 模型内部持有,无法外部 shift;
  • llama-serverGGML_OPENVINO_STATEFUL_EXECUTION=1 时仅支持单聊天会话/线程。

GPU 特定

  • llama-server -np > 1:并发请求会被批处理合并,可能轻微降低单请求吞吐。

NPU 特定

  • 默认上下文解析为模型训练上下文(如 Llama 3.2 1B 为 131072),在 NPU 上可能 OOM、失败或性能劣化;可用 -lv 3 查看解析值。规避: 显式传 -c <N>(如 -c 1024);
  • NPU 使用固定 prefill 块大小的静态图(默认 256,可用 GGML_OPENVINO_PREFILL_CHUNK_SIZE 配置);较大的 prefill/batch 设置可能需要调参;
  • llama-server -np > 1(多并行序列)不支持;
  • llama-perplexity:需要 -b 512 或更小。

进行中

  • 性能与内存优化
  • 精度验证
  • 更广的量化覆盖
  • 更多模型架构支持

OpenVINO 后端处于积极开发中,修复与改进持续进行,docs/backend/OPENVINO.md 也会随版本更新。

登录后查看全文
热门项目推荐
相关项目推荐