mistral.rs UQFF 格式全解析:从文件布局到分片加载的量化模型格式参考
2026/9/17 19:16:27 网站建设 项目流程

mistral.rs UQFF 格式全解析:从文件布局到分片加载的量化模型格式参考

【免费下载链接】mistral.rsFast, flexible LLM inference项目地址: https://gitcode.com/GitHub_Trending/mi/mistral.rs

UQFF(Universal Quantized File Format)是 mistral.rs 原生的量化模型文件格式,用于持久化预量化权重并实现免运行时转换的直接加载。本文以仓库 UQFF 格式参考文档 为主体,结合mistralrs-quantmistralrs-core中的读写实现,完整讲解 UQFF 的目录结构、分片(shard)内部布局、混合量化类型的自描述机制、版本兼容规则与张量并行加载语义,帮助你理解 UQFF 文件到底是什么、如何生成、如何校验,以及加载器内部究竟做了什么。

使用提示:日常使用 UQFF 模型并不需要了解本文的底层布局——按 UQFF 使用指南 加载即可;本文面向需要排查问题、二次开发或深度理解格式的读者。

为什么需要 UQFF:设计目标与定位

UQFF 解决的核心问题是:让"量化一次、到处加载"成为可能。普通的 safetensors 模型在每次启动时都要经历 ISQ(in-situ quantization,原位量化)的运行时转换,既耗时又无法保证跨机器一致性;而 UQFF 把量化结果直接落盘,加载时跳过转换步骤。

由此衍生的三个设计约束,贯穿了 UQFF 的全部细节:

  • 自描述(self-describing):每个量化层条目都携带格式标签与元数据,加载器无需外部清单即可确定每个张量的反序列化方式——这也是单个文件内可以混合多种量化类型的前提;
  • 推理专用(inference-only):UQFF 只保存前向推理所需的权重,不包含优化器状态或训练元数据;
  • 目录即分发单位:UQFF 的导出结果是一个自包含目录,单独的 shard 文件无法独立加载。

从实现上看,UQFF 的"规范实现"分处两端:读路径(reader 与张量编码)位于 mistralrs-quant/src/uqff(mod.rsreader.rstensor.rs等),写路径位于 mistralrs-core/src/pipeline/isq.rs(write_uqff_artifactswrite_uqff_type等函数)。

导出目录结构:一份完整的 UQFF 资产包含什么

一个 UQFF 导出结果是一个目录,其中包含三类内容:

  1. 量化权重分片:一个或多个<stem>-<shard>.uqff文件,存放量化层权重,例如q4k-0.uqffq4k-1.uqff
  2. 残差 safetensorsresidual.safetensors,存放未量化张量,典型代表是各类归一化层(norm)与稠密词嵌入(dense embeddings);
  3. 模型资产副本:从源仓库复制、使目录自包含的 JSON/模板文件,包括config.jsontokenizer.jsontokenizer_config.jsongeneration_config.json,以及存在时一并复制的modules.jsonchat_template.jinjaprocessor_config.jsonpreprocessor_config.json

加载器(from_uqff)被指向一个或多个 shard 文件;residual.safetensors与上述 JSON 资产通过**同级路径查找(sibling-path lookup)**自动拾取——也就是说,加载器在 shard 文件所在目录内按约定文件名寻找配套文件,这正是"目录是分发单位"的直接体现:单独拷走一个 shard 而没有配套的 residual 与config.json是无法加载的。

Shard 内部布局:自描述层的字节级约定

每个.uqffshard 都是标准 safetensors 文件,其条目(entry)按命名约定组织。每一个量化层都通过一组相邻条目实现自描述:

条目名类型含义
<key>.weight原始数据层数据本体:GGML 家族的原始块数据(raw blocks)、AFQ/MXFP4/FP8 的打包张量(packed tensors),或未量化回退层中的原生 safetensors 张量
<key>.weight.formatu8 标量量化家族标签,加载器据此分发到对应的反序列化器(deserializer)
<key>.weight.dtype/<key>.weight.shapeu32GGML 类型的附加元数据(块类型码 / 逻辑形状)
<key>.weight.scales/.bits/.group_size依类型而定AFQ 家族的附加元数据(缩放、位宽、分组大小)
<key>.bias张量该层存在偏置时出现

