向 llama.cpp 添加新的模型架构
添加新模型需要以下几个步骤:
- 将模型转换为 GGUF 格式
- 在
llama.cpp中定义模型架构 - 构建 GGML 图实现
完成这些步骤后,您就可以提交 PR 了。
同时,确保示例和主要 GGML 后端(CUDA、METAL、CPU)与新架构正常工作也很重要,特别是:
1. 将模型转换为 GGUF 格式
这一步需要在 Python 中使用 convert 脚本和 gguf 库来完成。
根据模型架构的不同,您可以使用 convert_hf_to_gguf.py 或 examples/convert_legacy_llama.py(适用于 .pth 格式的 llama/llama2 模型)。
转换脚本会读取模型配置、分词器、张量名称和数据,并将它们转换为 GGUF 元数据和张量。
实现 HF 模型所需的步骤:
- 在新的
Model子类中定义模型的Model.register注解,示例:
@Model.register("MyModelForCausalLM")
class MyModel(Model):
model_arch = gguf.MODEL_ARCH.MYMODEL
- 在 constants.py 中定义 GGUF 张量的布局
在 MODEL_ARCH 中添加枚举条目,在 MODEL_ARCH_NAMES 中添加模型的用户友好名称,在 MODEL_TENSORS 中添加 GGUF 张量名称。
falcon 模型的示例:
MODEL_ARCH.FALCON: [
MODEL_TENSOR.TOKEN_EMBD,
MODEL_TENSOR.OUTPUT_NORM,
MODEL_TENSOR.OUTPUT,
MODEL_TENSOR.ATTN_NORM,
MODEL_TENSOR.ATTN_NORM_2,
MODEL_TENSOR.ATTN_QKV,
MODEL_TENSOR.ATTN_OUT,
MODEL_TENSOR.FFN_DOWN,
MODEL_TENSOR.FFN_UP,
]
- 将原始张量名称映射到 GGUF 中的标准化等效名称
一般来说,在向 GGUF 添加新张量名称之前,请确保等效命名不存在。
找到等效的 GGUF 张量名称后,将其添加到 tensor_mapping.py 文件中。
如果张量名称是重复层/块的一部分,关键字 bid 会替代它。
注意力层中归一化张量的示例:
block_mappings_cfg: dict[MODEL_TENSOR, tuple[str, ...]] = {
# Attention norm
MODEL_TENSOR.ATTN_NORM: (
"gpt_neox.layers.{bid}.input_layernorm", # gptneox
"transformer.h.{bid}.ln_1", # gpt2 gpt-j refact qwen
"transformer.blocks.{bid}.norm_1", # mpt
...
)
}
transformer.blocks.{bid}.norm_1 将被映射为 GGUF 中的 blk.{bid}.attn_norm。
根据模型配置、分词器、代码和张量布局,您可能需要重写:
Model#set_gguf_parametersModel#set_vocabModel#write_tensors
注意: 张量名称必须以
.weight或.bias后缀结尾,这是约定俗成的规则,像quantize这样的工具期望这样才能处理权重。
2. 在 llama.cpp 中定义模型架构
必须在 llama.cpp 中定义模型参数和张量布局:
- 定义新的
llm_arch - 在
LLM_TENSOR_NAMES中定义张量布局 - 在
llm_load_hparams中添加任何非标准元数据 - 在
llm_load_tensors中创建推理张量 - 如果模型有 RoPE 操作,在
llama_rope_type中添加 RoPE 类型
注意:
ggml中的维度通常与pytorch维度的顺序相反。
3. 构建 GGML 图实现
这是最有趣的部分,您需要在 llama_build_graph 中提供新模型架构的推理图实现。
查看现有的实现,如 build_llama、build_dbrx 或 build_bert。
一些 ggml 后端不支持所有操作。后端实现可以在单独的 PR 中添加。
注意: 要调试推理图,您可以使用 llama-eval-callback。
GGUF 规范
https://github.com/ggml-org/ggml/blob/master/docs/gguf.md
参考资源
- YaRN RoPE 缩放 https://github.com/ggml-org/llama.cpp/pull/2268
- 支持百川系列模型 https://github.com/ggml-org/llama.cpp/pull/3009
- 支持注意力偏置 https://github.com/ggml-org/llama.cpp/pull/4283
- Mixtral 支持 https://github.com/ggml-org/llama.cpp/pull/4406
- BERT 嵌入 https://github.com/ggml-org/llama.cpp/pull/5423
- Grok-1 支持 https://github.com/ggml-org/llama.cpp/pull/6204
- Command R Plus 支持 https://github.com/ggml-org/llama.cpp/pull/6491
- 支持 DBRX 架构 https://github.com/ggml-org/llama.cpp/pull/6515
- 如何将 HuggingFace 模型转换为 GGUF 格式 https://github.com/ggml-org/llama.cpp/discussions/2948