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을 열어 주세요.

라이브러리

라이브러리언어The input is a single word "Notes". 참고
huggingface_hubPython그리고 이를 의존하는 모든 라이브러리(예: transformers, diffusers, datasets, mlx, vllm …)
hf-hubRust
swift-huggingfaceSwift
@huggingface/hubJavaScriptNode.js 전용
SMILEJavaHuggingFaceHub 문서를 참조하세요

응용 프로그램

Application언어The input is a single word "Notes". 참고
llama.cppC++#20775 이후
Llama-macOSSwiftllama.cpp 기반으로 구축된 macOS 앱
HuggingFaceModelDownloader시작
oMLXPythonmacOS 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/ 디렉터리에 한 번만 저장되고, 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}

리포지토리 폴더 이름

Repositories는 캐시 루트에서 평탄한 디렉터리로 저장됩니다. 폴더 이름에는 리포지토리 유형과 리포지토리 ID가 인코딩되어 있습니다:

{type}s--{repo_id_with_slashes_replaced_by_--}

규칙:

  • 리포지토리 유형은 복수형으로 표시됩니다: models, datasets, spaces
  • 리포지토리 ID의 슬래시(/)는 --로 대체됩니다
  • 모든 부분 사이의 구분자는 --입니다.
  • 대소문자가 유지됩니다

예:

Hub 저장소 ID레포지토리 유형캐시 폴더 이름
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/ 디렉터리에는 실제 파일 내용이 저장됩니다. 각 파일은 Hub의 파일 etag를 파일 이름으로 사용합니다:

  • Git 추적 파일: SHA-1 해시(16진수 40자)로 이름이 지정됨
  • Git LFS 파일: SHA-256 해시(16진수 64자)로 이름이 지정됩니다

이것은 평탄한 디렉터리이며 하위 디렉터리가 없습니다. 다른 리비전 간에 동일한 파일은 한 번만 저장됩니다. 항목은 일반 파일이거나 shared blob store로 향하는 상대 심볼릭 링크입니다. 리더는 이를 따라야 합니다.

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

refs/: 브랜치 및 태그 참조

refs/ 디렉터리는 사람이 읽을 수 있는 참조(브랜치 이름, 태그, PR 번호)를 커밋 해시로 매핑합니다.

각 참조는 단일 줄로 구성된 일반 텍스트 파일이며, 이 줄에는 전체 커밋 해시(16진수 40자)가 포함되어 있습니다.

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

branch 또는 tag 이름으로 파일이 다운로드되면, 해당 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

주요 속성:

  • Symlinks는 상대 경로를 사용합니다: ../../blobs/{hash}
  • 두 리비전 사이에 파일이 변경되지 않은 경우, 두 심볼릭 링크 모두 동일한 blob을 가리키며 데이터 중복이 발생하지 않습니다
  • Hub의 하위 디렉토리에 있는 파일은 스냅샷에서 하위 디렉토리로 표시됩니다(전체 상대 경로가 유지됩니다).

스냅샷을 전환하는 것은 로컬 git 저장소에서 git checkout를 사용하는 것과 유사합니다.

.no_exist/ : 비존재 캐시

.no_exist/ 디렉터리는 Hub에 존재하지 않지만 요청된 파일들을 추적합니다. 이를 통해 선택적 파일에 대한 반복적인 HTTP 요청을 방지합니다.

구조는 snapshots/와 동일합니다. 각 커밋 해시마다 하위 디렉터리가 하나씩 있으며, 누락된 파일 이름으로 명명된 빈 파일(심볼릭 링크가 아님)을 포함합니다.

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

이것들은 빈 마커 파일일 뿐이므로 디스크 사용량은 무시할 수 있는 수준입니다.

공유된 blob 저장소

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와 공유 파일은 매니페스트에 나열된 심볼릭 링크가 더 이상 해당 파일로 가리키지 않는 경우에만 삭제합니다
  • manifest가 없거나 읽을 수 없는 경우, 공유 파일을 유지합니다

삭제 동작 및 이전 버전 클라이언트의 제한 사항에 대해서는 huggingface_hub 캐시 가이드를 참조하세요.

락 파일

Lock 파일은 동시 실행 중인 프로세스가 동일한 blob을 동시에 다운로드하는 것을 방지합니다. 캐시 루트(리포지토리 폴더 내부가 아닌)의 .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 MB 파일은 디스크에 한 번만 저장됩니다.

파일 해석 로직

디스크에서 캐시된 파일을 찾으려면:

  1. 리비전을 커밋 해시로 해석

    • 수정판이 이미 40자 16진 문자열인 경우, 이를 그대로 사용합니다.
    • 그렇지 않은 경우, refs/{revision}에 있는 파일을 읽어서 커밋 해시를 가져옵니다
  2. 스냅샷 확인

    • snapshots/{commit_hash}/{relative_path}를 찾아보세요
    • (심볼릭 링크 또는 파일로) 존재하는 경우, 해당 파일은 캐시에 저장됩니다. 심볼릭 링크를 따라가면 콘텐츠를 가져올 수 있습니다
  3. 존재하지 않는지 확인

    • .no_exist/{commit_hash}/{relative_path}을(를) 찾아보세요
    • 존재하는 경우, 해당 파일은 이 리비전에서는 Hub에 존재하지 않는 것으로 알려져 있습니다
  4. 캐시 미스

    • 두 경로 모두 존재하지 않으면, 해당 파일은 아직 캐시되지 않은 것입니다.

Windows 동작

캐시는 심볼릭 링크에 의존합니다. 심볼릭 링크를 사용할 수 없는 Windows 시스템에서는 캐시가 제한된 모드로 작동합니다. 이 모드에서는 심볼릭 링크 대신 실제 파일 사본이 snapshots/에 직접 배치됩니다. blobs/ 디렉터리와 공유 blob 저장소는 이 모드에서 사용되지 않습니다.

이는 동일한 파일 내용이 리비전 간에 중복되어 디스크 사용량이 증가할 수 있음을 의미합니다. Windows에서 심볼릭 링크(symlink) 지원을 활성화하려면 개발자 모드를 활성화하거나 관리자로 실행하세요.

Update on GitHub