Kendi Bilgisayarında LLM Çalıştırırken KV Cache Nedir, Nasıl Hesaplanır?

Kendi bilgisayarında bir LLM çalıştırmaya başlayan çoğu kişi önce model dosyasının boyutuna bakıyor:

“Model 28 GB ise, demek ki 32 GB VRAM yeter.”

Ama pratikte iş o kadar basit değil.

Çünkü belleği kullanan tek şey modelin kendisi değil. Modelin yanında bir de çalışma sırasında büyüyen ayrı bir alan var: KV cache.

Özellikle uzun context kullanıyorsan, büyük belge veriyorsan, çok uzun sohbetler yapıyorsan ya da agent tarzı işler deniyorsan, bir noktadan sonra asıl mesele model boyutundan çok KV cache olmaya başlıyor.

Bu yazıda önce KV cache’in ne olduğunu anlatacağım, sonra da kendi bilgisayarında model çalıştırırken bunu nasıl kaba şekilde hesaplayabileceğini göstereceğim.


Önce en temel soru: KV cache nedir?

KV cache, çok basit anlatımla, modelin konuşma boyunca geçmişi hatırlamak için tuttuğu ara dikkat belleğidir.

Buradaki “KV” şuradan gelir:

  • K = Key
  • V = Value

Transformer tabanlı modeller, her yeni token geldiğinde geçmiş token’lara tekrar bakmak zorundadır. Ama bunu her seferinde her şeyi sıfırdan hesaplayarak yaparsa çok yavaş olur. Bunun yerine geçmiş token’lar için bazı attention bilgilerini saklar. İşte bu saklanan veri yapısına KV cache denir.

Yani KV cache, modelin şunu yapabilmesini sağlar:

  • “Biraz önce ne denmişti?”
  • “Prompt’un önceki kısmında ne vardı?”
  • “Bu belgede yukarıda ne yazıyordu?”
  • “Sohbetin başındaki bağlam neydi?”

Başka bir deyişle:

Model weights modelin bilgisidir, KV cache ise o anki konuşmanın çalışma hafızasıdır.

Bu ayrım çok önemlidir.


Model weights ile KV cache aynı şey değil

Yerelde model çalıştırırken bellekte kabaca üç şey vardır:

  1. Model weights
    Yani indirdiğin model dosyası. GGUF, safetensors ya da başka format olabilir.
  2. KV cache
    Sohbet veya prompt uzadıkça büyüyen çalışma belleği.
  3. Diğer overhead
    Runtime, backend, temporary buffer’lar, graph memory, batching, multimodal parçalar vs.

Yeni başlayanların en sık yaptığı hata şu:

“Model 28 GB ise, toplam kullanım da 28 GB civarı olur.”

Hayır. Çünkü model belleğe yüklenir, ama onun üstüne bir de context’e bağlı olarak büyüyen KV cache gelir.

Kısa promptlarda bu fark küçük olabilir. Ama context büyüdükçe ciddi hale gelir.


KV cache neden önemli?

KV cache özellikle şu durumlarda önemlidir:

  • uzun sohbetler
  • büyük sistem prompt’ları
  • kitap / PDF / uzun belge özetleme
  • RAG
  • browser-use ve agent senaryoları
  • kod deposu veya döküman analizi
  • çok yüksek context pencereleri

Kısacası:
Ne kadar uzun bağlam, o kadar fazla KV cache.

Bu yüzden bazı kullanıcılar şunu yaşar:

  • model açılır
  • kısa promptlarda sorunsuz çalışır
  • ama context büyüyünce yavaşlar, taşar veya VRAM yetmez

Sebep çoğu zaman model değil, KV cache’tir.


En basit mantık: KV cache context arttıkça büyür

KV cache’in temel davranışı şudur:

Context uzadıkça KV cache lineer büyür.

Yani çok kaba biçimde:

  • 8k context → belli bir bellek
  • 16k context → yaklaşık 2 katı
  • 32k context → yaklaşık 4 katı
  • 64k context → yaklaşık 8 katı

Bu yüzden bir modelin “128k destekliyor” olması, senin donanımında 128k’yı rahat çalıştıracağı anlamına gelmez.

Teknik destek başka şeydir, pratik kullanım başka şeydir.


Genel formül

KV cache’i kaba hesaplamak için şu mantık yeterli:

KV cache bytes ≈ tokens × layers × 2 × kv_heads × head_dim × bytes_per_value

Burada:

  • tokens = context uzunluğu
  • layers = KV cache tutan attention katman sayısı
  • 2 = hem K hem V tutuluyor
  • kv_heads = key/value head sayısı
  • head_dim = her head’in boyutu
  • bytes_per_value = veri tipi
    • fp16 / bf16: 2 byte
    • q8: 1 byte
    • q4: yaklaşık 0.5 byte

Bu formül sana yaklaşık bir fikir verir. Yüzde yüz son rakamı vermez ama kapasite planlaması için çok işe yarar.


Her modelde aynı şekilde mi büyür?

Hayır. Burası önemli.

Bazı modellerde her katman klasik full attention kullanır. Bu durumda KV cache daha ağır olur.

Bazı modellerde ise hybrid attention vardır. Yani her katman aynı tip attention değildir. Böyle mimarilerde KV cache çok daha hafif olabilir.

Örneğin Qwen3.5-35B-A3B’nin resmi config dosyasında şunlar görülüyor:

  • num_hidden_layers: 40
  • full_attention_interval: 4
  • num_key_value_heads: 2
  • head_dim: 256

Bu şu anlama geliyor: 40 katmanın hepsi aynı şekilde KV yükü üretmiyor; yaklaşık her 4 katmandan biri full attention gibi davranıyor. Bu da klasik dense 35B modellere kıyasla KV cache’i ciddi biçimde hafifletebiliyor.