其中<key>即层的权重路径,例如model.layers.0.self_attn.q_proj。源码 reader.rs 中的load_format读取<key>.weight.format的 u8 标量并转换为QuantizedSerdeType枚举(GgufUnquantHqqFp8AfqF8Q8Mxfp4等),随后load_linear依据该枚举把反序列化分发到GgufMatMulUnquantLinearAfqLayerFP8LinearHQQLayerMXFP4Layer等对应的deserialize_uqff实现。

此外,safetensors 的元数据中还包含信息性生产方字段uqff.produceruqff.producer.mistralrs.versionuqff.producer.mistralrs.git_revision。这些字段仅用于溯源(provenance),加载器不校验其内容。

MoE 专家层的三个规范键

MoE(Mixture of Experts)模型的专家层使用每个 block 三个规范键:

  • <...>.experts.gate_proj
  • <...>.experts.up_proj
  • <...>.experts.down_proj

三者各持一份堆叠权重,形状为[num_experts, out, in]。源码 mod.rs 中的QuantizedExpertKeys::new正是按{experts_prefix}.gate_proj/.up_proj/.down_proj构造这三个键名。值得注意的是,堆叠专家权重并非所有量化后端都支持:reader 在加载时若发现三阶(rank-3)堆叠权重搭配 HQQ、FP8 或 F8Q8 格式,会直接报错拒绝——这三种格式不支持"堆叠专家 gather",这一点有专门的单元测试uqff_rejects_stacked_backend_without_gather_on_load覆盖。

版本标量条目

每个 shard 集(shard set)的头部还会写入三个 u32 标量条目:uqff.version.majoruqff.version.minoruqff.version.patch。这三个条目由 mod.rs 中的uqff_version_tensors()生成,当前仓库的版本常量为UQFF_VERSION_MAJOR = 1UQFF_VERSION_MINOR = 2UQFF_VERSION_PATCH = 0(见 mod.rs)。

混合量化:一个文件里为什么可以同时存在多种类型

因为每个层都自描述,单个 UQFF 文件天然允许混合多种量化类型。三种典型来源如下:

  1. Topology 固定的层:由 topology 配置 显式指定类型的层会保持其固定类型,例如在整体 Q4K 文件中把lm_head钉在q8_0
  2. 敏感张量自动提精度:模型声明的语言 token 嵌入与输出头(output head)使用 量化类型参考 中记录的更高精度默认值。例如afq4shard 集中,这些张量以 AFQ6 存储;q4kshard 集中则以 Q6K 存储。关键在于每个加载器都声明精确的路径,因此仅仅名称相似(如以embed_tokensword_embeddingslm_head结尾)的视觉、音频等辅助张量不会被隐式提精度;
  3. 形状不支持的层按层回退:形状无法满足目标类型的层会单独回退。例如输入维度不能被 AFQ 分组大小整除的 AFQ 层,会以未量化形式存储。

混合类型的打包因子(pack factor)计算在 reader 中有一套保守逻辑:pack_factor会对所有层布局聚合取最小值,而pack_factor_for则返回单个键的精确值。相关单元测试(如mixed_uqff_uses_conservative_default_and_exact_per_key_factors)验证了嵌入层以 AFQ6/AFQ8 存储时,全局因子取嵌入层因子、单键因子精确到层的行为。

分片规则:10 GiB 软上限与按类型分片

写路径(writer)把张量流切分为<stem>-0.uqff<stem>-1.uqff、……,每个 shard 的软上限为 10 GiB。若一次运行指定了多个 ISQ 类型,则每种类型生成一套独立的 shard 集(如q4k-0.uqffafq4-0.uqff),但共享同一个residual.safetensors与同一批模型资产。

配套的 UQFF 使用指南 进一步说明:约定命名的 shard 共享前缀且以-0-1结尾,如q4k-0.uqffq4k-1.uqff只需选择其中一个,加载器即可发现连续的 shard 集合。当uqff_report.json存在并声明了输出时,其 shard 列表具有权威性,允许使用自定义文件名。

