起因很简单。我在 Ollama 上跑着 huihui_ai/qwen3.5-abliterated:0.8B 和 huihui_ai/lfm2.5-abliterated:latest 这两个模型,觉得挺有意思,就想着能不能把它们转成 HuggingFace 的 safetensors 格式。没别的,就是好奇,想看看这个转换到底能不能做到无损。
说实话,如果你只是想用模型,直接去 HuggingFace 下载原始模型肯定更靠谱。做这个工具纯粹是为了好玩,想拆解一下模型结构,看看 GGUF 里面到底装了什么东西,能不能原封不动地搬出来。
项目叫 FanFu,中文名凡赴。没什么深意,就是觉得这个名字读起来顺口。
先看看转换出来的效果
转换过程其实挺直观的。Ollama 下载的 GGUF 文件经过反量化和张量映射,变成 HuggingFace 格式的 safetensors。

Conversion Pipeline
我拿两个实际模型做了完整测试。qwen3.5-abliterated:0.8B 这个模型有 536 个 GGUF 张量,转完之后变成 572 个 HF 张量,多出来的 36 个是因为 fused QKV 被自动拆成了 Q、K、V 三个独立的投影矩阵。lfm2.5-abliterated:latest 则是 148 进 148 出,没有 QKV 拆分。

Tensor Count
实际跑一下看看
先拿 qwen3.5 试试水。在终端里直接问它 2+2 等于几:
$ ollama run huihui_ai/qwen3.5-abliterated:0.8B "What is 2+2?"
模型会先输出一段 thinking 过程,然后给出答案:
Thinking Process:
1. **Analyze the Request:** The user is asking a simple, basic question: "What is 2+2?"
2. **Identify the Mathematical Truth:** In mathematics, the sum of 2 and 2 is simply 4.
3. **Format the Output:** The answer should be direct and clear.
...done thinking.
2 + 2 = 4.
再试试让它写个阶乘函数:
$ ollama run huihui_ai/qwen3.5-abliterated:0.8B "Write a Python function to calculate factorial"
输出了一段完整的 Python 代码,包括错误处理和测试用例,质量还行。
换 lfm2.5 试试同样的问题:
$ ollama run huihui_ai/lfm2.5-abliterated:latest "What is the capital of France?"
Thinking...
The capital of France is **Paris**. Known for its rich history, cultural significance,
and iconic landmarks like the Eiffel Tower and Louvre Museum, Paris remains a global
hub for art, fashion, and cuisine.
让它写阶乘函数:
$ ollama run huihui_ai/lfm2.5-abliterated:latest "Write a Python function to calculate factorial"
def factorial(n):
result = 1
for i in range(1, n + 1):
result *= i
return result
两个模型在 Ollama 下跑起来都没什么问题。现在关键问题是,转成 HF 格式之后,权重是不是还一样。
权重对比结果
转换完成后,我逐张量对比了 GGUF 和 HF 的权重值。结果是这样的:

Test Results
所有能对比的张量,匹配率都是 100%。qwen3.5 的 536 个 GGUF 张量全部正确映射到了 572 个 HF 张量,lfm2.5 的 148 个张量也是一一对应。最大误差控制在 1e-3 以内,对于从量化格式反量化到 FP32 来说,这个精度已经很好了。
支持的量化类型覆盖了 GGUF 里常见的这些:

Quantization Types
F32、F16、BF16 这些标量类型直接读取就行,Q4_0、Q8_0 这些基础量化需要按 32 的 block size 反量化,Q4_K、Q5_K、Q6_K 这些 K-Quants 则是 256 的 block size,每种都有对应的反量化算法。
两个模型的架构差异
qwen3.5 和 lfm2.5 的内部结构差别挺大的。qwen3.5 是个混合架构,有标准的注意力层,也有 SSM/Mamba 层,还带了个 12 层的 Vision Tower 和 MTP 多层预测头。lfm2.5 则是比较纯粹的 Transformer 架构,但每个注意力层旁边还挂了 Shortconv 层。

