llama.cpp GGML-VirtGPU 后端:让虚拟机内的 LLM 推理直接调度宿主 GPU
llama.cpp GGML-VirtGPU 后端让虚拟机内的 LLM 推理直接调度宿主 GPU【免费下载链接】llama.cppLLM inference in C/C项目地址: https://gitcode.com/GitHub_Trending/ll/llama.cppGGML-VirtGPU 是 llama.cpp / GGML 生态中一个面向虚拟化场景的加速后端应用如llama-server、llama-bench运行在客户机虚拟机内而真正的张量计算被转发到宿主机的 Metal、Vulkan 等原生后端执行二者之间通过 virtio-gpu 超调用hypercall与宿主机-客户机共享内存完成零拷贝数据传输。读完本文你将理解该后端的三段式架构、APIRAPI Remoting通信协议、完整的 CMake 构建选项与全部环境变量配置并能在 macOS podman/libkrun 容器环境中完成一次真实的构建、启动与基准测试。什么是 GGML-VirtGPU 后端GGML-VirtGPU 后端的定位非常明确让 GGML 应用在虚拟机内运行时把机器学习计算卸载到宿主硬件上。它依赖两个上游组件virtio-gpu虚拟机标准 GPU 虚拟化设备接口VirglRenderer 的 API RemotingAPIR组件用于在宿主侧完成远程 API 调用的转发。整个后端被拆分为两个库分别运行在虚拟化的两侧客户侧前端remoting frontend即ggml-virtgpu实现 GGML 后端接口运行在虚拟机内与 virtgpu 设备交互宿主侧后端remoting backend即ggml-virtgpu-backend一个符合 VirglRenderer APIR 规范的库运行在宿主机上与 VirglRenderer 以及一个真实的 GGML 设备后端Metal、Vulkan 等对接。这一划分在源码目录中清晰可见前端位于 ggml/src/ggml-virtgpu/virtgpu.cpp、virtgpu-shm.cpp、virtgpu-forward-*.cpp等文件宿主后端位于 ggml/src/ggml-virtgpu/backend/backend.cpp、backend-dispatched-*.cpp等文件。架构总览该后端由三大组件构成关键组件客户侧前端ggml-virtgpu/实现 GGML 后端接口把所有操作转发到宿主宿主侧后端ggml-virtgpu/backend/接收转发来的操作并在真实硬件后端上执行通信层使用 virtio-gpu 超调用与共享内存完成高效数据传输。从源码结构看前端以标准的 GGML 后端注册方式接入ggml-backend-reg.cpp 中的ggml_backend_virtgpu_reg()返回后端注册表reg并在首次初始化时预取并缓存宿主侧的设备描述、设备数量、内存总量/剩余量、buffer type 等信息设备名会被加上[virtgpu]前缀展示避免每次查询都走一次远程调用。文件末尾的GGML_BACKEND_DL_IMPL(ggml_backend_virtgpu_reg)宏则说明该注册入口同时支持动态库GGML_BACKEND_DL加载模式。操作系统支持OS状态后端CI 测试备注MacOS 14支持ggml-metalX在 MacOS 14 上编译时可用MacOS 15支持ggml-metalX在 MacOS 14 或 15 上编译时可用MacOS 26未测试Linux开发中ggml-vulkan未通过本地可用CI 中出现死锁从表格可以看出该工作最初聚焦于提升 llama.cpp 在 macOS 容器中的性能主要在 macOS 上测试Linux经由krun的支持仍在推进中。通信协议超调用与共享内存后端使用两种主要通信机制超调用DRM_IOCTL_VIRTGPU_EXECBUFFER从客户机触发宿主机的远程执行共享内存页用于张量与参数的零拷贝数据传输。每次连接使用两个固定的共享内存缓冲区数据缓冲区Data Buffer24 MiB承载命令/响应数据与张量传输回复缓冲区Reply Buffer16 KiB承载命令回复与状态信息动态数据缓冲区Data Buffers按需分配的宿主-客户共享缓冲区直接充当 GGML buffer 使用。在源码中可以看到对应的等待参数virtgpu.cpp 定义了握手与加载远程库的超时上限——APIR_HANDSHAKE_MAX_WAIT_MS 2s、APIR_LOADLIBRARY_MAX_WAIT_MS 60s。握手阶段virtgpu_handshake交换双方的协议主/次版本号主版本不一致时记录错误、次版本不一致时记录警告若握手失败源码给出的首要提示是“很可能在 hypervisor 中加载了错误的 virglrenderer 库”。APIR 协议VirglRenderer 的 API Remoting 协议定义了三种命令类型HANDSHAKE协议版本协商与能力发现LOADLIBRARY在宿主机上动态加载后端库FORWARDAPI 函数调用转发图执行、buffer 操作等。LOADLIBRARY失败时前端会区分多种错误码并给出对应提示例如APIR_LOAD_LIBRARY_ENV_VAR_MISSING缺环境变量、APIR_LOAD_LIBRARY_CANNOT_OPEN无法打开后端库等帮助定位宿主机侧的 misconfiguration。二进制序列化命令与数据通过自定义二进制协议序列化特点包括基础类型采用定长编码变长数组带长度前缀缓冲区边界检查错误恢复机制。序列化/反序列化代码由脚本从 YAML 配置生成见下文“开发与代码生成”前后端共享 backend/shared/ 下的协议头文件apir_cs.h、apir_cs_ggml.h等。支持的操作设备操作设备枚举、能力查询、内存信息总量/剩余量、后端类型探测缓冲区操作缓冲区分配与释放、张量数据在宿主与客户机之间传输、内存拷贝与清零计算操作计算图执行转发FORWARD命令携带序列化后的计算图宿主侧backend-dispatched-backend.cpp负责反序列化并调度到真实后端执行。构建要求与 CMake 选项客户侧依赖libdrmDRM/virtio-gpu 通信通过pkg_check_modules(DRM REQUIRED libdrm)探测见 ggml/src/ggml-virtgpu/CMakeLists.txt支持 C20 的编译器构建时显式指定-stdc20CMake该子目录声明cmake_minimum_required(VERSION 3.19)。前端构建时CMake 还会通过ExternalProject从 virglrenderer 上游下载venus_hw.h头文件到include/目录并在ggml-backend-buffer.cpp等源文件上编译出ggml-virtgpu库。宿主侧依赖支持 APIR 的 virglrenderer相关变更仍在等待上游合入目标后端库libggml-metal、libggml-vulkan等。构建选项两个 CMake 开关定义在 ggml/CMakeLists.txt约 L236-L237选项默认值说明GGML_VIRTGPUOFF启用 VirtGPU 后端前端GGML_VIRTGPU_BACKENDOFF构建宿主侧后端组件可取ON、OFF或ONLYONLY表示只构建宿主后端、跳过客户前端宿主机通常没有 libdrm 等 Linux 依赖从 ggml/src/ggml-virtgpu/CMakeLists.txt 的逻辑看GGML_VIRTGPU_BACKEND ! ONLY时编译前端GGML_VIRTGPU_BACKEND ! OFF时进入backend/子目录构建宿主后端。此外只有当未启用GGML_BACKEND_DL动态后端加载时前端才会向 ggml 注入GGML_USE_VIRTGPU_FRONTEND编译宏否则后端以独立动态库形式按需加载。环境变量配置整个系统的配置分为三层各环境的完整语义、取值与示例见 docs/backend/VirtGPU/configuration.md。以下按组件归类汇总。客户前端Guest变量形式作用GGML_VIRTGPU_BACKEND_LIBRARY路径指定宿主侧后端库路径GGML_VIRTGPU_DEBUG布尔启用调试日志GGML_REMOTING_USE_APIR_CAPSET存在即生效读取于 virtgpu.cpp控制使用哪个 virtio-gpu 能力集capset设置后使用 APIR capset长期方案不设置则使用 Venus capset便于在未修改的 hypervisor 上测试默认为不设置HypervisorVirglrenderer/APIR这些变量用于向“原生支持 APIR 的 hypervisor”过渡的临时阶段未来会由 hypervisor 直接以命令行参数/配置键方式传入而移除变量类型说明VIRGL_APIR_BACKEND_LIBRARY路径必需virglrenderer 要动态加载的 APIR 后端库路径对应配置键apir.load_library.path例如export VIRGL_APIR_BACKEND_LIBRARY/path/to/libggml-remotingbackend.soVIRGL_ROUTE_VENUS_TO_APIR存在即生效临时绕过方案把 Venus capset 的调用路由到 APIR便于在未修改的 hypervisor 上测试会破坏 Vulkan/Venus 的正常行为待 hypervisor 原生支持 APIR 后移除VIRGL_APIR_LOG_TO_FILE路径可选将 APIR 组件的调试日志写入指定文件默认输出到stderr宿主后端Host变量类型说明APIR_LLAMA_CPP_GGML_LIBRARY_PATH路径必需真实 GGML 后端库路径Metal、CUDA、Vulkan 等对应配置键ggml.library.path未设置时后端初始化直接失败APIR_LLAMA_CPP_GGML_LIBRARY_REG符号名可选加载库后调用的后端注册函数对应配置键ggml.library.reg默认ggml_backend_init。常用取值Metal 为ggml_backend_metal_reg、CUDA 为ggml_backend_cuda_reg、Vulkan 为ggml_backend_vulkan_regAPIR_LLAMA_CPP_LOG_TO_FILE路径可选将宿主侧 GGML 后端日志写入指定文件读取逻辑见 backend.cppAPIR_LLAMA_CPP_GGML_LIBRARY_PATH的典型设置示例# macOS Metal 后端 export APIR_LLAMA_CPP_GGML_LIBRARY_PATH/opt/llama.cpp/lib/libggml-metal.dylib # Linux CUDA 后端 export APIR_LLAMA_CPP_GGML_LIBRARY_PATH/opt/llama.cpp/lib/libggml-cuda.so # macOS 或 Linux Vulkan 后端 export APIR_LLAMA_CPP_GGML_LIBRARY_PATH/opt/llama.cpp/lib/libggml-vulkan.so配置流程从 backend.cpp 的加载逻辑可以印证整个流程Hypervisor 准备virglrenderer 加载VIRGL_APIR_BACKEND_LIBRARY指定的 APIR 后端库上下文创建APIR 上下文创建时把环境变量填入配置表apir.load_library.path←VIRGL_APIR_BACKEND_LIBRARYggml.library.path←APIR_LLAMA_CPP_GGML_LIBRARY_PATHggml.library.reg←APIR_LLAMA_CPP_GGML_LIBRARY_REG后端初始化宿主后端通过回调读取配置virgl_cbs-get_config(ctx_id, ggml.library.path)返回库路径virgl_cbs-get_config(ctx_id, ggml.library.reg)返回注册函数名动态加载后端dlopen指定的 GGML 库并调用注册函数完成初始化。常见的错误提示均来自宿主后端的日志前缀ggml-virtgpu-backend:缺少库路径cannot open the GGML library: env var APIR_LLAMA_CPP_GGML_LIBRARY_PATH not defined注册符号解析失败cannot find the GGML backend registration symbol ...客户端库未定义注册函数时的提示cannot register the GGML library: env var APIR_LLAMA_CPP_GGML_LIBRARY_REG not defined。完整配置示例macOS 宿主 Metal# Hypervisor 环境 export VIRGL_APIR_BACKEND_LIBRARY/opt/llama.cpp/lib/libggml-virtgpu-backend.dylib # 宿主后端配置 export APIR_LLAMA_CPP_GGML_LIBRARY_PATH/opt/llama.cpp/lib/libggml-metal.dylib export APIR_LLAMA_CPP_GGML_LIBRARY_REGggml_backend_metal_reg # 可选日志 export VIRGL_APIR_LOG_TO_FILE/tmp/apir.log export APIR_LLAMA_CPP_LOG_TO_FILE/tmp/ggml.log # 客户机配置 export GGML_REMOTING_USE_APIR_CAPSET1系统限制与前提仅限虚拟机只能在支持 virtio-gpu 的虚拟机中工作依赖宿主配置需要正确配置的宿主侧后端延迟开销每次操作都伴随一次 VM escape存在小量额外开销共享内存上限在libkrunhypervisor 下RAM VRAM 可寻址内存被限制在 64 GB因此最大可用 GPU 显存为64GB - RAM与硬件 VRAM 大小无关。上游依赖状态过渡期注意事项该后端有两组尚未合入上游的依赖处于过渡期VirglRenderer需要 APIR 变更上游 MR 1590。当前可用 virglrenderer 从源码构建的方式测试macOSkrunkit与 Linuxkrun各有对应的开发分支VMM/hypervisor需要 hypervisor 学会路由新引入的 APIR capset。在 hypervisor 补丁合入前环境变量VIRGL_ROUTE_VENUS_TO_APIR1允许借用 Venus capset 走 APIR 路径但会破坏 Vulkan/Venus 的正常行为环境变量GGML_REMOTING_USE_APIR_CAPSET则告知ggml-virtgpu前端使用 APIR capset待相关 hypervisor 完成补丁后将成为默认行为。开发工作流代码生成协议的前后端桩代码由 YAML 配置生成工作流见 docs/backend/VirtGPU/development.md# 重新生成协议代码 cd ggml-virtgpu/ python regenerate_remoting.py对应源码为 regenerate_remoting.py 与函数清单 ggmlremoting_functions.yaml产物包括virtgpu-forward.gen.h、backend-dispatched.gen.h等生成文件。新增一个远程操作的步骤在ggmlremoting_functions.yaml中添加工具函数定义用regenerate_remoting.py重新生成代码在virtgpu-forward-*.cpp中实现客户侧转发在backend-dispatched-*.cpp中实现宿主侧处理。这种“YAML 声明 → 代码生成 → 两侧实现”的模式保证了客户前端与宿主后端的命令编号、序列化格式始终一致。实战在 macOS 容器中构建与测试以下流程基于 docs/backend/VirtGPU/development.md适用于 macOS 宿主 podmanlibkrunprovider容器的开发/测试环境。前置条件macOS 宿主系统、带libkrunprovider 的容器运行时podman machine、以及带 APIR 支持的开发版 virglrenderermacOS 用 krunkit 开发分支Linux 用 krun 开发分支均需从源码构建。第 1 步构建宿主侧后端macOS在 macOS 上以ONLY模式构建 llama.cpp只产出宿主后端与 Metal 库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 # 先构建 Metal 后端库 TARGETSggml-metal cmake --build $LLAMA_MAC_BUILD --parallel 8 --target $TARGETS # 再构建原生基准测试工具用于对比 EXTRA_TARGETSllama-run llama-bench cmake --build $LLAMA_MAC_BUILD --parallel 8 --target $EXTRA_TARGETS第 2 步构建 virglrenderermacOSVIRGL_BUILD_DIR$PWD/build # -Dvenustrue 与 VIRGL_ROUTE_VENUS_TO_APIR1 组合 # 可在无补丁 hypervisor 上把 APIR 请求经 Venus 后端路由便于测试 meson setup $VIRGL_BUILD_DIR \ -Dvenustrue \ -Dapirtrue ninja -C $VIRGL_BUILD_DIR第 3 步构建客户前端Linux 容器内方式 A容器内直接编译LLAMA_LINUX_BUILD$PWD/build-virtgpu cmake -S . -B $LLAMA_LINUX_BUILD -DGGML_VIRTGPUON ninja -C $LLAMA_LINUX_BUILD方式 B用 containerfile 预构建镜像依赖libdrm-devel、gcc-c、libcurl-devel入口为/app/remoting/src/build/bin/llama-servermkdir -p empty_dir podman build -f remoting.containerfile ./empty_dir -t localhost/llama-cpp.virtgpu第 4 步配置 krunkit 环境并启动VIRGL_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-virtgpu-backend 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 # 使用 libkrun 作为容器 provider 并启动 export CONTAINERS_MACHINE_PROVIDERlibkrun podman machine start可用以下命令确认 krunkit 确实加载了自编译的 virglrenderer 库lsof -c krunkit | grep virglrenderer # 预期输出应指向 $VIRGL_BUILD_DIR/src/libvirglrenderer.1.dylib第 5 步运行测试容器# 可选挂载模型缓存目录 mkdir -p models PODMAN_CACHE_ARGS-v models:/models --user root:root --cgroupns host --security-opt labeldisable -w /models # 注意 --device /dev/dri把 virtio-gpu 设备传入容器 podman run $PODMAN_CACHE_ARGS -it --rm --device /dev/dri localhost/llama-cpp.virtgpu容器内运行基准测试/app/remoting/build/bin/llama-bench -m ./llama3.2开发文档给出的示例输出性能因环境而异| 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 |注意backend一列显示为ggml-virtgpu说明计算确实经由 VirtGPU 后端转发到了宿主 Metal。排障SSH 下的 DYLD_LIBRARY_PATH 失效⚠️ 在 macOS 上从 SSH 会话设置DYLD_LIBRARY_PATH不生效安全限制。文档给出的替代方案是用符号链接替换 Homebrew 的 virglrenderer 库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小结与延伸阅读GGML-VirtGPU 后端把“容器/虚拟机里的 llama.cpp”与“宿主机 GPU 的算力”用 virtio-gpu APIR 远程调用 共享内存三者缝合起来前端实现标准 GGML 后端接口ggml_backend_virtgpu_reg宿主后端按需dlopen任意真实后端库配合GGML_VIRTGPU/GGML_VIRTGPU_BACKEND两个 CMake 开关与一组跨三层的环境变量即可完成搭建。当前它已可在 macOS 14/15 Metal 上稳定使用Linux Vulkan 路径仍在开发中且受 APIR 上游合入进度与 hypervisor 补丁状态制约属于面向未来容器化推理部署的过渡性架构。延伸阅读均在本仓库内后端总览docs/backend/VirtGPU.md配置参考docs/backend/VirtGPU/configuration.md开发与测试docs/backend/VirtGPU/development.md前端实现ggml/src/ggml-virtgpu/宿主后端实现ggml/src/ggml-virtgpu/backend/【免费下载链接】llama.cppLLM inference in C/C项目地址: https://gitcode.com/GitHub_Trending/ll/llama.cpp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →