Hub documentation

Локальный кэш Hub

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Локальный кэш Hub

Этот документ описывает структуру хранения данных локального кэша HF Hub на диске. Он предназначен в качестве справочного материала для повторной реализации системы кэширования на любом языке.

Ниже приведён частичный список библиотек и приложений, использующих эту структуру кэша. Пожалуйста, отправьте PR, чтобы добавить свой проект.

Библиотеки

БиблиотекаЯзыкПримечания
huggingface_hubPythonИ любая библиотека, которая от него зависит (например, transformers, diffusers, datasets, mlx, vllm …)
hf-hubRust
swift-huggingfaceSwift
@huggingface/hubJavaScriptТолько Node.js
SMILEJavaСм. документацию HuggingFaceHub

Приложения

ПрименениеЯзыкПримечания
llama.cppC++С момента #20775
Llama-macOSSwiftmacOS-приложение, созданное на базе llama.cpp
HuggingFaceModelDownloaderПерейти
oMLXPythonСервер инференса MLX для macOS, начиная с 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/ с адресацией по содержимому и доступны через символьные ссылки в snapshots/. Именованные ссылки (ветки, теги) отслеживаются в refs/. Начиная с huggingface_hub 1.32, файлы, загруженные с помощью hf_xet, хранятся один раз для всего кэша в общем хранилище блобов в корне кэша. Запись 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}

Именование папок репозитория

Репозитории хранятся в виде плоских каталогов в корне кэша. Имя папки кодирует тип репозитория и его идентификатор:

{type}s--{repo_id_with_slashes_replaced_by_--}

Правила:

  • Тип репозитория принимает множественное число: models, datasets, spaces
  • Символы прямой косой черты (/) в идентификаторе репозитория заменяются на --
  • Разделитель между всеми частями — --
  • Регистр символов сохраняется

Примеры:

ID репозитория HubТип репозиторияИмя папки кэша
julien-c/EsperBERTo-smallмодельmodels--julien-c--EsperBERTo-small
huggingface/DataMeasurementsFilesdatasetdatasets--huggingface--DataMeasurementsFiles
dalle-mini/dalle-minispacespaces--dalle-mini--dalle-mini

Buckets не обрабатываются этим кэшем, так как они не поддерживаются git. Вместо этого используйте специальную команду hf buckets sync.

Внутри папки репозитория

Каждое кэшированное репозиторий имеет одинаковую внутреннюю структуру:

<repo_folder>/
├── blobs/
├── refs/
├── snapshots/
└── .no_exist/    # may not always be present

blobs/ : хранилище файлов с адресацией по содержимому

Каталог blobs/ хранит фактическое содержимое файлов. Имя каждого файла соответствует его etag на Hub:

  • Файлы, отслеживаемые Git: идентифицируются по их хешу SHA-1 (40 шестнадцатеричных символов)
  • Файлы Git LFS: именуемые по их хэшу SHA-256 (64 шестнадцатеричных символа)

Это плоский каталог — без подкаталогов. Идентичные файлы в разных ревизиях хранятся только один раз. Запись представляет собой либо обычный файл, либо относительную символьную ссылку в общее хранилище блобов; читателям следует переходить по ней.

blobs/
├── 403450e234d65943a7dcf7e05a771ce3c92faa84dd07db4ac20f592037a1e4bd   # SHA-256 (LFS)
├── 7cb18dc9bafbfcf74629a4b760af1b160957a83e                           # SHA-1 (git)
└── d7edf6bd2a681fb0175f7735299831ee1b22b812                           # SHA-1 (git)

refs/: ссылки на ветки и теги

Каталог refs/ сопоставляет человекочитаемые ссылки (имена веток, теги, номера PR) с хэшами коммитов.

Каждая ссылка представляет собой текстовый файл, содержащий одну строку: полный хеш коммита (40 шестнадцатеричных символов).

refs/
├── main            # contains e.g. "bbc77c8132af1cc5cf678da3f1ddf2de43606d48"
├── 2.4.0           # a tag
└── refs/
    └── pr/
        └── 1       # pull request reference

