sunucu.com.tr
Yapay Zeka

LLM VRAM hesaplama: model ağırlığı, KV cache ve eşzamanlı kullanıcıya göre GPU sunucu seçimi

LLM VRAM hesaplama için gereken formül, config.json'dan KV cache hesabı, 8B, 32B ve 70B modeller için tek kullanıcı ile 8 eşzamanlı kullanıcı karşılaştırması, Ollama ve vLLM'de belleği düşüren ayarlar ve gerçek kullanımı nvidia-smi ile doğrulama.

sunucu.com.tr Ekibi11 dk okuma

GPU sunucu kiralamadan ya da kart satın almadan önce LLM VRAM hesaplama işini kâğıt üzerinde yapmak, yanlış donanıma para vermenin önüne geçer. Sorun genelde model dosyasının boyutuna bakıp kararı vermekte. Oysa bağlam uzunluğu ve eşzamanlı kullanıcı sayısı arttıkça KV cache, model ağırlığı kadar yer kaplayabilir. Bu rehber, kendi sunucusunda açık ağırlıklı bir model çalıştırmak isteyen sistem yöneticileri ve KOBİ sahipleri için hazırlandı.

LLM VRAM hesaplama formülü

Çıkarım (inference) sırasında GPU belleğini üç kalem doldurur:

Toplam VRAM ≈ model ağırlıkları + KV cache + çalışma zamanı ek yükü

  • Model ağırlıkları: Parametre sayısı ile parametre başına bayt sayısının çarpımı. Sabittir, model yüklendiği anda belleğe oturur.
  • KV cache: Her token için her katmanda saklanan key ve value vektörleri. Bağlam uzunluğu ve eşzamanlı istek sayısıyla doğrusal büyür.
  • Ek yük: CUDA bağlamı, aktivasyonlar, geçici tamponlar ve bellek parçalanması. Pratikte kart başına 1 ile 3 GB arası ya da toplamın kabaca %10'u kadar pay bırakmak güvenlidir.

Bu üç kalemi ayrı ayrı hesaplarsanız hangi kalemin darboğaz olduğunu da görürsünüz. Örneğin tek kullanıcıda sorun olmayan bir kurulum, 8 kullanıcıda yalnız KV cache yüzünden belleğe sığmayabilir.

Model ağırlığını hesaplama: parametre başına bayt

Model ağırlığı için formül basittir: parametre sayısı (milyar) × parametre başına bayt = GB.

Hassasiyet Parametre başına yaklaşık bayt 8B model 32B model 70B model
FP16 / BF16 2 ~16 GB ~64 GB ~140 GB
FP8 1 ~8 GB ~32 GB ~70 GB
INT8 / GGUF Q8_0 ~1,06 ~8,5 GB ~34 GB ~74 GB
GGUF Q4_K_M ~0,6 ~5 GB ~20 GB ~42 GB
INT4 (GPTQ, AWQ) ~0,5 ile 0,55 ~4,5 GB ~18 GB ~38 GB

GGUF Q4_K_M tek tip 4 bit değildir. Bazı katmanları daha yüksek hassasiyette tuttuğu için ortalama parametre başına 4,5 ile 5 bit arasında kalır. Bu yüzden 0,5 yerine yaklaşık 0,6 bayt ile hesaplamak gerçeğe daha yakın sonuç verir. En doğru değer her zaman indirdiğiniz dosyanın kendisidir: GGUF dosyasının boyutu, ağırlıkların VRAM'de kaplayacağı alana çok yakındır.

MoE modellerinde dikkat: Mixture of Experts modellerinde token başına yalnız bir kısım parametre çalışır, ama tüm uzmanların bellekte durması gerekir. VRAM hesabında "aktif parametre" değil toplam parametre sayısını kullanın. Aktif parametre hızı belirler, belleği değil.

KV cache hesabı: config.json'dan değerleri okuma

KV cache, modelin daha önce gördüğü tokenları yeniden hesaplamamak için tuttuğu bellektir. Token başına boyut şöyle bulunur:

KV (token başına) = 2 × katman sayısı × KV head sayısı × head_dim × eleman başına bayt

Baştaki 2, key ve value için ayrı ayrı saklama yapıldığını gösterir. Toplam KV cache ise:

Toplam KV = token başına KV × bağlam uzunluğu × eşzamanlı istek sayısı

Değerleri modelin Hugging Face sayfasındaki config.json dosyasından alırsınız:

  • num_hidden_layers: katman sayısı
  • num_key_value_heads: KV head sayısı. Bu alan yoksa num_attention_heads kullanılır.
  • head_dim: yoksa hidden_size / num_attention_heads ile hesaplanır.

