ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

text-generation-inference Llamacpp Backend 构建与部署指南:GGUF 模型在 CPU/GPU 上的推理实战

text-generation-inference Llamacpp Backend 构建与部署指南:GGUF 模型在 CPU/GPU 上的推理实战 text-generation-inference Llamacpp Backend 构建与部署指南GGUF 模型在 CPU/GPU 上的推理实战【免费下载链接】text-generation-inferenceLarge Language Model Text Generation Inference项目地址: https://gitcode.com/GitHub_Trending/te/text-generation-inference导读本文面向在 text-generation-inferenceTGI生态中需要以 GGUF 格式部署大语言模型的开发者完整讲解backends/llamacpp后端的源码结构、llama.cpp 依赖的编译安装、Docker 镜像构建与运行、以及从 CLI 参数到批处理调度与采样链的底层实现原理。读完本文你将掌握如何从零构建 tgi-llamacpp 镜像、在 CPU 与 GPU 场景下启动服务、使用自定义 GGUF 文件并理解该后端如何将 TGI 的 HTTP/流式接口与 llama.cpp 的 C API 无缝对接。Llamacpp 后端在 TGI 多后端体系中的定位TGI 通过多后端架构支持不同的推理引擎API 交互在各后端间保持一致便于无缝切换参见 docs/source/multi_backend_support.md。其中TGI CUDA 后端默认的 NVIDIA GPU 高性能后端包含大量自研优化TGI TRTLLM 后端基于 NVIDIA TensorRT 加速需按 GPU 架构逐模型编译TGI Llamacpp 后端集成 llama.cpp 推理引擎同时针对 CPU 与 GPU 计算优化TGI Neuron 后端面向 AWS Trainium/Inferentia 芯片。Llamacpp 后端的核心价值在于它让 TGI 可以直接消费GGUF 格式的模型文件从而充分利用 Hugging Face 生态中海量 GGUF 量化模型Q4_K_M、Q8_0 等在没有专属 GPU 或希望避免额外编译成本的场景下用纯 CPU 或混合 CPU/GPU 方式提供服务。该后端的文档入口位于 backends/llamacpp/README.md更完整的部署说明见 docs/source/backends/llamacpp.md。后端源码结构概览backends/llamacpp目录包含四个 Rust 源文件与一个依赖清单backends/llamacpp/ ├── Cargo.toml # 构建依赖bindgen、pkg-config ├── README.md # 构建与安装指引 ├── requirements.txt # Python 侧依赖转换脚本所需 └── src/ ├── main.rs # CLI 参数解析、模型解析、服务启动 ├── backend.rs # LlamacppBackend 实现Backend trait ├── llamacpp.rs # 通过 bindgen 生成的 FFI 绑定 └── quantize.rs # GGUF 量化Q4_0封装其中llamacpp.rs通过include!(concat!(env!(OUT_DIR), /llamacpp.rs))在编译期引入由 bindgen 从 llama.cpp 头文件生成的 FFI 绑定pkg-config用于在构建时定位系统级安装的 llama.cpp 库。整个 crate 名为text-generation-router-llamacpp依赖 router 中的text-generation-router并复用其server、validation、infer等模块因此对外暴露的 HTTP 接口与 TGI 其他后端完全一致。环境准备安装 llama.cpp 系统库官方 README 明确指出如果所有依赖都已安装到系统层面直接执行cargo build即可只有当你想尝试不同版本的 llama.cpp 时才需要按以下步骤手动安装。推荐的安装方式是将 llama.cpp 安装到自定义前缀目录并在构建 TGI 时通过PKG_CONFIG_PATH指向它LLAMACPP_PREFIX$(pwd)/llama.cpp.out git clone https://github.com/ggerganov/llama.cpp cd llama.cpp cmake -B build \ -DCMAKE_INSTALL_PREFIX$LLAMACPP_PREFIX \ -DLLAMA_BUILD_COMMONOFF \ -DLLAMA_BUILD_TESTSOFF \ -DLLAMA_BUILD_EXAMPLESOFF \ -DLLAMA_BUILD_SERVEROFF cmake --build build --config Release -j cmake --install build几个 CMake 选项的取舍LLAMA_BUILD_COMMON/TESTS/EXAMPLES/SERVER全部关闭是因为 TGI 后端只依赖 llama.cpp 的库文件libllama、libggml 等并不需要其自带的 server 可执行文件或示例程序从而显著缩短编译时间。随后构建 TGI 的 llamacpp 后端 cratePKG_CONFIG_PATH$LLAMACPP_PREFIX/lib/pkgconfig cargo buildpkg-config会在$LLAMACPP_PREFIX/lib/pkgconfig中查找 llama.cpp 的.pc描述文件从而把正确的头文件路径和链接参数传给 bindgen 与 Rust 编译器。如果 llama.cpp 与 TGI 的 ABI 不匹配编译期即可暴露出来这也是“实验不同 llama.cpp 版本”时必经的验证环节。构建 Docker 镜像对生产部署而言推荐直接构建 Docker 镜像免去手工管理 llama.cpp 依赖的复杂度。Dockerfile 位于仓库根目录的 Dockerfile_llamacpp其构建过程可分为三个阶段依赖阶段基于nvidia/cuda:12.8.0-cudnn-devel-ubuntu24.04安装 clang、cmake、pkg-config 等工具下载指定 tag 的 llama.cpp 源码默认llamacpp_versionb4827编译并安装库文件与convert_hf_to_gguf.py转换脚本Rust 构建阶段使用 cargo-chef 缓存依赖编译text-generation-router-llamacpp的 release 产物运行阶段基于 CUDA runtime 镜像安装 Python 虚拟环境安装 requirements.txt 中固定的transformers4.49、huggingface-hub0.28.1、hf-transfer0.1.9、torch2.6.0并把编译好的libllama.so、libggml*.so与二进制复制进镜像最后以text-generation-router-llamacpp作为 ENTRYPOINT。构建命令如下详见 docs/source/backends/llamacpp.mddocker build \ -t tgi-llamacpp \ https://github.com/huggingface/text-generation-inference.git \ -f Dockerfile_llamacpp注意由于镜像默认以宿主 CPU 的原生指令集GGML_NATIVEON编译官方强烈建议在与运行环境相同的主机架构上构建镜像以获得最优性能跨架构迁移可能导致性能下降甚至无法运行。构建参数一览Dockerfile 支持通过--build-arg覆盖以下参数参数默认值说明llamacpp_versionbXXXXb4827指定 llama.cpp 的具体版本 tagllamacpp_cudaONOFF是否启用 CUDA 加速llamacpp_nativeONON是否自动检测并启用 CPU 原生指令llamacpp_cpu_arm_archARCH[FEATURE]...native指定目标 ARM CPU 架构与特性cuda_archARCH75-real;80-real;86-real;89-real;90-real目标 CUDA 架构列表例如在非 Graviton4 的 ARM 机器上构建面向 AWS Graviton4armv9-a i8mm 特性的镜像时docker build \ -t tgi-llamacpp \ --build-arg llamacpp_nativeOFF \ --build-arg llamacpp_cpu_arm_archarmv9-ai8mm \ https://github.com/huggingface/text-generation-inference.git \ -f Dockerfile_llamacpp同理如需启用 GPU 支持可在构建时传入--build-arg llamacpp_cudaON并配合cuda_arch指定目标 GPU 架构。运行 Docker 镜像CPU 推理docker run \ -p 3000:3000 \ -e HF_TOKEN$HF_TOKEN \ -v $HOME/models:/app/models \ tgi-llamacpp \ --model-id Qwen/Qwen2.5-3B-Instruct要点说明-p 3000:3000暴露 TGI 的 HTTP 服务端口HF_TOKEN用于访问需要授权的 Hugging Face 模型仓库-v $HOME/models:/app/models将本地模型目录挂载进容器。服务启动时会先在models/目录下查找 GGUF 文件未找到则自动下载模型并现场转换生成详见下文“自动生成与自定义 GGUF”小节--model-id指向 Hugging Face 仓库名。GPU 加速推理docker run \ --gpus all \ -p 3000:3000 \ -e HF_TOKEN$HF_TOKEN \ -v $HOME/models:/app/models \ tgi-llamacpp \ --n-gpu-layers 99 \ --model-id Qwen/Qwen2.5-3B-Instruct--n-gpu-layers 99表示将尽可能多的层加载进显存VRAM这是 CPU/GPU 混合推理的核心参数值越大GPU 承担的算力越多推理越快当显存不足时应适当调小该值让部分层留在 CPU 上执行。使用自定义 GGUF自动生成与手动指定GGUF 文件对用户是可选项如果models目录中没有现成 GGUF后端会在启动时自动生成。这一逻辑可以在 main.rs 中看到若未显式指定--model-gguf后端默认寻找models/{model_id}/model.gguf路径代码第 238 行若该文件不存在则通过hf_hub下载模型仓库的全部文件到缓存ApiBuilder会读取HUGGINGFACE_HUB_CACHE、HF_TOKEN、HF_HUB_USER_AGENT_ORIGIN等环境变量并调用 llama.cpp 自带的convert_hf_to_gguf.py脚本把 Hugging Face 权重转换为临时 GGUF 文件随后调用 quantize.rs 中的model()函数以Q4_0 量化QuantizeType::MostlyQ4_0对应 ggml 枚举值 2对临时文件做二次量化得到最终的models/{model_id}/model.gguf。其中量化调用的是llamacpp::model_quantize并设置了quantize_output_tensor true与nthread线程数。若转换或量化失败进程会以对应错误码退出。如果你希望跳过这一自动流程例如模型作者已提供特定精度的量化版本可以手动挂载并指定 GGUFdocker run \ -p 3000:3000 \ -e HF_TOKEN$HF_TOKEN \ -v $HOME/models:/app/models \ tgi-llamacpp \ --model-id Qwen/Qwen2.5-3B-Instruct \ --model-gguf models/qwen2.5-3b-instruct-q4_0.gguf注意即使提供自定义 GGUF--model-id依然必须指定因为后端仍需通过 model-id 从 Hugging Face 拉取tokenizer.json在 main.rs 中通过api_repo.get(tokenizer.json)获取用于请求校验与 token 解码模型本身的权重则完全来自 GGUF 文件。CLI 参数全解析完整的参数列表可通过docker run tgi-llamacpp --help查看这些参数全部定义于 main.rs 的Args结构体均同时支持命令行与同名环境变量传入。下面按类别说明模型加载参数参数默认值说明--model-id必填模型仓库名称如Qwen/Qwen2.5-3B-Instruct--revisionmain模型仓库的 revision--model-gguf自动生成GGUF 模型文件路径相对容器内/app--n-gpu-layers0卸载到显存的层数0表示纯 CPU--split-modelayer多 GPU 切分方式layer、row或一个 GPU 编号--numadisabledNUMA 策略disabled、distribute、isolate、numactl、mirror--disable-mmap关闭禁用模型内存映射mmap--use-mlock关闭锁定内存防止换页--disable-offload-kqv关闭禁用 KQV 计算卸载到 GPU--disable-flash-attention关闭禁用 flash attention实验特性--type-kf16K cache 数据类型--type-vf16V cache 数据类型--defrag-threshold-1.0KV cache 空洞/总大小超过该阈值时触发碎片整理并发与批处理参数参数默认值说明--n-threads自动CPU 核数生成阶段使用的线程数--n-threads-batch同--n-threads批处理阶段线程数--max-concurrent-requests2 × batch size最大并发请求数--max-input-tokens1024单请求最大输入 token 数--max-total-tokens2048单请求最大总 token 数输入 输出--max-batch-total-tokensbatch size × max-total-tokens一个批次的 token 上限--max-physical-batch-total-tokens同 max-batch-total-tokens物理批次 token 上限--max-batch-size同 n-threads-batch每个批次的最大请求数--batch-timeout5ms源码硬编码批处理收包超时见 backend.rs 中LlamacppConfig服务与观测参数参数默认值说明--hostname0.0.0.0监听地址--port/-p3000HTTP 服务端口--prometheus-port9000Prometheus 指标端口--json-output关闭日志以 JSON 格式输出--otlp-endpoint无OTLP 遥测端点--otlp-service-nametext-generation-inference.routerOTLP 服务名--cors-allow-origin无CORS 允许来源可多个--validation-workers2用于 payload 校验与截断的 tokenizer 工作线程数--disable-grammar-support关闭禁用 grammar 支持--max-client-batch-size4单请求最大输入条数--usage-statson使用统计收集级别--payload-limit2000000最大请求体字节数--max-image-fetch-size1073741824最大图片抓取字节数--tokenizer-config-path无tokenizer 配置文件路径参数之间的约束关系main.rs 在启动前会做一组参数校验违反任一约束都会直接报错退出--max-input-tokens必须小于--max-total-tokens--max-total-tokens必须小于等于--max-batch-total-tokens--max-batch-size × --max-total-tokens必须小于等于--max-batch-total-tokens。同时--max-batch-total-tokens会作为 llama.cpp 的上下文大小n_ctx与批大小n_batch传入见 backend.rs 的context_default_params设置这解释了为何批处理预算直接受限于 KV cache 上下文窗口。源码级原理从 HTTP 请求到 token 流理解该后端的最佳方式是沿着请求链路阅读 backend.rs。整体架构是一个生产者-消费者模型调度scheduleLlamacppBackend::schedule实现Backendtrait把ValidGenerateRequest转成LlamacppRequest含 input_ids、top_k、top_p、typical_p、temperature、seed、repetition_penalty、frequency_penalty、max_new_tokens 等并通过无界 channel 发送给内部任务成批batching一个异步任务以5ms的batch_timeout收集请求当累计 token 数超过max_batch_total_tokens或请求数达到max_batch_size时把整批请求交给阻塞线程推理循环阻塞线程持有 llama.cpp 的llama_model/llama_context/llama_batch对每个序列执行 prefill 与 decodellama_decode计算 logits随后由采样器链逐 token 采样流式返回每个 token 通过InferStreamResponse::Intermediate实时回传满足max_new_tokens或遇到 EOG tokenvocab_is_eog时发送InferStreamResponse::End携带完整生成文本、generated_tokens与finish_reasonEndOfSequenceToken或Length。采样器链与日志回调每个请求都会构建一条 llama.cpp 采样器链LlamacppSampler::new依次串联top_k → top_p → typicaltypical_p→ temperature → penaltiesrepeat/frequency/present→ dist按 seed 分布采样。如果任一采样器初始化失败该请求会以IncompleteGeneration错误终止。值得注意的是部分参数在请求级被固定min_keep置 0关闭、penalty_last_n固定为 64、penalty_present固定为 0.0禁用 presence penalty——这些是当前实现的取舍从代码注释// disabled可以确认。另外llama.cpp 的 ggml 日志通过llamacpp_log_callback桥接到tracing按debug/info/warn/error级别对应输出方便与 TGI 既有日志体系统一排查问题。健康检查与生命周期health()直接返回内部watch::Receiverbool的状态模型加载成功、上下文初始化完成后置true因此服务在模型尚未就绪时会对健康检查返回不可用。后端还提供了 graceful shutdown 通道debug 构建下由 Ctrl-C 触发用于在退出前安全回收模型与上下文。能力边界与注意事项模型格式本后端消费 GGUF 格式模型与 TGI 默认 CUDA 后端safetensors 权重 Flash Attention的加载路径不同官方文档将“与 GGUF 格式及全量化格式兼容”列为核心能力并提示 GGUF 相关的约束未来可能通过运行时动态生成来缓解。性能与可移植性Docker 镜像默认按构建机 CPU 原生指令集编译跨主机迁移可能损失性能多后端文档将该后端定位为“面向 CPU 与 GPU 优化的推理引擎”具体性能表现取决于硬件与量化档位本文不做臆测。API 一致性由于复用text-generation-router的 server 层本后端对外提供与 TGI 其他后端一致的 HTTP、流式SSE与 OpenAI 兼容接口切换后端无需改动客户端代码。参数取舍请求级采样参数如 presence penalty当前被硬编码禁用如需更细粒度的采样控制可关注后续版本对 backend.rs 的更新。总结TGI 的 Llamacpp 后端将 llama.cpp 的 GGUF 推理能力无缝融入 TGI 统一的服务框架通过convert_hf_to_gguf.py Q4_0 量化的自动流水线用户只需指定--model-id即可在 CPU 或 GPU 上启动服务借助--n-gpu-layers、--split-mode、--type-k/--type-v、--numa等参数可以针对不同硬件精细调优而 backend.rs 中 5ms 动态批处理 采样器链 流式回传的实现则保证了与 TGI 其他后端一致的吞吐行为与接口体验。若需深入建议继续阅读 Dockerfile_llamacpp、main.rs 与 backend.rs 三个核心文件。【免费下载链接】text-generation-inferenceLarge Language Model Text Generation Inference项目地址: https://gitcode.com/GitHub_Trending/te/text-generation-inference创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表