Hub documentation
Hub ローカルキャッシュ
Hub ローカルキャッシュ
このドキュメントは、HF Hub のローカルキャッシュのディスク上でのレイアウトを説明しています。どの言語でもキャッシュシステムを再実装するためのリファレンスとして意図されています。
このキャッシュレイアウトを使用しているライブラリやアプリケーションの例を以下に示します。ご自身のプロジェクトを追加する場合は、プルリクエスト(PR)を作成してください。
ライブラリ
| ライブラリ | 言語 | 注記 |
|---|---|---|
huggingface_hub | Python | これに依存するライブラリ(例: transformers、diffusers、datasets、mlx、vllm など) |
hf-hub | Rust | |
swift-huggingface | Swift | |
@huggingface/hub | JavaScript | Node.js のみ |
SMILE | Java | HuggingFaceHubのドキュメントを参照してください |
アプリケーション
| アプリケーション | 言語 | 注記 |
|---|---|---|
llama.cpp | C++ | #20775以降 |
Llama-macOS | Swift | llama.cppをベースに構築されたmacOSアプリ |
HuggingFaceModelDownloader | Go | |
oMLX | Python | macOS MLX推論サーバー、v0.4.0以降 |
キャッシュの保存場所
デフォルトのキャッシュディレクトリは次のとおりです:
~/.cache/huggingface/hubこれは環境変数で上書きできます:
HF_HUB_CACHE- キャッシュディレクトリへの直接パス(優先されます)HF_HOME- Hugging Face ホームディレクトリへのパス。設定されている場合、キャッシュは$HF_HOME/hubに保存されます
概要
<CACHE_DIR>/
├── .locks/ # Lock files for concurrent download safety
├── blobs/ # Shared blob store: Xet files deduplicated across repos
├── models--<org>--<repo>/ # Cached model repositories
├── datasets--<org>--<repo>/ # Cached dataset repositories
└── spaces--<org>--<repo>/ # Cached space repositoriesダウンロードされた各リポジトリには、フラットな単一のフォルダが割り当てられます。各リポジトリのフォルダ内では、ファイルはblobs/ディレクトリに1回のみ保存され、snapshots/のシンボリックリンクを介してアクセスされます。名前付きリファレンス(ブランチ、タグ)はrefs/で管理されます。huggingface_hub 1.32以降、hf_xetでダウンロードされたファイルは、キャッシュのルートにある共有ブロブストアに、キャッシュ全体で1回のみ保存されます。リポジトリのblobs/エントリは、そのファイルへのシンボリックリンクになります。
スキーマ
┌──────────────────────────────────────────┐
│ Repository folder │
│ models--julien-c--EsperBERTo-small │
└──────────────┬───────────────────────────┘
│
┌─────────────┬───────┴───────┬──────────────┐
│ │ │ │
v v v v
┌───────┐ ┌────────┐ ┌────────────┐ ┌──────────┐
│ refs/ │ │ blobs/ │ │ snapshots/ │ │.no_exist/│
└───┬───┘ └────┬───┘ └──────┬─────┘ └────┬─────┘
│ │ │ │
│ │ │ │
"main" contains Files stored One folder Empty marker
commit hash by content per commit files for
e.g. "aaaaaa" hash (SHA-1 hash, e.g. files known
or SHA-256) aaaaaa/ not to exist
Resolves a bbbbbb/
branch/tag to │
a snapshot ──────────────────────► Contains symlinks
to ../../blobs/{hash}リポジトリのフォルダ命名
リポジトリは、キャッシュのルートディレクトリにフラットなディレクトリとして保存されます。フォルダ名には、リポジトリの種類とリポジトリ ID がエンコードされています。
{type}s--{repo_id_with_slashes_replaced_by_--}ルール:
- リポジトリの種類は複数形です:
models、datasets、spaces - リポジトリID内のスラッシュ(
/)は--に置き換えられます - すべての部分の区切り文字は
--です - 大文字と小文字は保持されます
例:
| HubリポジトリID | リポジトリの種類 | キャッシュフォルダ名 |
|---|---|---|
julien-c/EsperBERTo-small | model | models--julien-c--EsperBERTo-small |
huggingface/DataMeasurementsFiles | dataset | datasets--huggingface--DataMeasurementsFiles |
dalle-mini/dalle-mini | space | spaces--dalle-mini--dalle-mini |
Buckets は git 基盤ではないため、このキャッシュでは処理されません。代わりに専用の
hf buckets syncコマンドを使用してください。
リポジトリフォルダ内
キャッシュされたリポジトリはすべて同じ内部構造を持っています:
<repo_folder>/
├── blobs/
├── refs/
├── snapshots/
└── .no_exist/ # may not always be presentblobs/ : コンテンツアドレス方式のファイルストレージ
blobs/ ディレクトリには、実際のファイル内容が保存されます。各ファイルは、Hub 上のファイル etag に基づいて命名されます:
- Gitで管理されているファイル: SHA-1ハッシュ(16進数40文字)で識別されます
- Git LFS ファイル: SHA-256 ハッシュ(16 進数 64 文字)で識別されます
これはフラットなディレクトリであり、サブディレクトリは存在しません。異なるリビジョン間で同一のファイルは1回のみ保存されます。エントリは通常のファイルか、共有ブロブストアへの相対シンボリックリンクのいずれかであり、読み取り側はそれを追跡する必要があります。
blobs/
├── 403450e234d65943a7dcf7e05a771ce3c92faa84dd07db4ac20f592037a1e4bd # SHA-256 (LFS)
├── 7cb18dc9bafbfcf74629a4b760af1b160957a83e # SHA-1 (git)
└── d7edf6bd2a681fb0175f7735299831ee1b22b812 # SHA-1 (git)refs/: ブランチとタグのリファレンス
refs/ ディレクトリは、人間が読みやすい参照(ブランチ名、タグ、PR 番号)をコミットハッシュにマッピングします。
各リファレンスは、完全なコミットハッシュ(16進数40文字)を1行だけ含むプレーンテキストファイルです。
refs/
├── main # contains e.g. "bbc77c8132af1cc5cf678da3f1ddf2de43606d48"
├── 2.4.0 # a tag
└── refs/
└── pr/
└── 1 # pull request referenceブランチ名またはタグ名を使用してファイルをダウンロードすると、対応する ref ファイルが最新のコミットハッシュで作成または更新されます。
snapshots/ : リビジョンビュー
snapshots/ ディレクトリには、キャッシュされた各リビジョン(コミットハッシュ)ごとに1つのサブディレクトリが含まれます。各リビジョンディレクトリは、Hub上のリポジトリのファイル構造を反映していますが、ファイルは ../../blobs/{hash} 内の シンボリックリンク になっています。
snapshots/
├── 2439f60ef33a0d46d85da5001d52aeda5b00ce9f/
│ ├── README.md -> ../../blobs/d7edf6bd2a681fb0175f7735299831ee1b22b812
│ └── pytorch_model.bin -> ../../blobs/403450e234d65943a7dcf7e05a771ce3c92faa84dd07db4ac20f592037a1e4bd
└── bbc77c8132af1cc5cf678da3f1ddf2de43606d48/
├── README.md -> ../../blobs/7cb18dc9bafbfcf74629a4b760af1b160957a83e
└── pytorch_model.bin -> ../../blobs/403450e234d65943a7dcf7e05a771ce3c92faa84dd07db4ac20f592037a1e4bd主なプロパティ:
- Symlinksは相対パスを使用します:
../../blobs/{hash} - 2つのリビジョン間でファイルに変更がない場合、両方のシンボリックリンクは同じblobを指し、データの重複は発生しません。
- Hub上のサブディレクトリ内のファイルは、スナップショット内でサブディレクトリとして表されます(完全な相対パスが保持されます)。
スナップショットの切り替えは、ローカルの git リポジトリでgit checkoutを使用することと似ています。
.no_exist/ : 非存在キャッシュ
.no_exist/ ディレクトリは、リクエストされたが Hub に存在しないファイルをトラッキングします。これにより、オプションのファイルに対する HTTP リクエストの繰り返しを回避できます。
構造はsnapshots/を模倣しています。各コミットハッシュに対応するサブディレクトリが1つ存在し、欠落ファイルの名前を付けた空ファイル(シンボリックリンクではありません)が含まれています。
.no_exist/
└── 2439f60ef33a0d46d85da5001d52aeda5b00ce9f/
└── config_that_does_not_exist.json # empty fileこれらは空のマーカーファイルのみであるため、ディスク使用量はごくわずかです。
共有ブロブストア
Xet 経由でダウンロードされたファイルは、リポジトリ間で重複排除されます。そのようなファイルはキャッシュのルートにある blobs/ 配下に一度だけ保存され、それが必要な各リポジトリにはコピーではなく相対シンボリックリンクが作成されます。
<CACHE_DIR>/
├── blobs/
│ ├── .huggingface-shared-blobs # marker file, contains the layout version ("1")
│ └── 73/ # first two hex characters of the Xet hash
│ ├── 73b079dc7bd546aed26d20a82289bd752fc52a2fda13e7f2b551f3af73845b59 # the file, named by its Xet hash (64 hex characters)
│ ├── 73b079dc7bd546aed26d20a82289bd752fc52a2fda13e7f2b551f3af73845b59.refs # manifest: one line per repo blob that references it (path relative to the cache root)
│ └── 73b079dc7bd546aed26d20a82289bd752fc52a2fda13e7f2b551f3af73845b59.lock # lock file
│
└── models--HuggingFaceTB--SmolLM2-135M-Instruct/
└── blobs/
└── 5af571cbf074e6d21a03528d2330792e532ca608f24ac70a143f6b369968ab8c -> ../../blobs/73/73b079dc7bd546aed26d20a82289bd752fc52a2fda13e7f2b551f3af73845b59主なプロパティ:
- リポジトリのエントリは etag 名を保持したまま、相対シンボリックリンクになります:
../../blobs/{xet_hash[:2]}/{xet_hash} snapshots/のレイアウトは変更されないため、ファイルの解決には影響しません- マーカーファイルはストアを識別します。キャッシュルートに存在する空でない
blobs/ディレクトリは、このマーカーファイルがない限り、使用も変更もされません。 - ストアにはシンボリックリンクと
hf_xetが必要です。共有に失敗した場合、ファイルは従来どおりリポジトリフォルダに保存されます。HF_HUB_DISABLE_SHARED_BLOBS=1でストアを無効にできます。 - 新しいダウンロードのみがストアを介して行われます。旧バージョンや他のクライアントによって書き込まれたファイルは、リポジトリフォルダ内に通常のファイルとして保持されるため、キャッシュには両方が含まれる可能性があります。
キャッシュの読み取りのみを行う実装は、変更を必要としません。シンボリックリンクの追跡は従来どおり動作します。
キャッシュから削除する実装では、リポジトリのブロブがシンボリックリンクである場合、それをストアへの参照として扱う必要があります。
- リポジトリの
blobs/にあるシンボリックリンクを削除してください。共有ファイル自体を削除しないでください。 - マニフェストを確認して削除する前に
<xet_hash>.lockをロックします - マニフェストにリストされているシンボリックリンクがまだそのファイルを指していない場合のみ、共有ファイルとその
.refsを削除します - マニフェストが存在しないか、読み取れない場合は、共有ファイルを保持します。
削除の動作と旧バージョンのクライアントでの制限については、huggingface_hub のキャッシュガイドを参照してください。
ロックファイル
ロックファイルは、並行するプロセスが同じブロブを同時にダウンロードすることを防止します。これらは、リポジトリフォルダ内ではなく、キャッシュのルートにある.locks/ディレクトリに保存されます。
<CACHE_DIR>/.locks/<repo_folder_name>/<blob_hash>.lock例:
<CACHE_DIR>/.locks/models--julien-c--EsperBERTo-small/403450e234d65943a7dcf7e05a771ce3c92faa84dd07db4ac20f592037a1e4bd.lock完全な例
~/.cache/huggingface/hub/
├── .locks/
│ └── models--julien-c--EsperBERTo-small/
│ └── 403450e234d65943a7dcf7e05a771ce3c92faa84dd07db4ac20f592037a1e4bd.lock
│
└── models--julien-c--EsperBERTo-small/
├── blobs/
│ ├── [321M] 403450e234d65943a7dcf7e05a771ce3c92faa84dd07db4ac20f592037a1e4bd
│ ├── [ 398] 7cb18dc9bafbfcf74629a4b760af1b160957a83e
│ └── [1.4K] d7edf6bd2a681fb0175f7735299831ee1b22b812
│
├── refs/
│ └── main # contains "bbc77c8132af1cc5cf678da3f1ddf2de43606d48"
│
├── snapshots/
│ ├── 2439f60ef33a0d46d85da5001d52aeda5b00ce9f/
│ │ ├── README.md -> ../../blobs/d7edf6bd2a681fb0175f7735299831ee1b22b812
│ │ └── pytorch_model.bin -> ../../blobs/403450e234d65943a7dcf7e05a771ce3c92faa84dd07db4ac20f592037a1e4bd
│ │
│ └── bbc77c8132af1cc5cf678da3f1ddf2de43606d48/
│ ├── README.md -> ../../blobs/7cb18dc9bafbfcf74629a4b760af1b160957a83e
│ └── pytorch_model.bin -> ../../blobs/403450e234d65943a7dcf7e05a771ce3c92faa84dd07db4ac20f592037a1e4bd
│
└── .no_exist/
└── 2439f60ef33a0d46d85da5001d52aeda5b00ce9f/
└── optional_config.json # empty filepytorch_model.bin が両方のリビジョンで同じブロブを指している点に注意してください。321 MB のファイルはディスク上に1回のみ保存されます。
ファイル解決ロジック
ディスク上のキャッシュされたファイルの場所を特定するには:
リビジョンをコミットハッシュに解決する
- リビジョンがすでに40文字の16進数文字列である場合は、そのまま直接使用します。
- それ以外の場合は、
refs/{revision}のファイルを読み取り、コミットハッシュを取得します。
スナップショットを確認する
snapshots/{commit_hash}/{relative_path}を検索してください- 存在する場合(シンボリックリンクまたはファイルとして)、ファイルはキャッシュされます。シンボリックリンクをたどってコンテンツを取得します
存在しないことを確認する
.no_exist/{commit_hash}/{relative_path}を検索してください- 存在する場合、そのファイルはこのリビジョンのHub上に存在しないことが知られています
キャッシュミス
- どちらのパスも存在しない場合、ファイルはまだキャッシュされていません。
Windowsでの動作
キャッシュはシンボリックリンクに依存しています。シンボリックリンクが利用できない Windows システムでは、キャッシュは劣化モードで動作します。このモードでは、シンボリックリンクの代わりに、実際のファイルのコピーがsnapshots/に直接配置されます。blobs/ディレクトリと共有ブロブストアはこのモードでは使用されません。
これは、同じファイルの内容がリビジョン間で重複する可能性があることを意味し、ディスク使用量が増加します。Windows でシンボリックリンクのサポートを有効にするには、開発者モードを有効にするか、管理者として実行してください。
Update on GitHub