- 人工智能
- 大模型
- 推理引擎
- 本地部署
- 模型量化
- 模型优化
【免费下载链接】ik_llama.cpp
llama.cpp fork with additional SOTA quants and improved performance
导读
随着 DeepSeek、Qwen 等厂商开始直接发布 FP8(E4M3)格式的原生权重,推理引擎面临一个新问题:如何不经过 BF16/FP16 中间环节,直接读取并处理 FP8 原生模型。本文以 ik_llama.cpp 仓库中编号 454 的 PR(Add support for FP8 GGUF creation and re-quantization,WIP)为核心,复盘该 PR 的目标、实现思路(weight_scale_inv与 FP8_E4M3 量化方法)、关键设计讨论(FP8 矩阵乘法的两种实现路径),并结合当前仓库中的转换脚本与量化工具源码进行佐证。读完本文,你将理解 FP8 原生模型进入 GGUF 生态所需的技术拼图,以及该 PR 最终被关闭的原因与后续启示。
一、背景:FP8 原生模型与 E4M3 格式
FP8 是 8 位浮点格式,常见两种变体:
- E4M3:4 位指数 + 3 位尾数,精度较高,是权重存储的主流选择;
- E5M2:5 位指数 + 2 位尾数,动态范围更大,常用于激活值。
PR #454 的目标明确限定在E4M3:直接处理 FP8(E4M3)原生模型——先创建一个 FP8 GGUF,再进一步量化成可用于推理的 GGUF。PR 作者saood06明确指出,对 FP8 权重直接推理不在该 PR 范围内(类似于 #169 的做法)。
该 PR 最初用 Qwen/Qwen3-0.6B-FP8 这个微型模型验证:成功创建 GGUF 并能够 dump。作者选择该模型的理由是它「与 DeepSeek 使用相同的 scale 方式」且体积小。而 RedHatAI/Mistral-Nemo-Instruct-2407-FP8 这类模型对 scale 的处理方式不同,作者认为若要支持所有 FP8 原生模型,这一点必须在后续解决。
注:本 PR 为 WIP 草稿,创建于 2025-05-24,最终于 2025-06-15 因实现代码错误被作者主动关闭(Closed)。
二、PR 目标:一条「FP8 GGUF → 再量化」的管线
该 PR 提出的管线分两步:
- 创建 FP8 GGUF:把 HF 上以 FP8(E4M3)原生存储的权重直接打包为 GGUF,保留其 FP8 表示,而不是先反量化到 FP16/BF16 再存储;
- 再量化:把 FP8 GGUF 作为中间产物,量化为可供推理引擎直接加载的常规量化格式(如 Q8_0 或各 IQ 系量化)。
从当前仓库源码可以确认这条管线的可行性基础:
- convert_hf_to_gguf.py 中
LazyTorchTensor._dtype_str_map已经映射了"F8_E4M3": torch.float8_e4m3fn和"F8_E5M2": torch.float8_e5m2,说明转换脚本具备识别 safetensors 中 FP8 dtype 的能力; - examples/quantize/quantize.cpp 是仓库内完成「再量化」环节的成熟工具(
llama-quantize),其量化类型表中包含 Q8_0、Q6_0、MXFP4、IQ4_XS 等一系列目标格式。
也就是说,PR #454 所设想的「创建 FP8 GGUF + 再量化」两步,在仓库现有工具链中分别对应转换脚本(识别 FP8 输入)与量化工具(产出推理格式)两大环节。
三、实现细节:weight_scale_inv 与 FP8_E4M3
PR 目前只实现了第一步(FP8 GGUF 创建),涉及两个关键组成部分:
weight_scale_inv:FP8 原生模型(尤其 DeepSeek 系)通常为按块存储的逆缩放因子张量,用于把 FP8 整数位型还原为真实浮点值。该 PR 需要把这一张量一并纳入 GGUF 的张量集合并正确映射;- FP8_E4M3 量化方法:在 GGUF 类型体系中新增一个表示 FP8 E4M3 的量化类型入口。
作者在 PR 中特别说明:FP8_E4M3的枚举值暂时设为 999,因为作者不确定它应该插入到枚举的哪个位置。这一细节侧面反映了给 GGUF 新增一种存储类型的「命名与编号」成本。
作为参照,当前仓库中 GGUF/ggml 的类型体系可以印证这一点:
- gguf-py/gguf/constants.py 中的
GGMLQuantizationType枚举按编号管理(如F16 = 1、BF16 = 30); - ggml/include/ggml.h 中
ggml_type枚举同样按编号排列(GGML_TYPE_F16 = 1、GGML_TYPE_Q8_0 = 8、GGML_TYPE_BF16 = 30),并已扩展到 200+ 号段的 R 系列变体。
可见在枚举中插入新类型会影响 GGUF 文件头解析、块大小表(GGML_QUANT_SIZES)与量化工具的类型表等多处代码,这也是 PR 作者以 999 占位、等待上游确认槽位的原因。
四、关键设计讨论:FP8 矩阵乘法的两条实现路径
PR 讨论区中,项目作者 ikawrakow 在 2025-05-25 提出了 FP8 权重矩阵乘法实现的核心设计问题,这是整个讨论中最具技术价值的部分:
路径 A:先乘 scale 再做 FP8 乘加
在乘以 FP8 张量之前,需要先用 fp8 的 scale 去乘激活值。
即把weight_scale_inv从权重侧转移到激活侧,让 FP8 的块级缩放体现在激活上,之后直接做 FP8 位型之间的乘加。PR 作者表示这正是他打算采用的方案:「这是对我来说最有意义的做法,即便另一种方案可能更好」。
路径 B:直接转换为 Q8_0,把 scale 折进 Q8_0 的量
另一种选择是直接把 FP8 张量转换为 Q8_0,把 scale 折叠进 Q8_0 的量中。
Q8_0 在 ggml 中是 32 元素一块、带一个 fp16 scale 的经典量化类型(见 ggml/include/ggml.h 与 gguf-py/gguf/constants.py 中GGML_QUANT_SIZES对 Q8_0 的(32, 34)定义)。由于 FP8 E4M3 只有 3 位尾数,其数值集合有限,完全可以无损映射到 8 位整数再配以合适的 scale 表达,从而复用 ggml 中成熟的 Q8_0 内核,无需为 FP8 编写新的 CPU 内核。
作者最终仍然选择了路径 A(先乘 scale 再做 FP8 乘加),但该 PR 后续因实现代码本身存在错误而被关闭,两条路径的取舍最终未在该 PR 内收敛为可合并代码。
五、衍生讨论:FP4 与 IQ4 的等价性
PR 关闭前夕(2025-06-15),社区成员whatever1983带来了 NVIDIA 官方 FP4 版 DeepSeek-V3-0324 的消息,并据此提出「FP8 还没做完就已被 FP4 淘汰」的观点。ikawrakow 的回应澄清了一个关键技术事实:
FP4 转成其他 4 位表示(如 IQ4_K、IQ4_XS)是绝对无损的。只需要使用一张与 NVIDIA 的 16 个不同 fp4 值匹配的替代查找表,你就得到了 fp4 实现……4 位就是 4 位,可以直接使用,无需等待 Zen6 或 AMX-FP4,也无需 Chitu 内核,只需很小的改动即可工作。
这与仓库中 IQ4 系量化(如 examples/quantize/quantize.cpp 中的IQ4_XS、IQ4_NL、IQ4_KT等)的设计理念一致:IQ4 系列本身就基于 16 值查找表,恰好能容纳 FP4 的 16 个离散值,因此从 FP4 原生模型到 IQ4 是「表示级无损」的搬运,而不是有损再量化。
ikawrakow 还补充了两个观点:其一,从 FP4 模型出发做 2/3 位量化,质量可能高于从 FP8/BF16 出发的同类量化;其二,NVIDIA 该 FP4 模型约 420GB,更接近 5 bpw 而非 4 bpw,原因可能是部分张量不是 FP4,或采用了 block=8 + fp8 scale 的方案。这些讨论为后续 FP4/IQ4 工作提供了方向,但与 FP8 无关的细节此处不再展开。
六、PR 结局与复盘
2025-06-15,作者saood06主动关闭了该 PR,理由非常直白:
关闭它,因为尽管这个方案理论上可行,但我的实现是错的……这是一个代码有误的 PR,除了作为实现思路的参考外,几乎没有在其基础上继续开发的价值。
作者同时回应了对 NVIDIA FP4 量化「有推理增益」的猜测:基准数字存在误差区间与测试方法差异,且没有任何证据表明 NVIDIA 做了量化感知训练或量化后微调;DeepSeek 的约 425GB FP4 量化表现与未量化版本大致相当,并不算惊艳——仓库讨论区 #477 中展示的曲线在约 370GB 规模就已接近零损失。至于成本与功耗之争,作者也指出讨论已偏离 PR 本身的技术主题。
七、给后续实现者的启示
综合 PR 正文、讨论与当前仓库源码,可以提炼出几条可复用的结论:
- FP8 GGUF 创建是可行的第一步:转换脚本 convert_hf_to_gguf.py 已具备读取 F8_E4M3 dtype 的能力,
weight_scale_inv的映射是打通「FP8 原生权重 → FP8 GGUF」的关键; - FP8 推理矩阵乘法有两条清晰路线:先乘 scale 再 FP8 乘加,或折叠 scale 为 Q8_0 复用现有内核。后者实现成本更低,但前者更能保留 FP8 原生计算路径,为未来支持 FP8 硬件加速留出空间;
- GGUF 新增类型存在系统性成本:从类型枚举编号(参考 ggml/include/ggml.h 与 gguf-py/gguf/constants.py)到量化类型表(参考 examples/quantize/quantize.cpp 起的类型列表)都需同步扩展,枚举编号占位(如 999)只是临时手段;
- FP4 与 IQ4 表示级等价:FP4 的 16 个离散值可无损映射到 IQ4 查找表,这条路径为未来处理 FP4 原生模型提供了比 FP8 更直接的思路。
该 PR 虽已关闭,但其提出的「FP8 GGUF 创建 + 再量化」管线框架、weight_scale_inv处理思路以及关于 FP8/FP4 矩阵乘法的设计讨论,仍可作为在 ik_llama.cpp 中接入 FP8/FP4 原生模型的重要参考。
- 人工智能
- 大模型
- 推理引擎
- 本地部署
- 模型量化
- 模型优化
【免费下载链接】ik_llama.cpp
llama.cpp fork with additional SOTA quants and improved performance
相关推荐
【亲测免费】 ComfyUI-GGUF:为原生ComfyUI模型提供GGUF量化支持
ComfyUI GGUF:为原生ComfyUI模型提供GGUF量化支持 项目介绍 ComfyUI GGUF 是一个开源项目,旨在为原生的 ComfyUI 模型提
人工智能模型量化本地部署1Panel 文件管理完整指南:不碰 SSH 也能管好服务器文件
1Panel 文件管理完整指南:不碰 SSH 也能管好服务器文件 半夜要往生产机丢一个配置补丁,你还得先开 SSH、翻路径、敲一串 cp 和 scp 。1Pan
人工智能大模型推理引擎本地部署模型量化模型优化ik_llama.cpp 对 Microsoft BitNet I2_S 模型的重新量化支持:把三元 GGUF 重铸为 IQ2_BN
ik_llama.cpp 对 Microsoft BitNet I2_S 模型的重新量化支持:把三元 GGUF 重铸为 IQ2_BN 导读 本篇技术指南围绕 i
人工智能大模型推理引擎本地部署模型量化模型优化
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考