- Дата публикации
Как Mistral выловила утечку памяти в vLLM и почему это важно всем, кто крутит большие модели
Что появилось / что изменилось
Mistral AI запустила инженерную серию Deep Dive и первым кейсом разобрала очень неприятный баг: утечку памяти в vLLM при продакшн-нагрузке.
Кейс конкретный:
- связка: vLLM + модель Mistral Medium 3.1;
- режим раздельного сервинга Prefill/Decode (P/D disaggregation);
- включена компиляция графа;
- транспорт KV-кэша через NIXL поверх UCX.
В этом сетапе системная память на decode-ноде росла линейно — примерно на 400 МБ в минуту под трафиком, похожим на продакшн. Ошибок и крэшей не было, только медленное раздувание RSS до состояния out-of-memory через несколько часов.
Команда Mistral:
- подтвердила, что утечка воспроизводится не только у них, через issue в GitHub vLLM;
- сузила проблему до decode-части P/D-сервинга и передачи KV-кэша через NIXL;
- показала, как от Python-профайлеров дошла до kernel-level трассировки и Heaptrack.
Главное изменение для индустрии — появился детальный разбор, как реально искать такие утечки в стекe vLLM + UCX + NIXL, когда стандартные инструменты бессильны.
Как это работает
Сетап, в котором всплыла утечка, выглядит так.
Prefill/Decode disaggregation:
- Роутер отправляет prefill‑запрос на отдельный vLLM-инстанс:
max_tokens=1;- пустые метаданные KV Transfer. Prefill‑нода считает KVCache для запроса.
- После этого роутер отправляет decode‑запрос на другую vLLM-ноду, уже с метаданными KVCache.
- Передача KVCache идёт через NIXL, который у Mistral работает поверх UCX (Unified Communication X).
- Decode‑нода принимает KVCache и дальше генерирует токены, расширяя этот кэш.
Проблема проявлялась только на стороне decode. Prefill‑инстансы вели себя нормально. Это сразу наводит на мысль, что утечка связана с обработкой и использованием переданного KVCache, а не с обычным инференсом.
Дальше команда пошла по лестнице инструментов:
- Memray и Guppy 3: показали нормальную картину, утечек в Python-объектах не видно.
- GDB: попытка дебага приводила к крашу процесса.
- Valgrind: vLLM слишком тяжёлый, запуск нереалистично медленный и местами просто не работает.
Поэтому Mistral перешла к Heaptrack. Это профайлер, который подменяет вызовы malloc/free и логирует все аллокации с бэктрейсами.
Как они его вшили в vLLM:
- выставили
LD_PRELOAD=libheaptrack_preload.soдля воркер‑процесса vLLM; - Heaptrack перехватывает все аллокации, пишет их в файл
heaptrack.<pid>; - потом они прогоняют дамп через
heaptrack_interpretи получают сжатый отчётheaptrack.vllm.<pid>.gz.
Ключевая идея: не пытаться смотреть на Python-уровень, а считать каждое malloc и free в нативном коде, где и прячутся такие утечки.
Что это значит для вас
Если вы крутите большие модели через vLLM и особенно используете:
- раздельный Prefill/Decode‑сервинг;
- передачу KV‑кэша по сети (NIXL, UCX, Infiniband);
- графовую компиляцию,
вам нельзя полагаться только на отсутствие крэшей. Здесь утечка проявлялась как плавный рост памяти без ошибок, по 400 МБ в минуту. Такой сценарий легко пропустить, если вы смотрите только на latency и throughput.
Практические выводы:
-
Всегда проверяйте продакшн‑сетап, а не только «облегчённую» версию. Mistral пробовала меньшие модели и другие настройки — и не могла воспроизвести баг. Утечка проявлялась только в реальной тяжёлой конфигурации.
-
Не ограничивайтесь Python-профайлерами. Если Memray и Guppy 3 ничего не показывают, а память всё равно растёт, значит, проблема в C/C++‑слое, CUDA, сетевой библиотеке или драйверах.
-
Используйте Heaptrack или аналогичные инструменты. Для vLLM‑подобных систем Valgrind часто бесполезен: слишком медленно. Подмена
malloc/freeчерезLD_PRELOADдаёт шанс поймать реальную картину под нагрузкой. -
Следите за decode‑нодами отдельно от prefill. В P/D‑архитектуре поведение у них разное. Логика передачи KVCache и сетевые библиотеки могут вести себя совсем не так, как обычный инференс.
-
Не стесняйтесь идти к авторам библиотек. Mistral открыла issue в GitHub vLLM и убедилась, что проблема воспроизводится не только у них. Это экономит недели локального шаманства.
Если вы работаете из России, доступ к репозиториям и блогам Mistral, GitHub, а также к бинарям Heaptrack может потребовать VPN — это уже зависит от вашего провайдера и корпоративной политики.
Место на рынке
По сути, это не новый продукт, а честный отчёт о том, что происходит, когда вы строите продакшн‑сервинг больших моделей на vLLM с раздельным Prefill/Decode и тяжёлым сетевым стеком.
На фоне других стэков:
- vLLM часто выбирают как быстрый и экономный рантайм для LLM, но такие кейсы напоминают, что цена — сложность дебага на нативном уровне.
- Сервинг через TensorRT-LLM, FasterTransformer или собственные C++‑решения даёт больше контроля, но требует своей инфраструктуры профайлинга и тоже не застрахован от подобных утечек.
Конкретных цифр сравнения по скорости или стабильности Mistral не приводит, поэтому честно: мы не знаем, насколько этот баг влияет на vLLM по сравнению, например, с TensorRT-LLM под такой же нагрузкой.
Польза этого разбора в другом:
- он даёт реальный чек‑лист по поиску утечек в сложном AI‑стеке;
- показывает, что даже зрелые библиотеки вроде UCX и популярные рантаймы типа vLLM могут вести себя неожиданно в специфичных конфигурациях.
Если вы строите свой сервинг LLM, особенно с разнесённым Prefill/Decode и сетевой передачей KVCache, кейс Mistral — хороший ориентир, какие инструменты и шаги закладывать в свою инженерную практику с первого дня.