版本兼容机制:major 严格、minor 向前兼容

每个 shard 集携带的三个 u32 版本标量是加载时兼容性判定的依据。UqffReader::open(见 reader.rs)的执行逻辑如下:

  • major 不同 → 拒绝:报错并提示用mistralrs quantize重新生成;
  • minor 新于当前构建支持 → 拒绝:报错提示文件由更新版本的 mistral.rs 写出,建议升级;
  • 同 major 下 minor 更旧 → 接受:向后兼容;
  • 完全没有版本条目 → 拒绝:判定为 pre-1.0 的旧文件。

同时open还会做跨 shard 的键一致性校验(validate_shard_tensor_keys):版本标量在所有 shard 中必须一致,任何重复张量键都会被拒绝并指出冲突文件。这些规则均有对应单元测试(uqff_reader_rejects_conflicting_versions_across_shardsuqff_reader_rejects_malformed_version_copiesuqff_reader_rejects_duplicate_tensor_keys_across_shards)。

版本演进的两个里程碑

  • UQFF 1.1:引入内联的未量化线性条目(weight.format = Unquant)。此前形状不支持量化的层权重需要挪进residual.safetensors;1.1 之后这类层可以直接以未量化条目内联在 shard 中,使混合文件保持完整。
  • UQFF 1.2:量化后的 token 嵌入改为常规层条目存储,并residual.safetensors中省略其原始稠密权重。读者仍然接受 token 嵌入留在 residual 文件中的 UQFF 1.1 文件(向后兼容)。

兼容性红线:UQFF 1.x 与 pre-1.0 版本产出的文件不兼容。旧文件加载时会直接报错,请用mistralrs quantize重新生成。reader 中甚至专门检测"所有键都形如数字"的旧式文件并给出明确提示(Pre-1.0 UQFF artifacts are no longer supported)。

张量并行下的加载语义:切片还是复制?

UQFF shard 中存储的是完整张量;在张量并行(tensor parallelism)场景下,每个 rank 在加载时切出自己的那部分,而非在文件中预分片。这一点从源码可以确认:

  • shard_range(mod.rs)把Shard(简单均分或显式偏移区间)解析为(dim, start, len)三元组;
  • load_tensor_sharded(reader.rs)先在 CPU 上narrow出目标切片并contiguous(),再搬运到目标设备,确保设备只看到自己那份数据;
  • bias 的切分遵循bias_shard语义:输入维被切分时偏置跳过(归约后由调用方补加),非输入维被切分时则嵌入匹配的偏置切片(BiasShard::Narrow)。

切分打包(packed)输入维需要块对齐(block alignment)。典型模型维度满足此要求;当对齐不成立时(出现在部分专家层),该 rank 会复制完整张量而非切片。块对齐量由shard_alignment(reader.rs)按类型返回:GGML 类型返回块大小、AFQ 返回 group size、MXFP4/F8Q8 返回 32、FP8 与未量化返回 1,而HQQ 明确不支持分片加载

底层块数据的切片由slice_blocked_data(mod.rs)实现,支持沿末维(打包维,要求 start/len 均为块的整数倍)、外维与中间维切片,并有slice_blocked_last_dimslice_blocked_outer_dimslice_blocked_3d_middle_dim等测试覆盖。

从生成到校验:UQFF 的完整工作流

虽然布局参考文档聚焦于格式本身,但配合 UQFF 使用指南 可以拼出完整工作流。

生成 UQFF

# 从 safetensors 模型源量化导出 mistralrs quantize \ -m google/gemma-4-E4B-it \ --isq q4k \ -o gemma-q4k.uqff # 从本地 GGUF 文件量化导出(-f 推断 GGUF,-m 可省略) mistralrs quantize \ -f /path/model-BF16.gguf \ --isq q4k \ -o model-q4k.uqff # 从 GGUF 仓库导出(--quant 选输入产物,--isq 选输出 UQFF 格式) mistralrs quantize \ -m <gguf-repo> \ --quant 8 \ --isq q4k \ -o output/

