Blog
Model Eğitimi

Unsloth, Transformers ve PEFT Uyumsuzluğu: EmptyLogits Sorunu

Unsloth hızlandırmalarının Hugging Face model çıktı sözleşmesiyle nerede çakıştığını; EmptyLogits, adapter, merge ve sürüm sorunları üzerinden inceliyoruz.

DEHA Araştırma17 Temmuz 202620 dk okuma

Unsloth, büyük dil modellerini daha hızlı ve daha düşük VRAM ile eğitmek için standart Hugging Face eğitim yolunun bazı bölümlerini özel Triton kernel'ları, manuel backpropagation uygulamaları, optimize loss hesapları ve runtime patch'lerle değiştirir. Bu yaklaşım güçlü bir performans avantajı sağlayabilir. Ancak Transformers, TRL, PEFT ve Accelerate'in beklediği Python sınıfları ve model çıktı sözleşmeleriyle Unsloth'un optimize yolu aynı sürümde buluşmadığında gerçek uyumluluk sorunları ortaya çıkabilir.

Bu durum “Unsloth, Hugging Face ile çalışmaz” anlamına gelmez. Aksine Unsloth, Transformers modellerini yüklemek, PEFT LoRA adaptörleri oluşturmak ve TRL trainer'larıyla eğitim yapmak üzere tasarlanmıştır. Doğru ifade şudur: Unsloth temel olarak Hugging Face uyumludur; fakat standart yürütme yolunu patch ettiği için sürüm, ModelOutput, adapter ve export sözleşmelerindeki değişikliklere daha hassastır.

Sizin yaşadığınız “boş çıktı” neydi?

Büyük olasılıkla PEFT ağırlıkları veya dataset label'ları boş değildi. Unsloth, tam vocabulary logits tensörünü bellekte üretmemek için optimize loss yolunu kullandı ve outputs.logits alanında gerçek tensor yerine EmptyLogits döndürdü. Training loss ve gradient hesaplanabilirken Transformers/Accelerate evaluation kodu tensor logits beklediği için kırıldı. Bu, “eğitim yapılmadı” ile “standart değerlendirme çıktısı üretilmedi” arasındaki önemli farktır.

1 Unsloth matematiği mi değiştiriyor?

Hedef, farklı bir optimizasyon problemi çözmek değil; aynı model ve loss hesabını daha verimli bir yürütme yoluyla hesaplamaktır. Unsloth el yazımı Triton kernel'ları, özel autograd/backprop yolları, fused işlemler, quantization ve gradient checkpointing optimizasyonları kullanabilir. Hugging Face'in resmi TRL entegrasyon sayfası Unsloth'u Transformers uyumlu bir workflow olarak tanımlar ve özel kernel/backprop yolunun yaklaşık sonuç üretmemeyi hedeflediğini belirtir (Hugging Face TRL - Unsloth entegrasyonu).

Buna rağmen matematiksel hedefin aynı olması API çıktısının aynı olacağını garanti etmez. Standart model tüm logits tensörünü döndürürken optimize yol yalnızca loss için gereken parçaları hesaplayabilir. Gradient sayısal olarak doğru olsa bile ModelOutput yapısı, ara tensorlar, dtype veya state-dict isimleri dışarıdan farklı görünebilir. Uyumluluk sorunu çoğu zaman tam burada oluşur.

2 Transformers hangi çıktı sözleşmesini bekler?

Transformers dokümantasyonuna göre model çıktıları ModelOutput alt sınıflarıdır. Causal language model akışında labels verildiğinde çıktı tipik olarak loss ve logits alanlarını taşır. Trainer training sırasında loss'u kullanır; evaluation, prediction veya compute_metrics ise logits'i toplayabilir (Transformers ModelOutput dokümantasyonu).

# Standart beklenti
outputs = model(**batch)

loss = outputs.loss       # scalar tensor
logits = outputs.logits   # [batch, sequence, vocabulary] tensor

# Evaluation tarafı logits'i GPU'lar arasında pad/gather edebilir,
# argmax alabilir veya compute_metrics fonksiyonuna gönderebilir.