Eleman başına bayt, KV cache'in hassasiyetidir: FP16 için 2, FP8 ya da q8_0 için yaklaşık 1, q4_0 için yaklaşık 0,5.

GQA ve MLA farkı

Eski modellerde KV head sayısı attention head sayısına eşitti. Güncel modellerin çoğu GQA (Grouped Query Attention) kullanır: örneğin 64 attention head'e karşılık yalnız 8 KV head bulunur. Bu, KV cache'i 8 kat küçültür. Formülde num_attention_heads değil num_key_value_heads kullanmanız bu yüzden önemlidir. Yanlış alanı kullanırsanız sonucu birkaç kat büyük bulursunuz.

DeepSeek ailesindeki MLA (Multi-head Latent Attention) ise key ve value'yu ayrı tutmak yerine sıkıştırılmış tek bir gizli vektör saklar. Bu modellerde formül değişir: token başına KV, kabaca katman sayısı × (kv_lora_rank + qk_rope_head_dim) × bayt olarak hesaplanır ve baştaki 2 çarpanı yoktur. MLA'lı modellerde uzun bağlam, aynı boyuttaki GQA modeline göre çok daha az bellek ister.

Hesabı betikle yapmak

Aşağıdaki betik bir config.json dosyasını okuyup token başına ve toplam KV cache boyutunu yazdırır. Ubuntu 24.04 ve Debian 12 için hazırlandı, jq ve awk gerektirir. Sistemde hiçbir şeyi değiştirmez; geri almak için betik dosyasını silmeniz yeterlidir. GQA modelleri içindir, MLA modellerinde yukarıdaki farklı formülü kullanın. Çok modlu bazı modellerde değerler text_config altında durur; o durumda alanları elle okuyun.

bash
#!/usr/bin/env bash
# kv-hesap.sh: config.json'dan KV cache boyutunu hesaplar (GQA modelleri için)
# Kullanım: ./kv-hesap.sh config.json BAGLAM KULLANICI BAYT
# Örnek:    ./kv-hesap.sh config.json 8192 8 2
set -euo pipefail

CONFIG="${1:-config.json}"   # modelin config.json dosyası
BAGLAM="${2:-8192}"          # istek başına bağlam uzunluğu (token)
KULLANICI="${3:-1}"          # eşzamanlı istek sayısı
BAYT="${4:-2}"               # KV hassasiyeti: FP16=2, FP8/q8_0=1, q4_0=0.5

command -v jq >/dev/null || { echo "jq gerekli: sudo apt install jq"; exit 1; }

L=$(jq '.num_hidden_layers' "$CONFIG")
KV=$(jq '.num_key_value_heads // .num_attention_heads' "$CONFIG")
HD=$(jq '.head_dim // (.hidden_size / .num_attention_heads)' "$CONFIG")

echo "Katman: $L | KV head: $KV | head_dim: $HD"

awk -v l="$L" -v kv="$KV" -v hd="$HD" -v b="$BAYT" -v c="$BAGLAM" -v u="$KULLANICI" 'BEGIN {
  tok = 2 * l * kv * hd * b          # token başına bayt
  top = tok * c * u                  # toplam bayt
  printf "Token başına KV: %.0f KiB\n", tok / 1024
  printf "Toplam KV cache: %.2f GiB\n", top / 1024 / 1024 / 1024
}'

Örnek hesaplar: 8B, 32B ve 70B model

Örnekler için yaygın üç mimariyi kullanalım. Hepsi GQA ile 8 KV head ve 128 head_dim kullanır:

  • 8B sınıfı (Llama 3.1 8B gibi): 32 katman. Token başına 2 × 32 × 8 × 128 × 2 = 131.072 bayt, yani 128 KiB.
  • 32B sınıfı (Qwen2.5 32B gibi): 64 katman. Token başına 256 KiB.
  • 70B sınıfı (Llama 3.1 70B gibi): 80 katman. Token başına 320 KiB.

8.192 tokenlık bağlamda istek başına KV cache: 8B için 1 GiB, 32B için 2 GiB, 70B için 2,5 GiB. Aşağıdaki tabloda her istek 8K bağlam kullanıyor, KV cache FP16 ve ek yük için yaklaşık 2 ile 3 GB eklendi. Değerler yuvarlanmış tahminlerdir.

