如何在虚拟机中用 llama.cpp VirtGPU 后端把计算卸载到宿主机 GPU 并跑通 llama-server

发布时间:2026/9/10 13:54:52
如何在虚拟机中用 llama.cpp VirtGPU 后端把计算卸载到宿主机 GPU 并跑通 llama-server 如何在虚拟机中用 llama.cpp VirtGPU 后端把计算卸载到宿主机 GPU 并跑通 llama-server【免费下载链接】llama.cppLLM inference in C/C项目地址: https://gitcode.com/GitHub_Trending/ll/llama.cpp如果你的推理任务只能在容器/虚拟机里运行但希望计算真正落在宿主机的 GPU 上llama.cpp 的ggml-virtgpu后端就是文档中描述的做法Guest 端运行 llama.cpp前端库ggml-virtgpu通过 virtio-gpu 超调用和共享内存把操作转发出去Host 端由 VirglRenderer APIR 组件加载libggml-virtgpu-backend再由它动态加载宿主机上的真实 GGML 后端库macOS 上是libggml-metal也可以是 Vulkan/CUDA 等。按 docs/backend/VirtGPU/development.md 的说明这条路径目前主要在macOS 宿主机 libkrun 容器上验证过Linux 宿主机viakrun文档标注为进行中CI 尚未跑通。适用前提与平台支持根据 docs/backend/VirtGPU.md 的 OS 支持表OS状态宿主机后端备注MacOS 14Supportedggml-metal需在 MacOS 14 上编译MacOS 15Supportedggml-metal在 MacOS 14 或 15 上编译均可LinuxUnder developmentggml-vulkan本地可用CI 出现死锁运行这套环境还需要支持 virtio-gpu 的虚拟机文档测试用的是 podman libkrunprovider 的机器带 APIR 补丁、仍在评审中的 virglrenderer 开发分支development 文档列出了 macOS 用main-macos、Linux 用main-linux分支的补丁集地址以文档为准Guest 侧依赖libdrm、C20 编译器、CMake 3.14宿主机上有目标后端库如libggml-metal.dylib。注意一个限制在libkrun虚拟化下RAM VRAM 的可寻址内存上限是 64 GBGPU 可用内存最大为64GB - RAM与硬件 VRAM 大小无关。第一步在 macOS 宿主机构建 virtgpu backend在宿主机上克隆 llama.cpp 源码并按 development 文档 的配置构建。关键点GGML_VIRTGPU_BACKENDONLY表示只构建 Host 端 backend这些 CMake 选项定义在 ggml/CMakeLists.txt 中GGML_VIRTGPU控制 Guest 前端默认均为OFFmkdir llama.cpp cd llama.cpp git clone https://github.com/ggml-org/llama.cpp.git src cd src LLAMA_MAC_BUILD$PWD/build/ggml-virtgpu-backend cmake -S . -B $LLAMA_MAC_BUILD \ -DGGML_NATIVEOFF \ -DLLAMA_CURLON \ -DGGML_VIRTGPUON \ -DGGML_VIRTGPU_BACKENDONLY \ -DGGML_METALON TARGETSggml-metal cmake --build $LLAMA_MAC_BUILD --parallel 8 --target $TARGETS # Build additional tools for native benchmarking EXTRA_TARGETSllama-run llama-bench cmake --build $LLAMA_MAC_BUILD --parallel 8 --target $EXTRA_TARGETSggml-metal目标必须在 Mac 上原生构建文档注明 Working when compiled on MacOS 14 or 15产物是后面要传给 Host 后端加载的libggml-metal.dylib。第二步构建带 APIR 支持的 virglrenderer宿主机标准发布的 virglrenderer 还不带 APIR 组件需要从 development 文档给出的开发分支编译mkdir virglrenderer cd virglrenderer git clone https://gitlab.freedesktop.org/kpouget/virglrenderer -b main-macos src cd src VIRGL_BUILD_DIR$PWD/build # -Dvenustrue 和 VIRGL_ROUTE_VENUS_TO_APIR1 会把 APIR 请求经由 Venus 后端路由 # 便于在未打补丁的 hypervisor 上测试 meson setup $VIRGL_BUILD_DIR \ -Dvenustrue \ -Dapirtrue ninja -C $VIRGL_BUILD_DIR产出的libvirglrenderer.1.dylib需要被 krunkit 加载第四步会配置。第三步构建 Guest 端容器镜像入口为 llama-serverGuest 端是 Linux 容器。development 文档给出两条路径主路径是构建镜像Option B镜像的ENTRYPOINT就是llama-server容器依赖在构建时用dnf安装git cmake gcc gcc-c libcurl-devel libdrm-devel构建时通过LLAMA_CPP_CMAKE_FLAGS-DGGML_VIRTGPUON打开前端cat EOF remoting.containerfile FROM quay.io/fedora/fedora:43 USER 0 WORKDIR /app/remoting ARG LLAMA_CPP_REPOhttps://github.com/ggml-org/llama.cpp.git ARG LLAMA_CPP_VERSIONmaster ARG LLAMA_CPP_CMAKE_FLAGS-DGGML_VIRTGPUON ARG LLAMA_CPP_CMAKE_BUILD_FLAGS--parallel 4 RUN dnf install -y git cmake gcc gcc-c libcurl-devel libdrm-devel RUN git clone \${LLAMA_CPP_REPO} src \\ git -C src fetch origin \${LLAMA_CPP_VERSION} \\ git -C src reset --hard FETCH_HEAD RUN mkdir -p build \\ cd src \\ set -o pipefail \\ cmake -S . -B ../build \${LLAMA_CPP_CMAKE_FLAGS} \\ cmake --build ../build/ \${LLAMA_CPP_CMAKE_BUILD_FLAGS} ENTRYPOINT [/app/remoting/src/build/bin/llama-server] EOF mkdir -p empty_dir podman build -f remoting.containerfile ./empty_dir -t localhost/llama-cpp.virtgpu可选分支Option A如果你不构建镜像也可以直接在 Linux 容器里cmake -S . -B build -DGGML_VIRTGPUON ninja -C build构建前端并手动运行二进制适用于调试而不是常驻服务。第四步设置环境变量并启动 libkrun 机器环境变量分三段分别作用于 Guest 前端、VirglRendererhypervisor 侧和 Host 后端完整说明见 docs/backend/VirtGPU/configuration.md。以下VIRGL_BUILD_DIR与LLAMA_MAC_BUILD需要替换为你第一、二步的实际构建目录文档原文标注 adapt these paths to your systemVIRGL_BUILD_DIR$HOME/remoting/virglrenderer/build LLAMA_MAC_BUILD$HOME/remoting/llama.cpp/build-backend # 让 krunkit 加载我们编译的 virglrenderer export DYLD_LIBRARY_PATH$VIRGL_BUILD_DIR/src # 让 Virglrenderer 加载 ggml-remotingbackend必填 export VIRGL_APIR_BACKEND_LIBRARY$LLAMA_MAC_BUILD/bin/libggml-virtgpu-backend.dylib # 让 remoting backend 加载 ggml-metal 后端 export APIR_LLAMA_CPP_GGML_LIBRARY_PATH$LLAMA_MAC_BUILD/bin/libggml-metal.dylib export APIR_LLAMA_CPP_GGML_LIBRARY_REGggml_backend_metal_reg其中VIRGL_APIR_BACKEND_LIBRARY是必填项缺了它 virglrenderer 不知道该加载哪个 APIR backend 库APIR_LLAMA_CPP_GGML_LIBRARY_PATH也是必填项缺失时后端初始化失败并报错cannot open the GGML library: env var APIR_LLAMA_CPP_GGML_LIBRARY_PATH not definedAPIR_LLAMA_CPP_GGML_LIBRARY_REG是加载库后要调用的注册函数名Metal 用ggml_backend_metal_reg缺省为ggml_backend_init若设了库路径但注册函数报错信息为cannot register the GGML library: env var APIR_LLAMA_CPP_GGML_LIBRARY_REG not defined。过渡期还有两个环境变量需要理解VIRGL_ROUTE_VENUS_TO_APIR1是在未打补丁的 hypervisor 上让 Venus capset 请求绕道 APIR 的临时开关它会破坏正常的 Vulkan/Venus 行为GGML_REMOTING_USE_APIR_CAPSET则告诉ggml-virtgpu前端使用 APIR capset默认不设走 Venus便于在未修改的 hypervisor 上测试。然后以 libkrun 作为 provider 启动机器export CONTAINERS_MACHINE_PROVIDERlibkrun podman machine start第五步启动容器并验证链路验证 1krunkit 是否加载了正确的 virglrendererlsof -c krunkit | grep virglrenderer文档给出的示例输出数值随你的构建不同而不同只用于确认指向你自建目录下的libvirglrenderer.1.dylibkrunkit 50574 user txt REG 1,14 2273912 10849442 ($VIRGL_BUILD_DIR/src)/libvirglrenderer.1.dylib验证 2跑通容器内的 llama.cpp# Optional model caching mkdir -p models PODMAN_CACHE_ARGS-v models:/models --user root:root --cgroupns host --security-opt labeldisable -w /models podman run $PODMAN_CACHE_ARGS -it --rm --device /dev/dri localhost/llama-cpp.virtgpu--device /dev/dri把 virtio-gpu 设备挂进容器前端正是靠它与宿主机通信。镜像 ENTRYPOINT 是llama-server容器启动后即以服务方式运行文档在容器内给出的验证命令是基准测试需要模型文件示例挂载的缓存目录里放./llama3.2/app/remoting/build/bin/llama-bench -m ./llama3.2文档的示例输出原文明确 performance may vary仅示意 backend 列显示ggml-virtgpu| model | size | params | backend | ngl | test | t/s | | ------------------------------ | ---------: | ---------: | ---------- | --: | ------------: | -------------------: | | llama 3B Q4_K - Medium | 1.87 GiB | 3.21 B | ggml-virtgpu | 99 | pp512 | 991.30 ± 0.66 | | llama 3B Q4_K - Medium | 1.87 GiB | 3.21 B | ggml-virtgpu | 99 | tg128 | 85.71 ± 0.11 |如果链路不通可以把两侧的调试日志重定向到文件排查VIRGL_APIR_LOG_TO_FILE/tmp/apir.logAPIR 组件日志默认输出到 stderr、APIR_LLAMA_CPP_LOG_TO_FILE/tmp/ggml-backend-debug.logHost 端 GGML 后端日志。排错与已知限制从 SSH 设置DYLD_LIBRARY_PATH在 macOS 上不生效。development 文档给出一个变通方案把 Homebrew 里的libvirglrenderer.1.dylib替换成指向自建目录的符号链接VIRGL_BUILD_DIR$HOME/remoting/virglrenderer/build BREW_VIRGL_DIR/opt/homebrew/Cellar/virglrenderer/0.10.4d/lib VIRGL_LIBlibvirglrenderer.1.dylib cd $BREW_VIRGL_DIR mv $VIRGL_LIB ${VIRGL_LIB}.orig ln -s $VIRGL_BUILD_DIR/src/$VIRGL_LIB副作用说明这会移动并覆盖 Homebrew 安装的 virglrenderer 库文件影响本机所有使用它的程序且要求有对应目录写权限BREW_VIRGL_DIR中的版本路径需按你实际安装情况替换。仅建议在隔离的开发机上使用。每项操作都有 VM 逃逸开销文档 Limitations 原话Small overhead from VM escaping for each operation。Linux 宿主路径尚未稳定CI 处于死锁状态krun支持进行中文档明确 mainly tested on macOS 容器。上游依赖仍在评审APIR 是 virglrenderer 的待合并补丁且 hypervisorVMM需要学会路由新的 APIR capset这两点落地前过渡期环境变量VIRGL_ROUTE_VENUS_TO_APIR、GGML_REMOTING_USE_APIR_CAPSET才有意义。进一步细节可参考 docs/backend/VirtGPU.md架构、通信协议、共享内存布局与 docs/backend/VirtGPU/configuration.md全部环境变量及默认值Guest 前端的构建依赖libdrm、C20、venus_hw.h 头文件自动下载见 ggml/src/ggml-virtgpu/CMakeLists.txt。【免费下载链接】llama.cppLLM inference in C/C项目地址: https://gitcode.com/GitHub_Trending/ll/llama.cpp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考