# SGLang RadixCache: повторный префикс, вытеснение и границы кеша

Источник: https://modelium.tech/zhurnal/sglang-radix-cache/

RadixCache в SGLang сохраняет KV-состояние повторяющегося префикса, чтобы следующий запрос мог не вычислять его заново. В версии исходников от 18 сентября 2026 года политика вытеснения по умолчанию — LRU; при нехватке памяти кешируемый префикс может исчезнуть. Разделяйте клиентские потоки по `cache_salt` и проверяйте попадания на собственной модели: высокий общий hit rate сам по себе не доказывает изоляцию данных или ускорение каждого запроса.

**Проверено по исходникам SGLang на коммите **`**94602c9**`** от 18 сентября 2026 года, наблюдение 30 сентября 2026 года.** Это протокол для своего стенда, не результат прогона Modelium: сервер и модель здесь не запускались. Описанные ключи и флаги могут измениться в вашей сборке. [s1](#src-s1) [s4](#src-s4)

## Что повторно использует RadixCache?

При обработке запроса сервер хранит key/value-состояния уже обработанных токенов — KV-кеш. RadixCache организует совместимые **префиксы последовательности токенов** в дерево и позволяет новому запросу использовать начальные вычисления, если ключи совпадают. Это экономия части работы prefill, а не кеш готового текста ответа: суффикс, настройки генерации и новая часть запроса всё равно обрабатываются отдельно. В коде `RadixKey` ключ включает токены и служебные компоненты; сравнение одной лишь строки из пользовательского интерфейса не устанавливает тождество токенов после chat template. [s4](#src-s4)

Для прикладного сценария возьмите длинную постоянную инструкцию и один и тот же разрешённый документ, затем задайте разные вопросы. Ожидаемая проверка — выросла ли повторно используемая доля токенов и сократилось ли время до первого токена на **этом** наборе. Само совпадение префикса не говорит о правильности ответа или величине ускорения: влияют версия модели и токенизатора, текущая очередь, доступный KV-пул и длина изменившегося суффикса. Это план эксперимента, а не измеренная характеристика SGLang у Modelium. [s3](#src-s3) [s4](#src-s4)

Практический маршрут: **задача с повторной инструкцией → выбранная совместимая модель/токенизатор → железо с достаточным KV-пулом → **[**локальный SGLang**](/zhurnal/sglang/)** → повторные запросы → проверка cache hit и результата**. Размер файла весов нельзя автоматически переводить в минимальную VRAM: остаток памяти под KV-пул зависит от вашего запуска. [s2](#src-s2) [s3](#src-s3)

## Как включить наблюдение, не подменяя им тест?

На отдельном локальном стенде с уже выбранной моделью проверьте аргументы именно своей версии через `python3 -m sglang.launch_server --help`. По закреплённой документации RadixCache не нужно «включать» отдельным флагом в обычном запуске: `--disable-radix-cache` по умолчанию `False`. Для анализа запустите сервер с `--model-path` вашей локально доступной модели и `--enable-metrics`; опционально добавьте `--enable-cache-report`, если вам нужны cached tokens в `usage.prompt_tokens_details` OpenAI-совместимого ответа. Не копируйте пример `MODEL_PATH` как реальный путь к существующим весам. [s2](#src-s2) [s3](#src-s3)

Проверьте на локальном `http://127.0.0.1:30000/metrics` наличие `sglang:cache_hit_rate` и гистограммы `sglang:time_to_first_token_seconds`. Первый показатель относится к наблюдаемому серверу, а не отдельно к каждому клиенту. Сохраняйте снимки метрик до и после каждой небольшой серии и журнал успешных ответов; значение из примера документации **не** есть результат Modelium. Если метрики недоступны, сначала проверьте флаг, порт и маршрутизацию, а не делайте вывод «кеш не работает». [s2](#src-s2) [s3](#src-s3)

Native API документация описывает POST `/generate` с полем `text`; для машинного эксперимента используйте JSON с одинаковым длинным `text`-префиксом и различающимися вопросами, зафиксируйте `sampling_params` и длину ответа. В закреплённой структуре запроса есть поле `cache_salt` как строка или список для батча. Задавайте **один и тот же salt только внутри одного разрешённого потока**, разные значения — для разных потоков; не передавайте чужой закрытый текст в тест. Перед началом убедитесь, что ваша установленная версия действительно принимает это поле и возвращает нормальный ответ — пример не выдаётся за исполненный запуск. [s6](#src-s6) [s7](#src-s7)

## Как сравнить попадание, промах и правильность?

Сделайте три серии на одном сервере и одной модели. **А:** после свежего запуска один длинный безопасный префикс + вопрос; сохраните исходный ответ, время до первого токена и cache metrics. **Б:** тот же префикс, тот же `cache_salt`, другой вопрос; сравните долю сохранённых токенов и задержку. **В:** тот же текст, но **другой** `cache_salt`; ожидайте отсутствие межпотокового reuse этого префикса и проверьте это по per-request отчёту/трассировке в вашей версии, а не по одному агрегированному `cache_hit_rate`. Для контроля повторите Б после В, чередуя потоки и фиксируя ошибки. Поле salt включается в ключ ветки `RadixKey` при наличии и тем самым задаёт отдельное пространство поиска префиксов в этой реализации. [s3](#src-s3) [s4](#src-s4) [s7](#src-s7)

Используйте обезличенные синтетические входы с заранее известными вопросами и проверяемыми ответами. Сравнивайте ответы с исходными данными вручную; при температуре, отличной от нуля, различие формулировок само по себе не доказывает порчу кеша. Запишите версию SGLang и commit, модель и ревизию, токенизатор, шаблон чата, GPU/CPU, размер KV-пула, режим HiCache/маршрутизатора, параметр salt, число запросов, конкурентность и порядок серий. Повторите опыт после рестарта для контроля прогрева; Modelium не утверждает, что A, Б или В уже запускались. [s2](#src-s2) [s4](#src-s4) [s8](#src-s8)

Если на Б попадания нет, прежде чем менять политику, проверьте фактические токены после шаблона, служебные ключи, salt, длину общего префикса, остаток свободного KV и вытеснение другими запросами. Если у вас включён внешний многоуровневый HiCache, данные могут перемещаться между уровнями; из одного показателя GPU-кеша нельзя заключать, что вся иерархия пуста. При сравнении сохраняйте одну и ту же нагрузку и используйте [разбор метрик SGLang](/zhurnal/sglang-metrics-prometheus/). [s3](#src-s3) [s4](#src-s4) [s8](#src-s8)

## Когда префикс вытесняется?

В закреплённой версии политика `lru` используется по умолчанию: при заполнении KV-пула сервер ищет доступные к вытеснению листья, а не узлы, удерживаемые выполняющимся запросом. Есть политики `lfu`, `slru` и `priority`; их смысл различается, и даже при приоритизации все доступные кандидаты могут быть освобождены, если памяти всё ещё мало. Смена политики — решение после проверки собственного hot set и частоты попаданий, не универсальное ускорение. [s1](#src-s1)

`--radix-eviction-policy-config` принимает JSON-настройку выбранной политики; `protected_threshold` относится к `slru`. Не переносите параметры одной политики в другую и не смешивайте LRU с настройками экспериментального Rust tree: документация предупреждает, что последний не принимает эту конфигурацию. Для штатного сервера начните с LRU и сравните два режима только после фиксации нагрузки и сохранения метрик. [s1](#src-s1) [s2](#src-s2)

Отдельная **session-aware** функция рассчитана на длительный диалог в `UnifiedRadixCache`: `session_id` при native `/generate` помогает сохранять ссылки на полезный KV при вытеснении, но это *мягкое предпочтение*, не закрепление KV в памяти. Документация прямо говорит, что `session_id` **не восстанавливает историю диалога**: приложение передаёт полный нужный контекст. Нельзя использовать session ID как механизм безопасности или замену разделению запросов. [s5](#src-s5)

## Достаточен ли `cache_salt` для безопасности клиентов?

Нет: исходный код показывает разделение ключа кеша по salt в рассматриваемой реализации, но **не** аттестует весь многопользовательский контур. Соль должны назначать на доверенной стороне шлюза, а не брать произвольную от клиента; проверяйте аутентификацию, доступ к логам и метрикам, маршрутизатор, резервные копии и внешние KV-хранилища отдельно. Не ставьте содержимое секретного документа в качестве salt и не называйте успешную серию В доказательством полной изоляции. Это граница архитектурной проверки Modelium, не сертификация SGLang. [s4](#src-s4) [s7](#src-s7) [s8](#src-s8)

**Следующий шаг:** если модель уже отвечает через [SGLang](/zhurnal/sglang/), откройте [инструкцию по метрикам](/zhurnal/sglang-metrics-prometheus/) и сохраните серию А/Б/В для двух синтетических потоков. Решение о сохранении RadixCache или изменении политики принимайте по успешным ответам, реальному reuse и задержке на своей нагрузке; при неподтверждённой границе доступа держите потоки на отдельных инстансах до отдельного security-review. [s1](#src-s1) [s3](#src-s3) [s4](#src-s4)

## Источники

1. [SGLang: Radix Cache Eviction Policies](https://github.com/sgl-project/sglang/blob/94602c9c2b7cbdb8efd5c52802dac6a1c180089e/docs/docs/advanced_features/radix_eviction_policy.mdx) — получено 2026-09-30
2. [SGLang: Server Arguments](https://github.com/sgl-project/sglang/blob/94602c9c2b7cbdb8efd5c52802dac6a1c180089e/docs/docs/advanced_features/server_arguments.mdx) — получено 2026-09-30
3. [SGLang: Production Metrics](https://github.com/sgl-project/sglang/blob/94602c9c2b7cbdb8efd5c52802dac6a1c180089e/docs/docs/references/production_metrics.mdx) — получено 2026-09-30
4. [SGLang: RadixKey and RadixCache implementation](https://github.com/sgl-project/sglang/blob/94602c9c2b7cbdb8efd5c52802dac6a1c180089e/python/sglang/srt/mem_cache/radix_cache.py) — получено 2026-09-30
5. [SGLang: Session-Aware Radix Cache](https://github.com/sgl-project/sglang/blob/94602c9c2b7cbdb8efd5c52802dac6a1c180089e/docs/docs/advanced_features/session_radix_cache.mdx) — получено 2026-09-30
6. [SGLang: Native API](https://github.com/sgl-project/sglang/blob/94602c9c2b7cbdb8efd5c52802dac6a1c180089e/docs/docs/basic_usage/native_api.mdx) — получено 2026-09-30
7. [SGLang: GenerateReqInput cache_salt](https://github.com/sgl-project/sglang/blob/94602c9c2b7cbdb8efd5c52802dac6a1c180089e/python/sglang/srt/managers/io_struct.py) — получено 2026-09-30
8. [SGLang: HiCache hierarchy](https://github.com/sgl-project/sglang/blob/94602c9c2b7cbdb8efd5c52802dac6a1c180089e/docs/docs/advanced_features/hicache.mdx) — получено 2026-09-30
