Hub Python Library documentation
Verwalten des huggingface_hub Cache-Systems
Verwalten des huggingface_hub Cache-Systems
Caching verstehen
Das Hugging Face Hub Cache-System wurde entwickelt, um der zentrale Cache zu sein, der zwischen Bibliotheken geteilt wird, welche vom Hub abhängen. Es wurde in v0.8.0 aktualisiert, um das erneute Herunterladen von Dateien zwischen Revisionen zu verhindern.
Das Cache-System ist wie folgt aufgebaut:
<CACHE_DIR>
├─ <MODELS>
├─ <DATASETS>
├─ <SPACES>
Der <CACHE_DIR>
ist normalerweise das Home-Verzeichnis Ihres Benutzers. Es kann jedoch mit dem
cache_dir
-Argument in allen Methoden oder durch Angabe der Umgebungsvariablen
HF_HOME
oder HF_HUB_CACHE
angepasst werden.
Modelle, Datensätze und Räume teilen eine gemeinsame Wurzel. Jedes dieser Repositories enthält den Repository-Typ, den Namensraum (Organisation oder Benutzername), falls vorhanden, und den Repository-Namen:
<CACHE_DIR>
├─ models--julien-c--EsperBERTo-small
├─ models--lysandrejik--arxiv-nlp
├─ models--bert-base-cased
├─ datasets--glue
├─ datasets--huggingface--DataMeasurementsFiles
├─ spaces--dalle-mini--dalle-mini
Innerhalb dieser Ordner werden nun alle Dateien vom Hub heruntergeladen. Das Caching stellt sicher, dass eine Datei nicht zweimal heruntergeladen wird, wenn sie bereits existiert und nicht aktualisiert wurde; wurde sie jedoch aktualisiert und Sie fordern die neueste Datei an, wird die neueste Datei heruntergeladen (während die vorherige Datei intakt bleibt, falls Sie sie erneut benötigen).
Um dies zu erreichen, enthalten alle Ordner dasselbe Grundgerüst:
<CACHE_DIR>
├─ datasets--glue
│ ├─ refs
│ ├─ blobs
│ ├─ snapshots
...
Jeder Ordner ist so gestaltet, dass er das Folgende enthält:
Refs
Der Ordner refs
enthält Dateien, die die neueste Revision des gegebenen Verweises anzeigen.
Zum Beispiel, wenn wir zuvor eine Datei aus dem main
-Branch eines Repositories abgerufen haben,
wird der Ordner refs
eine Datei namens main
enthalten, die selbst den Commit-Identifikator der aktuellen HEAD-Branch enthält.
Wenn der neueste Commit von main
den Identifikator aaaaaa
hat, dann enthält er aaaaaa
.
Wenn derselbe Zweig mit einem neuen Commit aktualisiert wird, der den Identifikator bbbbbb
hat,
wird das erneute Herunterladen einer Datei von diesem Verweis die Datei refs/main
aktualisieren, um bbbbbb
zu enthalten.
Blobs
Der Ordner blobs
enthält die tatsächlichen Dateien, die wir heruntergeladen haben. Der Name jeder Datei ist ihr Hash.
Snapshots
Der Ordner snapshots
enthält Symlinks zu den oben erwähnten Blobs.
Er besteht selbst aus mehreren Ordnern: einem pro bekannter Revision!
In der obigen Erklärung hatten wir zunächst eine Datei von der Revision aaaaaa
abgerufen, bevor wir eine Datei
von der Revision bbbbbb
abgerufen haben. In dieser Situation hätten wir jetzt zwei Ordner im Ordner snapshots
: aaaaaa
und bbbbbb
.
In jedem dieser Ordner leben Symlinks, die die Namen der Dateien haben, die wir heruntergeladen haben.
Wenn wir zum Beispiel die Datei README.md
in der Revision aaaaaa
heruntergeladen hätten, hätten wir den folgenden Pfad:
<CACHE_DIR>/<REPO_NAME>/snapshots/aaaaaa/README.md
Diese README.md
-Datei ist tatsächlich ein Symlink, der auf den Blob verweist, der den Hash der Datei hat.
Durch das Erstellen des Grundgerüsts auf diese Weise ermöglichen wir den Mechanismus der Dateifreigabe:
Wenn dieselbe Datei in der Revision bbbbbb
abgerufen wurde, hätte sie denselben Hash und die Datei müsste nicht erneut heruntergeladen werden.
.no_exist (fortgeschritten)
Zusätzlich zu den Ordnern blobs
, refs
und snapshots
könnten Sie in Ihrem Cache auch einen .no_exist
Ordner finden.
Dieser Ordner hält fest, welche Dateien Sie einmal versucht haben herunterzuladen, die jedoch nicht auf dem Hub vorhanden sind.
Seine Struktur ist dieselbe wie der snapshots
Ordner mit einem Unterordner pro bekannter Revision:
<CACHE_DIR>/<REPO_NAME>/.no_exist/aaaaaa/config_that_does_not_exist.json
Im Gegensatz zum snapshots
Ordner handelt es sich bei den Dateien um einfache leere Dateien (keine Symlinks).
In diesem Beispiel existiert die Datei "config_that_does_not_exist.json"
nicht auf dem Hub für die Revision "aaaaaa"
.
Da dieser Ordner nur leere Dateien speichert, ist sein Speicherplatzverbrauch vernachlässigbar.
Sie fragen sich jetzt vielleicht, warum diese Information überhaupt relevant ist?
In einigen Fällen versucht ein Framework, optionale Dateien für ein Modell zu laden.
Das Speichern der Nicht-Existenz optionaler Dateien beschleunigt das Laden eines Modells, da 1 HTTP-Anfrage pro möglicher optionaler Datei gespart wird.
Dies ist zum Beispiel bei transformers
der Fall, wo jeder Tokenizer zusätzliche Dateien unterstützen kann. Beim ersten Laden des Tokenizers
auf Ihrem Gerät wird im Cache gespeichert, welche optionalen Dateien vorhanden sind (und welche nicht), um die Ladezeit bei den nächsten Initialisierungen zu beschleunigen.
Um zu testen, ob eine Datei lokal im Cache gespeichert ist (ohne eine HTTP-Anfrage zu senden), können Sie die try_to_load_from_cache()
Hilfsfunktion verwenden.
Sie gibt entweder den Dateipfad zurück (falls vorhanden und im Cache gespeichert), das Objekt _CACHED_NO_EXIST
(wenn die Nicht-Existenz im Cache gespeichert ist)
oder None
(wenn wir es nicht wissen).
from huggingface_hub import try_to_load_from_cache, _CACHED_NO_EXIST
filepath = try_to_load_from_cache()
if isinstance(filepath, str):
# file exists and is cached
...
elif filepath is _CACHED_NO_EXIST:
# non-existence of file is cached
...
else:
# file is not cached
...
In der Praxis
In der Praxis sollte Ihr Cache folgendermaßen aussehen:
[ 96] . └── [ 160] models--julien-c--EsperBERTo-small ├── [ 160] blobs │ ├── [321M] 403450e234d65943a7dcf7e05a771ce3c92faa84dd07db4ac20f592037a1e4bd │ ├── [ 398] 7cb18dc9bafbfcf74629a4b760af1b160957a83e │ └── [1.4K] d7edf6bd2a681fb0175f7735299831ee1b22b812 ├── [ 96] refs │ └── [ 40] main └── [ 128] snapshots ├── [ 128] 2439f60ef33a0d46d85da5001d52aeda5b00ce9f │ ├── [ 52] README.md -> ../../blobs/d7edf6bd2a681fb0175f7735299831ee1b22b812 │ └── [ 76] pytorch_model.bin -> ../../blobs/403450e234d65943a7dcf7e05a771ce3c92faa84dd07db4ac20f592037a1e4bd └── [ 128] bbc77c8132af1cc5cf678da3f1ddf2de43606d48 ├── [ 52] README.md -> ../../blobs/7cb18dc9bafbfcf74629a4b760af1b160957a83e └── [ 76] pytorch_model.bin -> ../../blobs/403450e234d65943a7dcf7e05a771ce3c92faa84dd07db4ac20f592037a1e4bd
Einschränkungen
Um ein effizientes Cache-System zu haben, verwendet huggingface-hub
Symlinks. Allerdings
werden Symlinks nicht auf allen Maschinen unterstützt. Dies ist eine bekannte Einschränkung,
insbesondere bei Windows. Wenn dies der Fall ist, verwendet huggingface_hub
nicht das blobs/
Verzeichnis,
sondern speichert die Dateien direkt im snapshots/
Verzeichnis. Dieser Workaround ermöglicht es den Nutzern,
Dateien vom Hub auf genau die gleiche Weise herunterzuladen und zu cachen.
Auch Werkzeuge zur Überprüfung und Löschung des Caches (siehe unten) werden unterstützt.
Allerdings ist das Cache-System weniger effizient, da eine einzelne Datei möglicherweise mehrmals heruntergeladen wird,
wenn mehrere Revisionen des gleichen Repos heruntergeladen werden.
Wenn Sie von dem Symlink-basierten Cache-System auf einem Windows-Gerät profitieren möchten, müssen Sie entweder den Entwicklermodus aktivieren oder Python als Administrator ausführen.
Wenn Symlinks nicht unterstützt werden, wird dem Nutzer eine Warnmeldung angezeigt, um ihn darauf hinzuweisen,
dass er eine eingeschränkte Version des Cache-Systems verwendet. Diese Warnung kann durch Setzen der
Umgebungsvariable HF_HUB_DISABLE_SYMLINKS_WARNING
auf true deaktiviert werden.
Assets zwischenspeichern
Zusätzlich zum Zwischenspeichern von Dateien aus dem Hub benötigen nachgelagerte Bibliotheken
oft das Zwischenspeichern von anderen Dateien, die in Verbindung mit HF stehen, aber nicht
direkt von huggingface_hub
behandelt werden (zum Beispiel: Dateien, die von GitHub heruntergeladen werden,
vorverarbeitete Daten, Protokolle,…). Um diese Dateien, die als assets
bezeichnet werden, zwischenzuspeichern,
kann man cached_assets_path()
verwenden. Dieser kleine Helfer generiert Pfade im HF-Cache auf eine einheitliche Weise,
basierend auf dem Namen der anfragenden Bibliothek und optional auf einem Namensraum und einem Unterordnernamen.
Das Ziel ist, dass jede nachgelagerte Bibliothek ihre Assets auf ihre eigene Weise verwaltet
(z.B. keine Regelung über die Struktur), solange sie im richtigen Assets-Ordner bleibt.
Diese Bibliotheken können dann die Werkzeuge von huggingface_hub
nutzen, um den Cache zu verwalten,
insbesondere um Teile der Assets über einen CLI-Befehl zu scannen und zu löschen.
from huggingface_hub import cached_assets_path
assets_path = cached_assets_path(library_name="datasets", namespace="SQuAD", subfolder="download")
something_path = assets_path / "something.json" # Machen Sie, was Sie möchten, in Ihrem Assets-Ordner!
cached_assets_path()
ist der empfohlene Weg, um Assets zu speichern, ist jedoch nicht verpflichtend. Wenn Ihre Bibliothek bereits ihren eigenen Cache verwendet, können Sie diesen gerne nutzen!
Assets in der Praxis
In der Praxis sollte Ihr Assets-Cache wie der folgende Verzeichnisbaum aussehen:
assets/ └── datasets/ │ ├── SQuAD/ │ │ ├── downloaded/ │ │ ├── extracted/ │ │ └── processed/ │ ├── Helsinki-NLP--tatoeba_mt/ │ ├── downloaded/ │ ├── extracted/ │ └── processed/ └── transformers/ ├── default/ │ ├── something/ ├── bert-base-cased/ │ ├── default/ │ └── training/ hub/ └── models--julien-c--EsperBERTo-small/ ├── blobs/ │ ├── (...) │ ├── (...) ├── refs/ │ └── (...) └── [ 128] snapshots/ ├── 2439f60ef33a0d46d85da5001d52aeda5b00ce9f/ │ ├── (...) └── bbc77c8132af1cc5cf678da3f1ddf2de43606d48/ └── (...)
Cache scannen
Derzeit werden zwischengespeicherte Dateien nie aus Ihrem lokalen Verzeichnis gelöscht:
Wenn Sie eine neue Revision eines Zweiges herunterladen, werden vorherige Dateien aufbewahrt,
falls Sie sie wieder benötigen. Daher kann es nützlich sein, Ihr Cache-Verzeichnis zu scannen,
um zu erfahren, welche Repos und Revisionen den meisten Speicherplatz beanspruchen.
huggingface_hub
bietet einen Helfer dafür, der über hf
oder in einem Python-Skript verwendet werden kann.
Cache im Terminal prüfen
Die bequemste Möglichkeit, Ihren HF-Cache zu untersuchen, ist der Befehl hf cache ls
.
Er listet standardmäßig alle gecachten Repositories zusammen mit Größe, letzter Nutzung und Referenzen auf.
➜ hf cache ls ID SIZE LAST_ACCESSED LAST_MODIFIED REFS ------------------------------------ ------- ------------- ------------- ------------------- dataset/glue 116.3K 4 days ago 4 days ago 2.4.0 main 1.17.0 dataset/google/fleurs 64.9M 1 week ago 1 week ago main refs/pr/1 model/Jean-Baptiste/camembert-ner 441.0M 2 weeks ago 16 hours ago main model/bert-base-cased 1.9G 1 week ago 2 years ago model/t5-base 10.1K 3 months ago 3 months ago main model/t5-small 970.7M 3 days ago 3 days ago main refs/pr/1 Found 6 repo(s) for a total of 12 revision(s) and 3.4G on disk.
Mit --revisions
wechseln Sie zur Ansicht auf Snapshot-Ebene. Filter akzeptieren
menschenlesbare Werte, sodass Ausdrücke wie size>1GB
oder accessed>30d
sofort funktionieren:
➜ hf cache ls --revisions --filter "size>1GB" --filter "accessed>30d" ID REVISION SIZE LAST_MODIFIED REFS ------------------------------------ ------------------ ------- ------------- ------------------- model/bert-base-cased 6d1d7a1a2a6cf4c2 1.9G 2 years ago model/t5-small 1c610f6b3f5e7d8a 1.1G 3 months ago main Found 2 repo(s) for a total of 2 revision(s) and 3.0G on disk.
Brauchen Sie maschinenlesbare Ausgaben? --format json
liefert strukturierte Objekte,
--format csv
erzeugt durch Komma getrennte Zeilen und --quiet
gibt nur Kennungen aus.
Alle Varianten lassen sich mit --cache-dir
kombinieren, wenn Ihr Cache nicht unter HF_HOME
liegt.
Mit Shell-Tools filtern
Die Tabellen-Ausgabe lässt sich weiterhin mit bekannten Tools verarbeiten. Das folgende
Beispiel zeigt alle Revisionen für t5-small
:
➜ eval "hf cache ls --revisions" | grep "t5-small" model/t5-small 1c610f6b3f5e7d8a 1.1G 3 months ago main model/t5-small 8f3ad1c90fed7a62 820.1M 2 weeks ago refs/pr/1
Den Cache von Python aus scannen
Für eine erweiterte Nutzung verwenden Sie scan_cache_dir()
, welches das von dem CLI-Tool
aufgerufene Python-Dienstprogramm ist.
Sie können es verwenden, um einen detaillierten Bericht zu erhalten, der um 4 Datenklassen herum strukturiert ist:
HFCacheInfo
: vollständiger Bericht, der vonscan_cache_dir()
zurückgegeben wirdCachedRepoInfo
: Informationen über ein gecachtes RepoCachedRevisionInfo
: Informationen über eine gecachtes Revision (z.B. “snapshot) in einem RepoCachedFileInfo
: Informationen über eine gecachte Datei in einem Snapshot
Hier ist ein einfaches Anwendungs-Beispiel in Python. Siehe Referenz für Details.
>>> from huggingface_hub import scan_cache_dir
>>> hf_cache_info = scan_cache_dir()
HFCacheInfo(
size_on_disk=3398085269,
repos=frozenset({
CachedRepoInfo(
repo_id='t5-small',
repo_type='model',
repo_path=PosixPath(...),
size_on_disk=970726914,
nb_files=11,
last_accessed=1662971707.3567169,
last_modified=1662971107.3567169,
revisions=frozenset({
CachedRevisionInfo(
commit_hash='d78aea13fa7ecd06c29e3e46195d6341255065d5',
size_on_disk=970726339,
snapshot_path=PosixPath(...),
# No `last_accessed` as blobs are shared among revisions
last_modified=1662971107.3567169,
files=frozenset({
CachedFileInfo(
file_name='config.json',
size_on_disk=1197
file_path=PosixPath(...),
blob_path=PosixPath(...),
blob_last_accessed=1662971707.3567169,
blob_last_modified=1662971107.3567169,
),
CachedFileInfo(...),
...
}),
),
CachedRevisionInfo(...),
...
}),
),
CachedRepoInfo(...),
...
}),
warnings=[
CorruptedCacheException("Snapshots dir doesn't exist in cached repo: ..."),
CorruptedCacheException(...),
...
],
)
Cache leeren
Das Durchsuchen Ihres Caches ist interessant, aber was Sie normalerweise als Nächstes tun möchten, ist
einige Teile zu löschen, um Speicherplatz freizugeben. Dies gelingt mit den CLI-Befehlen
hf cache rm
und hf cache prune
. Alternativ können Sie programmatisch den
delete_revisions()
-Helfer des zurückgegebenen HFCacheInfo
-Objekts nutzen.
Löschstrategie
Um einige Cache zu löschen, müssen Sie eine Liste von Revisionen übergeben, die gelöscht werden sollen. Das Tool wird
eine Strategie definieren, um den Speicherplatz auf der Grundlage dieser Liste freizugeben. Es gibt ein
DeleteCacheStrategy
Objekt zurück, das beschreibt, welche Dateien und Ordner gelöscht werden. Die
DeleteCacheStrategy
zeigt Ihnen, wie viel Speicherplatz voraussichtlich frei wird.
Sobald Sie mit der Löschung einverstanden sind, müssen Sie sie ausführen, um die Löschung wirksam zu machen.
Um Abweichungen zu vermeiden, können Sie ein Strategieobjekt nicht manuell bearbeiten.
Die Strategie zur Löschung von Revisionen ist folgende:
- Der Ordner
snapshot
, der die Revisions-Symlinks enthält, wird gelöscht. - Blob-Dateien, die nur von zu löschenden Revisionen verlinkt werden, werden ebenfalls gelöscht.
- Wenn eine Revision mit 1 oder mehreren
refs
verknüpft ist, werden die Referenzen gelöscht. - Werden alle Revisionen aus einem Repo gelöscht, wird das gesamte zwischengespeicherte Repository gelöscht.
Revisions-Hashes sind eindeutig über alle Repositories hinweg.
hf cache rm
akzeptiert daher sowohl Repository-Kennungen (z. B.model/bert-base-uncased
) als auch einzelne Revisions-Hashes – bei einem Hash müssen Sie das Repository nicht zusätzlich angeben.
Wenn eine Revision im Cache nicht gefunden wird, wird sie stillschweigend ignoriert. Außerdem wird, wenn eine Datei oder ein Ordner beim Versuch, ihn zu löschen, nicht gefunden wird, eine Warnung protokolliert, aber es wird kein Fehler ausgelöst. Die Löschung wird für andere Pfade im
DeleteCacheStrategy
Objekt fortgesetzt.
Cache vom Terminal aus leeren
Verwenden Sie hf cache rm
, um gecachte Repositories oder einzelne Revisionen zu löschen.
Übergeben Sie dazu eine oder mehrere Repository-Kennungen (z. B. model/bert-base-uncased
) oder Revisions-Hashes:
➜ hf cache rm model/bert-base-cased About to delete 1 repo(s) totalling 1.9G. - model/bert-base-cased (entire repo) Proceed with deletion? [y/N]: y Deleted 1 repo(s) and 1 revision(s); freed 1.9G.
Sie können Repositories und spezifische Revisionen mischen. Nutzen Sie --dry-run
, um den Effekt vorab zu prüfen,
oder --yes
, wenn keine Rückfrage erscheinen soll:
➜ hf cache rm model/t5-small 8f3ad1c --dry-run About to delete 1 repo(s) and 1 revision(s) totalling 1.1G. - model/t5-small: 8f3ad1c [main] 1.1G Dry run: no files were deleted.
Wenn Ihr Cache nicht im Standardverzeichnis liegt, kombinieren Sie den Befehl mit --cache-dir PFAD
.
Zum Aufräumen verwaister Snapshots steht hf cache prune
bereit. Der Befehl entfernt automatisch alle
Revisionen ohne Referenz:
➜ hf cache prune About to delete 3 unreferenced revision(s) (2.4G total). - model/t5-small: 1c610f6b [refs/pr/1] 820.1M d4ec9b72 [(detached)] 640.5M - dataset/google/fleurs: 2b91c8dd [(detached)] 937.6M Proceed? [y/N]: y Deleted 3 unreferenced revision(s); freed 2.4G.
Beide Befehle unterstützen --dry-run
, --yes
und --cache-dir
, sodass Sie Vorschauen erzeugen,
Automatisierungen bauen und alternative Cache-Verzeichnisse angeben können.
Cache aus Python leeren
Für mehr Flexibilität können Sie auch die Methode delete_revisions()
programmatisch verwenden.
Hier ist ein einfaches Beispiel. Siehe Referenz für Details.
>>> from huggingface_hub import scan_cache_dir
>>> delete_strategy = scan_cache_dir().delete_revisions(
... "81fd1d6e7847c99f5862c9fb81387956d99ec7aa"
... "e2983b237dccf3ab4937c97fa717319a9ca1a96d",
... "6c0e6080953db56375760c0471a8c5f2929baf11",
... )
>>> print("Will free " + delete_strategy.expected_freed_size_str)
Will free 8.6G
>>> delete_strategy.execute()
Cache deletion done. Saved 8.6G.