【免费下载链接】llama.cpp
LLM inference in C/C++
想让一个新的大语言模型跑在 llama.cpp 上吗?本文完整梳理了 llama.cpp 的模型添加流程:先用 Python 脚本把 HuggingFace 的 PyTorch 权重转换成 GGUF 格式,再在 C++ 侧注册模型架构并实现 GGML 推理图。即使你是第一次参与开源 LLM 项目,也能按步骤把新模型从权重文件变成可推理的 GGUF 文件。
一、先看懂全局:4 步完成一个模型移植
官方开发指南 docs/development/HOWTO-add-model.md 把整个流程拆成了 4 个阶段:
| 步骤 | 做什么 | 主要文件 |
|---|---|---|
| 1️⃣ 转换到 GGUF | 把 PyTorch 权重读出来,映射成 GGUF 张量和元数据 | conversion/、convert_hf_to_gguf.py |
| 2️⃣ 注册架构 | 在 C++ 侧声明新架构、参数和元数据 | src/llama-arch.h、src/llama-arch.cpp |
| 3️⃣ 实现推理图 | 用 GGML 张量运算搭建前向计算图 | src/models/、src/llama-model.cpp |
| 4️⃣ 可选:多模态 | 添加视觉/音频编码器 | docs/multimodal.md、tools/mtmd/ |
一个实用建议:动手前先跑git log --oneline -- src/models,看看最近 3 个"添加新模型"的提交。文档有时会滞后,最新的社区代码才是最可靠的参照(这一点项目内的 skills/add-new-model/SKILL.md 也反复强调)。
二、第 1 步:把 PyTorch 权重转换成 GGUF
GGUF 是 llama.cpp 的模型文件格式,包含模型元数据(层数、词表、chat 模板等)和量化张量。转换工作全部在 Python 侧完成,核心入口是 convert_hf_to_gguf.py,它按config.json里的architectures字段自动找到对应的转换类。
1. 注册转换类
在 conversion/ 目录下为新架构创建一个类(例如新架构叫MyModel),继承TextModel(纯文本模型)或MmprojModel(多模态模型):
@ModelBase.register("MyModelForCausalLM") @ModelBase.example("user/model") class MyModel(TextModel): model_arch = gguf.MODEL_ARCH.MYMODEL两个要点:
register的参数必须与config.json中的架构名完全一致,否则脚本无法自动匹配;example指向一个用于自动化测试的模型,优先选非门控的小模型。
TextModel与MmprojModel的基类定义在 conversion/base.py 中,已经帮你处理了大部分 hparam 读取、词表导出和元数据写入逻辑——你的子类只需要覆盖差异部分,不要重复实现基类已有的功能。
2. 定义 GGUF 张量布局
在 gguf-py/gguf/constants.py 中补充三样东西:
MODEL_ARCH:架构枚举(对应 GGUF 文件里的架构字符串);MODEL_ARCH_NAMES:人类可读的架构名称;MODEL_TENSORS:这个架构包含哪些张量(如token_embd、attn_qkv、ffn_down等)。
⚠️架构字符串要一次想清楚。GGUF 文件一旦以某个架构名发布,社区就会基于它做量化和分发,事后改名会破坏所有已有文件——项目官方文档特别警告了这一点。
3. 映射原始张量名
不同框架的权重命名五花八门(gpt_neox.layers.{bid}.input_layernorm、transformer.h.{bid}.ln_1……),llama.cpp 把它们统一成标准名。在 gguf-py/gguf/tensor_mapping.py 里为bid(块下标)层添加映射,例如某模型的 attention norm 权重最终都会落到blk.{bid}.attn_norm。
💡 通用规则:优先复用已有张量名,确认没有等价命名后再新增;张量名必须以
.weight或.bias结尾,否则 tools/quantize/ 等工具无法正确识别权重。
4. 运行转换
下载好模型权重后,一条命令即可完成转换(--outtype控制输出精度,支持f16、bf16、q8_0等):
python convert_hf_to_gguf.py /path/to/model --outtype f16转换脚本会读取模型配置、tokenizer、张量名称与数据,写出 GGUF 元数据和张量。如果你的模型配置特殊(比如词表非标准),可能还需要覆盖set_gguf_parameters、set_vocab或modify_tensors方法。
三、第 2 步:在 C++ 侧注册模型架构
GGUF 文件生成后,llama.cpp 本体还"不认识"这个架构。需要在 C++ 代码中声明它:
- 在 src/llama-arch.h 中新增一个
llm_arch枚举值; - 在 src/llama-arch.cpp 的
LLM_ARCH_NAMES映射表中注册架构名; - 如有特殊元数据,在 src/llama-model-loader.cpp 的加载器构造函数中读取;
- 如果模型使用 RoPE 位置编码,在 src/llama-model.cpp 的
llama_model_rope_type函数中补一个 case。
🔍 容易踩的坑:项目里存在多处对llm_arch做 switch/迭代的代码(比如 src/llama-model-saver.cpp、必需 hparam 校验列表)。漏掉其中一处是 CI 测试test-llama-archs失败的常见原因,建议直接全局搜索LLM_ARCH_逐一排查。
另外一个新手常忽略的细节:ggml 中张量的维度顺序通常与 PyTorch 相反。理解 ggml 的矩阵存储布局(见下图),能帮你避免一大类"形状对不上"的 bug:
上图展示了 ggml 中 A/B 矩阵的行主序(Row-major)与列主序(Column-major)布局,以及
C = ABᵀ等运算下各维度的对应关系。
四、第 3 步:实现 GGML 推理图
这是移植中最有挑战、也最有意思的部分——用 ggml 张量运算重建模型的前向计算图:
- 在 src/models/ 下新建
<name>.cpp,创建继承自llama_model_base的 struct(目前该目录已有 150+ 个架构实现,风格高度统一); - 在其
build_arch_graph方法中实现注意力、FFN、归一化等层级的图构建逻辑; - 在
llama_model_mapping函数中注册你的架构,让它能被正确实例化。
动手前先通读 10 个左右 src/models/ 下的现有文件(比如llama_model_llama、llama_model_dbrx、llama_model_bert),确认结构体布局与命名风格与当前代码一致——模式会随时间演进,照抄旧文档可能过时的代码。
🛠 调试工具推荐:用 examples/eval-callback/ 逐层打印中间张量,与 PyTorch 原始模型的输出逐层对比,能快速定位图构建错误。
五、可选:多模态编码器
如果你的模型带视觉/音频输入,需要额外做编码器支持(详见 docs/multimodal.md):
- 转换脚本中继承
MmprojModel而不是TextModel; - 在 src/models/clip.cpp 中添加编码器定义;
- 在
tools/mtmd中实现预处理器和编码器图。
⚠️ 关键原则:能复用就绝不新写。大量视觉编码器(siglip、pixtral、qwen 系列等)已经支持,你的模型通常只需要写一个新的 projector。需要新增预处理器或改动共享基础设施时,应当先把文本模型落地,编码器作为独立的后续 PR。
六、验证:确认你的转换是对的
examples/model-conversion/ 提供了一套完整的验证工具链,官方验证清单如下:
- 转换后检查原始与转换后张量的一致性;
- logits 校验:对比原始模型与转换后模型在同一输入下的 logits;
- 执行量化(tools/quantize/)并再次验证;
- 跑困惑度评估;
- 依次用 tools/cli、tools/completion/、tools/imatrix/、tools/quantize/、tools/server/ 做冒烟测试;
- 先保证 CPU 后端可用,CUDA/Metal 等后端可以作为独立 PR 后续补充。
📝 提示:如果新模型是某个已支持家族的新版本,先验证旧版本能通过 logits 校验。已有的数值差异可能与你的工作无关,提前区分能省下大量调试时间。
七、高频踩坑清单
这些是过往 PR 评审中反复出现的问题,提前自查可以少走很多弯路:
- ❌ 不要在 Python 转换脚本和 C++ 加载路径中重复校验同一个 hparam,选一层负责即可;
- ❌ 关键的 hparam(缺失会导致崩溃或输出错误的)必须硬报错,不要静默回退到默认值;
- ✅ 常量级张量变换(如
norm(1 + weight)、张量重排)尽量在转换时折进权重,而不是在推理图里做(Gemma 3 的做法); - ❌ 不要用自定义 sin/cos 去绕开 RoPE 限制,统一用
ggml_rope_ext,表达不了就先和 maintainer 讨论; - ✅ 聊天模板应在转换时注入 GGUF,不要硬编码进 C++ 二进制。
总结
给 llama.cpp 添加新模型的完整工作流可以浓缩为一句话:Python 侧把权重"翻译"成 GGUF,C++ 侧把架构"实现"成推理图。
- 在 conversion/ 注册转换类,补全 constants.py 与 tensor_mapping.py,运行 convert_hf_to_gguf.py 生成 GGUF;
- 在 src/llama-arch.h / src/llama-arch.cpp 注册架构;
- 在 src/models/ 实现 GGML 图并接入
llama_model_mapping; - 用 examples/model-conversion/ 工具链完成 logits 校验、量化与困惑度评估。
完整细节请阅读官方指南 docs/development/HOWTO-add-model.md,动手前记得先浏览几个最近合并的新模型 PR——社区最新的代码约定,永远是最好的参考。
【免费下载链接】llama.cpp
LLM inference in C/C++
相关推荐
llama.cpp 多模态实战:Granite Vision 模型从 HF 权重到 GGUF 的完整转换流程
llama.cpp 多模态实战:Granite Vision 模型从 HF 权重到 GGUF 的完整转换流程 Granite Vision(如 IBM 的 gr
人工智能大模型推理引擎本地部署模型推理服务模型量化llama.cpp 模型转换工作流详解:从 HuggingFace 模型到 GGUF 的转换、验证、量化与发布
llama.cpp 模型转换工作流详解:从 HuggingFace 模型到 GGUF 的转换、验证、量化与发布 本文围绕 examples/model conv
人工智能大模型推理引擎本地部署模型推理服务模型量化llama.cpp 多模态实战:MiniCPM-V 4.5 从 PyTorch 模型转换到 GGUF 推理全流程
llama.cpp 多模态实战:MiniCPM V 4.5 从 PyTorch 模型转换到 GGUF 推理全流程 本文基于仓库文档 MiniCPM V 4.5
人工智能大模型推理引擎本地部署模型推理服务模型量化
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考