Два Qwen3 на одном DGX Spark: расчёт занятой памяти

Автор разворачивает агент-стек на рабочей станции, подключённый к DGX Spark через LAN для вычислений на GPU. При росте флота агентов понадобилось запустить две модели параллельно: Qwen3-Next-80B для сложных задач и Qwen3-4B для быстрого отклика. Ollama не поддерживал нужного уровня контроля памяти, поэтому перешли на vLLM с LiteLLM прокси.
Процесс оказался нетривиален. На Spark (120 ГБ памяти) нужно было совместить две модели, но параметр gpu_memory_utilization считается от всей памяти GPU, не от свободной. 80B при 0.85 требовала 101.7 ГБ, но карта давала только 119.67. После трёхдневного перебора конфигов автор остановился на 0.80 для 80B и 0.10 для 4B, на практике потребовав 101.5 и 13.8 ГБ соответственно. Qwen3-Next использует Mamba вместо attention, что меняет расчёты для KV-кеша.
Ключевые факты
- gpu_memory_utilization в vLLM считается от полного объёма памяти GPU, а не от свободной, что запутывает расчёты при coresidency
- Qwen3-Next на Mamba требует другого подхода к планированию KV-кеша, чем классические attention-модели типа Llama
- Две конкурирующие процессы на GPU не переговариваются, только гонят друг друга, поэтому нужна эмпирическая калибровка после каждого перезапуска
- Инструмент вроде LiteLLM позволяет маршрутизировать запросы на одну из двух моделей через единую точку входа
- При развёртывании требуется резерв памяти 5 ГБ на CUDA-фреймворк и буфер на перезагрузку после сбоев
Ред. Параметр называется «utilization», считается от полной памяти и не делает того, что подсказывает интуиция. Классика именования в ML-инфраструктуре.
Почему это важно
Локальные LLM-кластеры становятся стандартом для приватных агент-стеков. Современный GPU даёт 100+ ГБ, но две крупные модели легко забить память. Умный контроль процессов через vLLM позволяет запускать быструю и медленную модель на одном железе вместо покупки второго GPU, экономя сотни тысяч рублей инфраструктуры.
Ред. Экономия на втором GPU честно конвертируется в три дня перебора конфигов. Где-то здесь спрятана почасовая ставка инженера, о которой не принято считать.
Кому это важно
Инженерам, которые разворачивают собственные LLM-бекенды под агент-системы. Разработчикам, критичным к приватности или контролю коста инференса. Teams, которые запускают многомодельные системы на месте (на DGX, на Spark или подобных) вместо облака.
Ред. «Критичным к контролю коста инференса» это вежливый способ сказать «тем, кто увидел счёт от облачного провайдера».
Как это применить
Загрузить большую модель первой, дать ей стабилизироваться. Запустить nvidia-smi и записать реальный расход памяти, не полагаясь на цифры из документации. Выделить вторую модель с запасом 5 ГБ на системные нужды и рестарт-цикл. Перепроверить конфиг после двух чистых рестартов обеих моделей. Если используется Qwen3-Next, учесть Mamba при расчётах KV-пула.
Ред. «Не полагайтесь на цифры из документации, запустите nvidia-smi» это, по сути, краткое содержание всей профессии.
Можно ли доверять
Пост основан на реальном боевом опыте, но не претендует на универсальность. Вывод автора верен: параметры vLLM нужно калибровать эмпирически, по факту. Документация vLLM может быть неточна в деталях для редких архитектур типа Qwen3-Next. Методология (загрузить, измерить, отрезервировать) применима, результаты, специфичны для конкретного GPU и модели.
Ред. Доверять можно ровно до следующего минорного релиза vLLM, который тихо поменяет, что именно считает «snapshot at process start».
Риски и подводные камни
Две процессы на GPU конкурируют без координации, поэтому пики нагрузки от одной могут заморозить другую. Неудачный рестарт одной модели может увеличить её остаточное потребление памяти за счёт оставшихся CUDA-контекстов. Мощные модели вроде Qwen3-Thinking полностью несовместимы с инструментальными вызовами в режиме auto, требуя switch на Instruct-версию и потери capability.
Ред. Два процесса делят один GPU, не разговаривая друг с другом и борясь за память. Кому-то это напомнит не только инфраструктуру.
«gpu_memory_utilization is a snapshot vLLM takes at process start, against total card memory. It is not a target against free memory.»
— Devashish, автор поста