Автор пишет про свой опыт развёртывания нескольких LLM на одной DGX Spark. У него работает fleet агентов под управлением оркестратора Clawrium и фреймворка Hermes. Раньше он просто держал одну модель через ollama — просто, но без гибкости. Перешёл на vLLM, чтобы держать на одном Spark (119.67 GiB unified memory) два Qwen3: 80B для тяжёлой работы и 4B для быстрых ответов. Связка — LiteLLM proxy на :4000.
Сразу начались проблемы. vLLM использует параметр gpu_memory_utilization как долю от всей памяти карты, а не от свободной. Когда автор пытался запустить 80B с 0.85, vLLM ругалась, что свободно 98 GiB, а целевое 101.7 GiB — хотя 4B уже занял 16 GiB. Первый урок: gpu_memory_utilization считает тотальную память, а не то, что осталось. Для двух процессов их доли должны в сумме давать ~0.95, чтобы оставалось место для CUDA overhead.
В итоге для 80B выставил 0.80 / 32k / 2 — загрузилось.
Дальше пришёл Hermes, и модель не отдавала tool_calls. Парсеры искали тег <tool_call> (единственное число), а модель в tool_choice: "auto" молчала — выдавала пустой ответ после <think>. Оказалось, Qwen3-Next-80B-Thinking вообще не поддерживает tool_choice: "auto" и игнорирует enable_thinking: false. Пришлось менять всю 80B на версию Instruct (77 GiB скачать, слить GPU, перезапустить с флагами --enable-auto-tool-choice --tool-call-parser hermes). Заработало.
Потом понадобилось увеличить контекст до 64k для агента-ревьюера. Подняли 80B до 0.85 / 65536 / 2 — загрузилось, но 4B начал перезапускаться 19 раз: свободно 12.58 GiB, а нужно 14.36. Реальная занятость 80B при 0.85 оказалась 101.5 GiB плюс ~5 GiB CUDA overhead — оставалось 12.5, не хватало. Опустили 80B обратно на 0.80, а 4B выставили 0.10 / 16384 / 8 — оба встали, хотя KV pool на 4B пришлось урезать.
Автор делает три вывода. Во-первых, реальная занятость (actual residency) отличается от целевого gpu_memory_utilization — у 80B при 0.80 оказалось на 8 GiB меньше, чем зарезервировано. Этот запас — единственное, что спасает при рестартах. Во-вторых, CUDA overhead не исчезает при малых аллокациях: 4B при 0.10 реально занимает 13.8 GiB, а не 12 GiB. В-третьих, на Qwen3-Next Mamba state alignment доминирует над attention KV — уменьшение max_model_len не пропорционально уменьшает KV pool, как на чистых attention-моделях.
Практический совет: грузите сначала большую модель, дайте ей устаканиться, смотрите nvidia-smi --query-gpu=memory.used --format=csv, отнимайте ~5 GiB на overhead второй модели, и только потом рассчитывайте её gpu_memory_utilization. И перепроверяйте после пары стабильных рестартов. Математика должна быть эмпирической, а не оптимистичной.