Hub Python Library documentation
Понимание кэширования
Понимание кэширования
huggingface_hub использует локальный файловый кэш для хранения отдельных файлов, загруженных с Hub, и для предотвращения повторной загрузки неизменённых файлов при обновлении репозитория. Кроме того, hf_xet хранит кэш шардов и промежуточные данные для оптимизации загрузок (см. Кэширование Xet).
В этом руководстве описаны инструменты управления кэшем, специфичные для Python, предоставляемые
huggingface_hub. Для языково-независимого обзора того, как работает система кэширования Hugging Face Hub, см. документацию Hub о локальном кэшировании.
Кэширование на основе файлов
Система кэширования Hugging Face Hub спроектирована как центральный кэш, общий для всех библиотек, зависящих от Hub. В версии v0.8.0 она была обновлена, чтобы предотвратить повторное скачивание одних и тех же файлов между ревизиями.
Система кэширования спроектирована следующим образом:
<CACHE_DIR>
├─ <MODELS>
├─ <DATASETS>
├─ <SPACES>
├─ <KERNELS>По умолчанию <CACHE_DIR> — это ~/.cache/huggingface/hub. Однако его можно настроить с помощью аргумента cache_dir во всех методах или, указав переменную окружения HF_HOME или HF_HUB_CACHE.
Модели, наборы данных, пространства и ядра имеют общий корень. Каждый из этих репозиториев содержит тип репозитория, пространство имён (организация или имя пользователя), если оно существует, и имя репозитория:
<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Именно в эти папки теперь загружаются все файлы с Hub. Кэширование гарантирует, что файл не будет загружен повторно, если он уже существует и не был обновлён; однако, если файл был обновлён, а вы запрашиваете последнюю версию, будет загружена именно последняя версия (при этом предыдущая версия сохранится на случай, если она снова понадобится).
Для достижения этого все папки содержат одинаковую структуру:
<CACHE_DIR>
├─ datasets--glue
│ ├─ refs
│ ├─ blobs
│ ├─ snapshots
│ ├─ trees
...Каждая папка предназначена для хранения следующего:
Ссылки
Папка refs содержит файлы, указывающие на последнюю ревизию данного ссылаемого объекта. Например, если мы ранее загрузили файл из ветки main репозитория, то в папке refs будет находиться файл с именем main, который, в свою очередь, содержит идентификатор коммита текущего head.
Если последний коммит ветки main имеет идентификатор aaaaaa, то он будет содержать aaaaaa.
Если та же ветка обновляется новым коммитом, у которого идентификатор bbbbbb, то повторное скачивание файла из этого ссылающегося объекта обновит файл refs/main, чтобы он содержал bbbbbb.
Blobs
Папка blobs содержит фактически загруженные файлы. Имя каждого файла — это его хеш.
Снимки
Папка snapshots содержит символические ссылки на упомянутые выше объекты. Она сама состоит из нескольких папок:
по одной на каждую известную ревизию!
В описании выше мы изначально загрузили файл из ревизии aaaaaa, а затем — из ревизии bbbbbb. В этой ситуации в папке snapshots теперь будут две папки: aaaaaa и bbbbbb.
В каждой из этих папок находятся символические ссылки, названные в честь скачанных файлов. Например, если мы скачали файл README.md в ревизии aaaaaa, то путь будет следующим:
<CACHE_DIR>/<REPO_NAME>/snapshots/aaaaaa/README.mdФайл README.md на самом деле является символьной ссылкой, указывающей на blob, содержащий хеш файла.
Создавая скелет таким образом, мы открываем механизм для общего использования файлов: если тот же файл был получен в ревизии bbbbbb, у него будет тот же хеш, и повторное скачивание файла не потребуется.
Деревья
Папка trees кэширует список файлов, содержащихся в репозитории на определённом коммите. Коммит неизменяем, поэтому его список файлов никогда не меняется. Это означает, что список можно кэшировать навсегда, не проверяя его повторно на Hub.
Каждый кэшированный список называется по хэшу коммита и хранится в виде JSON-файла, например trees/aaaaaa.json. Для каждого файла в репозитории на момент этого коммита он содержит данные, необходимые для загрузки файла: его путь, размер и хэш. Это та же информация, которую Hub вернул бы в противном случае, но обычно для её получения требуется один сетевой запрос на каждый файл.
Этот кэш записывается функцией snapshot_download(). При первом скачивании коммита список файлов запрашивается один раз и сохраняется здесь. При следующем скачивании того же коммита список читается с диска, а не запрашивается повторно. В результате повторное выполнение загрузки при полностью заполненном кэше требует лишь одного сетевого запроса: того, который нужен для разрешения имени ветки или тега в хеш коммита.
Обе функции snapshot_download() и hf_hub_download() читают этот кэш, чтобы избежать сетевых запросов. При загрузке файла с хэшем коммита в качестве ревизии (именно так snapshot_download() внутренне обрабатывает каждый файл) метаданные загрузки читаются из кэшированного списка файлов, и сетевой запрос для конкретного файла пропускается. Это означает, что hf_hub_download() для одного файла также выигрывает от списка файлов, сохранённого ранее snapshot_download() для того же коммита.
Поскольку кэшированный список файлов точно описывает содержимое коммита, snapshot_download() также может определить, является ли локальный снимок полным. Если Hub недоступен (вы работаете в автономном режиме, соединение не устанавливается или вы передали local_files_only=True), а в локальном снимке отсутствуют ожидаемые файлы, snapshot_download() вызывает IncompleteSnapshotError вместо возврата частичной папки. Ранее неполный снимок возвращался без предупреждения, из-за чего вы могли работать с отсутствующими файлами, не зная об этом. Файлы, исключённые с помощью allow_patterns или ignore_patterns, не учитываются как отсутствующие. Исключение предоставляет путь к неполному снимку через атрибут snapshot_path, что позволяет при необходимости найти частично закэшированные файлы.
.no_exist (расширенные возможности)
Помимо папок blobs, refs и snapshots, в вашем кэше может также присутствовать папка .no_exist. Она хранит сведения о файлах, которые вы пытались скачать, но которые отсутствуют на Hub. Её структура совпадает со структурой папки snapshots и содержит по одной подпапке на каждую известную ревизию:
<CACHE_DIR>/<REPO_NAME>/.no_exist/aaaaaa/config_that_does_not_exist.jsonВ отличие от папки snapshots, файлы здесь представляют собой простые пустые файлы (без символьных ссылок). В этом примере
файл "config_that_does_not_exist.json" не существует на Hub для ревизии "aaaaaa".
Поскольку в этой папке хранятся только пустые файлы, её размер на диске пренебрежимо мал.
Теперь вы, возможно, задаетесь вопросом, почему эта информация вообще важна?
В некоторых случаях фреймворк пытается загрузить необязательные файлы для модели. Сохранение информации об отсутствии необязательных файлов ускоряет загрузку модели, так как экономит один HTTP-запрос на каждый возможный необязательный файл.
Например, в transformers каждый токенизатор может поддерживать дополнительные файлы.
При первой загрузке токенизатора на вашем компьютере он кэширует, какие необязательные файлы существуют (а какие нет), чтобы ускорить время загрузки при следующих инициализациях.
To test if a file is cached locally (without making any HTTP request), you can use the try_to_load_from_cache() helper. It will either return the filepath (if exists and cached), the object _CACHED_NO_EXIST (if non-existence
is cached) or None (if we don’t know).
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
...На практике
На практике ваш кэш должен выглядеть как следующее дерево:
[ 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
└── [ 96] trees
├── [ 521] 2439f60ef33a0d46d85da5001d52aeda5b00ce9f.json
└── [ 521] bbc77c8132af1cc5cf678da3f1ddf2de43606d48.jsonCACHEDIR.TAG
huggingface_hub автоматически создаёт файл CACHEDIR.TAG в каталоге кэша. Этот
тег соответствует стандарту Cache Directory Tagging Standard и сообщает инструментам резервного копирования (например, Borg,
restic, rsync), что каталог содержит данные кэша, которые можно повторно загрузить, и его можно безопасно
исключить из резервных копий.
Ограничения
Для обеспечения эффективной системы кэширования huggingface-hub использует символьные ссылки. Однако символьные ссылки не поддерживаются на всех машинах. Это известное ограничение, особенно для Windows. В таком случае huggingface_hub не использует каталог blobs/, а сохраняет файлы непосредственно в каталоге snapshots/. Этот обходной путь позволяет пользователям скачивать и кэшировать файлы из Hub точно так же. Инструменты для просмотра и удаления кэша (см. ниже) также поддерживаются. Однако система кэширования становится менее эффективной, поскольку один и тот же файл может быть скачан несколько раз, если загружаются несколько ревизий одного и того же репозитория.
Если вы хотите воспользоваться кэш-системой на основе символьных ссылок на машине с Windows, вам необходимо либо включить режим разработчика, либо запускать Python с правами администратора.
Если вы хотите проактивно использовать режим кэша без символьных ссылок (например, на общей файловой системе, которая плохо работает с симлинками), вы можете установить переменную окружения HF_HUB_DISABLE_SYMLINKS в значение 1. Файлы будут копироваться непосредственно в snapshots/, а не ссылаться на blobs/ через симлинки.
Если символические ссылки не поддерживаются, пользователю отображается предупреждение о том, что используется урезанная версия системы кэширования. Это предупреждение можно отключить, установив переменную окружения HF_HUB_DISABLE_SYMLINKS_WARNING в значение true.
Общие объекты данных (blobs) между репозиториями
По умолчанию файлы Xet также дедуплицируются между репозиториями. Файл Xet, загруженный через hf_xet, хранится один раз в <CACHE_DIR>/blobs/<prefix>/<xet_hash>, а запись blobs/<etag> репозитория представляет собой относительную символьную ссылку на него. Когда другой репозиторий запрашивает тот же файл, он получает символьную ссылку вместо загрузки: байты не передаются, и дополнительное место не используется. Структура снапшота не меняется. Файл-маркер идентифицирует хранилище, поэтому каталог blobs, не созданный huggingface_hub, никогда не изменяется.
Каждый общий файл имеет манифест <xet_hash>.refs, в котором перечислены блоки репозитория, использующие его. Команда hf cache rm читает этот манифест, чтобы проверять только те общие файлы, на которые влияет удаление, а hf cache prune удаляет общие файлы, которые больше не используются ни одним кэшированным репозиторием. Манифест служит лишь подсказкой: каждая запись проверяется по файловой системе, а файл с отсутствующими или нечитаемыми метаданными сохраняется. При очистке приоритет отдаётся сохранению данных, которые можно освободить, а не нарушению валидной записи кэша.
Размеры для каждого репозитория остаются логическими, поэтому общий файл учитывается для каждого репозитория, который его использует. Значение size_on_disk для всего кэша является физическим: каждый общий файл учитывается один раз, включая файлы, которые больше не используются ни одним репозиторием.
Старые клиенты (huggingface_hub, huggingface.js, hf-hub, llama.cpp и всё, что следует по символическим ссылкам) продолжают читать и скачивать файлы как обычно, в тех же папках репозитория. Два ограничения:
huggingface_hub<=1.31оставляет общие файлы удалённого репозитория в хранилище, гдеhf cache lsпомечает их, аhf cache pruneудаляет. Инструменты очистки кэша других клиентов могут вместо этого удалить общий файл, который всё ещё используется другими репозиториями; затронутые файлы будут повторно загружены при следующем использовании. Используйте актуальную версиюhuggingface_hubдляhf cache rm,hf cache pruneи программной очистки.- Их сканеры кэша могут сообщать о верхнеуровневом каталоге
blobsкак о неизвестной записи.
Хранилище требует структуру кэша на основе символьных ссылок и отключается переменной HF_HUB_DISABLE_XET=1. Любая ошибка при обмене файлами, например, неподдерживаемая файловая система, ошибка разрешений или существующий немаркированный каталог blobs, приводит к безмолвному переходу на обычное локальное хранилище репозитория. Чтобы полностью отказаться от этого режима, установите HF_HUB_DISABLE_SHARED_BLOBS=1.
Закрепление ревизии (продвинуто)
Если вы интегрируете Hub в ML-библиотеку, единый вызов snapshot_download() по-прежнему является рекомендуемым подходом: он определяет ревизию один раз, загружает всё параллельно и кэширует список файлов. Далее приведены сведения, полезные только для сложных библиотек, которые загружают и подключают множество компонентов отдельно (config, weights, tokenizer, processor, adapters, …) и не могут использовать единый вызов.
Когда библиотека скачивает несколько файлов по одному, каждый вызов снова должен разрешить revision="main" в хеш коммита. Это стоит один HTTP-запрос на файл, а что ещё хуже, два запроса, сделанных с разницей в несколько секунд, могут попасть в два разных коммита, если репозиторий был обновлён между ними.
HfApi.resolve_revision() разрешает ревизию один раз и возвращает ResolvedRevision:
>>> from huggingface_hub import resolve_revision
>>> revision = resolve_revision("openai-community/gpt2")
>>> revision
ResolvedRevision(initial=None, resolved='607a30d783dfa663caf39e06633721c8d4cfcd7e')ResolvedRevision является подклассом str, поэтому его можно передавать в любой метод huggingface_hub, принимающий аргумент revision. Его строковое значение — это то, что пользователь запросил изначально (здесь "main", благодаря чему сообщения об ошибках читаются легко), а .resolved содержит хеш коммита:
>>> revision == "main"
True
>>> revision.resolved
'607a30d783dfa663caf39e06633721c8d4cfcd7e'Вспомогательные функции для загрузки (hf_hub_download(), snapshot_download(), get_cached_repo_tree()) определяют ResolvedRevision и используют хеш коммита напрямую. Каждый файл гарантированно поступает из одного и того же коммита, а после кэширования файлов HTTP-запросы не требуются вовсе:
>>> from huggingface_hub import hf_hub_download
>>> config = hf_hub_download("openai-community/gpt2", "config.json", revision=revision)
>>> weights = hf_hub_download("openai-community/gpt2", "model.safetensors", revision=revision)Сопоставление revision -> commit hash также записывается в папку refs/ кэша (см. Refs). Это означает, что если позже Hub недоступен (офлайн-режим, ошибка соединения, таймаут, простой Hub), HfApi.resolve_revision() прозрачно переключается на значение из кэша. Если в кэше тоже ничего нет, возникает RevisionResolutionError.
Хеш коммита имеет значение только для того репозитория, относительно которого он был разрешён, а помощники для загрузки используют его как есть. Поэтому ResolvedRevision следует передавать только в тот репозиторий, для которого он был разрешён. Если библиотека также загружает данные из другого репозитория (базовая модель, адаптер, компонент, находящийся в собственном репозитории, …), ей нужен ревизия, разрешённая для этого репозитория. Просто передайте ResolvedRevision обратно в HfApi.resolve_revision(): он запоминает, к какому репозиторию относится, и снова разрешает изначально запрошенную ревизию ("main" здесь) для нового репозитория.
>>> other_revision = resolve_revision("openai-community/gpt2-medium", revision=revision) # resolves "main" again
>>> other_revision.resolved
'6dcaa7a952f72f9298047fd5137cd6e4f05f41da'
>>> config = hf_hub_download("openai-community/gpt2-medium", "config.json", revision=other_revision)Кэширование Xet
Для обеспечения более эффективной загрузки hf_xet добавляет каталог xet в существующий кэш huggingface_hub. В нём хранятся шарды (структура данных, сопоставляющая файлы с фрагментами) и промежуточные данные, используемые для дедупликации и возобновления загрузки. Подробнее о системе хранения Xet см. в этом разделе.
hf_xet больше не использует локальный кэш чанков для загрузок. Установка переменной HF_XET_CHUNK_CACHE_SIZE_BYTES не активирует такой кэш. Скачанные файлы по-прежнему сохраняются в файловом кэше.
Каталог xet, по умолчанию расположенный в ~/.cache/huggingface/xet, можно настроить с помощью HF_XET_CACHE. Его структура следующая:
<CACHE_DIR> ├─ xet │ ├─ environment_identifier │ │ ├─ shard-cache │ │ ├─ staging
Каталог environment_identifier представляет собой закодированную строку (на вашем компьютере он может выглядеть как https___cas_serv-tGqkUaZf_CBPHQ6h). Это используется в процессе разработки, что позволяет локальным и производственным версиям кэша существовать одновременно. Также это применяется при загрузке из репозиториев, расположенных в разных регионах хранения. В каталоге xet вы можете увидеть несколько таких записей, каждая из которых соответствует отдельной среде, но их внутренняя структура одинакова.
Внутренние каталоги служат следующим целям:
shard-cacheсодержит кэшированные фрагменты, которые используются при загрузке.staging— это рабочее пространство, предназначенное для поддержки возобновляемых загрузок.
Они описаны ниже.
Кэш шардов и промежуточные данные управляются hf_xet как слой оптимизации для загрузок. Для управления загруженными файлами используйте файловые API кэша huggingface_hub.
shard-cache
Этот кэш используется при загрузке контента в Hub. Каталог плоский и содержит только файлы шардов, каждый из которых использует ID в качестве имени шарда.
<CACHE_DIR> ├─ xet │ ├─ environment_identifier │ │ ├─ shard-cache │ │ │ ├─ 1fe4ffd5cf0c3375f1ef9aec5016cf773ccc5ca294293d3f92d92771dacfc15d.mdb │ │ │ ├─ 906ee184dc1cd0615164a89ed64e8147b3fdccd1163d80d794c66814b3b09992.mdb │ │ │ ├─ ceeeb7ea4cf6c0a8d395a2cf9c08871211fbbd17b9b5dc1005811845307e6b8f.mdb │ │ │ ├─ e8535155b1b11ebd894c908e91a1e14e3461dddd1392695ddc90ae54a548d8b2.mdb
В shard-cache содержатся шарды, которые:
- Сгенерировано локально и успешно загружено в CAS
- Скачано из CAS в рамках глобального алгоритма дедупликации
Shards обеспечивают сопоставление файлов и фрагментов. Во время загрузки каждый файл разбивается на фрагменты, и хеш каждого фрагмента сохраняется. Затем проверяется каждый shard в кэше. Если shard содержит хеш фрагмента, который присутствует в локальном файле, загружаемом в данный момент, то этот фрагмент можно отбросить, поскольку он уже хранится в CAS.
Все фрагменты имеют срок действия 3–4 недели с момента их загрузки. Фрагменты, срок действия которых истёк, не загружаются при загрузке данных и удаляются через одну неделю после истечения срока действия.
staging
Если загрузка прерывается до того, как новый контент будет зафиксирован в репозитории, вам потребуется возобновить передачу файла. Однако возможно, что некоторые блоки были успешно загружены до прерывания.
Чтобы вам не приходилось начинать загрузку заново, каталог staging служит рабочей областью во время загрузки, храня метаданные успешно загруженных фрагментов. Каталог staging имеет следующую структуру:
<CACHE_DIR>
├─ xet
│ ├─ environment_identifier
│ │ ├─ staging
│ │ │ ├─ shard-session
│ │ │ │ ├─ 906ee184dc1cd0615164a89ed64e8147b3fdccd1163d80d794c66814b3b09992.mdb
│ │ │ │ ├─ xorb-metadata
│ │ │ │ │ ├─ 1fe4ffd5cf0c3375f1ef9aec5016cf773ccc5ca294293d3f92d92771dacfc15d.mdbПо мере обработки файлов и успешной загрузки чанков их метаданные сохраняются в xorb-metadata в виде шарда. При возобновлении сессии загрузки каждый файл обрабатывается повторно, и для проверки используются шарды в этом каталоге. Содержимое, которое было успешно загружено, пропускается, а новое содержимое загружается (и его метаданные сохраняются).
В то же время shard-session хранит информацию о файлах и фрагментах для обработанных файлов. При успешном завершении загрузки содержимое этих фрагментов перемещается в более долговечный shard-cache.
Ограничения
Кэш shard-cache имеет мягкое ограничение в 16 ГБ, которое можно настроить с помощью переменной окружения HF_XET_SHARD_CACHE_SIZE_LIMIT. Высокоуровневого API для управления этим кэшем нет.
Кэш шардов и промежуточные данные используются для оптимизации загрузок. Для работы с самими ресурсами рекомендуется использовать API системы кэша huggingface_hub.
Если вам необходимо освободить место, занятое Xet, или отладить потенциальные проблемы, связанные с кэшем, просто полностью удалите кэш xet, выполнив команду rm -rf ~/<cache_dir>/xet, где <cache_dir> — это расположение кэша Hugging Face, как правило, ~/.cache/huggingface
Пример дерева каталогов кэша xet:
<CACHE_DIR> ├─ xet │ ├─ environment_identifier │ │ ├─ shard-cache │ │ │ ├─ 1fe4ffd5cf0c3375f1ef9aec5016cf773ccc5ca294293d3f92d92771dacfc15d.mdb │ │ │ ├─ 906ee184dc1cd0615164a89ed64e8147b3fdccd1163d80d794c66814b3b09992.mdb │ │ │ ├─ ceeeb7ea4cf6c0a8d395a2cf9c08871211fbbd17b9b5dc1005811845307e6b8f.mdb │ │ │ ├─ e8535155b1b11ebd894c908e91a1e14e3461dddd1392695ddc90ae54a548d8b2.mdb │ │ ├─ staging │ │ │ ├─ shard-session │ │ │ │ ├─ 906ee184dc1cd0615164a89ed64e8147b3fdccd1163d80d794c66814b3b09992.mdb │ │ │ │ ├─ xorb-metadata │ │ │ │ │ ├─ 1fe4ffd5cf0c3375f1ef9aec5016cf773ccc5ca294293d3f92d92771dacfc15d.mdb
Чтобы узнать больше о Xet Storage, см. этот раздел.
Кэширование ресурсов
Помимо кэширования файлов из Hub, библиотеки нижнего уровня часто требуют кэширования других файлов, связанных с HF, но не обрабатываемых напрямую huggingface_hub (например, файлы, загруженные с GitHub, предобработанные данные, журналы и т. д.). Для кэширования таких файлов, называемых assets, можно использовать cached_assets_path(). Этот небольшой помощник генерирует пути в кэше HF единообразным образом на основе имени запрашивающей библиотеки и, при необходимости, пространства имён и имени подпапки. Цель состоит в том, чтобы позволить каждой библиотеке нижнего уровня управлять своими assets по-своему (например, без ограничений на структуру), при условии, что они остаются в правильной папке assets. Затем эти библиотеки могут использовать инструменты из huggingface_hub для управления кэшем, в частности, для сканирования и удаления частей assets из команды CLI.
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" # Do anything you like in your assets folder !cached_assets_path() — рекомендуемый способ хранения ресурсов, но он не обязателен. Если ваша библиотека уже использует собственный кэш, вы можете использовать его!
Ресурсы на практике
На практике кэш ваших ресурсов должен выглядеть как следующее дерево:
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/
└── (...)Управление файловой кэши
Осмотр кэша
На данный момент кэшированные файлы никогда не удаляются из вашего локального каталога: при загрузке новой ревизии ветки предыдущие файлы сохраняются на случай, если они снова понадобятся. Поэтому может быть полезно проверить каталог кэша, чтобы узнать, какие репозитории и ревизии занимают больше всего места на диске. huggingface_hub предоставляет вспомогательные функции, которые можно использовать из CLI hf или из Python.
Осмотр кэша из терминала
Выполните hf cache ls, чтобы посмотреть, что хранится локально. По умолчанию команда агрегирует
информацию по репозиториям:
➜ 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.
Добавьте --revisions, чтобы получить список всех кэшированных снапшотов, и используйте цепочки фильтров, чтобы сосредоточиться на важном. Фильтры понимают размеры и длительность в удобном для человека формате, поэтому выражения вроде size>1GB или accessed>30d работают сразу:
➜ 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.
Нужен вывод в машиночитаемом формате? Используйте --format json для получения структурированных объектов или --format csv для электронных таблиц. Альтернативный вариант — --quiet: он выводит только идентификаторы (по одному на строку), что позволяет передавать их в другие инструменты через конвейер. Используйте --sort, чтобы упорядочить записи по accessed, modified, name или size (добавьте :asc или :desc, чтобы задать порядок сортировки), а --limit — чтобы ограничить результат первыми N записями. Сочетайте эти параметры с --cache-dir, если нужно проверить кэш, хранящийся вне HF_HOME.
Фильтрация с помощью стандартных утилит оболочки
Табличный вывод означает, что вы можете продолжать использовать инструменты, которые вам уже знакомы. Например, фрагмент кода ниже находит все кэшированные ревизии, связанные с 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
Осмотр кэша из Python
Для более продвинутого использования воспользуйтесь scan_cache_dir() — это утилита на Python, которую вызывает CLI-инструмент.
Вы можете использовать его для получения подробного отчёта, структурированного вокруг 4 dataclasses:
- HFCacheInfo: полный отчёт, возвращаемый scan_cache_dir()
- CachedRepoInfo: информация о кэшированном репозитории
- CachedRevisionInfo: информация о кэшированной ревизии (например, «snapshot») внутри репозитория
- CachedFileInfo: информация о кэшированном файле в снимке
Вот простой пример использования. Подробности — в справочнике.
>>> 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(...),
...
],
)Проверьте кэш
huggingface_hub может проверить, что ваши кэшированные файлы соответствуют контрольным суммам на Hub. Используйте CLI hf cache verify, чтобы проверить целостность файлов для конкретного ревизии конкретного репозитория:
>>> hf cache verify meta-llama/Llama-3.2-1B-Instruct
✅ Verified 13 file(s) for 'meta-llama/Llama-3.2-1B-Instruct' (model) in ~/.cache/huggingface/hub/models--meta-llama--Llama-3.2-1B-Instruct/snapshots/9213176726f574b556790deb65791e0c5aa438b6
All checksums match.Проверьте конкретную кэшированную ревизию:
>>> hf cache verify meta-llama/Llama-3.1-8B-Instruct --revision 0e9e39f249a16976918f6564b8830bc894c89659См. справку по CLI
hf cache verifyдля получения подробной информации об использовании и полного списка параметров.
Очистите кэш
Сканирование кэша — это интересно, но обычно следующим шагом вы хотите удалить некоторые его части, чтобы освободить место на диске. Это можно сделать с помощью команд CLI hf cache rm и hf cache prune. Также можно программно использовать помощники delete_revisions() и delete_files() из объекта HFCacheInfo, который возвращается при сканировании кэша.
Стратегия удаления
Чтобы удалить часть кэша, необходимо передать список ревизий для удаления. На основе этого списка инструмент определяет стратегию освобождения места. Возвращается объект DeleteCacheStrategy, описывающий, какие файлы и папки будут удалены. Объект DeleteCacheStrategy позволяет узнать, сколько места ожидается к освобождению. После того как вы согласитесь с удалением, его необходимо выполнить, чтобы изменения вступили в силу. Чтобы избежать расхождений, вручную редактировать объект стратегии нельзя.
Стратегия удаления ревизий следующая:
- удаляется папка
snapshot, содержащая символьные ссылки на ревизии. - Файлы blobs, на которые ссылаются только удаляемые ревизии, также удаляются.
- если ревизия связана с одним или несколькими
refs, ссылки удаляются. - если все ревизии из репозитория удалены, весь кэшированный репозиторий удаляется.
Удаление отдельных файлов с помощью delete_files() подчиняется той же логике: записи снимков удаляются, а их блоки (blobs) удаляются только в том случае, если на них не ссылаются другие кэшированные файлы. Ссылки (refs) и папки снимков сохраняются.
Хеши ревизий уникальны во всех репозиториях. Поэтому
hf cache rmпринимает либо идентификатор репозитория (например,model/bert-base-uncased), либо «голый» хеш ревизии; при передаче хеша указывать репозиторий отдельно не нужно.
Если ревизия не найдена в кэше, она будет молча проигнорирована. Кроме того, если файл или папка не найдены при попытке их удаления, в журнал будет записано предупреждение, но ошибка не будет выброшена. Удаление продолжится для остальных путей, содержащихся в объекте DeleteCacheStrategy.
Очистить кэш из терминала
Используйте hf cache rm для постоянного удаления репозиториев или ревизий из кэша. Передайте
один или несколько идентификаторов репозиториев (например, model/bert-base-uncased) или хэши ревизий:
➜ 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.
Вы также можете использовать hf cache rm в сочетании с hf cache ls --quiet, чтобы массово удалить записи, выбранные по фильтру:
>>> hf cache rm $(hf cache ls --filter "accessed>1y" -q) -y
About to delete 2 repo(s) totalling 5.31G.
- model/meta-llama/Llama-3.2-1B-Instruct (entire repo)
- model/hexgrad/Kokoro-82M (entire repo)
Deleted 2 repo(s) and 2 revision(s); freed 5.31G.Смешивайте репозитории и ревизии в одном вызове. Добавьте --dry-run, чтобы просмотреть влияние,
или --yes, чтобы пропустить запрос подтверждения при использовании в скриптах:
➜ 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.Чтобы удалить отдельный файл, а не весь репозиторий, например, одну GGUF-квантизацию, передайте URI файла hf://. Файл удаляется из всех кэшированных ревизий репозитория, а его blob удаляется только в том случае, если на него больше не ссылаются другие кэшированные файлы. Ревизия остаётся доступной, а удалённый файл будет скачан повторно при следующем обращении к нему. Пути должны совпадать точно: папки и glob-паттерны не поддерживаются.
➜ hf cache rm hf://models/unsloth/gemma-3-27b-it-GGUF/gemma-3-27b-it-Q4_K_M.gguf --dry-run About to delete 1 file(s) totalling 16.5G. - model/unsloth/gemma-3-27b-it-GGUF@3f4b5c1d2e6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c/gemma-3-27b-it-Q4_K_M.gguf Dry run: no files were deleted.
При работе вне расположения кэша по умолчанию используйте команду в паре с --cache-dir PATH.
Чтобы массово очистить кэш от мусора, выполните hf cache prune. Команда автоматически удаляет ревизии, на которые больше не ссылаются ветки или теги, оставшиеся файлы .incomplete от прерванных загрузок, а также общие блоки данных, на которые больше не ссылаются ни один из кэшированных репозиториев:
➜ hf cache prune
About to delete 3 unreferenced revision(s) and 2 incomplete download(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) and 2 incomplete download(s); freed 2.4G.Файлы .incomplete — это частичные объекты, оставшиеся после прерванной загрузки. Они не отслеживаются при сканировании по ревизиям, поэтому hf cache ls лишь указывает на них подсказкой (Found X incomplete download(s) ...), тогда как именно команда hf cache prune удаляет их. Команда hf cache rm никогда не затрагивает такие файлы, за исключением случаев, когда удаляется весь репозиторий.
Обе команды поддерживают --dry-run, --yes и --cache-dir, что позволяет просматривать изменения, автоматизировать процесс и указывать альтернативные каталоги кэша по мере необходимости.
Очистить кэш из Python
Для большей гибкости вы также можете использовать метод delete_revisions() программно. Ниже приведен простой пример. Подробности — в справочнике.
>>> 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()