Model ve ağırlık Ağırlık 1 kullanıcı toplam 8 eşzamanlı kullanıcı toplam
8B Q4_K_M ~5 GB ~8 GB ~15 GB
8B FP16 ~16 GB ~19 GB ~26 GB
32B Q4_K_M ~20 GB ~24 GB ~38 GB
32B FP8 ~32 GB ~36 GB ~50 GB
70B Q4_K_M ~42 GB ~47 GB ~65 GB
70B FP8 ~70 GB ~75 GB ~93 GB
70B FP16 ~140 GB ~145 GB ~163 GB

Tablodan çıkan pratik sonuçlar:

  • 8B Q4_K_M tek kullanıcı için 12 GB'lık bir karta rahat sığar, 8 kullanıcıda 16 GB sınırına dayanır.
  • 32B Q4_K_M tek kullanıcıyla 24 GB'lık karta sığar, ama 8 kullanıcıda 48 GB sınıfı bir kart ya da iki kart gerekir.
  • 70B Q4_K_M tek 48 GB'lık kartta kısa bağlamla çalışır; 8 kullanıcı ya da 32K bağlam istiyorsanız 80 GB sınıfı kart ya da çoklu kart düşünün.

Bağlamı 32K'ya çıkardığınızda KV cache 4 katına çıkar. 70B modelde 8 kullanıcı × 32K bağlam FP16 KV cache tek başına 80 GiB eder. Bu, uzun belge özetleyen bir RAG uygulamasında ağırlıklardan bile fazla yer tutabilir.

Bir not: vLLM gibi motorlar KV cache'i sayfalar halinde dinamik dağıtır, yani 8 kullanıcının hepsi aynı anda tam bağlamı doldurmuyorsa gerçek kullanım daha düşük olur. Yine de kapasite planlamasında en kötü durumu hesaplamak, yoğun saatte isteklerin kuyrukta beklemesini önler.

Belleği düşürme: Ollama ve vLLM ayarları

Ollama: flash attention ve KV cache nicemleme

Ollama'da iki ayar belleği doğrudan etkiler. OLLAMA_FLASH_ATTENTION=1 flash attention'ı açar. OLLAMA_KV_CACHE_TYPE ise KV cache hassasiyetini belirler: f16 varsayılandır, q8_0 belleği yaklaşık yarıya indirir ve kalite kaybı genelde fark edilmez, q4_0 dörtte bire indirir ama uzun bağlamda kaliteyi daha belirgin etkileyebilir. KV cache nicemleme flash attention açık olmadan çalışmaz. Ayrıntılar Ollama SSS sayfasında yer alır.

Unutulan bir nokta: Ollama'da paralel istek sayısı bağlamı çarpar. 8K bağlam ve OLLAMA_NUM_PARALLEL=4 ile model 32K'lık KV cache ayırır.

Aşağıdaki adımlar Ollama'yı systemd servisi olarak kurduğunuz Ubuntu 24.04 ve Debian 12 sunucular için hazırlandı. Dosya her çalıştırmada aynı içerikle yeniden yazıldığı için tekrar çalıştırmak güvenlidir. OLLAMA_NUM_PARALLEL ve OLLAMA_CONTEXT_LENGTH değerlerini kendi hesabınıza göre değiştirin.

bash
# Ollama servisi için bellek ayarlarını içeren override dosyası oluşturur
sudo mkdir -p /etc/systemd/system/ollama.service.d

sudo tee /etc/systemd/system/ollama.service.d/bellek.conf >/dev/null <<'EOF'
[Service]
Environment="OLLAMA_FLASH_ATTENTION=1"
Environment="OLLAMA_KV_CACHE_TYPE=q8_0"
Environment="OLLAMA_NUM_PARALLEL=4"
Environment="OLLAMA_CONTEXT_LENGTH=8192"
EOF

# systemd'yi yeniden okut ve servisi yeniden başlat
sudo systemctl daemon-reload
sudo systemctl restart ollama

Geri almak için yalnız bu override dosyasını kaldırıp servisi yeniden başlatın:

bash
# Yalnız eklenen override dosyasını kaldırır, Ollama kurulumuna dokunmaz
sudo rm /etc/systemd/system/ollama.service.d/bellek.conf
sudo systemctl daemon-reload
sudo systemctl restart ollama

Ollama'yı sunucu dışındaki kullanıcılara açacaksanız portu doğrudan internete açmak yerine Nginx ters vekil ve kimlik doğrulama ile güvenli erişim kurmanızı öneririz.

vLLM: gpu-memory-utilization ve max-model-len

