Где бизнес платит за одно и то же дважды

Представьте внутреннего помощника, который отвечает на вопросы по инструкции для отдела продаж. В каждый запрос приложение добавляет одну и ту же системную инструкцию, большой фрагмент регламента и только затем конкретный вопрос сотрудника. Локальная модель каждый раз должна обработать входной текст перед первым словом ответа. Если общая часть длинная и не меняется, это повторение вычислений. Оно влияет на задержку и на то, сколько запросов выдержит имеющийся сервер.

В vLLM для такого случая предусмотрено Automatic Prefix Caching (APC): движок сохраняет KV-кэш уже обработанных блоков и повторно использует его, когда начало нового запроса совпадает с прежним. Это не хранение готового ответа и не поиск по документам. Модель всё равно обрабатывает новый вопрос и генерирует новый ответ. Механизм касается вычисления общей начальной части промпта — этапа prefill. Документация vLLM прямо предупреждает: этап генерации новых токенов, decode, от кэша префикса быстрее не становится.

Для российского малого бизнеса это может быть полезнее покупки следующего GPU, если одна локальная модель обслуживает множество коротких запросов по устойчивым шаблонам: классифицирует обращения, заполняет поля CRM, объясняет правила возврата или отвечает на повторные вопросы к одному руководству. Но сначала нужно понять, сколько в реальной нагрузке общего текста, а не просто включить опцию и объявить экономию.

Что именно должно совпасть

Ключевое слово — «префикс». Общая часть должна идти в начале в одинаковом порядке и после токенизации давать совпадающие блоки. Если перед общей инструкцией вставляется текущая дата, случайный идентификатор, имя пользователя или меняющийся список инструментов, повторное использование может оборваться уже на первых блоках. Если документ в RAG каждый раз выбирается и сортируется иначе, кэшировать длинное общее начало тоже сложнее.

Практичная архитектура для пилота:

  • зафиксировать системную инструкцию и неизменные правила в начале;
  • отделить переменные данные — вопрос, карточку клиента, свежие записи — и передавать их после общего блока;
  • версионировать шаблон, чтобы изменение правил сознательно создавало новый префикс;
  • не подменять RAG кэшем: поиск по актуальным документам по-прежнему нужен, если ответ зависит от изменяющейся базы знаний;
  • проверять, что порядок и сериализация сообщений в приложении не меняются от запроса к запросу.

Такой порядок нельзя навязывать вопреки качеству ответа или правилам доступа. Общий блок — лишь та часть контекста, которую действительно допустимо разделять между запросами. Персональные и конфиденциальные данные нельзя размещать в «общей инструкции» ради более красивой метрики попаданий.

Модельный расчёт без обещаний окупаемости

Пусть за рабочий день приходит 1 000 запросов. Каждый содержит 2 000 токенов одинаковой инструкции и справочного текста, затем 300 токенов уникального вопроса и контекста; ответ в среднем занимает 200 токенов. Это учебный сценарий, не измерение какой-либо компании. Без повторного использования префикса движок должен обработать 2,3 млн входных токенов: 1 000 × (2 000 + 300). Если бы общий префикс сохранялся идеально и все последующие запросы попадали в кэш, объём повторной обработки входа приблизился бы к 302 тыс. токенов: одна обработка 2 000 общих токенов плюс 1 000 × 300 уникальных. Разница около 2 млн токенов вычислений prefill.

Это не означает снижение счёта или времени ответа на 87%. Токены в этой арифметике — показатель потенциально устранённой повторной работы, а не денежный тариф. Генерация 200 тыс. выходных токенов остаётся, кэш занимает память, первый запрос прогревает его, часть запросов промахнётся, а сервер может большую часть времени ждать людей. При фиксированной аренде GPU экономия станет денежной только если вы реально сократите часы использования, удержите меньшую конфигурацию, отложите расширение или получите больше полезных задач на том же оборудовании. При оплате собственного сервера важны также электричество, обслуживание и резерв мощности.

Поэтому коэффициент из демонстрационного примера нельзя переносить в бюджет. Независимый исследовательский бенчмарк PrefixBench-H100, опубликованный в сентябре 2026 года, специально меняет длину общего начала, разнообразие хвостов запроса, конкуренцию, размер ответа и давление на кэш. Авторы показывают область, где время до первого токена заметно улучшается, и область, где нехватка памяти размывает выигрыш. Это измерение на H100 и в заданных условиях, а не обещание результата для вашего сервера.

Как замерить эффект на своём потоке

Возьмите обезличенную выборку за неделю: не менее нескольких сотен реальных запросов одного процесса, включая часы пиков и простоя. Если перенос текста за пределы контура запрещён, собирайте статистику внутри него и не сохраняйте сами обращения в аналитических выгрузках. Разбейте задачи на классы: одинаковый регламент с разными вопросами, длинные диалоги, разнородные разовые запросы. Посчитайте длину повторяющегося начального блока после той же токенизации, которую применяет рабочая модель.

Затем проведите два прогона на одной модели и одном оборудовании: с APC и без него. Сохраняйте порядок и скорость поступления запросов, лимит одновременной обработки и длину ответов. Один прогон «все запросы сразу» не воспроизводит рабочий день: прогретый кэш в тесном тесте может выглядеть лучше, чем в потоке с длинными паузами и вытеснением блоков. Учитывайте время прогрева, перезапуски, обновления промптов и то, обслуживаются ли запросы одной репликой сервера.

В vLLM доступны метрики запросов и попаданий префиксного кэша, доли использованных KV-блоков, времени до первого токена, времени prefill и полного времени ответа. Смотрите их вместе с числом завершённых полезных задач в час и долей ответов, принятых человеком без исправления. Ускорение плохого ответа не является экономией. Зафиксируйте стоимость часа конкретной конфигурации, а не абстрактную цену токена, и рассчитайте стоимость принятой задачи в обоих режимах.

Простой критерий решения: если задержка первого токена падает, пиковая пропускная способность растёт, качество не меняется, а память не вытесняет другие нужные запросы, кэш имеет практическую ценность. Если ответы в основном длинные, запросы не имеют общего начала или сервер почти не загружен, оптимизировать APC раньше качества данных и процесса преждевременно.

Ограничения и безопасность

KV-кэш конкурирует за память с активными запросами. При насыщении памяти блоки могут вытесняться, и ожидаемые попадания пропадают. В распределённом контуре важна и маршрутизация: повторный запрос, попавший на другой экземпляр без соответствующего состояния, не использует локальный кэш первого. Ни один процент попаданий сам по себе не гарантирует сокращения задержки при изменении очередей или конкуренции.

У общего кэша есть граница безопасности. Документация vLLM описывает возможность определить по времени ответа, встречался ли на общем сервере некоторый префикс другого клиента. Для многопользовательского контура предусмотрен `cache_salt`: разные секретные значения разделяют кэш между доверенными группами. Это снижает совместное использование блоков и, следовательно, потенциальную выгоду. Соль не следует делать предсказуемым идентификатором клиента; конкретную схему изоляции обязан определить ответственный за безопасность. В одноклиентском локальном контуре такая настройка может быть не нужна, но контроль доступа к самому серверу всё равно обязателен.

Начните с одного процесса и одного шаблона. За неделю измерьте частоту общего префикса, стоимость принятого ответа и разницу между режимами. Только после этого решайте, нужен ли более мощный сервер, и стоит ли менять сборку промпта. Кэш — способ не считать одно и то же повторно, а не универсальная скидка на локальный ИИ.

Фото серверной: Carl Lender, лицензия CC BY 2.0; редакцией выполнен центральный квадратный кроп. Страница оригинала и лицензии указана в источниках.