Yerel olarak büyük dil modelleri çalıştırmak genellikle sert bir duvara çarpar: VRAM sınırlamaları. Güçlü ayrı GPU'lara sahip olsanız bile, video bellek kapasitenizi aşan modeller, geliştiricileri kuantizasyon (doğruluk kaybı) veya yavaş CPU çıkarımı arasında seçim yapmaya zorlar. Apple Silicon ve yeni nesil AMD platformlarında, Birleşik Bellek Mimarisi (UMA) üçüncü bir yol sunar. Sistem RAM'ini ve GPU belleğini tek bir havuz olarak ele alarak, kritik hesaplamaları GPU'da tutarken tam bellek bant genişliğini kullanmak için belirli bileşenleri, örneğin dikkat başlarını, stratejik olarak taşıyabiliriz.
Neden Dikkat Başları İdeal Adaylardır
Bir transformer modelinin tüm parçaları eşit yaratılmamıştır. Feed-Forward Ağlardaki (FFN) Matris-Matris çarpımı hesaplama yoğunudur ve GPU hızlandırmadan en çok faydalanan kısımdır. Ancak, Dikkat işlemleri (özellikle Q, K, V projeksiyonları ve ardından gelen softmax), özellikle daha uzun dizi uzunluklarında daha çok bellek bant genişliğine bağlı olabilir.
UMA kurulumunda, "GPU" temelde yüksek hızda sistem RAM'ine erişebilen (M2/M3/M4 Max çiplerinde genellikle 100GB/s'yi aşan hızlarda) bir yardımcı işlemcidir. Bu nedenle, dikkat başlarının ağırlık matrislerini sistem RAM'ine taşımak, PCIe bağlantılı bir ayrı GPU'da olduğu gibi aynı cezayı uygulamaz. Veri alma işlemi yeterince hızlıdır, bu da modeli yüksek bant genişliğine sahip bellekte tutmanın hesaplama kazancı, "yavaş" sistem RAM'inden erişim gecikmesinin hafif etkisini genellikle aşar.
Python'da Uygulama Stratejisi
PyTorch gibi kütüphaneleri veya özel çıkarım motorlarını kullanarak cihaz yerleşimini manuel olarak kontrol edebiliriz. Anahtar nokta, katman indekslerini belirlemek ve belirli parametre tensörlerini 'cpu' cihazına taşırken geri kalanını 'cuda' veya 'mps' cihazında tutmaktır.
import torch
def hybrid_load_model(model, offload_ratio=0.5, layer_type='attention'):
"""
Dikkat katmanlarının bir kısmını CPU'ya taşır.
Standart bir Transformer yapısı varsayar.
"""
layers = list(model.named_parameters())
total_layers = len([l for l in layers if 'self_attn' in l[0]])
# Taşınacak katmanları belirle
offload_count = int(total_layers * offload_ratio)
# Strateji: En erken katmanları taşı (genellikle nihai logit'ler için daha az kritik)
# veya aralıklı olarak taşı. Burada ilk N dikkat bloğunu taşıyoruz.
target_layers = [l[0] for l in layers if 'self_attn' in l[0]][:offload_count]
for name, param in model.named_parameters():
if name in target_layers:
param.data = param.data.to('cpu')
param.data = param.data.float() # RAM'de daha yüksek doğruluğu koru
else:
# Kritik katmanların GPU'da kalmasını sağla
if param.device.type != 'cuda' and param.device.type != 'mps':
param.data = param.data.to('cuda' if torch.cuda.is_available() else 'mps')
model.eval()
return model
# Örnek kullanım
# model = load_llama_model(path="llama-7b-gguf")
# hybrid_model = hybrid_load_model(model, offload_ratio=0.3, layer_type='attention')
Veri Hareketi Aşırı Yükünü Yönetme
UMA transfer maliyetlerini en aza indirse de ortadan kaldırmaz. Her ileri geçiş, dikkat ağırlıklarının hesaplama için GPU'ya taşınmasını gerektirir (veya arka uç destekliyorsa CPU'da hesaplanmasını). Bunu en aza indirmek için taşınan katmanları toplu işleme (batching) yapmayı düşünün. Ağırlıkları katman katman taşımak yerine, birden fazla dikkat başını gruplayın ve bunları tek bir toplu işlemde aktarın.
Ayrıca, dinamik şekil korumalarıyla torch.compile'ı kullanın. PyTorch'un derleyicisi genellikle veri hareketi işlemlerini çekirdek başlatmalarıyla birleştirebilir ve gecikmeyi hesaplama yoğun işlemlerin arkasına saklar. Apple Silicon'da, birleşik bellek ataması için yerel destek sunan Metal Performance Shaders (MPS) arka ucunu kullandığınızdan emin olun.
Pratik Örnek: 13B Model Çalıştırma
16-bit kayan noktalı bir 13 milyar parametreli model düşünün. Bu, yaklaşık 26GB bellek gerektirir. Standart bir 16GB GPU bunu sığdıramaz. Ancak, 32GB birleşik belleğe sahip bir MacBook Pro bunu sığdırabilir.
- Taban Kelime Gömüleri (Embeddings): GPU'da tut (hız için kritik).
- FFN Katmanları: GPU'da tut (hesaplama yoğun).
- Dikkat Başları (Katmanlar 1-16): CPU/RAM'e taşı.
Dikkat başlarının %50'sini taşıyarak, GPU VRAM'inde yaklaşık 6.5GB boşaltırsınız. Bu, modelin yüklenmesine olanak tanır. Çıkarım sırasında, GPU yoğun FFN matematiğini işlerken, CPU dikkat projeksiyonunu işler. Bir M3 Max çipinde, bu hibrit yaklaşım, saf CPU kurulumundaki saniyede <5 token'a kıyasla saniyede 25-35 token hızına ulaşabilir.
Sonuç
Birleşik Bellek Mimarilerinde hibrit CPU-GPU çıkarımı sadece bir yedek plan değildir; yerel AI geliştirmesi için birincil bir stratejidir. Dikkat başlarını zekice taşıyarak, token üretim hızından ödün vermeden daha büyük modelleri çalıştırma yeteneğini açığa çıkarırsınız. Donanım evrilmeye devam ettikçe, yerel LLM performansının sınırlarını zorlamak için bu yerleşim stratejilerini ustalaşmak anahtar olacaktır. Modelinizin bellek kullanımını profillemeyle başlayın, bant genişliğine bağlı bileşenleri belirleyin ve belirli donanım yapılandırmanız için ideal noktayı bulmak için kısmi taşımayı deneyin.