vLLM varsayılan olarak GPU belleğinin %90'ını önceden ayırır ve ağırlıklardan arta kalanı KV cache'e verir. Bu yüzden nvidia-smi vLLM ile her zaman dolu görünür; bu bir sorun değildir. Ayarlanacak dört parametre:

  • --max-model-len: istek başına en uzun bağlam. Modelin desteklediği en yüksek değeri bırakırsanız vLLM bunu sığdıramayınca açılışta hata verir.
  • --max-num-seqs: aynı anda işlenecek en fazla istek.
  • --gpu-memory-utilization: vLLM'in kullanacağı bellek oranı. Kartta başka süreç varsa düşürün.
  • --kv-cache-dtype fp8: KV cache'i FP8'de tutar, kapasiteyi yaklaşık ikiye katlar.

Aşağıdaki komut vLLM'in güncel sürümleri için hazırlandı; ORNEK_MODEL yerine Hugging Face model kimliğini yazın. Geri almak için süreci durdurup parametreleri çıkararak yeniden başlatmanız yeterlidir. Parametrelerin güncel listesi vLLM belgelerinde bulunur.

bash
# 8 eşzamanlı istek ve 16K bağlam için örnek vLLM başlatma komutu
vllm serve ORNEK_MODEL \
  --max-model-len 16384 \
  --max-num-seqs 8 \
  --gpu-memory-utilization 0.90 \
  --kv-cache-dtype fp8

vLLM açılışta günlüğe ayrılan KV cache boyutunu ve seçilen bağlam uzunluğunda kaç isteği aynı anda taşıyabileceğini yazar. Bu satır, kâğıt üzerindeki hesabınızın en iyi sağlamasıdır. Yeniden başlatma sürelerini kısaltmak istiyorsanız vLLM 0.31.0 ile gelen preload özelliğine göz atabilirsiniz.

Hesabı sunucuda doğrulama

Model yüklendikten sonra gerçek kullanımı ölçün. Aşağıdaki komutlar NVIDIA sürücüsü kurulu tüm Linux dağıtımları için hazırlandı ve sistemde değişiklik yapmaz.

bash
# Kart başına kullanılan ve toplam belleği CSV olarak gösterir
nvidia-smi --query-gpu=index,name,memory.used,memory.total --format=csv

# Yük testi sırasında 2 saniyede bir izlemek için
watch -n 2 nvidia-smi --query-gpu=index,memory.used,utilization.gpu --format=csv

# Ollama'da yüklü modelleri, bellek boyutunu ve GPU/CPU dağılımını gösterir
ollama ps

ollama ps çıktısındaki PROCESSOR sütununa bakın. "100% GPU" görüyorsanız model tamamen VRAM'dedir. "%40/%60 CPU/GPU" gibi bir değer, bazı katmanların sistem belleğine taştığını gösterir. Bu durumda yanıt hızı belirgin biçimde düşer.

Ölçümü boş sistemde değil, beklediğiniz eşzamanlı kullanıcı sayısını taklit eden bir yük altında yapın. Birkaç terminalden aynı anda uzun istek göndermek basit ama işe yarar bir testtir.

Sık yapılan hatalar

Bağlam uzunluğunu unutmak. En yaygın hata, yalnız model dosyasının boyutuna bakmaktır. 128K bağlamı destekleyen bir modeli varsayılan ayarla açmak, kısa sohbetler için bile gereğinden büyük KV cache ayırabilir. İhtiyacınız olan bağlamı açıkça sınırlayın.

Paralel istek çarpanını gözden kaçırmak. Ollama'da OLLAMA_NUM_PARALLEL, vLLM'de --max-num-seqs KV cache'i doğrudan çarpar. Tek kullanıcıda yaptığınız testi 10 kişilik ekibe genellemeyin.

CPU'ya taşan katmanları fark etmemek. Model hata vermeden çalışıyor diye VRAM'e sığdığını varsaymayın. Ollama ve llama.cpp sığmayan katmanları sessizce sistem belleğine aktarabilir. Saniyede üretilen token sayısı beklenenin çok altındaysa ilk bakılacak yer ollama ps çıktısıdır.

Eğitim ile çıkarımı karıştırmak. Bu yazıdaki hesaplar yalnız çıkarım içindir. Tam ince ayar (full fine-tuning) gradyanlar ve optimizer durumu nedeniyle parametre başına kabaca 16 bayt ve üzerini ister. LoRA ve QLoRA bunu ciddi biçimde düşürür ama yine de çıkarımdan fazlasını gerektirir.

