llama.cpp 简介:为什么大家都在聊这个项目?

第一次听说 llama.cpp,是在一次技术交流会上。有人提到“用笔记本就能跑 LLaMA”,我当时第一反应是不信。毕竟以前调大模型,不搞几块 A100 都不好意思打招呼。但试过一次之后,嗯,真香。

llama.cpp 本质上是一个 C++ 实现的大模型推理引擎。它的目标很简单:让大语言模型在普通硬件上跑起来。不需要昂贵的 GPU,不需要复杂的依赖环境,甚至能跑在树莓派上。这一章我会把它是什么、能干什么、支持哪些模型理清楚。

项目背景

2023 年初,Meta 开源了 LLaMA 系列模型。大家发现这些模型效果惊人,但推理需要 GPU,平民玩家根本玩不动。随后出现过一些推理方案,要么依赖 Python 生态导致部署臃肿,要么限制在特定平台上,没有解决本质问题。

这时,一个叫 ggerganov 的开发者出手了。他之前写过 whisper.cpp(语音识别)、ggml(张量库),这次把目光投向了 LLaMA。我记得项目刚放出时,GitHub 上 star 数涨得飞快,几天就破万了。为什么?因为它做到了两件事:纯 CPU 推理 和 极简依赖。

举个简单的例子:一个 7B 参数的 LLaMA 模型,用 PyTorch 推理需要 28GB 显存以上(还得是 FP16)。而 llama.cpp 通过 4-bit 量化,能把内存需求压缩到 4-5GB,一台 16GB 内存的消费级笔记本就能跑。说白了,它把大模型从数据中心拉到了开发者手里。

功能特点

我整理了 llama.cpp 最核心的几个能力,尤其是跟模型转换关系紧密的部分:

特点说明为什么重要
纯 CPU 推理不依赖 NVIDIA GPU、CUDA、PyTorch降低硬件门槛,可部署在 ARM 架构上
GGUF 格式专门设计的模型打包格式,兼顾效率和可扩展性本教程的核心,转换目标就是 GGUF
量化支持支持 Q4_0 / Q4_K_M / Q6_K / Q8_0 等多种量化级别可将模型压缩 4-8 倍,内存消耗大幅降低
跨平台Windows / macOS / Linux / Android / iOS 都能编译运行一次编译,到处推理
流式输出支持逐 token 生成,无需等待整个序列交互体验好,适合对话场景
API 接口提供 HTTP 服务器模式,兼容 OpenAI API 规范方便集成到现有应用中
低内存占用使用 mmap 映射文件,避免一次性加载全部权重可以运行比物理内存还大的模型

个人习惯:我一般先用 Q4_K_M 量化做原型验证,等效果稳定后再考虑更高精度版本。Q4_K_M 在压缩比和质量之间找到了不错的平衡点,对大多数任务来说够用了。

支持的模型架构

llama.cpp 支持的模型架构一直在扩展。截至目前,主流的 LLM 架构基本都覆盖了。我根据实际使用经验,分成几类来说:

LLaMA 系列(原生支持)

这是最早支持的系列,包括 LLaMA 1/2/3、Alpaca、Vicuna、WizardLM 等衍生模型。如果你手上有一个基于 LLaMA 架构的模型,转换起来最省心。

Mistral / Mixtral 系列

Mistral 7B 和 Mixtral 8x7B(MoE 架构)都支持。我记得第一次跑 Mixtral 时有点意外——它用 4-bit 量化后,内存需求仍然在 24GB 左右。MoE 模型的 KV 缓存比普通模型更大,这个细节在做转换时要注意。

Qwen / Qwen2 系列

阿里通义千问的开源版本。llama.cpp 对 Qwen 系列支持不错,但 Qwen2 的 tokenizer 有点特殊(用了 tiktoken),转换时需要额外指定 tokenizer 配置。我吃过一次亏,转换出来的模型怎么调都不输出中文,后来发现是 tokenizer 文件没配对。

Baichuan 系列

百川智能的模型,7B 和 13B 版本都支持。Baichuan 的架构跟 LLaMA 略有差异,主要是 embedding 层和 head 层的处理方式不同。不过 llama.cpp 已经做了适配,直接转换就行。

其他架构

还有 Phi(微软)、Gemma(Google)、DeepSeek、Falcon、MPT、StableLM 等,全部支持。具体列表可以在 llama.cpp 的 convert.py 脚本参数里看到最新的支持情况。

踩坑提醒:我曾经遇到过一个社区模型,官方说基于 LLaMA 架构,但实际 embedding 层和 head 层绑定了权重(tied embedding)。llama.cpp 默认不处理这种结构,转换出来的模型推理时 loss 一直降不下去。后来翻 GitHub Issues 才发现需要在转换脚本加 --tie-embeddings 参数。遇到非主流模型时,先查一下项目的 opened/closed issues 能省很多时间。

典型工作流

先让你对整个链条有个印象。下面这张图展示了从原始模型文件到高效推理的完整路径:

llama.cpp 模型获取与推理完整流程 源模型 PyTorch / SafeTensors convert.py 格式转换 + 分片合并 GGUF 文件 统一打包格式 quantize 工具 Q4_0 / Q8_0 等 llama.cpp 推理 main 二进制 / server 命令行交互 ./main -m model.gguf -p "你好" HTTP API 服务 ./server -m model.gguf --host 0.0.0.0 llama.cpp 不负责训练,只负责推理。训练器是原项目(如 LLaMA Factory),转换连接两者。

核心认知:llama.cpp 的输入是 GGUF 格式,输出是推理结果。你手上的 PyTorch 模型、SafeTensors 模型、HuggingFace 模型,都得先过 convert.py 这一关,变成 GGUF 才能用。量化是对 GGUF 文件再加工,压缩体积、牺牲精度换取性能。

为什么选择 llama.cpp?

如果你在“到底用哪个推理框架”这件事上犹豫,我分享几个判断点:

  • 硬件受限:只有 CPU,或者内存不到 32GB。llama.cpp 是当下 CPU 推理性能最好的方案,没有之一。
  • 部署简单:不想装 Python、CUDA、PyTorch 那一整套。llama.cpp 编译出来就是一个单二进制文件,甚至能静态链接。
  • 嵌入式或边缘设备:在树莓派、OpenWrt 路由器、手机上跑。llama.cpp 有 ARM Neon 和 RISC-V 的优化版本。
  • 需要高并发 API:llama.cpp server 模式支持连续批处理(continuous batching),吞吐量非常可观。

当然,它也有短板。如果你有 8 张 A100,想跑全精度 70B 模型做训练,llama.cpp 显然不是你的选择。但话说回来,你真要干那事,也不会来看这篇教程了对吧?

一点经验:我最初对量化有偏见,总觉得损失太多。后来在实际项目中发现,Q4_K_M 级别的量化在文本生成任务上的表现,跟 FP16 差距小到可以忽略——除非你做的是数学推理或代码生成这种精度敏感任务。所以我的建议是:先量化,再优化。真要不够,再往上调。