Когда файл загружается с использованием имени ветки или тега, соответствующий файл ref создаётся или обновляется с последним хэшем коммита.

snapshots/ : представления ревизий

Каталог snapshots/ содержит один подкаталог для каждой кэшированной ревизии (хеш коммита). Каждый каталог ревизии повторяет структуру файлов репозитория на Hub, но файлы являются символическими ссылками, указывающими на ../../blobs/{hash}.

snapshots/
├── 2439f60ef33a0d46d85da5001d52aeda5b00ce9f/
│   ├── README.md -> ../../blobs/d7edf6bd2a681fb0175f7735299831ee1b22b812
│   └── pytorch_model.bin -> ../../blobs/403450e234d65943a7dcf7e05a771ce3c92faa84dd07db4ac20f592037a1e4bd
└── bbc77c8132af1cc5cf678da3f1ddf2de43606d48/
    ├── README.md -> ../../blobs/7cb18dc9bafbfcf74629a4b760af1b160957a83e
    └── pytorch_model.bin -> ../../blobs/403450e234d65943a7dcf7e05a771ce3c92faa84dd07db4ac20f592037a1e4bd

Ключевые свойства:

  • Символические ссылки используют относительные пути: ../../blobs/{hash}
  • Если файл не изменялся между двумя ревизиями, оба символических ссылки указывают на один и тот же blob без дублирования данных
  • Файлы в подкаталогах на Hub представлены в снапшоте как подкаталоги (полный относительный путь сохраняется)

Переключение между снимками аналогично использованию git checkout в локальном git-репозитории.

.no_exist/ : кэш отсутствия

Каталог .no_exist/ отслеживает файлы, которые запрашивались, но отсутствуют в Hub. Это позволяет избежать повторных HTTP-запросов для необязательных файлов.

Структура повторяет структуру snapshots/: один подкаталог на каждый хеш коммита, содержащий пустые файлы (не символьные ссылки) с именами отсутствующих файлов.

.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 отключает хранилище
  • Только новые загрузки проходят через хранилище. Файлы, записанные более старыми версиями или другими клиентами, остаются обычными файлами в папке репозитория, поэтому кэш может содержать и то, и другое

Реализации, которые только читают кэш, не требуют изменений: переход по символическим ссылкам работает как и прежде.

Реализации, удаляющие данные из кэша, должны рассматривать blob репозитория, являющийся символьной ссылкой, как ссылку на хранилище:

  • Удалите символьную ссылку в 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 file

Обратите внимание, что pytorch_model.bin указывает на один и тот же blob в обеих ревизиях. Файл размером 321 МБ хранится на диске только один раз.

Логика разрешения файлов

Чтобы найти кэшированный файл на диске:

  1. Разрешить ревизию в хеш коммита

    • Если ревизия уже является 40-символьной шестнадцатеричной строкой, используйте её напрямую
    • В противном случае прочитайте файл по пути refs/{revision}, чтобы получить хеш коммита
  2. Проверьте снимок

    • Ищите snapshots/{commit_hash}/{relative_path}
    • Если файл существует (в виде символической ссылки или обычного файла), он кэшируется. Следуйте по символической ссылке, чтобы получить содержимое
  3. Проверка отсутствия

    • Ищите .no_exist/{commit_hash}/{relative_path}
    • Если файл существует, то известно, что он отсутствует на Hub для данной ревизии
  4. Промах кэша

    • Если ни один из путей не существует, файл ещё не был закэширован

Поведение в Windows

Кэш использует символические ссылки. На системах Windows, где символические ссылки недоступны, кэш работает в деградированном режиме: вместо ссылок в snapshots/ размещаются фактические копии файлов. В этом режиме каталог blobs/ и общий хранилище блобов не используются.

Это означает, что содержимое одного и того же файла может дублироваться между ревизиями, что увеличивает использование дискового пространства. Чтобы включить поддержку символьных ссылок в Windows, активируйте Developer Mode или запустите процесс от имени администратора.

Update on GitHub