num_attention_heads ile hesaplamak. GQA modellerinde bu, KV cache'i gerçeğin birkaç katı gösterir ve gereksiz büyük donanım almanıza yol açar.

Ek yüke pay bırakmamak. Hesap %100 doluluk veriyorsa uygulamada sığmaz. Sürücü sürümü, CUDA grafikleri ve parçalanma birkaç GB yer tutabilir.

Sonuca göre GPU sunucu seçimi

Hesabınızı bitirdiğinizde toplam VRAM ihtiyacı sizi üç seçenekten birine yönlendirir:

Tek kart yeterliyse: 8B ile 32B arası nicemlenmiş modeller ve az sayıda kullanıcı için en basit ve en verimli yol budur. Kartlar arası iletişim maliyeti yoktur, kurulum ve izleme kolaydır.

Çoklu kart gerekiyorsa: 70B sınıfı modeller, FP8 ya da FP16 hassasiyet veya çok sayıda eşzamanlı kullanıcı genelde birden fazla kart ister. vLLM'de --tensor-parallel-size ile model kartlara bölünür. Bu kurulumda kartlar arası bağlantı hızı performansı belirgin etkiler, toplam VRAM'in yanında bunu da sorun. Sürekli yük taşıyacak ve verisi kurum dışına çıkmaması gereken kurulumlarda paylaşılmayan donanıma sahip fiziksel sunucu da değerlendirilebilir.

Kiralama mantıklıysa: Hangi modelin işinize yarayacağından emin değilseniz önce kiralayın, gerçek yük altında ölçün, sonra uzun vadeli karar verin. Hesapladığınız VRAM değerine göre GPU sunucu seçeneklerini karşılaştırabilirsiniz.

Sık sorulan sorular

70B model için kaç GB VRAM gerekir?

Q4_K_M nicemlemeyle ağırlıklar yaklaşık 42 GB tutar. Tek kullanıcı ve 8K bağlamla toplam ihtiyaç 46 ile 48 GB civarındadır. FP8 ile bu değer 75 GB'a, FP16 ile 145 GB'ın üzerine çıkar. Eşzamanlı kullanıcı ve bağlam arttıkça KV cache payını ayrıca ekleyin.

KV cache'i q8_0 yapmak kaliteyi düşürür mü?

Çoğu kullanımda q8_0 ile fark edilir bir kalite kaybı görülmez ve bellek yaklaşık yarıya iner. q4_0 daha fazla tasarruf sağlar ama özellikle uzun bağlamlı işlerde yanıt kalitesini etkileyebilir. Kendi tipik istemlerinizle karşılaştırmalı deneme yapmanız en güvenli yoldur.

Model VRAM'e sığmazsa ne olur?

Ollama ve llama.cpp sığmayan katmanları sistem belleğine aktarır; model çalışır ama çok yavaşlar. vLLM ise genelde açılışta bellek hatası verir. Çözüm daha küçük nicemleme, daha kısa bağlam, daha az paralel istek ya da daha fazla VRAM'dir.

Sistem belleği (RAM) ne kadar olmalı?

Model yüklenirken dosya önce diskten okunur ve bazı motorlar geçici olarak RAM kullanır. Pratik bir kural, sistem belleğini en az toplam VRAM kadar tutmaktır. Katmanların CPU'ya taşmasını bilerek kullanacaksanız RAM daha da önem kazanır.

Eşzamanlı kullanıcı sayısını nasıl tahmin ederim?

Toplam kullanıcı sayısı değil, aynı saniyede yanıt bekleyen istek sayısı önemlidir. 30 kişilik bir ekipte aynı anda üretim yapan istek sayısı çoğu zaman bunun küçük bir kısmıdır. Birkaç gün boyunca istek günlüklerini inceleyip yoğun saatteki en yüksek değeri esas alın.

Sonuç

LLM VRAM hesaplama, üç kalemi ayrı ayrı toplamaktan ibarettir: ağırlık, KV cache ve ek yük. Ağırlık nicemlemeyle, KV cache bağlam uzunluğu ve paralel istek sayısıyla belirlenir. Hesabı config.json üzerinden yapın, flash attention ve KV cache nicemleme ile belleği düşürün, sonra nvidia-smi ve ollama ps ile gerçek yük altında doğrulayın. Donanım kararını bu ölçümden sonra vermek, hem eksik hem de gereğinden büyük yatırımın önüne geçer.

  • #llm
  • #vram
  • #kv cache
  • #gpu sunucu
  • #ollama
  • #vllm
  • #nicemleme

İlgili yazılar

Yapay Zeka yazıları