Hugging FaceのようなAIモデルハブを巡っていると、過去によく見られた `.bin` や `.pth` ファイルの代わりに `.safetensors` という拡張子のファイルが徐々に増えてきました。 この投稿では `.safetensors` が一体何であるのか、なぜ登場したのか、そして従来の方式と比べてどのように強力な利点があるのかを技術的な観点から詳細に見ていきます。 --- 1. .safetensorsとは何か? -------------------- `.safetensors` は **Hugging Face** が開発した新しい **テンソル(Tensor)保存フォーマット** です。 ディープラーニングモデルは数十億のパラメータ(重み、Weights)で構成されており、これらの巨大な数字の塊をファイルとして保存し読み込む役割を果たします。従来事実上の標準として使用されていたPythonの `pickle` モジュールに基づく保存方式の致命的な欠点(セキュリティと速度)を解決するために作られました。 簡単に言えば、 **「より安全で、より速いモデル保存ファイル」** です。 --- 2. なぜ登場したのか:従来の方式(Pickle)の問題点 ----------------------------- 従来のPyTorchモデル(`.bin`, `.pth`)は内部的にPythonの `pickle` モジュールを使用してデータをシリアライズ(Serialization)します。しかし、 `pickle` には致命的な問題があります。 ### セキュリティの脆弱性(Arbitrary Code Execution) {#sec-52e6e86f3007} `pickle` は単にデータを保存するのではなく、 **Pythonオブジェクトそのものを保存** します。この過程でPythonコードを含む可能性があり、悪意のあるハッカーがモデルファイルの内部にシステムを破壊するコードや個人情報を盗むコードを埋め込むことができます。ユーザーが無意識にモデルを `load()` する瞬間に、その悪性コードが実行されます。 > 問題事例の例: > > ユーザーがインターネットからダウンロードした model.bin をロードする -> ファイル内部に隠されたコードが実行される -> ユーザーのSSHキーやパスワードがハッカーのサーバーに送信される。 `.safetensors` はこのようなセキュリティの脅威を根本から阻止するために登場しました。 --- 3. .safetensorsの核心的特徴 --------------------- ### 3.1. 安全性(Safety) {#sec-5d3bc26a9b1f} `.safetensors` はその名の通り **安全** です。このフォーマットは純粋なテンソルデータとメタデータ(JSON形式)のみを保存します。実行可能なコードが含まれる余地が全くないため、信用できないソースからダウンロードしたファイルでも安心してロードできます。 ### 3.2. ゼロコピー(Zero-Copy)および速度 {#sec-665884a096f6} 大容量LLM(大規模言語モデル)やStable Diffusionモデルを読み込む際の速度が劇的に向上します。 * **従来方式:** ファイルをCPUメモリにコピー -> 逆シリアライズ(Unpickling) -> 再びテンソル形式に変換 -> GPUに移動。(不必要なコピー処理が発生) * **safetensors:** **メモリマッピング(Memory Mapping, mmap)** 技術を活用します。オペレーティングシステムがファイル自体をメモリアドレスに直接マッピングするため、不必要なコピー処理なしにディスクからデータを即座に使用できます。これを **ゼロコピー(Zero-Copy)** と呼びます。 ### 3.3. レイジーローディング(Lazy Loading) {#sec-19defdea1e5d} 全モデルをメモリに完全に読み込まず、必要な部分だけを選択的に迅速に読み込むことができます。 例えば、100GBのモデルファイルから特定のレイヤーの重みだけを確認したい場合、従来方式では100GB全体を読む必要がありましたが、.safetensorsを使用すればその部分だけを抜き出して読むことができます。分散学習環境や推論最適化時に非常に有利です。 ### 3.4. フレームワーク互換性 {#sec-a54b3c99bea9} 特定のディープラーニングフレームワーク(PyTorchなど)に依存しません。 * PyTorch * TensorFlow * JAX * PaddlePaddle このような多様なフレームワークで簡単に読み書きできるように設計されています。 --- 4. ファイル構造 --------- `.safetensors` ファイルは非常にシンプルな構造を持っています。 1. **ヘッダー(Header):** ファイルの前部分に位置し、JSON形式に従います。各テンソルの名前、データタイプ(dtype)、形状(shape)、およびデータが保存されている位置(offset)情報を含みます。 2. **データ(Data):** ヘッダーの後に続くバイナリデータの塊です。純粋なテンソル値でぎっしり詰まっています。 このような構造のおかげでファイルをすべて読み込むことなく、ヘッダーだけを読むことでモデルの構造を把握することも可能です。 ### 4-1. 実践的なヒント:ターミナルでヘッダーおよびメタデータを確認する {#sec-12144d701b4b} ダウンロードした `.safetensors` ファイルが量子化モデルか、またはどのレイヤーが含まれているかを確認するために数GBを超えるモデルをすべてロードするのは非効率的です。 `safetensors` ライブラリは全ファイルを読み込むことなく、ヘッダー情報だけを迅速にスキャンできる機能を提供します。ターミナルで次のような **Python One-liner(一行コマンド)** を入力すると、即座に確認できます。 もちろん、Hugging Faceのモデルをダウンロードしたページに行き、右上のfile infoをクリックすれば確認することもできます。しかし、ここでは私のターミナルで直接確認する方法を説明します。 #### 事前準備 最初にライブラリがインストールされている必要があります。 ``` pip install safetensors ``` #### コマンド(ターミナル入力) `model.safetensors` の部分に実際のファイルパスを入力してください。 ```bash 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])" # あまりにも長いので上位5個のみ出力 ``` #### 出力結果の解釈 このコマンドを実行すると二つの重要な情報が得られます。 1. **Metadata:** モデル制作者が埋め込んだ情報です。ここに `format: gptq` や `quantization: int4` などの情報が書かれている場合、ファイル名に書いてなくても量子化モデルであることがわかります。(ただし、制作者がメタデータを空にしている場合は `None` と表示されることがあります。) 2. **Keys:** モデルを構成するレイヤーの名前です。これによりモデルの構造を把握することができます。 --- 5. 比較要約: .bin (Pickle) vs .safetensors -------------------------------------- | **特徴** | **.bin / .pth (Pickleベース)** | **.safetensors** | | --- | --- | --- | | **セキュリティ** | **危険** (悪性コードの実行可能) | **安全** (データのみ保存) | | **ロード速度** | 遅い (CPU負荷発生) | **非常に速い** (ゼロコピー) | | **メモリ効率** | 全体ロード必要 | 必要な分だけロード(レイジーローディング) | | **互換性** | Python/PyTorch依存的 | フレームワーク非依存的 | --- 6. 使用例(Python) -------------- `safetensors` ライブラリを使用してテンソルを保存し読み込む簡単な例です。 ```python 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をはじめとする主要なコミュニティではすでに基本フォーマットとして定着しています。 今後モデルをダウンロードまたは配布する際には、できる限り `.bin` の代わりに `.safetensors` を使用することをお勧めします。セキュリティの脅威から安全で、モデルの読み込み時間も劇的に短縮されるでしょう。 ![safetensorフォーマットの利点を象徴する画像](/media/whitedec/blog_img/safetensor-format-image.webp "safetensorフォーマットの利点を象徴する画像")