Transformers 的 GGUF 支持:加载量化模型、反量化到 PyTorch 再微调的完整指南
GGUF 是一种面向 GGML/llama.cpp 生态的单文件模型格式,Transformers 通过在 from_pretrained 中提供 gguf_file 参数,可以直接读取 Hub 上常见的 GGUF 量化检查点:先把配置、分词器元数据和权重从文件中解析出来,再将量化权重反量化(dequantize)为 PyTorch 张量,从而把原本只能在 ggml 运行时中推理的模型带回 Transformers 生态做训练与微调。读完本文,你将掌握 gguf_file 的完整用法、当前支持的反量化类型与模型架构清单、底层“元数据映射 + 张量重排”的源码实现,以及如何把微调结果保存并转回 GGUF。
什么是 GGUF:单文件模型格式
GGUF 是 GGML 推理框架(llama.cpp、whisper.cpp 等项目基于它)使用的模型存储格式。它的核心设计是单文件格式(single-file format):
- 一个
.gguf文件通常同时包含模型配置属性、分词器词表(token、score、merges 等)以及其他元数据; - 同时包含模型全部权重张量,且张量以文件中声明的量化类型存储;
- 文件支持快速检视(inspection):可以先只读取 KV 元数据而不加载张量,这在 Hub 上用于对 GGUF 仓库做快速扫描。
由于量化存储大幅降低了文件体积,GGUF 成为 Hub 上 LLM 社区分享权重的主流格式之一(例如 Q4_K、Q6_K、IQ2_XXS 等各种量化级别的文件)。
在 Transformers 中加载 GGUF:gguf_file 参数
[!NOTE] 文档明确标注:GGUF 加载功能仍处于高度实验阶段,欢迎社区贡献以覆盖更多量化类型和模型架构(见 docs/source/ar/gguf.md)。
加载 GGUF 文件的方式是在 分词器和模型的 from_pretrained 调用中都传入 gguf_file 参数,两者可以来自同一个 GGUF 文件:
from transformers import AutoTokenizer, AutoModelForCausalLM
model_id = "TheBloke/TinyLlama-1.1B-Chat-v1.0-GGUF"
filename = "tinyllama-1.1b-chat-v1.0.Q6_K.gguf"
tokenizer = AutoTokenizer.from_pretrained(model_id, gguf_file=filename)
model = AutoModelForCausalLM.from_pretrained(model_id, gguf_file=filename)
加载完成后,你就拥有了一份未量化(dequantized)的完整模型,可以在 PyTorch 环境中与 Trainer、PEFT 等工具链自由组合。加载路径支持两种位置:
gguf_file指向本地文件:直接以文件路径读取;gguf_file指向 Hub 上的文件名:走标准的cached_file下载/缓存逻辑(与常规检查点下载一致)。
加载的底层调用链
从源码结构看,gguf_file 参数贯穿了分词器、配置、模型三条加载路径:
- 分词器侧:tokenization_utils_base.py 中,
vocab_files_count > 1的缺失检查对 GGUF 豁免;当检测到gguf_file时,直接令vocab_files["vocab_file"] = gguf_file,即以 GGUF 文件充当词表文件。 - 配置侧:configuration_utils.py 中,
gguf_file会取代config.json成为“配置来源”,通过load_gguf_checkpoint(resolved_config_file, return_tensors=False)["config"]只解析元数据(不读张量)来构建 config 字典。 - 模型侧:modeling_utils.py 的
from_pretrained对gguf_file做了三件事:- 校验约束(下文“限制”一节详述);
- 在
torch.device("meta")上实例化一个虚拟(dummy)模型,仅用它的state_dict键名生成 GGUF→HF 张量名映射; - 调用 modeling_gguf_pytorch_utils.py 中的
load_gguf_checkpoint(..., return_tensors=True, model_to_load=dummy_model, torch_dtype=dtype)得到张量字典,再按普通state_dict流程装入真实模型。
load_gguf_checkpoint 内部的核心步骤:
- 用
gguf.GGUFReader打开文件,读取general.architecture判断架构(并做若干补丁,例如 llama.cpp 中 Mistral 复用 llama 架构名、T5 系架构识别等); - 遍历文件所有 KV 字段,按映射表重命名为 Transformers 配置键;
- 对每个张量调用 gguf 包的
dequantize(tensor.data, tensor.tensor_type)反量化(源码位置),随后经过架构专属的TensorProcessor做张量重排/拆分,再映射到 HF 参数名; - 若传入
torch_dtype(即from_pretrained的dtype参数),张量会在反量化后立即转换到目标 dtype 以节省显存,例如测试 test_q6_k_fp16 中dtype=torch.float16加载 Q6_K 文件并断言lm_head.weight.dtype == torch.float16。
原文档强调“先反量化到 fp32 再加载权重”——从源码看,反量化结果默认为 fp32 张量,但通过 dtype 参数可以在转换时直接落到 float16/bfloat16。
支持的量化类型
文档列出的支持反量化的量化类型如下(初始范围依据 Hub 上常见的共享文件确定):
- F32
- F16
- BF16
- Q4_0
- Q4_1
- Q5_0
- Q5_1
- Q8_0
- Q2_K
- Q3_K
- Q4_K
- Q5_K
- Q6_K
- IQ1_S
- IQ1_M
- IQ2_XXS
- IQ2_XS
- IQ2_S
- IQ3_XXS
- IQ3_S
- IQ4_XS
- IQ4_NL
[!NOTE] 要支持 GGUF 反量化,必须安装
gguf>=0.10.0。仓库中该门槛定义于 import_utils.py 的GGUF_MIN_VERSION = "0.10.0",is_gguf_available与测试装饰器require_gguf均以此为最低版本。
安装方式:pip install "gguf>=0.10.0"(配合已安装的 PyTorch)。若版本不满足,加载会抛出 ImportError(见 modeling_gguf_pytorch_utils.py 中的错误提示)。
支持的模型架构
文档列出的当前受支持架构是 Hub 上最常见的几类:
- LLaMa
- Mistral
- Qwen2
- Qwen2Moe
- Phi3
- Bloom
- Falcon
- StableLM
- GPT2
- Starcoder2
- T5
从源码结构看,实际的支持面由 integrations/ggml.py 中的 GGUF_CONFIG_MAPPING 决定:其中除上述架构外,还包含了 qwen3、qwen3_moe、gemma2、gemma3、gemma4、umt5、mamba、nemotron、gpt_oss、lfm2、minimax_m2 等架构的元数据映射;modeling_gguf_pytorch_utils.py 中 GGUF_SUPPORTED_ARCHITECTURES 直接由该映射表的键推导,因此“文档列出的 11 种架构”可视为首批稳定支持的典型,而源码映射表是当前版本更完整的上界。测试文件 tests/quantization/ggml/test_ggml.py 的 GgufModelTests 类中也给出了各架构对应的 Hub 仓库实例(Mistral、Qwen2、Qwen2Moe、Phi3、Bloom、Falcon、T5、StableLM、GPT2、Starcoder2、Mamba、Nemotron、Gemma2/3、Qwen3 等)。
配置与分词器的元数据映射机制
GGUF 文件把配置和分词器都编码在 KV 字段中(键名形如 llama.context_length、tokenizer.ggml.merges)。Transformers 需要把它们翻译回自己的配置/分词器格式,核心是两组映射表和一套转换类:
配置映射(GGUF_CONFIG_MAPPING)
ggml.py 中的 GGUF_CONFIG_MAPPING 按架构逐一定义了 GGUF 键到 HF config 键的翻译,例如 llama 架构:
| GGUF 键 | Transformers config 键 |
|---|---|
context_length |
max_position_embeddings |
block_count |
num_hidden_layers |
feed_forward_length |
intermediate_size |
embedding_length |
hidden_size |
rope.dimension_count |
head_dim |
rope.freq_base |
rope_theta |
attention.head_count |
num_attention_heads |
attention.head_count_kv |
num_key_value_heads |
attention.layer_norm_rms_epsilon |
rms_norm_eps |
vocab_size |
vocab_size |
不同架构的命名体系差异很大(例如 Bloom 用 n_layer/n_head/layer_norm_epsilon,T5 用 d_model/d_kv/relative_buckets_count),映射表逐架构做了适配。此外 GGUF_CONFIG_DEFAULTS_MAPPING 用于补齐“Transformers 与 llama.cpp 默认值不同”的个别参数(如 qwen3_moe 的 norm_topk_prob)。
解析逻辑本身在 load_gguf_checkpoint:遍历 reader.fields,把 架构.键 拆开查映射表;解析不出来的键会打印 info 日志而不报错。tie_word_embeddings 也不来自元数据,而是根据文件中是否存在 output.weight 张量推断。
分词器映射与 fast tokenizer 重建
GGUF 的分词器字段映射定义在 GGUF_TOKENIZER_MAPPING:ggml.tokens/ggml.scores/ggml.merges/ggml.token_type 等字段分别对应词表、分数、BPE merges 与 token 类型,ggml.bos_token_id 等对应特殊 token id;tokenizer_config 部分还会解析 chat_template。
GGUF_TO_FAST_CONVERTERS 按架构分派到具体的转换器:
llama/deci→GGUFLlamaConverter(BPE,含 llama-3 字节级分词器兼容补丁)qwen2/qwen2_moe/qwen3/qwen3_moe/minimax_m2→GGUFQwen2Converterphi3→GGUFPhi3Converter(补齐<|system|>、<|user|>等特殊 token)bloom/falcon/stablelm/gpt2/starcoder2/mamba/nemotron→GGUFGPTConverter(GPT-2 风格 BPE)t5/umt5→GGUFT5Converter(Unigram)gemma2/gemma3_text/gemma4_text→GGUFGemmaConverter(Unigram,含空白 token 归一化补丁)
值得注意的是 GGUFTokenizerSkeleton:当 GGUF 文件中缺少 merges 字段(部分 LLaMA 系分词器)时,它会在运行时由 tokens 与 scores 重建 BPE merges 表并告警,保证分词器仍可实例化。
张量重排:从 GGUF 布局到 HF 布局
GGUF 的“标准化张量命名”(blk.N.BB.weight/bias)与 HF 的模块路径并不一致,且部分架构在转换时做过布局变换,反向加载时必须做逆变换。仓库为此实现了 TENSOR_PROCESSORS 注册表,按架构分派:
- LlamaTensorProcessor:对
attn_q/attn_k权重做逆行转置(_reverse_permute_weights),还原 llama.cpp 转换时的 KV 重排; - BloomTensorProcessor:把合并存储的
attn_qkv按 q/k/v 拆块并逆 reshape(含 bias 的对应处理); - GPT2TensorProcessor:对
attn_qkv、ffn_down、ffn_up、attn_output等权重做转置,并把 GGUF 的output.weight特判映射为lm_head.weight; - MambaTensorProcessor:
ssm_a取log(-x)还原指数形式,ssm_conv1d补回维度; - NemotronTensorProcessor / Gemma2TensorProcessor:norm 权重做
-1平移还原(这类模型 norm 存储的是weight - 1); - Qwen2MoeTensorProcessor / MiniMaxM2TensorProcessor:把 GGUF 中按专家堆叠的 MoE 张量(
ffn_gate_exps/ffn_up_exps/ffn_down_exps)拆分并交错写回 HF 的gate_up_proj(实现); - GptOssTensorProcessor:处理 128 专家 MoE 张量拆分与合并
gate_up_projs的交错还原。
名称映射本身复用 gguf 包的 get_tensor_name_map(见 get_gguf_hf_weights_map):先在 meta 设备上构造 dummy 模型拿到 HF 参数名,逐个查表得到 GGUF 名;对一张对多张的 MoE 场景回退到 perform_fallback_tensor_mapping。这个设计意味着新增架构支持 = 在 GGUF_CONFIG_MAPPING 加元数据映射、(如需要)在 TENSOR_PROCESSORS 加处理器、在 GGUF_TO_FAST_CONVERTERS 加分词器转换器。
保存模型并转回 GGUF
完成微调/训练后,标准流程是把 tokenizer 和 model 保存为 HF 格式,再用 llama.cpp 的 convert-hf-to-gguf.py 脚本转回 GGUF:
tokenizer.save_pretrained('directory')
model.save_pretrained('directory')
!python ${path_to_llama_cpp}/convert-hf-to-gguf.py ${directory}
仓库的集成测试 test_q2_k_serialization 验证了这条闭环的前半段:加载 Q2_K 文件 → 生成文本 → save_pretrained → 从本地目录重新加载 → 生成结果一致,说明反量化后的权重可以无损地序列化回 safetensors/PyTorch 格式。
限制与注意事项
以下限制均有源码或测试依据,使用时需留意:
- 不支持与量化配置叠加:传入
gguf_file时若同时带quantization_config(或从 Hub 加载量化模型),会直接抛ValueError(modeling_utils.py)——反量化本身就消除了二次量化的必要。 - 不支持 disk offload:
device_map中出现disk值会抛RuntimeError,测试 test_gguf_errors_disk_offload 专门验证了这一点;需要accelerate可用(检查位置)。 - 不支持与
state_dict同时传入:gguf_file与直接传state_dict二选一(modeling_utils.py)。 - 版本门槛:需要
gguf>=0.10.0且已安装 PyTorch,否则抛ImportError;gguf 包过旧还可能因架构缺失而报Unknown gguf model_type(错误处理)。 - 功能仍属实验性:与文档声明一致,量化类型和架构覆盖仍在扩展中。
参考文件
- 原文档:docs/source/ar/gguf.md(英文对照版见 docs/source/en/gguf.md)
- 核心加载实现:src/transformers/modeling_gguf_pytorch_utils.py
- 元数据/分词器映射:src/transformers/integrations/ggml.py
from_pretrained集成点:src/transformers/modeling_utils.py、src/transformers/configuration_utils.py、src/transformers/tokenization_utils_base.py- 测试用例:tests/quantization/ggml/test_ggml.py
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00