要点:--quant-f互斥;--isq可重复或逗号分隔以一次生成多个变体(此时-o需传目录,数字简写如--isq 4会同时写出afq4.uqffq4k.uqff);topology 钉住的层在每一个输出变体中都会保留。从 GGUF 生成的 UQFF 会保留源文件的 Q/K rotary 布局,若该布局为相邻(adjacent)形式,转换后动态 LoRA 与 X-LoRA 仍不受支持。

加载 UQFF

# CLI:-m 提供 tokenizer/基础模型解析,--from-uqff 接受文件名或简写/类型名 mistralrs run -m <repo> --from-uqff q4k-0.uqff
# Python:from_uqff 接收 shard 文件名(或列表) from mistralrs import Runner, Which runner = Runner( which=Which.Plain( model_id="<repo>", from_uqff="q4k-0.uqff", ), )
// Rust:UqffTextModelBuilder 接收基础仓库与首个 shard use mistralrs::UqffTextModelBuilder; let model = UqffTextModelBuilder::new("<repo>", vec!["q4k-0.uqff".into()]) .build() .await?;

UQFF 模型在张量并行下同样可用:每个 rank 只加载量化权重中属于自己的切片。

元数据命令:report / verify / inspect

quantize还会在 UQFF 文件旁写出uqff_report.json,记录生成的变体、shard 名、各层存储格式、生产方版本与回退层。加载器在其存在时会用它解析量化名称与 shard 集合(含自定义文件名);无 report 的约定命名 UQFF 仓库仍可正常加载。

# 为现有产物扫描生成 report mistralrs uqff report -m gemma4_26b_a4b/ \ --write \ --base-model google/gemma-4-26B-A4B-it \ --repo-id mistralrs-community/gemma-4-26B-A4B-it # 对远程 HF 仓库生成 report(--quant 选择分组) mistralrs uqff report -m mistralrs-community/gemma-4-26B-A4B-it --quant afq3 --json # 发布前校验结构 mistralrs uqff verify -m gemma4_26b_a4b/ # 交互式浏览张量 mistralrs uqff inspect -m mistralrs-community/gemma-4-26B-A4B-it --quant afq3

uqff reportuqff verifyuqff inspect均为仅元数据操作:对本地路径或已缓存的 Hugging Face 产物只做 seek-read 需要的字节区间;对远程 HF 仓库则使用 HTTP 字节区间请求(byte-range)读取 safetensors 头部与小体积 UQFF 元数据张量,不会下载完整模型权重

注意事项与边界

  • 推理专用:UQFF 不包含优化器状态或训练元数据,不可用于恢复训练;
  • 目录即分发单位residual.safetensorsconfig.json是加载的必要配套,单独的 shard 无法加载;
  • HQQ 的限制:HQQ UQFF 产物不支持分片加载(shard_alignment直接报错);
  • 堆叠专家限制:HQQ、FP8、F8Q8 格式不支持三阶堆叠专家权重的 gather,加载时会被拒绝;
  • 旧文件不兼容:pre-1.0 文件(无版本标签或旧式键名)必须用mistralrs quantize重新生成;
  • 存储扩张检查:reader 会校验各层驻留字节数不超过其稠密估计,否则提示使用等宽或更宽的模型 dtype 或显式设备映射(对应测试uqff_rejects_storage_expansion_that_a_pack_factor_cannot_represent)。

延伸阅读

  • UQFF 使用指南:生成与加载的完整命令手册;
  • 量化类型参考:AFQ、Q*K、FP8、NVFP4、MXFP4、HQQ 各家族与敏感张量精度策略;
  • 量化指南:格式选型与 imatrix 背景;
  • Topology 指南:逐层钉住量化类型;
  • 参考实现:mistralrs-quant/src/uqff(reader 与张量编码)、mistralrs-core/src/pipeline/isq.rs(writer);
  • 完整示例:Rust 示例 uqff 与 multimodal uqff。

【免费下载链接】mistral.rsFast, flexible LLM inference项目地址: https://gitcode.com/GitHub_Trending/mi/mistral.rs

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

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

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

立即咨询