İki DGX Spark sınıfı kutu, tek model: her birinde birer kopya, bölünmeye karşı

Operasyonlar

Yedi hafta boyunca yerel dil modelimiz, tensör paralelliği ile iki NVIDIA GB10 makinesi arasında bölünmüş olarak çalıştı. 22 Ekim'de bunu her makinede modelin tam bir kopyası ve önünde en az bağlantılı bir vekil sunucu ile değiştirdik. Verim saniyede yaklaşık 180'den 210 token'a yükseldi ve artık herhangi bir makineyi, modeli ortadan kaldırmadan yeniden başlatabiliyorsunuz.

Neden bölmüştük

Her makinede CPU ve GPU'nun paylaştığı 128 GB bellek var. Eylül ayında model tek bir makineye sığıyordu, ancak önbelleği zar zor sığıyordu: kullandığımız vLLM derlemesi bu modelin KV önbelleğini FP8'de tutamıyordu, bu nedenle önbellek BF16'daydı ve bir makine bunun için 499.110 token'a yer bırakıyordu. Bu, modelin 262.144 token'lık tam bağlamında iki istekten daha az. Doğrudan ağ bağlantısı üzerinden tensör paralelliği ile her iki makineye bölündüğünde, önbellek üç milyondan fazla token'a büyüdü. Modeli hız için değil, yer için bölmüştük.

Neler değişti

Aynı modelin daha yeni bir 4-bit derlemesi (NVFP4, kuantum farkındalıklı damıtma ile oluşturuldu) yaklaşık 71 GiB bellek kullanıyor ve GB10 için topluluk vLLM derlemesi (eugr/spark-vllm-b12x) önbelleğini FP8'de çalıştırıyor. Artık bir makine tüm modeli ve 0,76 ile 1,08 milyon token'lık bir önbelleği, makinenin belleğinin ne kadarını ayırdığına bağlı olarak tam bağlamda 2,9 ile 4,1 isteğe yetecek kadar yer tutuyor. Her iki kopya da modelin kendi spekülatif kod çözümlemesini (MTP, dört taslak token) kullanıyor. Geçiş yapmadan önce yeni derleme üzerinde araç çağırma testimizi çalıştırdık: 86 puan aldı, yerini aldığı derleme 75 puan almıştı.

Neyi ölçtük

İki makineye bölünmüşHer makinede bir kopya
KV önbelleği3 milyondan fazla token0,76 ve 1,08 milyon token
Tam bağlamda istekleryaklaşık 122,9 ve 4,1
Yükümüz altındaki verimyaklaşık 180 token/s210 token/s (111 + 99)
Başlatmayaklaşık 20 dakikakopya başına 5 ila 13 dakika
Bir makine yeniden başlatıldığındamodel çökerdiğer kopya hizmet verir

Tek kopya, aynı anda işlediği istek sayısına göre kendi başına: kısa istemlerle 1 istek saniyede 36 token, 4 istek 82, 8 istek 109 ve 16 istek 150 üretti. E-posta ajanımızın daha uzun istemleriyle 4 istek 81, 8 istek 113 ve 16 istek yalnızca 87 üretti: sekiz isteği aştıktan sonra daha fazlası işlemi yavaşlattı.

Bir öğleden sonra bir kopya aynı anda en fazla 12, diğeri 8 istek aldı. İlki saniyede 91 ile 93 token üretti ve dakikada 26 ile 27 isteği tamamladı; ikincisi saniyede 81 ile 83 token ve dakikada 22 istek üretti. Şimdi ikisi de 12 alıyor.

Nelerden vazgeçtik

Alan. Bölünmüş modelin üç milyondan fazla tokenlık tek bir önbelleği vardı; kopyaların iki daha küçük önbelleği var ve bir istek yalnızca kendisine hizmet eden kopyanın önbelleğini kullanabilir. Ajanlarımız çok sayıda kısa ve orta uzunlukta istek gönderir ve onlar için verim daha önemliydi. Aynı anda birkaç çok uzun bağlam sunuyorsanız, bölme hâlâ daha iyi bir tercih olabilir. Bölünmüş kurulumu sakladık ve geri geçiş tek bir betikle yapılır.

Geçiş sırasında neler ters gitti

  1. Model olmadan on bir dakika, ardından 30 saniyelik 502 hataları. Bölünmüş model, aynı makinelerde bir kopya yüklenmeden önce durmak zorunda kaldı, bu yüzden ajanlarımız yaklaşık on bir dakika bekledi. İlk kopya ayağa kalktığında, proxy yaklaşık 30 saniye daha "502 no live upstreams" yanıtı vermeye devam etti: backend'leri çalışmadıkları sırada başarısız olarak işaretlemişti (max_fails=3, fail_timeout=30s) ve süre dolana kadar onları tekrar denemedi.
  2. Vekil sunucuyu atlayan bir istemci. Toplu işlerimizden birinin yapılandırmasında ilk makinenin adresi vardı, bu yüzden tüm yükü bir kopyaya gitti ve diğer kopyada bolca kapasite boşta kaldı. Artık tüm istemciler vekil sunucu üzerinden geçiyor; makinelerin kendi adresleri yalnızca sağlık kontrolleri için kullanılıyor.
  3. Sıçrayan metrikler. Verim monitörümüz, proxy üzerinden vLLM'in /metrics uç noktasını okuyordu. İki backend ile ardışık okumalar farklı kopyalardan geldi, sayaçlar ileri geri sıçradı ve monitör modeli aç (starved) olarak raporladı. Artık her kopyayı doğrudan okuyup topluyor.
  4. Yeni kopyayı durduracak eski bir gözetim mekanizması. Bölünmüş kurulum, model yanıt vermeyi bıraktığında hizmetini yeniden başlatan bir gözetim mekanizmasına sahipti. Yeni hizmet, eskisiyle Conflicts= bildirir, bu yüzden bu yeniden başlatma yeni kopyayı durduracaktı. Sadece durdurulmakla kalmayıp systemctl disable --now ile kapatılması gerekiyordu, çünkü operasyon katmanımız etkin ancak çalışmayan birimleri yeniden başlatıyor.
  5. Başka işler yapan makinede bellek. Bir makine aynı zamanda veritabanlarımızı ve site derlemelerini çalıştırıyor. vLLM'in gpu-memory-utilization değeri 0.78 iken, diğer her şey için yalnızca 5 GiB kalıyordu, bu yüzden bunu 0.74'e düşürdük ve diğer kopya yükü taşırken yalnızca o kopyayı yeniden başlattık. Bu makinelerde, vLLM'e verdiğiniz pay, diğer her şeyin kullandığı bellekten çıkar.

Bu makinelerden iki tanesine sahipseniz

Factory Floor, bir veya iki makine için proxy ve başlatma yapılandırmalarını, modelleri geçirmeden önce çalıştırdığımız sağlık kontrolü ve araç kullanımı testini, ayrıca makinenin geri kalanı için gözetim mekanizmalarını ve bellek güvenlik kısıtlarını içerir.

Güncellendi: