Skip to content

模型加载与 GGUF 格式 — 概念

GGUF 文件格式

GGUF (GGML Universal File) 是二进制格式,结构如下:

┌──────────────────┐
│ Header            │  magic + version + tensor_count + metadata_count
├──────────────────┤
│ Metadata KV Pairs │  key-value 元数据(架构、超参数、词表等)
├──────────────────┤
│ Tensor Info Array │  每个张量的 name、dims、type、offset
├──────────────────┤
│ Alignment Padding │  对齐填充
├──────────────────┤
│ Tensor Data       │  所有张量的实际数据
└──────────────────┘

元数据 (Metadata)

GGUF 存储丰富的模型信息:

  • general.architecture — 模型架构名(如 "llama", "gpt2")
  • llama.context_length — 最大上下文长度
  • llama.embedding_length — embedding 维度
  • llama.block_count — Transformer 层数(注意:hparams 现在区分 n_layern_layer_all,后者包含 SWA/MTP 等额外层;另有 n_layer_nextn 专计 MTP/nextn 草稿层,对应公共 API llama_model_n_layer_nextn
  • llama.attention.head_count — 注意力头数
  • tokenizer.ggml.tokens — 词表
  • tokenizer.ggml.scores — token 分数

张量存储

每个张量记录:

  • 名称(如 blk.0.attn_q.weight
  • 维度(n_dims)
  • 数据类型(F16, Q4_0, NVFP4 等)
  • 在文件中的偏移量

NVFP4 是 NVIDIA 特定的 4-bit 浮点量化格式,通过 convert 工具的 compressed-tensors 模式支持。

GGUF 初始化方式

GGUF 现在支持三种初始化方式,内部统一通过 gguf_init_from_reader() 实现:

函数说明
gguf_init_from_file()从文件路径初始化(原有方式)
gguf_init_from_callback()从用户提供的回调函数初始化(支持网络流、加密存储等)
gguf_init_from_buffer()从内存缓冲区初始化(直接解析已加载的 GGUF 数据)

模型架构

llama-arch.h 定义了支持的模型架构枚举:

c
enum llm_arch {
    LLM_ARCH_LLAMA,
    LLM_ARCH_GPT2,
    LLM_ARCH_FALCON,
    LLM_ARCH_BAICHUAN,
    LLM_ARCH_STARCODER,
    LLM_ARCH_QWEN2,
    LLM_ARCH_DEEPSEEK32,        // DeepSeek V3.2 — DSA lightning indexer
    LLM_ARCH_DEEPSEEK4,         // DeepSeek V4 (dsv4) — 专用 KV cache
    LLM_ARCH_GEMMA4,            // Gemma 4 (含 Vision 多模态)
    LLM_ARCH_GEMMA4_ASSISTANT,  // Gemma 4 MTP 草稿助手 (E2B/E4B)
    LLM_ARCH_COHERE2MOE,        // Cohere2 MoE (North Code / TINY_AYA)
    LLM_ARCH_EAGLE3,            // EAGLE3 推测解码
    LLM_ARCH_DFLASH,            // DFlash 块扩散推测解码 draft
    LLM_ARCH_LAGUNA,            // Laguna (XS.2 / M.1 / S-2.1)
    LLM_ARCH_HY_V3,             // Hy3(含 MTP 推测解码)
    LLM_ARCH_MINIMAX_M3,        // MiniMax-M3(MSA 稀疏注意力)
    LLM_ARCH_NANBEIGE,          // Nanbeige4.2
    LLM_ARCH_QWEN4EXP,          // Qwen3.8-Flash-Next(PLE 逐层嵌入,lazy 读取旗舰)
    LLM_ARCH_GRANITE_SWA,       // GraniteSWA / GraniteMoeSWA 滑窗变体
    LLM_ARCH_BAILINGMOE3,       // BailingMoE-3(字节 Seed,MLA+MoE+DSpark)
    LLM_ARCH_DOTS3NOTE,         // dots.optim note(MLA + SWA 混合,红书)
    LLM_ARCH_HY_V4,             // 腾讯混元 4.0 preview
    LLM_ARCH_SPARK2_5,          // Spark2_5ForCausalLM(SWA 模式)
    LLM_ARCH_KIMI_K3,           // Kimi K3(KDA/delta-net 混合 MoE,回滚)
    LLM_ARCH_QWEN3TTS,          // Qwen3-TTS-0.6B(mtmd 音频生成)
    LLM_ARCH_POCKETTTS,         // Pocket TTS(mtmd 音频生成)
    LLM_ARCH_MINIMAX_01,        // MiniMax-Text-01 / M1(linear attention 混合)
    LLM_ARCH_MUSE_GLIMMER,      // MuseGlimmer ViT 视觉编码器(mmproj)
    LLM_ARCH_GRANITE_SWITCH,    // Granite-Switch(router 选 token adapter)
    // ... 共 150 个架构(本窗口 +12)
};

每种架构定义了:

  • 层结构(attention, FFN 的组成)
  • 张量命名规则
  • 特殊操作(如 RoPE 变体)

权重映射

模型加载时,将 GGUF 中的张量名映射到模型结构:

GGUF tensor name                    → 模型位置
blk.0.attn_q.weight                 → layers[0].attention.wq
blk.0.attn_k.weight                 → layers[0].attention.wk
blk.0.attn_v.weight                 → layers[0].attention.wv
blk.0.attn_output.weight            → layers[0].attention.wo
blk.0.ffn_gate.weight               → layers[0].ffn.w1
blk.0.ffn_up.weight                 → layers[0].ffn.w3
blk.0.ffn_down.weight               → layers[0].ffn.w2

内存映射 (mmap)

llama.cpp 使用 mmap 加载大模型:

  • 不将整个文件读入内存
  • 按需映射权重页到地址空间
  • 操作系统自动管理物理内存
  • 允许加载超过物理内存的模型

加载方式现由 llama_model_params::load_modeenum llama_load_mode)统一控制,取代了原先的三个布尔 use_mmap / use_mlock / use_direct_io

取值含义
LLAMA_LOAD_MODE_AUTO = -1新增且为默认:按设备能力自动选择(iGPU 上避开 mmap,153d324bc
LLAMA_LOAD_MODE_NONE无特殊模式
LLAMA_LOAD_MODE_MMAP内存映射模型(即 mmap)
LLAMA_LOAD_MODE_MLOCK强制常驻 RAM,禁止换页 / 压缩
LLAMA_LOAD_MODE_MMAP_MLOCKmmap + 常驻 RAM
LLAMA_LOAD_MODE_DIRECT_IO启用 direct I/O(若平台支持)

配套有 llama_load_mode_name()llama_load_mode_from_str()(AUTO 的判定依赖后端设备能力里新增的 mmap_support 布尔,ggml_backend_dev_caps)。> 这是一次破坏性变更e6dd0e29a#20834):旧代码里的 params.use_mmap = true; 已失效。CLI 侧 --mmap / --mlock / --direct-io 现已是 --load-mode 的 deprecated 别名。

懒加载(lazy mode)

本窗口引入按需读取权重enum llama_lazy_mode--lazy-mode / -lzm,默认 auto)与 load_mode 正交:

取值含义
LLAMA_LAZY_MODE_OFF全部一次性读入
LLAMA_LAZY_MODE_AUTO仅对标记且 > 4 GiB 的张量懒加载
LLAMA_LAZY_MODE_ON所有标记张量按需读取(需 mmap)

机制:架构用新的 TENSOR_READ_LAZY 标志标记特定张量(目前仅 gemma4 的 per_layer_tok_embd 与 qwen4exp 的 PLE 逐层嵌入表——「把 PLE/engram 嵌入留在磁盘上按需读」)。loader 记录每个 lazy 张量的文件字节区间,mmap 后对这些区间用 MADV_RANDOM(不预取、不 mlock);推理图对这些张量只做 ggml_get_rows,运行时靠缺页逐行读入——驻留内存的只有真正被用到的行。

其它加载器机制(本窗口):

  • load_mtp 参数llama_model_params::load_mtp)— MTP/nextn 张量默认不加载,仅在真正启用 MTP 时读取(82dbc4f01
  • TENSOR_ALLOW_RESHAPE 标志 — 只比较元素总数,允许 reshape 加载(deepseek4 使用)
  • RAM 峰值抑制 — 非 mmap 加载时按「大张量优先」稳定排序、非 host 上下文优先分区;staging 读缓冲改为逐张量作用域
  • 量化内存llama_model_quantize_params::max_buf_size(默认 8 GiB);loader 新增 unmap_weight()(逐层逐出 mmap 页)与 load_data_range()
  • 会话/状态版本LLAMA_SESSION_VERSION 9 → 10、LLAMA_STATE_SEQ_VERSION 2 → 3(多输出采样状态 + recurrent 回滚)
  • hparams 逐层化n_ff_exp / n_expert_used 从标量变为逐层数组(n_ff_exp_arr 等,标量自动广播),新增 n_expert_used_max()(Nemotron-3-Puzzle 有 5 种 expert 宽度 / 7 种 top-k);n_layer_nextn 的加载上收到共享 load_hparamsLLAMA_MAX_EXPERTS 512 → 1024(Kimi K3)

相关概念

新增转换功能

  • --fuse-qkv(本窗口,465e49b9c)— convert_hf_to_gguf.py 新旗标:当架构的张量映射声明了 ATTN_QKV 时,把逐层的 Q/K/V 权重(与 bias)在维度 0 上拼接为单个 attn_qkv 张量(减少小 GEMM 数量);已接线 14 个架构(deepseek2、gemma4、qwen35、qwen3next、kimi-linear 等)。运行时由图层新的 build_qkv 辅助函数消费
  • 转换包扩展conversion/ 从 83 增至 92 个模块(kimi_k3、hy_v4、qwen4exp、spark2_5、muse_glimmer、pockettts、qwen3tts 等);gguf_writer 支持 per-layer 的 expert_feed_forward_length / expert_used_count 数组、MLA+SWA 键、granite-switch adapter 键、dflash selector 键、rope_patternrecurrent_layers
  • gguf-py 读取加固 — kv/tensor 计数上限 2^30、字符串长度上限 1 GiB 并对照文件剩余大小校验;新增 gguf/lazy.py 模块;C 侧要求 general.alignment 必须为 UINT32
  • 本窗口新架构(+12) — Qwen3.8-Flash-Next(qwen4exp:linear/gdn + MoE + 超连接 + PLE 逐层嵌入)、MuseGlimmer ViT、Granite-Switch(单 router KV 层选 token adapter)、GraniteSWA/MoeSWA、BailingMoE-3(MLA+MoE,DSpark)、dots3-note(MLA+SWA 混合)、Tencent Hy 4(hy_v4)、Spark2.5、Kimi K3(KDA/delta-net 混合 MoE,LLAMA_MAX_EXPERTS 512→1024,支持循环态回滚)、Qwen3-TTS-0.6B、PocketTTS(后两者走 mtmd 音频生成)、MiniMax-Text-01/M1(linear attention 混合)
  • 复用既有架构的新模型 — Nemotron-3-Puzzle-75B(复用 nemotron-h,推动 per-layer MoE hparams)、Nemotron3.5 DSpark、GLM-4.5-Air MTP、DeepSeek V4 视觉输入、Nanbeige4.2-3B(一行复用)
  • Laguna — 全新架构 LLM_ARCH_LAGUNAlaguna)+ src/models/laguna.cpp,支持 Laguna XS.2 / M.1 / S-2.1,带 models/templates/poolside-Laguna-*.jinja 模板
  • Hy3 — 全新架构 LLM_ARCH_HY_V3hy_v3)+ src/models/hy-v3.cpp,含 MTP 推测解码
  • MiniMax-M3 — 全新架构 LLM_ARCH_MINIMAX_M3minimax-m3)+ src/models/minimax-m3.cpp,使用 MSA(MiniMax Sparse Attention),驱动 KV cache 的 k_idx indexer(见 KV Cache
  • Nanbeige — 全新架构 LLM_ARCH_NANBEIGEnanbeige)+ src/models/nanbeige.cpp,Nanbeige4.2
  • GLM 5.2 Indexer — 扩展现有 GLM 架构,复用 lightning indexer(88bfee142,非新架构)
  • DeepSeek V4 — 全新架构 LLM_ARCH_DEEPSEEK4(dsv4):convert/deepseek.py 转换脚本,新增 save-load 状态、Sinkhorn eps 纠正、rope 修复与 pro 模型支持,配套 DeepSeek V4 jinja 模板;专用 KV cache 见 KV Cache,推理图输入见 推理图
  • DFlash — 全新块扩散(block diffusion)推测解码 draft 架构 LLM_ARCH_DFLASH,新增 src/models/dflash.cpp;draft 通过 convert--target-model-dir 继承目标模型的 tokenizer 与 token embedding(如 z-lab/Qwen3-4B-DFlash 对应 Qwen/Qwen3-4B);draft 模型转换路径后续又重构,顺带修复 eagle3 convert
  • FP8 → Q8 转换convert_hf_to_gguf.py 现支持将 FP8 权重直接转换为 Q8_0 量化
  • Mistral3 NVFP4 scale — 模型加载时自动附加 NVFP4 权重缩放因子
  • 多新架构转换 — 支持 Gemma 4、Step3.7-Flash、MiniCPM5 tokenizer、Granite Embeddings R2
  • EAGLE3 — 新增推测解码架构,目标模型需启用层输入抽取(layer input extraction)供 draft 模型读取隐藏状态
  • Gemma4 MTP — Gemma 4 的 MTP 草稿助手(LLM_ARCH_GEMMA4_ASSISTANT,E2B / E4B),含无音频编码器场景的转换修复
  • Cohere2 MoE — 新增 cohere2-MoE 架构及 TINY_AYA vocab 转换
  • Mistral-Medium-3.5-128B — 修复该模型的权重转换
  • LoRA base arch — 修复 LoRA 转换时 base 模型架构检索
  • Granite Speech Plus — 新增语音模型(speech)的转换支持
  • LFM2.5 检索 / 嵌入 — 新增 LFM2.5-ColBERT-350M(检索)与 LFM2.5-Embedding-350M(嵌入)转换;补充 LFM2.5-230M 标签
  • unlimited-ocr — mtmd 新增 unlimited-ocr 模型转换器 + 一致性测试
  • glm-dsa — DSA indexer 张量按可选(optional)加载
  • convert rope_parameters — RoPE 参数处理更一致;修复 moe + mtp 同时存在时的量化
  • common 模型处理重构 — 统一模型加载路径

多模态输入 (mtmd)

mtmd(多模态输入处理)现已支持视频输入

  • 新增 lazy bitmap API,按需解码视频帧
  • mtmd_helper_video 辅助视频输入解析
  • server 端接受视频的 base64 编码
  • 新增 build_vit 批处理 APIpost-decode 回调,提升多模态吞吐与可扩展性
  • InternVL 批处理 — 为 InternVL 启用 batching;mtmd-cli 也支持批处理并新增视频测试
  • 预处理器重构 — 引入 mtmd_image_preproc_out,预处理器输出结构化;llava-uhd 概览图处理统一(始终 ov_img_first,不再使用 batch dim)
  • 加载进度回调 — mtmd 新增 load progress callback
  • 健壮性 — 多项 bug 修复与输入校验加强;Windows 下 utf8 处理修复
  • 本窗口:mtmd_tokenize_from_parts() 分件分词、位图合并 opt-in、TTS 音频生成子系统、Pillow 级精确缩放、webp 解码、--mmproj-device(详见 分词