Hub documentation

Cache local do Hub

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Cache local do Hub

Este documento descreve o layout em disco do cache local do HF Hub. Ele é destinado a servir como referência para reimplementar o sistema de cache em qualquer linguagem.

Aqui está uma lista parcial de bibliotecas e aplicativos que usam esse layout de cache. Abra um PR para adicionar o seu.

Bibliotecas

BibliotecaIdiomaObservações
huggingface_hubPythonE qualquer biblioteca que dependa dela (por exemplo, transformers, diffusers, datasets, mlx, vllm …)
hf-hubRust
swift-huggingfaceSwift
@huggingface/hubJavaScriptApenas Node.js
SMILEJavaVeja a documentação de HuggingFaceHub

Aplicações

AplicaçãoIdiomaObservações
llama.cppC++Desde #20775
Llama-macOSSwiftaplicativo para macOS, construído com llama.cpp
HuggingFaceModelDownloaderIr
oMLXPythonServidor de inferência MLX para macOS, desde a v0.4.0

Local do cache

O diretório de cache padrão é:

~/.cache/huggingface/hub

Isso pode ser substituído por variáveis de ambiente:

  • HF_HUB_CACHE - caminho direto para o diretório de cache (tem prioridade)
  • HF_HOME - caminho para o diretório inicial do Hugging Face; se definido, o cache fica em $HF_HOME/hub

Visão geral

<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

Cada repositório baixado recebe uma única pasta plana. Dentro de cada pasta de repositório, os arquivos são armazenados uma vez em um diretório blobs/ com endereçamento por conteúdo e acessados por meio de links simbólicos em snapshots/. Referências nomeadas (branches, tags) são rastreadas em refs/. Desde a versão 1.32 do huggingface_hub, os arquivos baixados com hf_xet são armazenados uma vez para todo o cache, em um armazenamento de blobs compartilhado na raiz do cache. A entrada blobs/ do repositório é, então, um link simbólico para esse arquivo.

Esquema

                     ┌──────────────────────────────────────────┐
                     │           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}

Nomeação de pastas do repositório

Os repositórios são armazenados como diretórios planos na raiz do cache. O nome da pasta codifica o tipo de repositório e o ID do repositório:

{type}s--{repo_id_with_slashes_replaced_by_--}

Regras:

  • O tipo de repositório é pluralizado: models, datasets, spaces
  • As barras diagonais (/) no ID do repositório são substituídas por --
  • O separador entre todas as partes é --
  • A capitalização é preservada

Exemplos:

ID do repositório no HubTipo de repositórioNome da pasta de cache
julien-c/EsperBERTo-smallmodelmodels--julien-c--EsperBERTo-small
huggingface/DataMeasurementsFilesdatasetdatasets--huggingface--DataMeasurementsFiles
dalle-mini/dalle-minispacespaces--dalle-mini--dalle-mini

Buckets não são tratados por este cache, pois não são baseados em git. Use o comando dedicado hf buckets sync em vez disso.

Dentro de uma pasta de repositório

Todo repositório em cache possui a mesma estrutura interna:

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

blobs/ : armazenamento de arquivos endereçado por conteúdo

O diretório blobs/ armazena o conteúdo real dos arquivos. Cada arquivo é nomeado de acordo com seu etag de arquivo no Hub:

  • Arquivos rastreados pelo Git: nomeados pelo seu hash SHA-1 (40 caracteres hexadecimais)
  • Arquivos Git LFS: nomeados pelo seu hash SHA-256 (64 caracteres hexadecimais)

Este é um diretório plano — sem subdiretórios. Arquivos idênticos em diferentes revisões são armazenados apenas uma vez. Uma entrada é um arquivo regular ou um link simbólico relativo para o shared blob store; os leitores devem segui-lo.

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

refs/ : referências de branch e tag

O diretório refs/ mapeia referências legíveis por humanos (nomes de branches, tags, números de PRs) para hashes de commit.

Cada referência é um arquivo de texto simples contendo uma única linha: o hash completo do commit (40 caracteres hexadecimais).

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

Quando um arquivo é baixado usando o nome de uma branch ou tag, o arquivo ref correspondente é criado ou atualizado com o hash do commit mais recente.

snapshots/ : visualizações de revisão

O diretório snapshots/ contém um subdiretório para cada revisão em cache (hash do commit). Cada diretório de revisão espelha a estrutura de arquivos do repositório no Hub, mas os arquivos são symlinks que apontam para ../../blobs/{hash}.

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

Principais propriedades:

  • Symlinks usam caminhos relativos: ../../blobs/{hash}
  • Se um arquivo não foi alterado entre duas revisões, ambos os links simbólicos apontam para o mesmo blob, sem duplicação de dados
  • Arquivos em subdiretórios no Hub são representados como subdiretórios no snapshot (o caminho relativo completo é preservado)

