
モデルファイル形式の基本
.safetensors、.bin、.gguf、.onnx…。拡張子の違いは「何をどう詰めた箱か」の違いです。安全性と、どのソフトで動かすかで選び方が決まります。
このページの内容(9項目)
モデルを「読み込んだだけ」で、パソコンが乗っ取られることがある。本当です。
昔ながらのPyTorchのモデルファイル(.bin や .pt)は、Pythonの pickle という仕組みで保存されています。pickleは便利な反面、読み込むときに任意のプログラムを実行できてしまいます。つまり、悪意のある人が作った「モデルファイル」は、開いた瞬間にウイルスとして動きうるのです。
いまHugging Faceで .safetensors ばかり見かけるのは、この問題への答えです。この章では、モデルファイルの主な形式を「箱の中身」と「安全性」と「使う場所」で整理します。
形式が違うと、何が違うのか
ひとことで言うと
モデルファイル形式とは「重み(数値の山)を、どんな構造でディスクに詰めるか」の約束ごと。中身の数値が同じでも、箱が違えば読めるソフトや安全性、読み込みの速さが変わります。
第2章で見たように、モデルは「重み・設定・トークナイザ」の3点セットです。形式によって、このうちどこまでを1つのファイルに入れるかが違います。
| 形式 | 中身 | 主な使い道 |
|---|---|---|
| safetensors | 重みだけ(設定・トークナイザは別ファイル) | Hugging Faceの標準。transformers、vLLMなど |
| PyTorch(.bin / .pt / .pth) | pickleで保存したPythonオブジェクト | 古いモデル、学習途中のチェックポイント |
| GGUF(.gguf) | 重み+設定+トークナイザを1ファイルに | llama.cpp、Ollama、LM Studioなど |
| ONNX(.onnx) | 計算グラフ+重み | ONNX Runtime、ブラウザ(Transformers.js)など |
| MLX | safetensors+設定(MLX向けの並びと量子化) | Apple シリコンのMac(mlx-lm) |
引っ越しの荷物にたとえると、safetensorsは「中身の一覧表が貼られた、規格どおりの段ボール」。pickleは「中身と一緒に『開けた人はこの手順で組み立てて』という指示書が入った箱」で、その指示書に何が書いてあるかは開けるまで分かりません。GGUFは「家具と説明書と工具が全部ひと箱に入ったセット」です。
pickle形式(.bin / .pt):便利だけど危ない
PyTorchの torch.save() は、テンソルやPythonのオブジェクトをpickleで保存します。Hugging Faceの古いモデルにある pytorch_model.bin がその代表です。pickleはデータそのものではなく「オブジェクトを組み立てる命令の列」なので、その命令に「このコマンドを実行せよ」を紛れ込ませることができます。
対策も進んでいます。PyTorch 2.6からは torch.load() の既定が weights_only=True になり、テンソルや基本的な型以外は読み込まないよう制限されました。Hugging Face Hubもアップロードされたpickleファイルをスキャンしています。それでも「知らない人のpickleは開かない」のが基本です。
注意
エラーを消すために weights_only=False を付ける手順をネットで見かけることがあります。これは制限を外す操作なので、信頼できる出どころのファイルにだけ使ってください。また、拡張子が .bin でも中身がpickleとは限りません(例: openai/gpt-oss-20b の metal/model.bin は、Apple シリコン用のMetal参照実装向けに変換した重み)。拡張子より、配布元の説明を見ましょう。
safetensors:いまの標準
safetensors はHugging Faceが作った、重みを保存するためだけのシンプルな形式です。中身はたった3つの部分でできています。
flowchart TD A["先頭 8バイト
ヘッダーの長さ N"] --> B["N バイトの JSON ヘッダー
テンソル名・型・形・位置"] B --> C["残り全部
テンソルの生データ"]
実際に Qwen/Qwen3.5-0.8B のファイルの先頭だけを読んでみると、ヘッダーは約60KBで、こんな項目が並んでいます(1項目だけ抜粋)。
{
"model.language_model.embed_tokens.weight": {
"dtype": "BF16",
"shape": [248320, 1024],
"data_offsets": [10368, 508569728]
},
...
}
語彙248,320 × 幅1,024 × 2バイト = 508,559,360バイト。data_offsets の差とぴったり一致します。
「どのテンソルが、どの型で、どの形で、データ部分の何バイト目から何バイト目にあるか」が書いてあるだけです。コードを実行する余地がないので安全で、さらに次のような利点があります。
- 部分読み込み(lazy loading)— ヘッダーを見れば位置が分かるので、必要なテンソルだけを読める。複数GPUに分けて載せるときに便利。
- 速い読み込み — データ部分をそのままメモリに対応づけられる(mmap)。CPUではほぼコピーなしで読める場合もある。
- BF16やFP8などの型を素直に扱える。
safetensorsは2026年4月にHugging FaceからPyTorch Foundation(Linux Foundation傘下)に移管され、特定企業に依存しない標準として運営されることになりました。transformers v5では保存形式がsafetensorsに一本化され、pickleで保存するオプションは削除されています2026年10月時点。
もう一歩深く
safetensorsには重みしか入らないので、設定(config.json)やトークナイザ(tokenizer.json)は別ファイルになります。だからHugging Faceのモデルは「フォルダ単位」でダウンロードするのが基本です。量子化済みのモデル(GPTQ、AWQ、FP8など)もsafetensorsで配布されることが多く、その場合は量子化の方式が config.json に書かれています。
分割ファイル(シャーディング)の読み方
大きなモデルは、重みが複数のファイルに分けて配布されます。これをシャーディング(sharding)と呼びます。ファイル名はこんな形です。
model-00001-of-00004.safetensors
model-00002-of-00004.safetensors
model-00003-of-00004.safetensors
model-00004-of-00004.safetensors
model.safetensors.index.json ← どのテンソルがどのファイルにあるかの目次
「00002-of-00004」は「4分割のうち2番目」という意味です。全部そろわないと読み込めないので、ダウンロードはフォルダごと行いましょう。index.json の中身は「テンソル名 → ファイル名」の対応表です。
分割の大きさの既定は、transformers v5で5GBから50GBに引き上げられました。HubのストレージがXetになり、大きなファイルを効率よく配れるようになったためです。そのため、最近のモデルはファイル数が少なめです。たとえば Qwen/Qwen3.5-0.8B は約1.75GBの1ファイル(…-00001-of-00001.safetensors)になっています2026年10月時点。
GGUF:ローカル実行のための「全部入り」
GGUF は、llama.cppとその土台のggmlのために作られた形式です。重みに加えて、アーキテクチャの設定、トークナイザの語彙、チャットテンプレートまでを1つのファイルに入れられます。量子化された重みを入れることが多く、ローカルでLLMを動かすツールの多く(llama.cpp、Ollama、LM Studioなど)が使っています。
Hugging Faceでは、リポジトリ名の末尾が -GGUF になっているものが目印です。Qwen3.5-0.8B-Q4_0.gguf のように、ファイル名に量子化の種類が入ります。構造や量子化の種類は第5章でじっくり扱います。
ONNX と MLX
ONNX
ONNX(Open Neural Network Exchange)は、重みだけでなく「どんな順番で何の計算をするか」という計算グラフも一緒に保存する形式です。グラフが入っているので、PyTorchがない環境でも、ONNX Runtimeなどの実行エンジンがあれば動きます。WindowsやスマートフォンやWebブラウザなど、さまざまな場所で動かしたいときに使われます。
ONNXファイルの本体はProtocol Buffersという形式で、2GBを超える大きなモデルは重みを外部ファイルに分けて保存します。たとえば onnx-community/Qwen3.5-0.8B-ONNX には、decoder_model_merged.onnx と decoder_model_merged.onnx_data の組が、FP16版・4bit版などいくつも並んでいます。このリポジトリはブラウザで動く Transformers.js でも使えます。LLM向けには、生成のループやKVキャッシュの管理まで面倒を見る ONNX Runtime GenAI もあります。
MLX
MLXは、AppleがApple シリコン向けに作った機械学習フレームワークです。LLM用の mlx-lm で使うモデルは、Hugging Faceの mlx-community などで配布されています。中身を見ると、実はsafetensorsと config.json の組み合わせです。たとえば mlx-community/Qwen3.5-0.8B-4bit の config.json には、4bit・グループサイズ64という量子化の設定が書かれています。
# Hugging Face のモデルを MLX 形式に変換し、4bit 量子化する
mlx_lm.convert --model Qwen/Qwen3.5-0.8B -q
つまり「MLX形式」は箱の規格というより、「MLXで読める並びと量子化にしたsafetensors」と考えると分かりやすいです。なおMLX自体はGGUFの読み書きにも対応しています。
どれを選べばいい?
形式選びは「どのソフトで動かすか」でほぼ決まります。
- GPUサーバーやPython(transformers、vLLMなど)→ safetensors
- 手元のPC(llama.cpp、Ollama、LM Studioなど)→ GGUF
- MacでMLX(mlx-lm)→ MLX用のsafetensors
- ブラウザやWindowsアプリ(Transformers.js、ONNX Runtime)→ ONNX
どの形式を選ぶにしても、pickle形式は信頼できる出どころのものだけにしましょう。同じモデルにsafetensors版があるなら、そちらを選ぶのが基本です。実行エンジンの違いは第6章以降で扱います。
よくある誤解
形式を変換すると、モデルの性能が変わる
形式の変換そのものは数値の詰め直しなので、性能は変わらない。変わるのは、変換と同時に量子化(ビット数を減らす)をしたとき
safetensorsは「量子化していない」形式だ
safetensorsはただの箱。FP8やGPTQ・AWQなど量子化済みの重みも入れられる
.bin ファイルはすべて危険なpickleだ
.bin は「バイナリ」という意味の汎用の拡張子。中身は配布元によって違う。ただし Hugging Face の pytorch_model.bin はpickle
確認クイズ
Q2. model-00003-of-00008.safetensors は何を意味する?
重みが8つに分割されているうちの3番目のファイルです。全部と model.safetensors.index.json がそろって初めて読み込めます。
Q3. 重み・設定・トークナイザを1つのファイルにまとめられる形式は?
GGUFです。safetensorsは重みだけなので、設定やトークナイザは別ファイルになります。
この章のまとめ
- 形式は「重みをどう詰めるか」の約束ごと。中身が同じでも、読めるソフトと安全性が違う。
- pickle形式(.bin/.pt)は読み込み時にコードを実行しうる。知らない出どころのものは開かない。
- safetensorsは「長さ+JSONヘッダー+生データ」だけの安全な標準。設定とトークナイザは別ファイル。
- 大きなモデルは分割され、index.json が目次になる。transformers v5 の既定の分割サイズは50GB。
- ローカルはGGUF、MacのMLXはMLX用safetensors、ブラウザやWindowsアプリはONNX。
さらに深く学ぶ
この章の内容をもう一歩掘り下げるための原典です。
出典・参考
- huggingface/safetensors(GitHub) — ファイル構造、他形式との比較(2026年10月確認)
- PyTorch Foundation Announces Safetensors…(PyTorch Blog, 2026年4月8日)
- Serialization semantics(PyTorch 2.6 ドキュメント) と BC-breaking change: torch.load weights_only=True(PyTorch dev-discuss)
- Pickle Scanning(Hub ドキュメント) — pickleの危険性とHubのスキャン
- Transformers v5 Migration Guide(GitHub) — safe_serialization=False の廃止、既定の分割サイズ50GB(2026年10月確認)
- GGUF 仕様(ggml-org/ggml docs/gguf.md)
- External Data(ONNX ドキュメント) — 2GBを超えるモデルの外部データ
- microsoft/onnxruntime-genai(GitHub)(2026年10月確認)
- ml-explore/mlx-lm(GitHub) と MLX: Saving and Loading Arrays — 変換コマンド、対応形式(2026年10月確認)
- Hugging Face 上の実例: Qwen/Qwen3.5-0.8B(safetensorsヘッダーはHTTPの範囲指定で先頭を取得して確認)、mlx-community/Qwen3.5-0.8B-4bit、onnx-community/Qwen3.5-0.8B-ONNX、openai/gpt-oss-20b(ファイル構成、2026年10月確認)
- openai/gpt-oss(GitHub) — Metal参照実装と metal/ 以下の変換済み重み