第4部 モデル形式と保存形式第4章

モデルファイル形式の基本

.safetensors、.bin、.gguf、.onnx…。拡張子の違いは「何をどう詰めた箱か」の違いです。安全性と、どのソフトで動かすかで選び方が決まります。

約14分で読めます2026年10月改訂

このページの内容(9項目)
  1. 形式が違うと、何が違うのか
  2. pickle形式(.bin / .pt):便利だけど危ない
  3. safetensors:いまの標準
  4. 分割ファイル(シャーディング)の読み方
  5. GGUF:ローカル実行のための「全部入り」
  6. ONNX と MLX
  7. どれを選べばいい?
  8. さらに深く学ぶ
  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)など
MLXsafetensors+設定(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["残り全部
テンソルの生データ"]
図: safetensors ファイルの構造

実際に 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

確認クイズ

Q1. safetensors が pickle より安全なのはなぜ?

  • 暗号化されているから
  • JSONのヘッダーと生データだけで、読み込み時にコードを実行する仕組みがないから
  • ファイルサイズが小さいから

safetensorsは「テンソルの名前・型・形・位置」の一覧と数値データだけでできています。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。

さらに深く学ぶ

この章の内容をもう一歩掘り下げるための原典です。

第4章の論文・資料をすべて見る →

出典・参考

  1. huggingface/safetensors(GitHub) — ファイル構造、他形式との比較(2026年10月確認)
  2. PyTorch Foundation Announces Safetensors…(PyTorch Blog, 2026年4月8日)
  3. Serialization semantics(PyTorch 2.6 ドキュメント) と BC-breaking change: torch.load weights_only=True(PyTorch dev-discuss)
  4. Pickle Scanning(Hub ドキュメント) — pickleの危険性とHubのスキャン
  5. Transformers v5 Migration Guide(GitHub) — safe_serialization=False の廃止、既定の分割サイズ50GB(2026年10月確認)
  6. GGUF 仕様(ggml-org/ggml docs/gguf.md)
  7. External Data(ONNX ドキュメント) — 2GBを超えるモデルの外部データ
  8. microsoft/onnxruntime-genai(GitHub)(2026年10月確認)
  9. ml-explore/mlx-lm(GitHub) と MLX: Saving and Loading Arrays — 変換コマンド、対応形式(2026年10月確認)
  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月確認)
  11. openai/gpt-oss(GitHub) — Metal参照実装と metal/ 以下の変換済み重み