☰
如何给 llama.cpp 添加新模型?从 PyTorch 权重到 GGUF 的完整转换工作流
2026/10/23 1:53:22 网站建设 项目流程

【免费下载链接】llama.cpp

LLM inference in C/C++

项目地址:https://gitcode.com/gh_mirrors/llamacpp14/llama.cpp
点击查看免费下载

想让一个新的大语言模型跑在 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++ 代码中声明它:

  1. 在 src/llama-arch.h 中新增一个llm_arch枚举值;
  2. 在 src/llama-arch.cpp 的LLM_ARCH_NAMES映射表中注册架构名;
  3. 如有特殊元数据,在 src/llama-model-loader.cpp 的加载器构造函数中读取;
  4. 如果模型使用 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 张量运算重建模型的前向计算图:

  1. 在 src/models/ 下新建<name>.cpp,创建继承自llama_model_base的 struct(目前该目录已有 150+ 个架构实现,风格高度统一);
  2. 在其build_arch_graph方法中实现注意力、FFN、归一化等层级的图构建逻辑;
  3. 在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/ 提供了一套完整的验证工具链,官方验证清单如下:

  1. 转换后检查原始与转换后张量的一致性;
  2. logits 校验:对比原始模型与转换后模型在同一输入下的 logits;
  3. 执行量化(tools/quantize/)并再次验证;
  4. 跑困惑度评估;
  5. 依次用 tools/cli、tools/completion/、tools/imatrix/、tools/quantize/、tools/server/ 做冒烟测试;
  6. 先保证 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++ 侧把架构"实现"成推理图。

  1. 在 conversion/ 注册转换类,补全 constants.py 与 tensor_mapping.py,运行 convert_hf_to_gguf.py 生成 GGUF;
  2. 在 src/llama-arch.h / src/llama-arch.cpp 注册架构;
  3. 在 src/models/ 实现 GGML 图并接入llama_model_mapping;
  4. 用 examples/model-conversion/ 工具链完成 logits 校验、量化与困惑度评估。

完整细节请阅读官方指南 docs/development/HOWTO-add-model.md,动手前记得先浏览几个最近合并的新模型 PR——社区最新的代码约定,永远是最好的参考。

【免费下载链接】llama.cpp

LLM inference in C/C++

项目地址:https://gitcode.com/gh_mirrors/llamacpp14/llama.cpp
点击查看免费下载

相关推荐

上一篇:如何理解Bromite的GNU GPL v3许可证:保护用户自由的终极指南
下一篇:Yet-Another-Bench-Script低带宽服务器测试:-i和-r标志的巧妙应用

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询