Yani şunu bilmek lazım:

Modelin “35B” olması, KV cache’in de mutlaka devasa olacağı anlamına gelmez. Mimari çok önemlidir.


Qwen3.5-35B-A3B üzerinden basit örnek

Şimdi bu modeli örnek alalım.

Resmi config’de görülen değerlere göre yaklaşık hesap:

  • 40 layer
  • her 4 layer’da bir full attention
  • yani yaklaşık 10 layer efektif KV yükü
  • num_key_value_heads = 2
  • head_dim = 256

Token başına değer sayısı:

10 × 2 × 2 × 256 = 10,240 değer/token

Buradan yaklaşık KV cache:

FP16 / BF16 KV

2 byte/değer:

10,240 × 2 = 20,480 byte/token
Yani yaklaşık 20 KB/token

Q8 KV

1 byte/değer:

yaklaşık 10 KB/token

Q4 KV

0.5 byte/değer:

yaklaşık 5 KB/token

Buna göre kaba toplam:

FP16 KV

  • 8k context → ~160 MB
  • 32k context → ~640 MB
  • 64k context → ~1.28 GB
  • 128k context → ~2.56 GB

Q8 KV

  • 8k → ~80 MB
  • 32k → ~320 MB
  • 64k → ~640 MB
  • 128k → ~1.28 GB

Q4 KV

  • 8k → ~40 MB
  • 32k → ~160 MB
  • 64k → ~320 MB
  • 128k → ~640 MB

Bunlar kaba tahminlerdir ama genel resmi anlamak için gayet yeterlidir.


llama.cpp tarafında neden KV tipi seçiyoruz?

llama.cpp’de -ctk ve -ctv parametreleriyle KV cache veri tipini seçebiliyorsun. Resmi dokümantasyonda f16, bf16, q8_0, q4_0, q4_1, q5_0, q5_1 gibi seçenekler yer alıyor.

Bu pratikte şu anlama geliyor:

  • f16 → daha güvenli, daha fazla bellek
  • q8_0 → iyi denge
  • q4_0 → agresif bellek tasarrufu

Uzun context hedefliyorsan, KV cache quantization bazen modeli quantize etmek kadar önemli hale gelir. Çünkü model ağırlıkları sabitken, KV cache context ile büyür.


Toplam VRAM nasıl düşünülmeli?

Kaba yaklaşım şu:

Toplam ihtiyaç ≈ model weights + KV cache + runtime overhead

Örnek:

  • model: 28.6 GB
  • KV cache: 32k contextte diyelim ~0.6–1 GB civarı
  • diğer overhead: backend’e göre birkaç yüz MB ile birkaç GB arası

Yani bir modeli çalıştırırken sadece model dosyasına bakmak yetmez. Özellikle sınırda bir GPU’n varsa, şu soruyu sorman gerekir:

“Bu model sadece açılıyor mu, yoksa istediğim context ile rahat çalışıyor mu?”

Bu ikisi aynı şey değil.


En sık yanlış anlaşılan konu

En çok karıştırılan üç şey şunlar:

  • model boyutu
  • aktif parametre sayısı
  • KV cache büyüklüğü

Bunlar aynı şey değildir.

Özellikle MoE ve hybrid modellerde, “aktif 3B” ya da “35B toplam parametre” gibi ifadeler görüp KV cache’i de buna göre tahmin etmek yanıltıcı olabilir.

KV cache daha çok şunlara bağlıdır:

  • attention layer yapısı
  • KV head sayısı
  • head dimension
  • context uzunluğu
  • cache veri tipi

Yani KV cache, modelin sadece “kaç milyar parametre” olduğuna bakılarak doğru tahmin edilemez.


Pratik kurallar

Yerelde LLM çalıştıran biri için en yararlı kısa kurallar bence şunlar:

1) Önce kullanım senaryosunu seç

Şunu netleştir:

  • kısa sohbet mi
  • kod mu
  • RAG mi
  • uzun belge analizi mi
  • agent / browser işi mi

Çünkü context ihtiyacını bu belirler.

2) Sadece model boyutuna bakma

Model açılıyor olabilir ama uzun contextte sorun çıkarabilir.

3) Uzun context istiyorsan KV cache’i ayrıca düşün

Bu, özellikle 24 GB / 32 GB / 48 GB GPU kullananlar için çok kritik.

4) Hybrid modelleri küçümseme

Bazı modeller kağıt üstünde büyük görünür ama KV cache tarafında beklenenden hafif olabilir.

5) llama.cpp’de KV quantization ciddi fark yaratabilir

Resmi dokümantasyonda desteklenen q8_0 ve q4_0 gibi seçenekler uzun contextte çok iş görebilir.


Sonuç

Kendi bilgisayarında LLM çalıştırırken asıl soru yalnızca:

“Model kaç GB?”

değil.

Daha doğru soru şu:

“Bu modeli, istediğim context ile, hangi KV cache tipiyle, gerçekten rahat çalıştırabilir miyim?”

KV cache’i anladığın anda şunlar da daha anlamlı hale gelir:

  • neden bazı büyük modeller sandığından hafif
  • neden bazı küçük modeller uzun contextte şişiyor
  • neden q4_0 ya da q8_0 gibi ayarlar bazen hayat kurtarıyor
  • neden “destekliyor” demek “pratikte rahat çalışıyor” demek değil

Yerelde LLM çalıştırırken en sağlıklı yaklaşım şu:

  • önce model weight’i not et
  • sonra hedef context’i seç
  • sonra KV cache’i kaba hesapla
  • en son runtime payı ekle

Böyle düşününce donanım planlaması çok daha mantıklı hale geliyor.

Comments

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir