/ Blog

GPU Bellek Yönetimi: HBM, GDDR6 ve Bellek Darboğazları

GPU bellek türleri (HBM3, GDDR6), bellek bantgenişliği ölçümü ve büyük model eğitiminde bellek yönetimi.

Modern yapay zeka ve yüksek başarımlı hesaplama iş yüklerinde GPU’nun ne kadar hızlı hesap yaptığından çok daha kritik bir soru öne çıkmaktadır: veriye ne kadar hızlı erişebilir? Eğitim süreleri uzadığında, model çalışmayı reddettiğinde ya da GPU kullanım oranı beklenmedik biçimde düşük kaldığında, suçlu çoğunlukla hesaplama kapasitesi değil, bellek bantgenişliğidir. Bu yazıda GPU bellek mimarilerini, HBM ile GDDR6 arasındaki farkları ve büyük model eğitiminde bellek darboğazlarını nasıl tespit edip giderebileceğinizi inceliyoruz.

GPU Bellek Mimarileri: Genel Bakış

GPU belleği, CPU belleğinden yapısal olarak farklı biçimde tasarlanmıştır. CPU, düşük gecikme süresiyle tekil veya küçük gruplar halinde bellek erişimini önceliklendirir. GPU ise binlerce iş parçacığının eş zamanlı çalışmasına olanak tanıyan geniş bantgenişliğini önceliklendirir; bu nedenle belleğin hem kapasitesi hem de aktarım hızı doğrudan iş yükü başarımını belirler.

Bellek Hiyerarşisi

Bir GPU’nun bellek yapısı birkaç katmandan oluşur:

  • Kayıt Dosyası (Register File): Her iş parçacığına özel, en hızlı ve en küçük depolama alanı.
  • L1 Önbellek / Paylaşımlı Bellek: Streaming Multiprocessor (SM) düzeyinde, programcı tarafından kontrol edilebilen bölge.
  • L2 Önbellek: Tüm SM’ler tarafından paylaşılan ikinci seviye önbellek.
  • Global Bellek (VRAM): HBM veya GDDR6 teknolojisiyle uygulanan ana GPU belleği.

Büyük model eğitimindeki darboğazların büyük çoğunluğu global bellek erişiminde ortaya çıkar.

HBM ve GDDR6: Teknik Karşılaştırma

High Bandwidth Memory (HBM)

HBM, yüksek bantgenişliği gerektiren hesaplama hızlandırıcıları için tasarlanmış dikey yığın bellek teknolojisidir. GPU ile aynı paket içinde ya da çok yakınında konumlandırılarak, geniş veri yolu genişliği sayesinde çok yüksek aktarım hızları elde edilir.

NVIDIA H100 SXM5 gibi veri merkezi GPU’larında kullanılan HBM3, 80 GB kapasiteyle 3.35 TB/s bantgenişliği sunar. Bu rakam, GDDR6X kullanan GeForce RTX 4090’ın bantgenişliğinin yaklaşık 4,5 katıdır.

HBM’nin avantajları:

  • Çok yüksek bantgenişliği (HBM3e’de 4.8 TB/s’ye kadar)
  • Geniş 1024-bit veya daha geniş veri yolu
  • Düşük güç tüketimi (bit başına)
  • Paket içi entegrasyon sayesinde kısa gecikme süresi

HBM’nin dezavantajları:

  • Yüksek üretim maliyeti
  • Sınırlı kapasite (mevcut teknolojide genellikle 80-192 GB)
  • Daha karmaşık paketleme süreci

GDDR6 ve GDDR6X

GDDR6, grafik ve oyun GPU’larında yaygın biçimde kullanılan, daha düşük maliyetli bellek teknolojisidir. RTX 4090’da 192-bit GDDR6X belleğiyle yaklaşık 1 TB/s bantgenişliği sağlanır.

GDDR6’nın avantajları:

  • Düşük maliyet
  • Yüksek kapasite seçenekleri
  • Geniş ekosistem desteği

GDDR6’nın dezavantajları:

  • HBM’ye kıyasla daha düşük bantgenişliği
  • Daha yüksek enerji tüketimi (bit başına)
  • Yüksek frekanslarda sinyal bütünlüğü kısıtları

Karşılaştırma Tablosu

ÖzellikHBM3 (H100 SXM)GDDR6X (RTX 4090)
Bantgenişliği3.35 TB/s~1.0 TB/s
Kapasite80 GB24 GB
Veri Yolu Genişliği5120-bit384-bit
Güç (bellek alt sistemi)~100W~60W
Kullanım AlanıVeri Merkezi / HPCGrafik / Tüketici
MaliyetYüksekOrta

Bellek Darboğazlarını Tespit Etmek

Bantgenişliği Kullanımını Ölçmek

NVIDIA Nsight Systems ve nvitop gibi araçlarla anlık bellek bant genişliği kullanımını izleyebilirsiniz. Ancak pratik bir başlangıç noktası olarak CUDA’nın kendi profilleme araçları yeterlidir:

# ncu ile bellek darboğazlarını tespit etmek
ncu --metrics \
  l1tex__t_bytes_pipe_lsu_mem_global_op_ld.sum,\
  l1tex__t_bytes_pipe_lsu_mem_global_op_st.sum,\
  dram__bytes_read.sum,\
  dram__bytes_write.sum \
  --target-processes all \
  python train.py

# Hızlı bellek bant genişliği kullanımı izleme (nvidia-smi)
nvidia-smi dmon -s mu -d 1

Çıktıda Memory-Util sütunu düşük, SM Util yüksekse hesaplama kapasitesi belleği bekliyor demektir; bu durum bellek darboğazına işaret eder. Tam tersi durumda ise hesaplama kapasitesi bellek kapasitesinin önüne geçmiştir.

Bellek Sınırlı Çekirdekler

Bir CUDA çekirdeğinin bellek sınırlı mı yoksa hesaplama sınırlı mı olduğunu anlamak için aritmetik yoğunluğu (arithmetic intensity) hesaplamak gerekir:

Aritmetik Yoğunluk = FLOP / Bellek Erişimi (Byte)

Bu değer düşükse (örneğin, matris-vektör çarpımında ~0.25 FLOP/byte) çekirdek büyük olasılıkla bellek sınırlıdır. Yüksekse (örneğin, matris çarpımında yüzlerce FLOP/byte) hesaplama sınırlıdır.

Büyük Model Eğitiminde Bellek Yönetimi

Bellek Tüketiminin Kaynakları

Büyük dil modellerinde GPU belleği birkaç ana bileşen tarafından tüketilir:

  1. Model Parametreleri: FP32’de parametre başına 4 byte, FP16/BF16’da 2 byte.
  2. Optimizer Durumu: Adam optimizer ile parametre başına ~8 byte ek yük (birinci ve ikinci moment).
  3. Gradyanlar: Parametre başına 4 byte (FP32) veya 2 byte (FP16).
  4. Aktivasyonlar: Aktivasyon işaretleme (checkpointing) yapılmadığında geri yayılım için tüm ara aktivasyonlar bellekte tutulur.
  5. KV Önbelleği: Transformer çıkarımında dikkat mekanizmasının anahtar-değer önbelleği.

Kaba bir hesapla, 7 milyar parametreli bir modeli BF16 ile eğitmek için yalnızca parametreler 14 GB yer kaplar; optimizer durumu ve gradyanlarla bu rakam 56 GB’ı aşar.

Bellek Optimizasyon Teknikleri

Karma Hassasiyet (Mixed Precision) Eğitim

FP16 veya BF16 kullanımı bellek gereksinimini yarıya indirir ve modern tensör çekirdeklerinde hesaplamayı hızlandırır:

from torch.cuda.amp import autocast, GradScaler

scaler = GradScaler()

for batch in dataloader:
    optimizer.zero_grad()
    with autocast(dtype=torch.bfloat16):
        output = model(batch)
        loss = criterion(output, target)
    scaler.scale(loss).backward()
    scaler.step(optimizer)
    scaler.update()

Gradyan Biriktirme (Gradient Accumulation)

Büyük efektif batch boyutu elde etmek için belleği değil, iterasyonları kullanın:

accumulation_steps = 8
optimizer.zero_grad()

for i, batch in enumerate(dataloader):
    with autocast(dtype=torch.bfloat16):
        loss = model(batch) / accumulation_steps
    loss.backward()

    if (i + 1) % accumulation_steps == 0:
        optimizer.step()
        optimizer.zero_grad()

Aktivasyon İşaretleme (Gradient Checkpointing)

İleri geçiş sırasında aktivasyonları bellekte tutmak yerine geri yayılım esnasında yeniden hesaplayarak bellek kullanımını önemli ölçüde azaltır; bunun bedeli yaklaşık %30-40 ek hesaplama sürecidir:

from torch.utils.checkpoint import checkpoint_sequential

# Model bloklarını aktivasyon işaretlemeyle çalıştır
output = checkpoint_sequential(model.layers, segments=4, input=x)

Flash Attention

Standart dikkat mekanizması O(n²) bellekle çalışır. Flash Attention, dikkat hesaplamasını döşeme (tiling) yöntemiyle doğrudan SRAM üzerinde gerçekleştirerek bellek kullanımını O(n)’e indirir:

# PyTorch 2.0+ yerleşik Flash Attention desteği
with torch.backends.cuda.sdp_kernel(enable_flash=True):
    output = torch.nn.functional.scaled_dot_product_attention(
        query, key, value, attn_mask=None, dropout_p=0.0
    )

Çok-GPU Dağıtık Eğitimde Bellek

Tek GPU belleği yetersiz kaldığında model paralelizmi devreye girer:

  • Veri Paralelizmi (DDP): Her GPU tam model kopyasını barındırır, farklı batch’ler üzerinde çalışır. Bellek tasarrufu sağlamaz.
  • Model Paralelizmi (Tensor/Pipeline): Model katmanları GPU’lar arasında bölünür. Her GPU toplam parametrelerin bir bölümünü barındırır.
  • ZeRO (Zero Redundancy Optimizer): DeepSpeed’in ZeRO aşamaları optimizer durumunu, gradyanları ve parametreleri GPU’lar arasında bölerek bellek kullanımını doğrusal ölçekte azaltır.

ZeRO-3 ile 8 GPU’ya yayılan bir eğitimde etkin bellek gereksinimi yaklaşık 8 kat düşebilir; bu, tek bir GPU’ya sığamayacak modellerin eğitilmesini mümkün kılar.

Pratik Öneriler

Bellek sorunlarını önlemek ve başarımı artırmak için şu adımları izlemenizi öneririz:

  1. Her zaman BF16 ile başlayın. Büyük model eğitiminde BF16, FP32’ye kıyasla hem daha az bellek tüketir hem de NVIDIA Ampere ve üstü mimarilerde tensör çekirdeklerinden tam verim alır.
  2. Nsight Compute veya PyTorch Profiler kullanın. Darboğazı tahmin etmek yerine ölçün; hesaplama sınırlı ve bellek sınırlı çekirdekler farklı optimizasyon yolları gerektirir.
  3. Aktivasyon işaretlemeyi varsayılan açık tutun. Özellikle uzun dizi uzunluklarında bellek tasarrufu, ek hesaplama maliyetini çoğunlukla fazlasıyla karşılar.
  4. KV önbellek boyutunu planlayın. Çıkarım ortamlarında dizi uzunluğu ve batch boyutu, KV önbellek boyutunu doğrudan belirler; kapasite planlamasını buna göre yapın.
  5. GPU seçiminde bantgenişliğini unutmayın. Büyük dil modeli iş yükleri için tepe FLOP/s değerinden çok bellek bantgenişliği belirleyicidir.

Sonuç

GPU bellek mimarisini ve darboğaz kaynaklarını anlamak, HPC ve yapay zeka iş yüklerinde başarımlı sistemler tasarlamanın temel taşlarından biridir. HBM3’ün sağladığı devasa bantgenişliği, büyük model eğitimini mümkün kılarken; doğru yazılım teknikleri bu bantgenişliğinden tam verim almanızı sağlar. Karma hassasiyet, aktivasyon işaretleme ve Flash Attention gibi yöntemler artık standart uygulama haline gelmiştir.

Mevasis olarak GPU bellek mimarisi, büyük model eğitimi ve HPC altyapı optimizasyonu konularında size destek olmaktan memnuniyet duyarız. İletişim için formu doldurun.