Vocabulary büyük olduğunda logits tensörü çok pahalıdır. Örneğin batch 2, sequence 4.096 ve vocabulary 128.000 için logits yaklaşık bir milyar elemandır. BF16'da yalnızca bu tensor yaklaşık 2 GB düzeyine çıkabilir. Bu nedenle tam logits üretmeden cross-entropy hesaplamak ciddi bellek tasarrufu sağlar.

3 EmptyLogits uyumsuzluğu nasıl oluşur?

Unsloth'un optimize eğitim yolu tam logits'i materialize etmek yerine loss'u daha parçalı/verimli hesaplayabilir ve logits alanına EmptyLogits adlı sentinel nesne yerleştirebilir. Trainer yalnızca loss kullanıyorsa eğitim devam eder. Fakat evaluation sırasında Accelerate bu değeri gerçek tensor sanarak farklı süreçler arasında pad etmeye çalışırsa şu sınıfta hata oluşur:

TypeError: Unsupported types
(<class 'unsloth.models._utils.EmptyLogits'>)
passed to _pad_across_processes

Bu hata Unsloth issue tracker'ında validation loss ve metric hesaplama sırasında raporlanmıştır. Örnektepreprocess_logits_for_metrics gerçek tensor beklerken EmptyLogits gelmektedir (Unsloth issue #3549). Dolayısıyla problem doğrudan “PEFT label formatı” değil, Unsloth model çıktısı ile Transformers/Accelerate evaluation sözleşmesi arasındadır.

4 Labels, loss, logits ve PEFT'i ayıralım

BileşenGöreviBoş olursa ne olur?
labelsHangi tokenlar için loss hesaplanacağını belirlerLoss üretilemez veya bütün tokenlar maskelenirse sıfır/NaN görülebilir
lossBackward ile ağırlık güncellemesini yönlendirirEğitim yapılamaz
logitsHer konumdaki vocabulary skorlarıLoss özel yoldan hesaplanabilir; fakat metric/prediction kırılabilir
PEFT adapterTrainable LoRA vb. parametreleri taşırGradient yoksa adapter değişmez; yanlış save/load'da anahtarlar kaybolabilir

“Logits boş geldi” ile “LoRA ağırlıkları güncellenmedi” aynı teşhis değildir. Adapter'ın gerçekten eğitildiğini anlamak için trainable parametreler, gradient norm, başlangıç-son checkpoint farkı ve kontrollü inference karşılaştırılmalıdır. Yalnızca outputs.logits alanına bakmak yeterli değildir.

5 Neden performans optimizasyonu entegrasyon riskini büyütür?

Standart Transformers yolu geniş bir model ailesi için ortak ve genel davranış sunar. Unsloth hız kazanmak için model sınıflarını, forward fonksiyonlarını, loss mapping'i, gradient checkpointing'i veya PEFT katmanlarını runtime sırasında patch edebilir. Bu şu bağımlılık yüzeyini oluşturur:

PyTorch + CUDA + Triton
        ↓
Transformers model implementation
        ↓
PEFT adapter wrapper
        ↓
TRL Trainer + Accelerate
        ↓
Unsloth / unsloth_zoo patches and optimized kernels

Bu katmanlardan biri sınıf adı, forward imzası, loss argümanı, output tipi veya state-dict anahtarını değiştirdiğinde diğer katman eski sözleşmeyi bekleyebilir. Unsloth release notlarında Transformers 5.x loss mapping, farklı PEFT sürümleri için LoRA extractor ve yeni model ailelerinin save/merge yollarıyla ilgili düzeltmeler bulunması bu uyumluluk yüzeyinin gerçek olduğunu gösterir (Unsloth sürüm notları).

6 Sürüm uyuşmazlığı sınıfları

Trainer argümanlarının değişmesi

TRL sürümleri arasında tokenizer/processing_class, max_seq_length/max_length, packing ve dataset parametrelerinin yeri değişebilir. Eski Unsloth notebook'u yeni TRL ile çalıştırıldığındaTrainingArguments has no attribute packing benzeri hatalar oluşmuştur (Unsloth issue #593).

Model mimarisinin değişmesi

Yeni Qwen, Gemma veya multimodal model sürümleri Transformers'a önce eklenebilir; Unsloth patch'i henüz bu sınıfı tanımayabilir. Tersi durumda Unsloth model repository'si, kurulu Transformers'ın tanımadığı yenimodel_type bekleyebilir.

PyTorch, CUDA, Triton ve xformers matrisi

Python paketi import edilebilirken kernel derlemesi GPU compute capability veya CUDA ABI nedeniyle kırılabilir. Conda ile kurulan CUDA'lı PyTorch'un pip dependency resolution sırasında CPU wheel ile değiştirilmesi de Unsloth issue kayıtlarında görülen ayrı bir kurulum problemidir (Unsloth issue #3308).

7 PEFT tarafındaki gerçek uyumluluk riskleri

PEFT, LoRA gibi küçük trainable adapter'ları base model katmanlarına sarar. Unsloth kendiget_peft_model yoluyla uygun modülleri patch eder. Buradaki riskler şunlardır:

  • Target module değişimi: Yeni model mimarisinde q_proj gibi isimler farklı olabilir.
  • Wrapping sırası: Model önce quantize, sonra PEFT ile sarılmalı; yanlış sırada salt quantized model eğitilmeye çalışılabilir.
  • State-dict anahtarları: PEFT sürümü adapter prefix veya modules-to-save davranışını değiştirebilir.
  • Yeni tokenlar: Tokenizer büyütülüp embedding/lm_head kaydedildiğinde reload öncesi vocabulary boyutu eşleşmelidir.
  • Adapter türü: rsLoRA, DoRA, LoftQ veya özel adapter seçenekleri her export yolunda aynı desteğe sahip olmayabilir.

Tokenizer'a yeni token eklendikten sonra adapter yüklemede embedding ve lm_head shape mismatch yaşanan gerçek bir vaka Unsloth issue tracker'ında yer alır. Checkpoint 128.260 token beklerken yeniden yüklenen base model 128.256 token kaldığı için PEFT state-dict yüklenemez (Unsloth issue #1343).

8 Quantization ve merge neden ayrıca risklidir?

QLoRA'da base model düşük bit hassasiyetinde tutulur, LoRA adapter'ı daha yüksek hassasiyette eğitilir. Orijinal QLoRA çalışması NF4, double quantization ve paged optimizer ile bellek tasarrufu sağlar (Dettmers ve ark., 2023). Ancak “4-bit base + adapter” checkpoint'i ile “adapter merge edilmiş 16-bit model” aynı artifact değildir.

Eğitim başarılı olsa bile şu dönüşümler ayrı ayrı bozulabilir:

  • Unsloth ile adapter-only save ve reload,
  • standart PeftModel.from_pretrained ile reload,
  • merge_and_unload sonrası Transformers inference,
  • merged 16-bit modelden GGUF quantization,
  • vLLM, llama.cpp veya Ollama ile serving.

Bu nedenle yalnızca eğitim sonunda “dosya oluştu” kontrolü yapılmamalıdır. Her hedef serving formatı için üretim öncesi round-trip kalite testi gerekir.

9 EmptyLogits ne zaman sorun, ne zaman optimizasyondur?

İşlemTam logits gerekli mi?EmptyLogits etkisi
Loss tabanlı trainingÖzel loss yolu varsa hayırEğitim devam edebilir
Validation lossHer zaman tam logits gerekmeyebilirTrainer gather davranışına göre kırılabilir
Token accuracy / argmax metricEvet veya önceden token id gerekirDoğrudan metric hesaplanamaz
BLEU, ROUGE, WERGeneration çıktısı daha uygundurTrainer logits yoluna bağlanırsa kırılır
Prediction exportİstenen çıktıya bağlıStandart prediction API uyumsuz olabilir

Çözüm körlemesine sentinel nesneyi sıfır tensorla değiştirmek değildir; bu sahte metric üretir. Hedef yalnızca validation loss ise trainer'ın prediction toplamasını kapatan doğru config kullanılmalı. Gerçek token metric gerekiyorsa desteklenen biçimde logits döndürme veya ayrı generation evaluation yolu seçilmelidir. Kullanılan Unsloth/TRL sürümünün resmi önerisi esas alınmalıdır.

10 Güvenli teşhis sırası

  1. Hata nesnesini okuyun: Boş olan labels mı, loss mu, logits mi, adapter state-dict mi?
  2. Trainable parametreleri yazdırın: LoRA parametreleri gerçekten requires_grad=True mi?
  3. Bir batch forward yapın: loss finite mı, logits tipi ne?
  4. Bir step backward yapın: Adapter gradient norm sıfırdan farklı mı?
  5. Standart baseline kurun: Aynı batch'i saf Transformers + PEFT ile çalıştırın.
  6. Evaluation'ı ayırın: Training çalışıyor, yalnızca metric gather mı kırılıyor?
  7. Round-trip yapın: Save, yeni process'te reload ve sabit prompt inference.
  8. Sürüm matrisini kaydedin: Tahminle değil kesin paket/commit bilgisiyle issue karşılaştırın.

11 Minimal sözleşme testi

batch = next(iter(trainer.get_train_dataloader()))
batch = {k: v.to(model.device) for k, v in batch.items()}

model.train()
outputs = model(**batch)

print("output type:", type(outputs))
print("loss:", outputs.loss)
print("logits type:", type(outputs.logits))

outputs.loss.backward()

trainable_grads = {
    name: param.grad.norm().item()
    for name, param in model.named_parameters()
    if param.requires_grad and param.grad is not None
}
print("gradient alan adapter sayısı:", len(trainable_grads))
print("örnek gradientler:", list(trainable_grads.items())[:5])

Bu test loss'un gerçekten üretildiğini ve trainable adapter'lara gradient ulaştığını gösterir. Logits özel bir sentinel ise training ile evaluation problemi ayrıştırılmış olur. Bütün gradientler yoksa issue artık yalnızcaEmptyLogits değildir; PEFT wrapping, loss maskesi veya frozen parametre yapılandırması incelenmelidir.

12 Adapter güncelleniyor mu nasıl kanıtlanır?

# Eğitimden önce trainable ağırlıkları kopyala
before = {
    n: p.detach().float().cpu().clone()
    for n, p in model.named_parameters()
    if p.requires_grad
}

trainer.train()

# Eğitimden sonra gerçek değişimi ölç
deltas = {
    n: (p.detach().float().cpu() - before[n]).norm().item()
    for n, p in model.named_parameters()
    if n in before
}

assert max(deltas.values()) > 0, "Trainable ağırlıklar değişmemiş"
print(sorted(deltas.items(), key=lambda x: x[1], reverse=True)[:10])

Bu kontrol “loss düştü” gözleminden daha doğrudandır. Ancak ağırlık değişmesi kaliteyi kanıtlamaz; kapalı eval ve base-adapter karşılaştırması yine gerekir. LoRA'nın düşük-rank ağırlık güncelleme yaklaşımı için orijinal LoRA çalışmasına ve PEFT rehberimize bakabilirsiniz.

13 Temiz environment ve sürüm kilitleme

Mevcut environment'ta rastgele pip install -U transformers peft trl çalıştırmak en riskli çözümdür. Bir paket düzelirken diğerinin desteklediği API bozulabilir. Güvenli akış:

# Ayrı ve temiz ortam oluşturun.
python -m venv .venv-unsloth
source .venv-unsloth/bin/activate

# Donanımınıza uygun resmi Unsloth kurulum yolunu kullanın.
pip install unsloth

# Çalışan ortamı tam olarak kaydedin.
python -m pip freeze > requirements.lock.txt
python -m torch.utils.collect_env > torch-environment.txt

# Kritik sürümleri loglayın.
python - <<'PY'
import torch, transformers, peft, trl, unsloth
for package in (torch, transformers, peft, trl, unsloth):
    print(package.__name__, getattr(package, "__version__", "unknown"))
PY

Production eğitiminde yalnızca paket sürümü değil, Unsloth/unsloth_zoo commit'i, base model revision, tokenizer revision, CUDA driver ve GPU modeli de sürümlenmelidir. Çalışan lock dosyası ayrı bir canary branch'te güncellenmeli; ana eğitim environment'ı doğrudan upgrade edilmemelidir.

14 Save ve reload sözleşmesi

Taşınabilir bir PEFT adapter artifact'ında en az şu öğeler birlikte tutulmalıdır:

  • adapter_config.json ve adapter ağırlıkları,
  • kesin base model repository ve revision,
  • tokenizer dosyaları, ek tokenlar ve chat template,
  • embedding resize bilgisi ve modules_to_save,
  • Unsloth, Transformers, PEFT ve TRL sürümleri,
  • merge/export yöntemi ve quantization config'i.

Adapter yalnızca Unsloth ile değil, hedefleniyorsa standart Transformers + PEFT ile de yeni process içinde yüklenmelidir. Aynı sabit prompt için base, unmerged adapter ve merged model çıktıları karşılaştırılmalıdır. Tokenizer vocabulary boyutu ve embedding matrisi bire bir eşleşmeden performans değerlendirmesine geçilmemelidir.

15 Unsloth ne zaman kullanılmamalı?

  • Yeni çıkan ve henüz patch desteği doğrulanmamış model mimarisinde kritik production eğitimi yapılacaksa,
  • özel ModelOutput, hidden state veya her step tam logits zorunluysa,
  • özel custom autograd/loss ile Unsloth patch'inin etkileşimi test edilmemişse,
  • donanım/CUDA kombinasyonu resmi veya CI test matrisinin dışındaysa,
  • ekip hız kazancından daha çok sade debugging ve referans implementasyon istiyorsa.

Böyle durumlarda önce saf Transformers + PEFT baseline kurmak daha doğrudur. Baseline kalite ve doğruluk referansı olur; Unsloth daha sonra kontrollü performans optimizasyonu olarak eklenir. Hızlandırma, model doğruluğu ve artifact taşınabilirliği kanıtlandıktan sonra varsayılan yapılmalıdır.

16 Akademik temel: hızlandırma neden mümkün?

Unsloth'un kullandığı bütün optimizasyonlar tek bir akademik çalışmadan gelmez; ancak temel yapı taşları literatürde iyi tanımlanmıştır. LoRA, tam ağırlık güncellemesini düşük-rank matrislerle temsil ederek trainable parametreyi azaltır (Hu ve ark., 2021). QLoRA, quantized frozen base model üzerinde LoRA eğitimini mümkün kılar (Dettmers ve ark., 2023). FlashAttention ise attention hesabını IO-aware tiling ile hızlandırıp bellek erişimini azaltır (Dao ve ark., 2022).

Bu çalışmalar performans optimizasyonunun neden mümkün olduğunu açıklar; belirli bir Unsloth release'inin belirli Transformers/PEFT sürümüyle uyumlu olduğunu kanıtlamaz. Kütüphane uyumluluğu akademik benchmark değil, sürüm bazlı integration ve round-trip test konusudur.

17 Production kontrol listesi

  1. Saf Transformers + PEFT ile küçük doğruluk baseline'ı oluşturun.
  2. Aynı seed, batch ve precision ile Unsloth koşusunu karşılaştırın.
  3. Loss, adapter gradient norm ve ağırlık delta değerlerini kaydedin.
  4. Training ve evaluation yollarını ayrı smoke test edin.
  5. outputs.logits tipini metric kullanmadan önce doğrulayın.
  6. Adapter-only save/reload testini yeni Python process'te çalıştırın.
  7. Standart PEFT loader ve hedef serving engine ile artifact'i açın.
  8. Merge edilmiş modelde sabit eval setini yeniden çalıştırın.
  9. Tüm dependency ve model revision'larını lock dosyasına alın.
  10. Upgrade'i doğrudan üretimde değil canary eğitiminde test edin.

18 Sonuç

Unsloth ile Transformers/PEFT arasında doğuştan bir uyumsuzluk yoktur. Unsloth bu ekosistemin üzerinde çalışır ve normal durumda PEFT adapter'ları ile Transformers uyumlu model artifact'ları üretir. Fakat hız için standart forward, backward, loss ve model patch yollarına müdahale etmesi; API ve çıktı sözleşmesi değişikliklerine karşı daha hassas bir sistem oluşturur.

Sizin karşılaştığınız boş değer büyük olasılıkla “PEFT'in beklediği label dönmedi” değil, optimize loss sırasında tam logits üretilmeyip EmptyLogits dönmesiydi. Bu durumda ağırlık güncellemesi çalışmış olabilir; kırılan bölüm evaluation/metric entegrasyonudur. Doğru teşhis için loss, logits, gradient ve adapter delta ayrı ayrı ölçülmelidir. En güvenli mimari, saf Hugging Face baseline'ı koruyup Unsloth'u testlerle doğrulanmış bir hızlandırma katmanı olarak kullanmaktır.

Eğitim hyperparameter'ları için LLM fine-tuning rehberini, TRL ve diğer framework seçenekleri için TRL alternatifleri rehberini inceleyebilirsiniz.

Sık sorulan sorular

Unsloth, Transformers ve PEFT ile uyumsuz mu?

Temel olarak hayır. Unsloth bu kütüphanelerle entegrasyon için tasarlanmıştır. Ancak özel kernel ve runtime patch'ler nedeniyle belirli sürüm kombinasyonlarında API, output, save veya merge sorunları oluşabilir.

EmptyLogits ağırlıkların güncellenmediği anlamına mı gelir?

Hayır. Loss özel optimize yoldan hesaplanıp adapter'lara gradient ulaşabilir. EmptyLogits çoğunlukla evaluation veya metric kodunun beklediği tam logits tensörünün üretilmediğini gösterir.

Adapter'ın gerçekten eğitildiği nasıl anlaşılır?

Trainable parametreleri, gradient normlarını ve eğitim öncesi-sonrası adapter ağırlık farkını ölçün. Ardından adapter'ı yeni process'te yükleyip kapalı eval çalıştırın.

Neden rastgele Transformers downgrade etmek doğru değil?

Bir model eski sürümle çalışırken başka model veya TRL/PEFT özelliği bozulabilir. Donanım ve model için doğrulanmış sürüm matrisi temiz environment'ta test edilip kilitlenmelidir.

Unsloth eğitimi sonrası standart PEFT ile model açılabilir mi?

Hedeflenen akış budur; ancak base revision, tokenizer boyutu, adapter config ve modules-to-save eşleşmelidir. Her release için save/reload round-trip testi yapılmalıdır.

Kaynakça

  1. Hugging Face. TRL: Unsloth Integration.
  2. Hugging Face. Transformers Model Outputs.
  3. Unsloth. EmptyLogits validation compatibility issue #3549.
  4. Unsloth. TRL packing argument compatibility issue #593.
  5. Unsloth. Added tokens and PEFT adapter reload issue #1343.
  6. Hu, E. J. ve ark. (2021). LoRA: Low-Rank Adaptation of Large Language Models.
  7. Dettmers, T. ve ark. (2023). QLoRA: Efficient Finetuning of Quantized LLMs.
  8. Dao, T. ve ark. (2022). FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness.

Bu yazı 17 Temmuz 2026 tarihinde hazırlanmıştır. Uyumluluk bilgisi sürüme bağlıdır; issue kayıtları belirli environment'ları temsil eder ve bütün sürümlerin hatalı olduğu anlamına gelmez.

Türkçe öncelikli yapay zeka çalışma alanını deneyin

Belge analizi, web ve akademik arama, makale, sunum ve kaynaklı sohbet özelliklerini tek çalışma alanında kullanın.

DEHA'yı Ücretsiz Dene →