Skip to content

模型加载与 GGUF 格式 — 代码走读

src/llama-model-loader.cpp — 模型加载器

这是模型加载的核心文件。

加载流程

llama_model_load_from_file()
  └── llama_model::load()
      ├── 1. 打开 GGUF 文件
      ├── 2. 解析 header & metadata
      ├── 3. 读取超参数 (hparams)
      ├── 4. 构建词表 (vocab)
      ├── 5. 分配 GGML context
      ├── 6. mmap 权重数据
      └── 7. 映射张量到模型结构

GGUF 解析

cpp
// 读取文件头
uint32_t magic = gguf_get_magic(ctx);
uint32_t version = gguf_get_version(ctx);
uint64_t n_tensors = gguf_get_n_tensors(ctx);
uint64_t n_kv = gguf_get_n_kv(ctx);

// 读取元数据
std::string arch = gguf_get_val_str(ctx, "general.architecture");
uint32_t n_layers = gguf_get_val_u32(ctx, "llama.block_count");

权重映射

模型加载器将 GGUF 张量名映射到内部结构:

cpp
// 遍历所有张量
for (int i = 0; i < n_tensors; i++) {
    const char * name = gguf_get_tensor_name(ctx, i);
    struct ggml_tensor * tensor = ggml_get_tensor(model_ctx, name);
    // 通过名称模式匹配分配到对应层
}

src/llama-arch.h — 架构定义

每种架构定义了其层结构和张量映射:

cpp
struct llm_layer {
    // Attention
    struct ggml_tensor * wq;
    struct ggml_tensor * wk;
    struct ggml_tensor * wv;
    struct ggml_tensor * wo;
    // FFN
    struct ggml_tensor * ffn_gate;
    struct ggml_tensor * ffn_up;
    struct ggml_tensor * ffn_down;
    // Norm
    struct ggml_tensor * attn_norm;
    struct ggml_tensor * ffn_norm;
};

gguf-py/ — Python GGUF 工具

提供 Python 接口来读写 GGUF 文件:

python
from gguf import GGUFReader

reader = GGUFReader("model.gguf")
for tensor in reader.tensors:
    print(f"{tensor.name}: {tensor.tensor_type}, shape={tensor.shape}")

关键函数索引

函数文件说明
llama_model_load_from_filellama-model.cppAPI 入口
llm_load_tensorsllama-model-loader.cpp加载所有张量
llm_load_hparamsllama-model-loader.cpp解析超参数
llm_load_vocabllama-model-loader.cpp加载词表
gguf_get_*ggml/src/gguf.cppGGUF 元数据读取