# Hub Yerel Önbellek

Bu belge, HF Hub yerel önbelleğinin disk üzerindeki yerleşimini açıklar. Herhangi bir dilde önbellek sistemini yeniden uygulamak için bir başvuru kaynağı olarak tasarlanmıştır.

Bu önbellek düzenini kullanan kütüphanelerin ve uygulamaların kısmi bir listesi aşağıdadır. Kendi projenizi eklemek için lütfen bir PR açın.

### Kütüphaneler

| Kütüphane | Dil | Notlar |
|---------|----------|-------|
| [`huggingface_hub`](https://github.com/huggingface/huggingface_hub) | Python | Ve ona bağımlı olan herhangi bir kütüphane (ör. `transformers`, `diffusers`, `datasets`, `mlx`, `vllm` …) |
| [`hf-hub`](https://github.com/huggingface/hf-hub) | Rust | |
| [`swift-huggingface`](https://github.com/huggingface/swift-huggingface) | Swift | |
| [`@huggingface/hub`](https://github.com/huggingface/huggingface.js) | JavaScript | Sadece Node.js |
| [`SMILE`](https://github.com/haifengl/smile) | Java | [`HuggingFaceHub`](https://haifengl.github.io/api/java/smile/util/HuggingFaceHub.html) belgelerini görüntüleyin |

### Uygulamalar

| Uygulama | Dil | Notlar |
|-------------|----------|-------|
| [`llama.cpp`](https://github.com/ggml-org/llama.cpp) | C++ | [#20775](https://github.com/ggml-org/llama.cpp/pull/20775) sonrası |
| [`Llama-macOS`](https://github.com/ggml-org/Llama-macOS) | Swift | `llama.cpp` üzerine inşa edilmiş macOS uygulaması |
| [`HuggingFaceModelDownloader`](https://github.com/bodaay/HuggingFaceModelDownloader) | Başla | |
| [`oMLX`](https://github.com/jundot/omlx) | Python | macOS MLX çıkarım sunucusu, [v0.4.0](https://github.com/jundot/omlx/commit/341aebbeaba1ca3452f83dedf03a0d102cef9fd4) sürümünden itibaren |

## Önbellek konumu

Varsayılan önbellek dizini şudur:

```
~/.cache/huggingface/hub
```

Bu, ortam değişkenleriyle geçersiz kılınabilir:
- `HF_HUB_CACHE` - önbellek dizinine doğrudan yol (önceliklidir)
- `HF_HOME` - Hugging Face ana dizinine giden yol; ayarlanırsa önbellek `$HF_HOME/hub` konumunda tutulur

## Genel Bakış

```
<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
```

Her indirilen depo, tek bir düz klasöre sahip olur. Her depo klasörünün içinde, dosyalar bir kez `blobs/` dizininde saklanır ve `snapshots/` sembolik bağlantıları üzerinden erişilir. Adlandırılmış referanslar (dallar, etiketler) `refs/` içinde izlenir. `huggingface_hub` 1.32 sürümünden itibaren, `hf_xet` ile indirilen dosyalar, önbellek kökünde bir [ortak blob deposu](#shared-blob-store) içinde tüm önbellek için bir kez saklanır. Deponun `blobs/` girdisi, o dosyaya giden bir sembolik bağlantıdır.

## Şema

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

## Depo klasörü adlandırma

Depolar, önbellek kökünde düz dizinler olarak saklanır. Klasör adı, depo türünü ve depo kimliğini kodlar:

```
{type}s--{repo_id_with_slashes_replaced_by_--}
```

Kurallar:
- Depo türü **çoğul**dur: `models`, `datasets`, `spaces`
- Depo kimliğindeki ileri eğik çizgiler (`/`) `--` ile değiştirilir
- Tüm parçalar arasındaki ayırıcı `--`'dir
- Büyük/küçük harf kullanımı korunur

Örnekler:

| Hub depo kimliği                          | Depo türü | Önbellek klasörü adı                            |
|--------------------------------------|-----------|----------------------------------------------|
| `julien-c/EsperBERTo-small`         | model     | `models--julien-c--EsperBERTo-small`         |
| `huggingface/DataMeasurementsFiles`  | dataset   | `datasets--huggingface--DataMeasurementsFiles` |
| `dalle-mini/dalle-mini`             | space     | `spaces--dalle-mini--dalle-mini`             |

> [!NOTE]
> Buckets, git tabanlı olmadıkları için bu önbellek tarafından işlenmez. Bunun yerine, özel `hf buckets sync` komutunu kullanın.

## Bir depo klasörünün içinde

Önbelleğe alınan her depo aynı iç yapıya sahiptir:

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

### `blobs/`: içerik adresli dosya depolama

`blobs/` dizini, dosya içeriklerini saklar. Her dosya, Hub üzerindeki dosya etag'ına göre adlandırılır:

- **Git tarafından izlenen dosyalar**: **SHA-1** özetleri (40 onaltılık karakter) ile adlandırılır
- **Git LFS dosyaları**: **SHA-256** özetleri (64 onaltılık karakter) ile adlandırılır

Bu düz bir dizindir -- alt dizinler yoktur. Farklı revizyonlar arasında aynı olan dosyalar yalnızca bir kez saklanır. Bir kayıt, ya normal bir dosyadır ya da [ortak blob deposuna](#shared-blob-store) giden göreli bir sembolik bağlantıdır; okuyucular bunu takip etmelidir.

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

### `refs/`: dal ve etiket referansları

`refs/` dizini, insan tarafından okunabilir referansları (dal adları, etiketler, PR numaraları) commit hash değerlerine eşler.

Her referans, tek bir satır içeren düz bir metin dosyasıdır: tam commit hash'i (40 onaltılık karakter).

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

Bir dosya, bir dal veya etiket adı kullanılarak indirildiğinde, ilgili ref dosyası en son commit hash'i ile oluşturulur veya güncellenir.

### `snapshots/`: revizyon görünümleri

`snapshots/` dizini, önbelleğe alınan her revizyon (commit hash) için bir alt dizin içerir. Her revizyon dizini, Hub'daki depoyun dosya yapısını yansıtır ancak dosyalar `../../blobs/{hash}` içine işaret eden **sembolik bağlantılardır**.

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

Özellikler:
- Symlinks **göreli yollar** kullanır: `../../blobs/{hash}`
- Bir dosya iki revizyon arasında değişmediyse, her iki sembolik bağlantı da veri kopyalanması olmadan **aynı blob**'a işaret eder
- Hub'daki alt dizinlerdeki dosyalar, görüntüde alt dizinler olarak temsil edilir (tam göreli yol korunur)

Anlık görüntüler arasında geçiş yapmak, yerel bir git deposunda `git checkout` kullanmaya benzer.

### `.no_exist/`: var olmayan önbellek

`.no_exist/` dizini, Hub üzerinde bulunmayan ancak istenen dosyaları izler. Bu, isteğe bağlı dosyalar için tekrarlayan HTTP isteklerini önler.

Yapı `snapshots/` dizinini yansıtır: her commit hash'i için bir alt dizin, eksik dosyanın adını taşıyan **boş dosyalar** (sembolik bağlantılar değil) içerir.

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

Bu yalnızca boş işaretçi dosyaları olduğu için disk kullanımı ihmal edilebilir düzeydedir.

## Paylaşımlı blob deposu

Xet üzerinden indirilen dosyalar, depolar arasında tekilleştirilir. Bu tür bir dosya, önbellek kökünde `blobs/` altında bir kez saklanır ve ona ihtiyaç duyan her depo, bir kopya yerine göreli bir sembolik bağlantı alır:

```
<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
```

Özellikler:
- Depo girişi etag adını korur ve **göreceli sembolik bağlantı** haline gelir: `../../blobs/{xet_hash[:2]}/{xet_hash}`
- `snapshots/` düzeni değişmediğinden [dosya çözümleme](#file-resolution-logic) etkilenmez
- İşaretçi dosya depoyu tanımlar: kök önbellekte, bu dosya olmadan boş olmayan bir `blobs/` dizini asla kullanılmaz veya değiştirilmez
- Store, sembolik bağlantılar ve `hf_xet` gerektirir. Paylaşım başarısız olursa, dosya daha önce olduğu gibi repo klasöründe saklanır. `HF_HUB_DISABLE_SHARED_BLOBS=1` store'u devre dışı bırakır
- Yalnızca yeni indirmeler mağaza üzerinden geçer. Eski sürümler veya diğer istemciler tarafından yazılan dosyalar, depo klasöründe normal dosyalar olarak kalır; bu nedenle bir önbellek her iki türü de içerebilir.

Sadece önbelleği okuyan uygulamalar için değişiklik gerekmez: sembolik bağlantıları izleme, daha önce olduğu gibi çalışmaya devam eder.

Önbellekten silme işlemini gerçekleştiren uygulamalar, sembolik bağlantı olan bir depo blob'unu depoya (store) bir referans olarak ele almalıdır:
- Depodaki `blobs/` dizinindeki sembolik bağlantıyı, işaret ettiği ortak dosyayı değil silin
- Manifesti kontrol etmeden ve silmeden önce `<xet_hash>.lock` dosyasını kilitleyin
- Ortak dosyayı ve `.refs` dosyasını, manifestte listelenen ve hâlâ bu dosyaya işaret eden bir sembolik bağlantı yoksa silin
- Manifest eksikse veya okunamıyorsa, paylaşılan dosyayı koruyun

Silme davranışı ve eski istemcilerle ilgili kısıtlamalar için [`huggingface_hub` önbellek kılavuzuna](https://huggingface.co/docs/huggingface_hub/guides/manage-cache#shared-blobs-across-repos) bakın.

## Kilit dosyaları

Kilit dosyaları, eşzamanlı süreçlerin aynı blob'u aynı anda indirmesini engeller. Bunlar, önbellek kökünde (repo klasörünün içinde değil) `.locks/` dizininde saklanır:

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

Örnek:
```
<CACHE_DIR>/.locks/models--julien-c--EsperBERTo-small/403450e234d65943a7dcf7e05a771ce3c92faa84dd07db4ac20f592037a1e4bd.lock
```

## Tam örnek

```
~/.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`'in her iki revizyonda da **aynı blob**'a işaret ettiğine dikkat edin. 321 MB'lık dosya diske yalnızca bir kez kaydedilir.

## Dosya çözümleme mantığı

Diskte önbelleğe alınmış bir dosyanın konumunu bulmak için:

1. **Revizyonu bir commit hash'ine çözümlen**
   - Revizyon zaten 40 karakterlik bir onaltılık diziyse, doğrudan kullanın
   - Aksi takdirde, commit hash'ini almak için `refs/{revision}` konumundaki dosyayı okuyun

2. **Snapshots'ı kontrol edin**
   - `snapshots/{commit_hash}/{relative_path}` içinde arayın
   - Eğer varsa (sembolik bağlantı veya dosya olarak), dosya önbelleğe alınır. İçeriği almak için sembolik bağlantıyı izleyin

3. **Var olmamasını kontrol edin**
   - `.no_exist/{commit_hash}/{relative_path}` öğesini arayın
   - Eğer varsa, dosyanın bu revizyon için Hub üzerinde mevcut olmadığı bilinir

4. **Önbellek kaçırması**
   - Hiçbir yol mevcut değilse, dosya henüz önbelleğe alınmamıştır

## Windows davranışı

Önbellek **sembolik bağlantılara** dayanır. Sembolik bağlantıların kullanılamadığı Windows sistemlerinde önbellek **degrade edilmiş modda** çalışır: sembolik bağlantılar yerine gerçek dosya kopyaları doğrudan `snapshots/` dizinine yerleştirilir. Bu modda `blobs/` dizini ve [ortak blob deposu](#shared-blob-store) kullanılmaz.

Bu, aynı dosya içeriğinin revizyonlar arasında kopyalanabileceği ve disk kullanımını artırabileceği anlamına gelir. Windows'ta sembolik bağlantı desteğini etkinleştirmek için [Geliştirici Modu](https://docs.microsoft.com/en-us/windows/apps/get-started/enable-your-device-for-development)'nu etkinleştirin veya yönetici olarak çalıştırın.

