在像 Hugging Face 這樣的 AI 模型集線器中瀏覽時,我們發現以 .safetensors 為擴展名的文件越來越常見,取代了之前常見的 .bin.pth 文件。

這篇文章將從技術的角度詳細介紹 .safetensors 究竟是什麼,為什麼出現,及其相較於傳統方式所擁有的強大優勢。


1. .safetensors 是什麼?



.safetensorsHugging Face 開發的新 張量(Tensor) 存儲格式

深度學習模型由數十億個參數(權重)組成,其作用是將這些龐大的數據集存儲到文件中並進行加載。這是為了解決基於 Python 的 pickle 模組作為實質標準使用時的致命缺陷(安全性和速度)而創建的。

簡而言之,它是一個 “更安全、更快速的模型存儲文件”


2. 為何出現:傳統方式(Pickle)的問題

傳統的 PyTorch 模型(.bin, .pth)在內部使用 Python 的 pickle 模組來執行數據的序列化。然而,pickle 存在致命問題。

安全漏洞 (Arbitrary Code Execution)

pickle 並不僅僅是儲存數據,而是 儲存 Python 對象本身。在這一過程中,可以包含 Python 代碼,惡意黑客可以在模型文件內嵌入破壞系統或竊取個人信息的代碼。當用戶不慎執行 load() 時,該惡意代碼便會被執行。

問題場景示例:

用戶加載從互聯網下載的 model.bin -> 隱藏的代碼被執行 -> 用戶的 SSH 密鑰或密碼被傳送至黑客的伺服器。

.safetensors 應運而生,以根本上阻止此類安全威脅。


3. .safetensors 的核心特性



3.1. 安全性 (Safety)

.safetensors 顧名思義是 安全的。這種格式僅儲存純粹的張量數據和元數據(JSON 形式)。由於根本沒有可執行代碼的存儲空間,因此即使是從不可靠來源下載的文件也可以放心加載。

3.2. 零拷貝 (Zero-Copy) 與速度

在加載大型 LLM(大規模語言模型)或 Stable Diffusion 模型時,速度驚人地快。

  • 傳統方式: 將文件複製到 CPU 記憶體 -> 反序列化 (Unpickling) -> 再轉換為張量形式 -> 移動到 GPU。(出現不必要的複製過程)

  • safetensors: 採用 記憶映射 (Memory Mapping, mmap) 技術。操作系統直接將文件映射到內存地址,因此可以在不經不必要的複製過程下立即使用磁碟中的數據。這被稱為 Zero-Copy

3.3. 懶加載 (Lazy Loading)

不需要將整個模型完全加載到內存中,而是可以選擇性地快速讀取所需部分。

例如,想要檢查 100GB 模型文件中特定層的權重,傳統方法需要讀取 100GB,但 .safetensors 只需針對該部分進行精確加載。在分散學習環境或推斷優化時非常有利。

3.4. 框架相容性

不依賴於特定的深度學習框架(如 PyTorch 等)。

  • PyTorch

  • TensorFlow

  • JAX

  • PaddlePaddle

設計為可在各種框架中輕鬆讀取和寫入。


4. 文件結構

.safetensors 文件結構非常簡單。

  1. 葉頭 (Header): 位於文件的前面,遵循 JSON 格式。包含每個張量的名稱、數據類型 (dtype)、形狀(shape)和數據存儲位置 (offset) 的信息。

  2. 數據 (Data): 繼葉頭後面的一個二進制數據塊。純粹的張量值緊密填充其中。

由於這種結構,僅通過讀取葉頭,即使不讀取整個文件,也能了解模型的結構。

4-1. 實用提示:在終端檢查葉頭和元數據

想要確認下載的 .safetensors 文件是否是量化模型,或者包含哪些層,讀取數個GB的模型是低效的。

safetensors 庫提供了一個功能,可以在不讀取整個文件的情況下快速掃描葉頭信息。使用終端輸入以下 Python 一行命令(One-liner) 即可立即確認。

當然,您也可以在下載 Hugging Face 模型的頁面上,點擊右上角的 file info 確認信息。但是,在這裡我將說明如何在自己的終端直接確認。

前期準備

首先需要安裝該庫。

pip install safetensors

命令(終端輸入)

model.safetensors 位置填入實際的文件路徑。

python -c "from safetensors import safe_open; \
with safe_open('model.safetensors', framework='pt', device='cpu') as f: \
    print('--- Metadata ---'); \
    print(f.metadata()); \
    print('\n--- Tensor Keys (Layers) ---'); \
    print(list(f.keys())[:5])" # 因為數量太多只顯示前五個

輸出結果解釋

執行此命令將獲得兩個重要信息。

  1. Metadata: 模型創建者嵌入的信息。如果顯示 format: gptqquantization: int4 等信息,即使文件名中沒有寫明,也可以判定為量化模型。(不過如果創建者清空了元數據,則顯示 None)。

  2. Keys: 組成模型層的名稱。可以通過這些信息了解模型的結構。


5. 比較總結: .bin (Pickle) vs .safetensors

特徵 .bin / .pth (基於 Pickle) .safetensors
安全性 風險(可能執行惡意代碼) 安全(僅保存數據)
加載速度 緩慢(CPU 負荷) 非常快(Zero-Copy)
內存效率 需要全面加載 按需加載(Lazy Loading)
相容性 依賴於 Python/PyTorch 框架獨立

6. 使用範例(Python)

以下是使用 safetensors 庫來存儲和加載張量的簡單示例。

import torch
from safetensors.torch import save_file, load_file

# 1. 創建並保存張量
tensors = {
    "embedding": torch.zeros((1024, 512)),
    "attention": torch.rand((512, 512))
}

# 將字典形式的張量保存到文件
save_file(tensors, "model.safetensors")

# 2. 加載文件
loaded = load_file("model.safetensors")
print(loaded["embedding"].shape) 
# 輸出:torch.Size([1024, 512])

7. 結論

.safetensors 不僅僅是文件擴展名的變化,而是 AI 模型的 安全性效率 的必然進化。在 Hugging Face 等主要社區中,它已經成為基本格式。

未來下載或發佈模型時,建議盡量使用 .safetensors 而非 .bin。這將確保安全性,並顯著縮短模型加載時間。

象徵 safetensor 格式優勢的圖片