Model Radar
qwen3.5 的词表有 248K,lfm2.5 是 65K。qwen3.5 的 GGUF 文件 1.0 GB,转成 FP32 的 safetensors 后膨胀到 3.3 GB。lfm2.5 的 GGUF 文件 731 MB,转完后 4.4 GB。体积变大是必然的,毕竟从量化格式恢复到了完整的 FP32 精度。
推理测试
除了权重对比,我还用 Ollama 对两个模型做了一组推理测试,覆盖数学、常识、代码生成、英文解释和中文理解:

Inference Test
两个模型在这些基础问题上表现都不错。qwen3.5 回答 2+2 的时候会先列个 thinking process 然后直接给出 "2 + 2 = 4",lfm2.5 则会多说几句 "The sum of 2 + 2 is 4"。代码生成方面,两个模型都能写出正确的阶乘函数。中文理解上,lfm2.5 对 "用一句话介绍北京" 的回答是 "Beijing, China's capital, embodies its rich history and cultural heritage.",虽然是用英文回的,但意思到了。
测试清单
整个项目写了 43 个测试,全部通过。
核心模块测试 23 个,覆盖了常量定义、异常处理、结果封装、张量映射、反量化往返测试、权重对比和命令行接口。转换验证测试 20 个,分别对 qwen3.5 和 lfm2.5 各做了 10 个测试,包括张量计数、张量映射覆盖率、Embedding/FFN/Attention 层权重验证、特殊结构验证(QKV 拆分、Vision Tower、MTP、SSM、Shortconv),以及最终的全权重匹配验证。
运行测试的命令很简单:
python -m pytest tests/ -v
输出大概是这样的:
tests/test_conversion_verification.py::TestQwen35Conversion::test_all_weights_match PASSED
tests/test_conversion_verification.py::TestLfm25Conversion::test_all_weights_match PASSED
...
================== 43 passed, 2 warnings in 71.29s ==================
怎么用
安装的话 pip install fanfu 就行。
pip install fanfu
转换命令:
fanfu gguf-to-hf model.gguf -o hf_model/
想指定输出精度可以加 -t 参数,f32、f16、bf16 都行。对比权重的话:
fanfu compare model.gguf hf_model/
Python API 也很直接:
from fanfu import convert_gguf_to_hf, compare_weights
result = convert_gguf_to_hf("model.gguf", "hf_model/")
print(f"Conversion: {result.success}")
最后
再说一遍,这个工具就是为了好玩。如果你需要微调模型,直接去 HuggingFace 下载原始模型肯定更省事。但如果你跟我一样,好奇 GGUF 里面到底装了什么,想看看量化后的权重能不能完整还原回来,那 FanFu 可以帮你做到这一点。
43 个测试全部通过,两个实际模型 100% 权重匹配,支持 11 种量化类型,处理了 QKV 拆分、Vision Tower、MTP、SSM、Shortconv 这些复杂结构。数据都在本地,不需要联网。
开源地址:https://github.com/CodeOfMe/FanFu
预览时标签不可点
Close
更多
Name cleared
微信扫一扫赞赏作者
Like the AuthorOther Amount
赞赏后展示我的头像
作品
暂无作品
Like the Author
Other Amount
¥
最低赞赏 ¥0
OK
Back
Other Amount
更多
赞赏金额
¥
最低赞赏 ¥0
1
2
3
4
5
6
7
8
9
0
.
大语言模型 · 目录
大语言模型
上一篇利用超强的小模型 OmniCoder-9B 试试 TurboQuant 量化 KV Cache: 2-bit 挑战 FP16下一篇JiXing(记行)-当 Agent 对话超出上下文限制,做了一个类似"虚拟机热迁移"草率方案
Close
更多
搜索「」网络结果
Close
调整当前正文文字大小
更多
100%