常见人工智能模型格式

📻 🎙️ 这是关于这篇博文的 AI 播客,欢迎收听!
此播客通过 ngxson/kokoro-podcast-generator 生成,使用了 DeepSeek-R1 和 Kokoro-TTS。
在过去的两年里,开源 AI 社区对新 AI 模型的开发充满热情。每天都有越来越多的模型在 Hugging Face 上发布,其中许多模型已用于生产应用。然而,开发者在使用这些模型时遇到的一个挑战是它们所采用的各种格式。
在本文中,我们将探讨当前常用的一些 AI 模型格式,包括 GGUF、PyTorch、Safetensors 和 ONNX。我们将讨论每种格式的优缺点,并提供何时使用它们的指导。
GGUF
GGUF 最初是为 llama.cpp 项目开发的。GGUF 是一种二进制格式,旨在实现快速模型加载和保存,并易于阅读。模型通常使用 PyTorch 或其他框架开发,然后转换为 GGUF 以与 GGML 配合使用。
随着时间的推移,GGUF 已成为开源社区中共享 AI 模型最流行的格式之一。它受到众多知名推理运行时的支持,包括 llama.cpp、ollama 和 vLLM。
目前,GGUF 主要用于语言模型。虽然也可以将其用于其他类型的模型,例如通过 stable-diffusion.cpp 实现的扩散模型,但它不如其在语言模型中的应用常见。
GGUF 文件包括:
- 一个以键值对形式组织的元数据部分。此部分包含模型的架构、版本和超参数等信息。
- 一个用于张量元数据的部分。此部分包含模型中张量的详细信息,例如它们的形状、数据类型和名称。
- 最后,是包含张量数据本身的部分。
图片来自 @mishig25 (GGUF v3)
GGUF 格式和 GGML 库还提供灵活的**量化方案**,可实现高效的模型存储,同时保持良好的准确性。一些最常见的量化方案有:
Q4_K_M
:大多数张量被量化为 4 位,部分量化为 6 位。这是最常用的量化方案。IQ4_XS
:几乎所有张量都量化为 4 位,但借助**重要性矩阵**。此矩阵用于校准每个张量的量化,可能会在保持存储效率的同时提高准确性。IQ2_M
:与IQ4_XS
类似,但采用 2 位量化。这是最具侵略性的量化方案,但仍能在某些模型上达到良好精度。适用于内存非常有限的硬件。Q8_0
:所有张量均量化为 8 位。这是侵略性最低的量化方案,精度几乎与原始模型相同。
Llama-3.1 8B 模型 GGUF 格式示例,链接在此
让我们回顾一下 GGUF 的优缺点:
- 优点:
- 简单:单文件格式易于共享和分发。
- 快速:通过与
mmap()
的兼容性实现模型的快速加载和保存。 - 高效:提供灵活的量化方案。
- 可移植:作为二进制格式,无需特定库即可轻松读取。
- 缺点:
- 大多数模型需要从其他格式(PyTorch、Safetensors)转换为 GGUF。
- 并非所有模型都可转换。有些模型不受 llama.cpp 支持。
- 模型保存为 GGUF 后,修改或微调模型并不容易。
GGUF 主要用于在生产环境中**提供模型服务**,在这些环境中快速加载时间至关重要。它也用于在开源社区中**共享模型**,因为这种格式的简单性便于分发。
有用的资源
- llama.cpp 项目,提供将 HF 模型转换为 GGUF 的脚本。
- HF 上的 gguf-my-repo 空间允许将模型转换为 GGUF 格式,无需本地下载。
- ollama 和 HF-ollama 集成允许通过
ollama run
命令从 HF Hub 运行任何 GGUF 模型。
PyTorch (.pt/.pth)
.pt/.pth 扩展名代表 PyTorch 的默认序列化格式,用于存储包含学习参数(权重、偏差)、优化器状态和训练元数据的模型状态字典。
PyTorch 模型可以保存为两种格式:
- .pt:这种格式保存整个模型,包括其架构和学习参数。
- .pth:这种格式只保存模型的状态字典,其中包含模型的学习参数和一些元数据。
PyTorch 格式基于 Python 的 pickle 模块,该模块用于序列化 Python 对象。为了理解 pickle
的工作原理,让我们看下面的例子:
import pickle
model_state_dict = { "layer1": "hello", "layer2": "world" }
pickle.dump(model_state_dict, open("model.pkl", "wb"))
pickle.dump()
函数序列化 model_state_dict
字典并将其保存到名为 model.pkl
的文件中。输出文件现在包含字典的二进制表示:
要将序列化后的字典加载回 Python,我们可以使用 pickle.load()
函数:
import pickle
model_state_dict = pickle.load(open("model.pkl", "rb"))
print(model_state_dict)
# Output: {'layer1': 'hello', 'layer2': 'world'}
正如您所见,pickle
模块提供了一种简便的 Python 对象序列化方法。然而,它也存在一些局限性:
- 安全性:任何东西都可以被 pickle,**包括恶意代码**。如果序列化数据未经验证,这可能导致安全漏洞。例如,Snyk 的这篇文章解释了如何对 pickle 文件进行后门攻击。
- 效率:它并非为延迟加载或部分数据加载而设计。这可能导致处理大型模型时加载缓慢和内存使用率高。
- 可移植性:它特定于 Python,这使得与其他语言共享模型变得困难。
如果您只在 Python 和 PyTorch 环境中工作,PyTorch 格式可能是一个合适的选择。然而,近年来,AI 社区已转向更高效和安全的序列化格式,例如 GGUF 和 Safetensors。
有用的资源
- PyTorch 文档关于保存和加载模型。
- executorch 项目提供了一种将 PyTorch 模型转换为
.pte
的方法,该格式可在移动和边缘设备上运行。
Safetensors
由 Hugging Face 开发的 safetensors 解决了传统 Python 序列化方法(如 PyTorch 使用的 pickle
)中存在的安全和效率限制。该格式使用受限的反序列化过程来防止代码执行漏洞。
一个 safetensors 文件包含:
- 一个以 JSON 格式保存的元数据部分。此部分包含模型中所有张量的信息,例如它们的形状、数据类型和名称。它还可以选择包含自定义元数据。
- 一个用于张量数据的部分。
Safetensors 格式结构图
- 优点:
- 安全:Safetensors 采用受限的反序列化过程,以防止代码执行漏洞。
- 快速:它专为延迟加载和部分数据加载而设计,可以缩短加载时间并降低内存使用量。这类似于 GGUF,您可以在其中
mmap()
文件。 - 高效:支持量化张量。
- 可移植:它旨在跨不同编程语言移植,从而便于与其他语言共享模型。
- 缺点:
- 量化方案不如 GGUF 灵活。这主要是由于 PyTorch 提供的量化支持。
- 需要一个 JSON 解析器来读取元数据部分。当使用 C++ 等没有内置 JSON 支持的低级语言时,这可能会出现问题。
注:虽然理论上元数据可以保存在文件中,但实际上,模型元数据通常存储在单独的 JSON 文件中。这既有利也有弊,具体取决于用例。
Safetensors 格式是 Hugging Face 的 transformers 库使用的默认序列化格式。它在开源社区中广泛用于**共享、训练、微调和提供 AI 模型服务**。Hugging Face 上发布的新模型都以 safetensors 格式存储,包括 Llama、Gemma、Phi、Stable-Diffusion、Flux 等等。
有用的资源
- transformers 库关于保存和加载模型的文档。
- bitsandbytes 指南,介绍了如何量化模型并将其保存为 safetensors 格式。
- HF 上的 mlx-community 组织提供与 MLX 框架(Apple Silicon)兼容的模型。
ONNX
开放神经网络交换(ONNX)格式提供了机器学习模型的供应商中立表示。它是 ONNX 生态系统的一部分,该生态系统包括用于 PyTorch、TensorFlow 和 MXNet 等不同框架之间互操作性的工具和库。
ONNX 模型以 .onnx
扩展名保存为单个文件。与 GGUF 或 Safetensors 不同,ONNX 不仅包含模型的张量和元数据,还包含模型的**计算图**。
将计算图包含在模型文件中,使得处理模型时具有更大的灵活性。例如,当发布新模型时,您可以轻松地将其转换为 ONNX 格式,而无需担心模型的架构或推理代码,因为计算图已保存在文件中。
ONNX 格式计算图示例,由 Netron 生成
- 优点:
- 灵活性:模型文件中包含计算图,在不同框架之间转换模型时提供更大的灵活性。
- 可移植性:得益于 ONNX 生态系统,ONNX 格式可以轻松部署到各种平台和设备,包括移动设备和边缘设备。
- 缺点:
- 对量化张量的支持有限。ONNX 不原生支持量化张量,而是将其分解为整数张量和比例因子张量。这可能导致处理量化模型时质量下降。
- 复杂的架构可能需要运算符回退或自定义实现来处理不受支持的层。这可能会导致将模型转换为 ONNX 格式时性能下降。
总的来说,如果您正在使用移动设备或进行浏览器内推理,ONNX 是一个不错的选择。
有用的资源
- Hugging Face 上的 onnx-community 组织,提供 ONNX 格式模型以及转换指南。
- transformer.js 项目,允许在浏览器中使用 WebGPU 或 WebAssembly 运行 ONNX 模型。
- onnxruntime 项目提供了一个在各种平台和硬件上运行的高性能推理引擎。
- netron 项目,允许在浏览器中可视化 ONNX 模型。
硬件支持
选择模型格式时,考虑模型将部署的硬件至关重要。下表显示了每种格式的硬件支持建议:
硬件 | GGUF | PyTorch | Safetensors | ONNX |
---|---|---|---|---|
CPU | ✅ (最佳) | 🟡 | 🟡 | ✅ |
GPU | ✅ | ✅ | ✅ | ✅ |
移动部署 | ✅ | 🟡 (通过 executorch) | ❌ | ✅ |
Apple 芯片 | ✅ | 🟡 | ✅ (通过 MLX 框架) | ✅ |
说明
- ✅:完全支持
- 🟡:部分支持或性能较低
- ❌:不支持
结论
在本文中,我们探讨了目前常用的一些 AI 模型格式,包括 GGUF、PyTorch、Safetensors 和 ONNX。每种格式都有其自身的优缺点,因此根据您的具体用例和硬件要求选择正确的格式至关重要。
脚注
mmap:内存映射文件是一种操作系统功能,允许将文件映射到内存中。这对于读取和写入大型文件非常有利,而无需将整个文件加载到内存中。
延迟加载:延迟加载是一种技术,它将数据的加载推迟到实际需要时才进行。这有助于减少内存使用量并提高处理大型模型时的性能。
计算图:在机器学习的上下文中,计算图是一种流程图,它说明了数据如何流经模型以及如何在每个步骤执行不同的计算(例如加法、乘法或激活函数应用)。