Материал подготовлен автоматически по первоисточникам: ссылки на них — в конце статьи.
KV-кэш длинных запросов научились выносить в память CPU с меньшими простоями GPU. В нерецензированном препринте HUST и UCloud, где числа получили сами авторы, система PulseInfer увеличила скорость декодирования до 4,7 раза относительно SGLang. Для собственного сервинга длинного контекста это сдвигает внимание с объёма памяти GPU на организацию обмена данными с CPU.
Перенос KV-кэша освобождает память, но загружает PCIe
При генерации модель хранит ключи и значения для уже обработанных токенов в KV-кэше. Чем длиннее контекст и больше одновременных запросов, тем больше памяти занимает этот кэш и тем меньше запросов помещается на GPU.
Разреженная выгрузка оставляет на GPU часто используемые блоки, а остальную историю переносит в оперативную память CPU. Перед вычислением внимания система выбирает нужные блоки и возвращает их через PCIe. Так можно увеличить пакет запросов, но GPU начинает ждать передачи данных.
Задержка меняется от слоя к слою и от одного шага генерации к другому. Фиксированная предварительная загрузка следующего слоя не справляется с длинным хвостом передач: иногда вычисления текущего слоя заканчиваются раньше, чем приходят данные для следующего.
Вторая проблема — размер операций. Когда каждая голова внимания выбирает блоки независимо, обмен распадается на передачи размером около 8 КБ. На PCIe 5.0×16 они дают примерно 6 ГБ/с при теоретическом пределе 64 ГБ/с: большую часть возможностей интерфейса съедают накладные расходы, а не сами данные.
PulseInfer переключает пакеты на границах слоёв
PulseInfer делит запросы на обычные и выгружаемые пакеты. KV-кэш первых остаётся на GPU, история вторых хранится преимущественно в памяти CPU.
Когда выгружаемому пакету нужны данные, система запускает передачу и переключает GPU на обычный пакет. На границе каждого слоя планировщик проверяет, завершился ли обмен. Если блоки уже пришли, GPU возвращается к отложенному пакету; если нет, продолжает полезные вычисления для обычного.
Такой планировщик не пытается заранее угадать длительность передачи. Он подстраивает число вычисленных слоёв под фактическую задержку и не смешивает короткие запросы с длинными в одном пакете. Короткий запрос поэтому не обязан ждать, пока система вернёт историю для соседнего длинного запроса.
Отдельный механизм решает, какие запросы выгружать. Он оценивает, сколько вычислений обычного пакета потребуется, чтобы скрыть обмен для выгружаемого, и ищет сочетание с наибольшей пропускной способностью. Это позволяет менять политику, когда в потоке становится больше длинных или коротких запросов.
Для сокращения числа передач PulseInfer выбирает одну поисковую голову внимания на слой. Её находят по тому, какую долю внимания она направляет на среднюю часть контекста, а затем используют выбранные ею блоки для всех голов слоя. Разрозненные блоки сначала собираются в промежуточном буфере, после чего система передаёт их одной крупной операцией и раскладывает на GPU.
Общий выбор может показаться более грубым, чем независимый выбор каждой головы. Однако потоковые головы обычно смотрят на начало и ближайшие токены, поэтому их решения добавляют шум при поиске информации в середине контекста. В проверенных задачах выбор специализированной поисковой головы сохранил среднее качество около полного внимания.
Работа меняет порядок проверки инфраструктуры, а не весь стек
PulseInfer реализовали поверх SGLang и проверили на трёх моделях размером от 14 до 230 млрд параметров. В испытания вошли синтетические нагрузки и промышленные трассы ServeGen и Mooncake; сравнение охватывало SGLang без выгрузки, ArkVale, InfiniGen и PQCache. Работа рассматривает декодирование в схеме, где подготовка контекста и генерация выполняются на разных экземплярах GPU.
Относительно лучшей системы выгрузки PulseInfer увеличил пропускную способность до 2,6 раза и сократил время на один выходной токен до 76%. На LongBench средние результаты остались близки к полному вниманию; на моделях Qwen они были немного выше, но это не доказывает общего улучшения качества.
Для команд с собственным сервингом длинного контекста вывод практический: одной оценки объёма памяти GPU недостаточно. Прототип нужно испытывать на реальном распределении длин запросов, отдельно измеряя простои GPU, размер передач через PCIe и долю запросов, чей KV-кэш приходится выгружать.
Статический порог длины запроса тоже выглядит рискованно. Лучший порог различался между двумя промышленными трассами, тогда как адаптивный допуск PulseInfer менял состав пакетов во время работы. Если нагрузка объединяет короткие диалоги, длинные документы и истории агентов, планировщик должен учитывать текущий обмен с CPU, а не только свободную память.
Работа пока не требует менять SGLang или закупать другую конфигурацию GPU. Она меняет план эксперимента: при дефиците памяти стоит сравнивать полное внимание не просто с выгрузкой KV-кэша, а с выгрузкой, которая разделяет пакеты, переключает их по слоям и объединяет мелкие передачи. Именно эти системные детали определили выигрыш PulseInfer.
Источники
Похоже на вашу задачу?
Расскажите, что собираете. За полчаса разложим на этапы и назовём сроки — это бесплатно и ни к чему не обязывает.



