Dalawang kahon na katumbas ng DGX Spark, iisang modelo: isang kopya sa bawat isa na mas mabilis kaysa hatiin ito
Ops
Sa loob ng pitong linggo, ang aming lokal na language model ay tumatakbo nang nahahati sa dalawang NVIDIA GB10 machines gamit ang tensor parallelism. Noong Oktubre 22, pinalitan namin ito ng buong kopya ng modelo sa bawat machine at isang least-connection proxy sa unahan. Ang throughput ay tumaas mula humigit-kumulang 180 hanggang 210 tokens bawat segundo, at maaari na ngayong i-restart ang alinman sa mga machine nang hindi nawawala ang modelo.
Bakit namin ito hinati
Ang bawat machine ay may 128 GB ng memory na ibinabahagi ng CPU at GPU. Noong Setyembre, ang modelo ay kasya sa isang machine, ngunit halos hindi kasya ang kanyang cache: ang vLLM build na ginamit namin ay hindi kayang panatilihin ang KV cache ng modelong ito sa FP8, kaya nasa BF16 ang cache, at may espasyo ang isang machine para sa 499,110 tokens nito. Mas kaunti ito kaysa dalawang request sa buong context ng modelo na 262,144 tokens. Nang hatiin ito sa parehong machines gamit ang tensor parallelism sa kanilang direktang network link, lumaki ang cache sa mahigit tatlong milyon na tokens. Hinati namin ang modelo para sa espasyo, hindi para sa bilis.
Ano ang nagbago
Ang mas bagong 4-bit build ng parehong modelo (NVFP4, ginawa gamit ang quantisation-aware distillation) ay gumagamit ng humigit-kumulang 71 GiB ng memory, at ang isang community vLLM build para sa GB10 (eugr/spark-vllm-b12x) ay pinapatakbo ang kanyang cache sa FP8. Ngayon, ang isang machine ay hawak ang buong modelo at isang cache na 0.76 hanggang 1.08 milyon na tokens, na may espasyo para sa 2.9 hanggang 4.1 requests sa buong context, depende sa kung gaano karaming memory ang ibinibigay ng machine. Parehong gumagamit ang mga kopya ng sariling speculative decoding ng modelo (MTP, apat na draft tokens). Bago lumipat, pinatakbo namin ang aming tool-calling test sa bagong build: nakakuha ito ng 86, habang ang build na pinalitan nito ay 75.
Ang aming sinusukat
| Nahahati sa dalawang machines | Isang kopya sa bawat machine | |
|---|---|---|
| KV cache | mahigit 3 milyon na tokens | 0.76 at 1.08 milyon na tokens |
| Requests sa buong context | humigit-kumulang 12 | 2.9 at 4.1 |
| Throughput sa ilalim ng aming load | humigit-kumulang 180 tokens/s | 210 tokens/s (111 + 99) |
| Pagbubukas | humigit-kumulang 20 minuto | 5 hanggang 13 minuto bawat kopya |
| Isang machine ang nagre-restart | ang modelo ay down | ang ibang kopya ang nagse-serve |
Isang kopya sa sarili nito, ayon sa bilang ng mga request na pinaglilingkuran nito nang sabay-sabay: sa mga maikling prompt, ang 1 request ay nagbibigay ng 36 tokens bawat segundo, ang 4 ay 82, ang 8 ay 109, at ang 16 ay 150. Sa mas mahahabang prompt ng aming email agent, ang 4 ay 81, ang 8 ay 113, at ang 16 ay 87 lamang: higit sa walong ganitong request, mas marami ang nagpapabagal.
Sa isang hapon, ang isang kopya ay tumatanggap ng hanggang 12 request nang sabay-sabay at ang isa ay 8. Ang una ay nagpro-produce ng 91 hanggang 93 tokens bawat segundo at nagtapos ng 26 hanggang 27 request bawat minuto; ang pangalawa ay 81 hanggang 83 tokens bawat segundo at 22 request bawat minuto. Pareho na silang tumatanggap ng 12 ngayon.
Ano ang isinuko namin
Espasyo. Ang split model ay may isang cache na higit sa tatlong milyon na tokens; ang mga kopya ay may dalawang mas maliit na cache, at ang isang request ay maaari lamang gamitin ang cache ng kopyang naglilingkod dito. Ang aming mga agent ay nagpapadala ng maraming maikli at katamtamang request, at para sa kanila, mas mahalaga ang throughput. Kung naglilingkod ka ng ilang napakahabang context nang sabay-sabay, maaaring mas mainam pa rin ang pag-split. Pinanatili namin ang split setup, at ang pagbalik dito ay isang script lamang.
Ano ang naging problema habang nagpapalit
- Labing-isang minuto nang walang model, pagkatapos ay 30 segundo ng mga 502. Kailangang huminto ang split model bago ma-load ang isang kopya sa parehong mga machine, kaya ang aming mga agent ay naghintay ng humigit-kumulang labing-isang minuto. Nang bumangon ang unang kopya, patuloy na sumasagot ang proxy ng "502 no live upstreams" sa loob ng humigit-kumulang 30 segundo pa: minarkahan nito ang mga backend bilang nabigo habang pababa ang mga ito (max_fails=3, fail_timeout=30s) at hindi na ito subukang muli hanggang sa matapos ang panahong iyon.
- Isang client na lumaktaw sa proxy. Isa sa aming mga batch job ay may address ng unang machine sa kanyang config, kaya ang buong load nito ay napunta sa isang kopya habang ang isa ay may sapat na kapasidad. Ngayon, lahat ng client ay dadaan sa proxy; ang mga address ng mga machine ay para lamang sa health checks.
- Mga metric na tumalon. Ang aming throughput monitor ay binabasa ang /metrics ng vLLM sa pamamagitan ng proxy. Sa dalawang backend, ang sunod-sunod na pagbasa ay galing sa magkaibang kopya, tumatalon-talon ang mga counter, at iniulat ng monitor na gutom ang model. Ngayon, binabasa nito ang bawat kopya nang direkta at pinagsasama ang mga ito.
- Lumang watchdog na pipigil sa bagong kopya. Ang split setup ay may watchdog na nag-restart ng serbisyo nito kapag tumigil na sumagot ang model. Idineklara ng bagong serbisyo ang Conflicts= sa lumang isa, kaya ang restart na iyon ay pipigil sa bagong kopya. Kailangan itong patayin gamit ang
systemctl disable --now, hindi lang ihinto, dahil ang aming ops layer ay nag-restart ng mga unit na enabled ngunit hindi tumatakbo. - Memory sa makina na gumagawa ng ibang trabaho. Isang makina ang tumatakbo rin ng aming mga database at site builds. Sa gpu-memory-utilization ng vLLM na 0.78, 5 GiB lang ang natira para sa lahat ng iba, kaya ibinaba namin ito sa 0.74 at ini-restart lang ang kopyang iyon habang ang isa pang kopya ang humahawak ng load. Sa mga makina na ito, ang share na ibinibigay mo sa vLLM ay galing sa parehong memorya ng lahat ng iba.
Kung mayroon kang dalawang makina na ganito
- Kung ang model at ang cache na kailangan mo ay kasya sa isang makina, magpatakbo ng kopya sa bawat isa sa likod ng least-connection proxy. Hatiin lang ang model kapag hindi kayang hawakan ng isang makina ang cache na kailangan mo.
- Ituro ang lahat ng client sa proxy, kabilang ang mga batch job at lumang configs.
- Basahin ang metrics mula sa bawat kopya nang direkta.
- Bigyan ang bawat makina ng sarili nitong memory share, ayon sa iba pang tumatakbo rito.
- Itakda kung ilang request ang hahawakan ng kopya nang sabay-sabay gamit ang sarili mong traffic: para sa aming mix, mas mabuti ang 12 kaysa 8.
- Inaasahan na ang paglipat ay tatanggalin ang model sa loob ng tagal ng pag-start ng kopya, at magplano para dito.
Factory Floor ang nagbibigay ng proxy at launch configs para sa isa o dalawang makina, ang health check at ang tool-use test na aming pinapatakbo bago magpalit ng model, kasama ang mga watchdog at memory guard para sa natitirang bahagi ng makina.