8 puan yazan darjeeling 2026-01-23 | 2 yorum | WhatsApp'ta paylaş

Özet:

  • Sorun durumu: vLLM’in Prefill/Decode ayrıştırılmış (disaggregated) servis ortamında dakikada 400 MB sistem belleği (RSS) sızıntısı oluşuyordu, ancak sıradan Python profilleyicileri bunu tespit edemiyordu.
  • Neden analizi: Heaptrack ve pmap ile sızıntının heap’te değil, anonim bellek eşlemelerinde (mmap) olduğunu doğruladılar; ardından BPFtrace ve otomatikleştirilmiş GDB betikleriyle nedeni izlediler.
  • Suçlunun tespiti: Yüksek performanslı iletişim kütüphanesi UCX, optimizasyon için mmap/munmap çağrılarını yakalıyordu; serbest bırakılan belleği hemen geri vermek yerine sınırsız biçimde bir kuyrukta biriktirmesi sorunun kaynağıydı.
  • Çözüm: UCX_MEM_MMAP_HOOK_MODE=none ortam değişkeni ayarlanarak UCX’in bellek hook özelliği devre dışı bırakıldı ve sorun çözüldü.

Ayrıntılı özet:

1. Gizemli bellek sızıntısı

Mistral AI ekibi, vLLM kullanılan Prefill/Decode ayrıştırılmış servis (NIXL tabanlı) ortamında sistem belleğinin dakikada 400 MB doğrusal olarak arttığını fark etti.

  • Belirti: Python heap belleği kararlıydı, ancak işletim sistemi düzeyindeki RSS (Resident Set Size) sürekli artıyor ve sonunda OOM’a (Out of Memory) yol açıyordu.
  • İlk denemelerin başarısızlığı: Memray, Guppy 3 gibi Python araçları her şeyin normal olduğunu gösterdi; standart GDB süreci çökertti, Valgrind ise kullanılmayacak kadar yavaştı.

2. Kernel seviyesinde derin analiz

Sorunun nedeninin uygulama seviyesi (Python/C++) değil, daha alt bir katman olduğunu sezerek sistem araçlarını kullandılar.

  • Heaptrack: Heap tahsislerinin (malloc/free) kararlı kaldığını, buna karşın RSS’nin arttığını görsel olarak doğruladı. Bu da sızıntının glibc heap yönetiminin dışında, anonim bellek eşlemelerinde (anonymous memory mappings) gerçekleştiğine işaret ediyordu.
  • pmap: /proc/<pid>/maps izlenerek belirli bir anonim eşleme alanının sürekli büyüdüğü ve adresinin değiştiği görüldü. Bu, mremap veya munmap sonrası mmap döngüsünün tekrarlandığı anlamına geliyordu.
  • BPFtrace: LD_PRELOAD ile de yakalanamayan (glibc’yi atlayan) sistem çağrılarını izlemek için BPFtrace kullanıldı. Sonuçta mmap çağrılarının doğrudan syscall üzerinden gerçekleştiği doğrulandı.

3. Suçlunun yakalanması: otomatik GDB betikleme

BPFtrace ile sorunlu sistem çağrısının adresi belirlendikten sonra, GDB kullanılarak yalnızca ilgili adreste (SYS_mmap) duracak şekilde bir betik yazıldı.

Kullanılan GDB betiği örneği:

# mmap sistem çağrısı (numara 9) için koşullu breakpoint ayarla  
break syscall if $rdi == 9  
commands  
  silent  
  # Sistem çağrısı dönüş noktasına geçici breakpoint ayarla  
  tbreak *0x00007ffff7d9525d  
  commands  
    silent  
    # Stack trace ve dönen adresi yazdır  
    bt  
    printf "Syscall returned: rax = 0x%012lx\n", $rax  
    continue  
  end  
  continue  
end  
  

Bu stack trace sayesinde UCX (Unified Communication X) kütüphanesinin Python’un mmap/munmap çağrılarını arada yakaladığına (intercept) dair kritik ipucu bulundu.

4. Neden: UCX’in aşırı optimizasyonu

UCX, InfiniBand aktarım performansını artırmak için bellek tahsisi/serbest bırakmayı hook’lar.

  • Mekanizma: munmap çağrıldığında belleği hemen işletim sistemine geri vermek yerine, daha sonra yeniden kullanmak veya temizlemek için bir "geçersiz kılma kuyruğuna (invalidation queue)" koyar.
  • Hata: Varsayılan ayar (UCX_RCACHE_MAX_UNRELEASED=inf) nedeniyle bu kuyruk sonsuza kadar büyüyebiliyordu ve vLLM’in belirli kullanım desenlerinde temizleme mantığı (ucp_worker_progress) düzgün çalışmadığından bellek sadece birikmeye devam ediyordu.

5. Çözüm yolu

vLLM durumunda yalnızca devasa bir KVCache bellek bölgesinin kaydedilmesi gerektiği için, UCX’in karmaşık bellek hook mekanizmasına aslında ihtiyaç yoktu.

  • Anlık çözüm: UCX_MEM_MMAP_HOOK_MODE=none ortam değişkeni ayarlanarak UCX’in bellek hook işlevi tamamen kapatıldı ve sızıntı önlendi.
  • Alternatif: UCX_RCACHE_MAX_UNRELEASED=1024 gibi bir ayarla kuyruk boyutu sınırlandırılarak temizliğin zorla tetiklenmesi de mümkün.
  • Atılan adım: İlgili düzeltme vLLM topluluğu için birleştirildi; gelecekteki NIXL sürümlerinde de varsayılan davranışın iyileştirilmesi planlanıyor.

2 yorum

 
jongyeans 2026-01-25

İnsan nasıl bir hayat yaşamalı da… bu düzeye
erişebilsin

 
ng0301 2026-01-23

Bu insanların birikiminin ne düzeyde olduğunu gerçekten kestiremiyorum.