Giriş: Standart Mikro Servislerin Ötesinde
Büyük Dil Modeli (LLM) çıkarım sistemleri, geleneksel mikro servislerden farklı olarak benzersiz kısıtlamalar altında çalışır. Durumsuz web API'lerinin aksine, LLM uç noktaları KV önbellek yönetimi için büyük ölçüde sınırlı GPU belleğine bağımlıdır ve genellikle akışkan yanıtlar için uzun ömürlü bağlantılar sürdürür. Bu özel donanıma bağımlılık, standart kaos mühendisliği uygulamalarını yetersiz kılar. Sadece bir konteyneri kapatamayız; VRAM'de tutulan durumu, modelin yeniden başlatılma maliyetini ve GPU sıfırlama döngülerine neden olan gecikme sıçramalarını dikkate almalıyız.
Bu yazıda, özellikle GPU arızalarını ve ağ bölünmelerini hedefleyen kaos deneyleri tasarlamayı ele alıyoruz. Amaç, "yeniden ayağa kalkıyor" durumundan, "akışkan istemciler için kabul edilebilir gecikme ve veri kaybı olmadan yeniden ayağa kalkıyor" durumuna geçmektir.
Senaryo 1: Ani GPU Arızasının Simüle Edilmesi
Üretim ortamlarında yaygın bir arıza modu, termal boğulma veya sürücü çökmesi nedeniyle bir GPU'nun PCI yuvasından düşmesidir. NVIDIA sürücülerini çalıştıran Kubernetes ortamlarında bu durum, genellikle bir düğümün cordon (izolasyon) altına alınması veya pod'un `SIGBUS` hatasıyla çökmesi olarak kendini gösterir.
Bunu test etmek için, orkestratörün tepki süresinin uygulamanın dahili hata yönetimini maskeleyebileceğinden, tüm düğümü yeniden başlatmadan hesaplama cihazının kaybını simüle etmemiz gerekir.
Bunu simüle etmek için `nvidia-smi`'yi sistem çağrılarıyla birleştirebilir veya daha pratik olarak, GPU yük altındayken çıkarım sunucu sürecine bir çökme enjekte edebiliriz.
#!/bin/bash
# chaos_gpu_crash.sh
# GPU erişim arızasını simüle etmek için çıkarım sürecine SIGBUS enjekte eder
PID=$(pgrep -f "vllm.engine" | head -n 1)
if [ -z "$PID" ]; then
echo "Inference process not found"
exit 1
fi
echo "Simulating GPU memory access failure on PID $PID"
# SIGBUS genellikle bellek eşlenmediğinde tetiklenir, VRAM erişim hatasını simüle eder
kill -BUS $PID
**İzlenmesi Gereken Temel Metrikler:**
* **Soğuk Başlatma Gecikmesi:** Bir sonraki isteğin sağlıklı bir replika tarafından hizmet edilmesinin ne kadar sürdüğü?
* **İstemci Yeniden Deneme Davranışı:** Yük dengeleyicileriniz veya istemcileriniz anında yeniden deniyor mu? Eğer öyleyse, kalan sağlıklı düğümleri geri birikimle (backlog) aşırı yüklüyor musunuz?
* **KV Önbellek Kaybı:** Uçuştaki kısmi üretimin, çerçeveniz tarafından destekleniyorsa kontrol noktasından (checkpoint) devam ettirildiğinin veya doğru şekilde sonlandırıldığının doğrulanması.
Senaryo 2: Ağ Bölünmeleri ve Geciken Düğümler
Dağıtık çıkarım kurulumlarında (örneğin, DeepSpeed veya vLLM'in tensör paralelliği kullanılması durumunda) ağ bölünmesi kritiktir. Tensör paralel grubundaki bir düğüm bağlantısını kaybederse, tüm çıkarım partisi başarısız olur. Ancak ayrıştırılmış bir mimaride (Prefill ve Decode ayrımı), ön uç yük dengeleyici ile çıkarım işçileri arasındaki bir bölünme farklı belirtilere neden olur.
Çıkarım arka ucunun erişilemez hale geldiği ancak API geçidinin (gateway) ayakta kaldığı bir ağ bölünmesini simüle edelim.
# tc (trafik kontrolü) kullanarak çıkarım arka uç pod'una %100 paket kaybı ekleyin
# Bu, düğümü tamamen düşürmeden bir ağ bölünmesini simüle eder
POD_IP=$(kubectl get pod -l app=inference-backend -o jsonpath='{.items[0].status.podIP}')
# Çıkarım arka ucuna giden tüm trafiği düşür
kubectl exec -it [gateway-pod] -- tc qdisc add dev eth0 root netem loss 100%
# Kaos penceresi için bekle
sleep 30
# Trafiği geri yükle
kubectl exec -it [gateway-pod] -- tc qdisc del dev eth0 root
**Beklenen Davranış:**
1. API geçidi, yapılandırılmış `proxy_read_timeout` (ör. 5s) içinde isteklerin zaman aşımına uğramalıdır.
2. Mümkünse geçit, alternatif replikalara hızlıca başarısız olmalıdır (fail-fast).
3. **Kritik:** Akışkan (SSE) yanıtlar için, istemci kapatılan bağlantıyı algılamalıdır. İstemci tarafı kodunuzun, akış ortasında kopmayı doğru şekilde ele alıp istemi yeniden kuyruğa alıp almadığını veya sessizce başarısız olup kullanıcı hayal kırıklığına yol açıp açmadığını test edin.
CI/CD'de Otomatik Kaos Testlerinin Uygulanması
Manuel kaos testleri sürdürülebilir değildir. Bu senaryoları LitmusChaos veya Chaos Mesh gibi araçlar kullanarak staging hattınıza entegre edin.
apiVersion: litmuschaos.github.io/v1alpha1
kind: ChaosExperiment
metadata:
name: llm-gpu-chaos
spec:
appinfo:
appkind: deployment
labelselector: "app=vllm-server"
chaosConfig:
chaosKind: "pod-kill"
# Düğüm düzeyinde GPU kurtarmasını tetiklemek için sert bir kapatmayı simüle edin
mode: "all"
duration: "120s"
**Doğrulama Stratejisi:**
Sadece pod'un yeniden başlatılıp başlatılmadığını kontrol etmeyin. Hizmetin *kalitesini* doğrulayın.
* **P99 Gecikme Kontrolü:** Arıza penceresi sırasında P99 gecikmesinin taban çizgisinin 2 katını aşmadığını doğrulayın.
* **Token Kaybı Kontrolü:** Akış için, istemcinin aldığı toplam token sayısının beklenen sayıyla eşleştiğini veya kesilmiş, bozuk bir yanıt yerine temiz bir hata döndürüldüğünü doğrulayın.
Sonuç
LLM çıkarımı, sadece başka bir durumsuz hizmet değildir. VRAM'deki durumlu yapısı, yüksek bellek ayak izi ve uzun süreli akışkan doğası, kaos mühendisliğine özel bir yaklaşım gerektirir. GPU arızalarını ve ağ bölünmelerini simüle ederek, yeniden deneme mantığınızdaki, yük dengeleme stratejilerinizdeki ve istemci tarafı hata yönetiminizdeki kritik boşlukları ortaya çıkarabilirsiniz. Küçük başlayın: staging ortamında tek bir GPU çökmesi enjekte edin. Etki alanını (blast radius) izleyin. İterasyon yapın. Dayanıklılık, kasıtlı başarısızlıklarla inşa edilir.
<<<