Alternar entre snapshots é semelhante ao uso de git checkout em um repositório git local.

.no_exist/ : cache de inexistência

O diretório .no_exist/ rastreia arquivos que foram solicitados, mas que não existem no Hub. Isso evita solicitações HTTP repetidas para arquivos opcionais.

A estrutura espelha snapshots/: um subdiretório para cada hash de commit, contendo arquivos vazios (não links simbólicos) nomeados de acordo com o arquivo ausente.

.no_exist/
└── 2439f60ef33a0d46d85da5001d52aeda5b00ce9f/
    └── config_that_does_not_exist.json    # empty file

O uso do disco é insignificante, pois se trata apenas de arquivos marcadores vazios.

Armazenamento de blobs compartilhado

Arquivos baixados por meio do Xet são deduplicados entre repositórios. Tal arquivo é armazenado uma única vez na raiz do cache, sob blobs/, e cada repositório que precisa dele recebe um link simbólico relativo em vez de uma cópia:

<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

Principais propriedades:

  • A entrada do repositório mantém seu nome de etag e se torna um link simbólico relativo: ../../blobs/{xet_hash[:2]}/{xet_hash}
  • O layout de snapshots/ não muda, portanto a resolução de arquivos não é afetada
  • O arquivo marcador identifica o armazenamento: um diretório blobs/ não vazio na raiz do cache sem ele nunca é usado ou modificado
  • A loja requer links simbólicos e hf_xet. Se o compartilhamento falhar, o arquivo é armazenado na pasta do repositório como antes. HF_HUB_DISABLE_SHARED_BLOBS=1 desativa a loja
  • Apenas novos downloads passam pela loja. Arquivos gravados por versões anteriores ou por outros clientes permanecem como arquivos comuns na pasta do repositório, portanto, um cache pode conter ambos

Implementações que apenas leem o cache não precisam de alterações: seguir links simbônicos funciona como antes.

Implementações que removem itens do cache devem tratar um blob de repositório que é um link simbólico como uma referência para o armazenamento:

  • Exclua o link simbólico no blobs/ do repositório, não o arquivo compartilhado para o qual ele aponta
  • Bloqueie <xet_hash>.lock antes de verificar o manifesto e excluir
  • Exclua o arquivo compartilhado e seu .refs apenas se nenhum link simbólico listado no manifesto ainda apontar para ele
  • Se o manifesto estiver ausente ou não puder ser lido, mantenha o arquivo compartilhado

Consulte o guia de cache do huggingface_hub para conhecer o comportamento de exclusão e as limitações com clientes mais antigos.

Arquivos de bloqueio

Arquivos de bloqueio impedem que processos concorrentes baixem o mesmo blob simultaneamente. Eles são armazenados em um diretório .locks/ na raiz do cache (não dentro da pasta do repositório):

<CACHE_DIR>/.locks/<repo_folder_name>/<blob_hash>.lock

Exemplo:

<CACHE_DIR>/.locks/models--julien-c--EsperBERTo-small/403450e234d65943a7dcf7e05a771ce3c92faa84dd07db4ac20f592037a1e4bd.lock

Exemplo completo

~/.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

Observe como pytorch_model.bin aponta para o mesmo blob em ambas as revisões. O arquivo de 321 MB é armazenado apenas uma vez no disco.

Lógica de resolução de arquivos

Para localizar um arquivo em cache no disco:

  1. Resolve a revisão para um hash de commit

    • Se a revisão já for uma string hexadecimal de 40 caracteres, use-a diretamente
    • Caso contrário, leia o arquivo em refs/{revision} para obter o hash do commit
  2. Verifique o snapshot

    • Procure por snapshots/{commit_hash}/{relative_path}
    • Se existir (como um link simbólico ou arquivo), o arquivo é armazenado em cache. Siga o link simbólico para obter o conteúdo
  3. Verificar inexistência

    • Procure por .no_exist/{commit_hash}/{relative_path}
    • Se existir, o arquivo é conhecido por não existir no Hub para esta revisão
  4. Cache miss

    • Se nenhum dos caminhos existir, o arquivo ainda não foi armazenado em cache

Comportamento no Windows

O cache depende de links simbólicos. Em sistemas Windows em que os links simbólicos não estão disponíveis, o cache opera em modo degradado: cópias reais dos arquivos são colocadas diretamente em snapshots/ em vez de links simbólicos. O diretório blobs/ e o armazenamento de blobs compartilhado não são usados neste modo.

Isso significa que o mesmo conteúdo de arquivo pode ser duplicado entre revisões, aumentando o uso do disco. Para habilitar o suporte a links simbólicos no Windows, ative o Developer Mode ou execute como administrador.

Update on GitHub