Skip to content

Recipes Integration.ru

sikkatu edited this page Nov 2, 2026 · 5 revisions

English | Русский | 中文

Интеграция с рецептами

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

Как это работает

Лаунчеры (scripts/run-tp4-uva.sh, scripts/run-tp4-hotsplit.sh из recipes/rtx-pro-6000/mimo-v2.6-pro-hotsplit) содержат блок KV-PERSIST:

KV_PERSIST="${KV_PERSIST:-0}"
if [ "$KV_PERSIST" = "1" ]; then
  ... вычисляет namespace идентичности кэша ...
  MODEL_ARGS=(--model "/models/$KV_PERSIST_NAMESPACE")
  MODEL_ARGS+=(--kv-transfer-config "$KV_TRANSFER_CONFIG")
  MODEL_ARGS+=(--enable-prompt-tokens-details)
  MODEL_ARGS+=(--block-size "$KV_PERSIST_BLOCK_SIZE")
fi
  • ВЫКЛ по умолчанию — без KV_PERSIST или с 0 рецепт ведёт себя байт-в-байт как раньше: нет коннектора, нет перемонтирования namespace, нет новых аргументов. Обычному запуску не нужны ни MODEL_DIR, ни установка kv-persistence.
  • ВКЛ (KV_PERSIST=1) блок делает четыре вещи (правка ревью, раунд 19):
    1. Namespace идентичности кэша — MODEL_DIR монтируется в /models/<namespace> (НЕ /model). LMCache ключует каждый L2-объект по model_config.model (значению --model), поэтому фиксированный путь /model заставлял КАЖДЫЙ деплоь делить один namespace: разные ревизии, KV-dtype или геометрии могли читать чужие KV-блоки. С namespace-путём каждая идентичность получает свой namespace, а несовместимый деплоь получает БЕЗОПАСНЫЙ промах — при условии, что namespace выведен из фактических аргументов движка (правка ревью: реальные значения KV_CACHE_DTYPE, MAX_MODEL_LEN, block size, TP size передаются в CLI как KVP_* переопределения, а auto резолвится в фактический dtype модели). Namespace выводится из python3 -m kvpersist.cli model-name (проверенный хэш идентичности), если найден клон kv-persistence (KVP_REPO_ROOT или ~/kv-persistence), иначе — из детерминированного хэша полей совместимости KV (config.json, индексы весов
      • размеры шардов, tokenizer-файлы, chat template, kv-dtype, max-model-len, block size, TP size). Поэтому для KV_PERSIST=1 обязателен MODEL_DIR.
    2. --kv-transfer-config — коннектор LMCache (тот же JSON, что и в собственном лаунчере kv-persistence).
    3. --enable-prompt-tokens-details — без него usage.prompt_tokens_details не сообщается, cached_tokens (единственный машиночитаемый счётчик переиспользования) недоступен, и приёмочный прогон kv-persistence (scripts/test-recovery.sh) никогда не даст PASS.
    4. Фиксируется --block-size (по умолчанию 16, переопределяется KV_PERSIST_BLOCK_SIZE) — гейту идентичности kv-persistence (verify-engine-identity.sh) нужен проверяемый аргумент движка. Ручки задокументированы в tp4.env.example / .ru / .zh (одинаковые имена, значения и порядок на трёх языках): KV_PERSIST, KV_PERSIST_HOST, KV_PERSIST_PORT, KV_PERSIST_NAMESPACE, KV_PERSIST_BLOCK_SIZE. ⚠️ KV_PERSIST_NAMESPACE (override) — если вы задаёте его вручную, ответственность за изоляцию лежит на вас: лаунчер не проверит соответствие namespace фактической конфигурации движка. Используйте override только если понимаете поля идентичности.

Включение — полный сценарий

  1. Установите и запустите сервис кэша по Quick Start, шаги 1–6.
  2. В tp4.env рецепта добавьте:
    KV_PERSIST=1
  3. Запустите рецепт как обычно:
    bash scripts/run-tp4-uva.sh

При активном блоке лаунчер печатает две строки подтверждения: KV_PERSIST=1: attaching LMCache connector … и KV_PERSIST=1: cache-identity namespace -> /models/<hash> ….

Проверьте идентичность движка до переиспользования

Блок рецепта не может запустить verify-engine-identity.sh из kv-persistence автоматически (в рецепте не подключён путь до клона kv-persistence), поэтому запустите его вручную ДО того, как доверять переиспользованию кэша:

bash ~/kv-persistence/scripts/verify-engine-identity.sh <имя-контейнера>

Выход 0 = идентичность подтверждена (переиспользование кэша разрешено в этих рамках). Выход 4 = MISMATCH (НЕ переиспользовать кэш — сверьте configs/mimo-v2.6-pro/identity.env.local с аргументами движка и запустите снова). Выход 5 = INCONCLUSIVE (сначала исправьте источники значений). Гейт сравнивает аргументы запуска контейнера и config.json обслуживаемой модели; при KV_PERSIST=1 лаунчер фиксирует --block-size и namespace-монтирование, так что все поля проверяемы. Гейт только читает конфиг движка — он не меняет поведение продакшена.

Имена портов на обеих сторонах

Три разные переменные называют одну точку (примечание ревью):

Сторона Хост Порт
сервис кэша (kv-persistence configs/generic/lmcache-server.env) LMCACHE_HOST LMCACHE_PORT
сервис кэша (док-алиас kv-persistence configs/generic/cache.env) KVP_LMCACHE_HOST KVP_LMCACHE_PORT
лаунчер рецепта (tp4.env) KV_PERSIST_HOST KV_PERSIST_PORT

Сторона рецепта — чем vLLM подключается К; сторона кэша — что сервис слушает НА. Если меняете порт на стороне кэша (LMCACHE_PORT), ОБЯЗАТЕЛЬНО укажите то же значение в KV_PERSIST_PORT на стороне рецепта — иначе vLLM не найдёт кэш, а коннектор молча ретраит мёртвую точку. То же с хостом. Дефолты совпадают (127.0.0.1:5555).

Два пути, один кэш — что совпадает и что различается

kv-persistence/scripts/run-vllm-with-persist.sh (специализированный лаунчер) и ветка KV_PERSIST=1 рецепта теперь согласованы по всему, что определяет совместимость кэша:

Параметр лаунчер kv-persistence рецепт KV_PERSIST=1 обычный запуск рецепта
--model /models/<namespace> /models/<namespace> /model или MODEL_ID
--kv-transfer-config да (LMCacheMPConnector) да (тот же JSON) нет
--enable-prompt-tokens-details да да нет
--block-size 16 (зафиксирован) 16 (зафиксирован, через KV_PERSIST_BLOCK_SIZE) не передаётся (дефолт движка)
MAX_NUM_SEQS 2 2 2 (env; проверено пользователем: скорость не падает, дефолт удобнее)
KV_CACHE_DTYPE auto (резолвится в dtype модели) auto (резолвится в dtype модели) auto (env)
MAX_MODEL_LEN 1048576 1048576 1048576 (env)
гейт идентичности автоматически (отказ при несовпадении) ручное напоминание нет
Специализированный лаунчер дополнительно запускает гейт идентичности автоматически
и ОТКАЗЫВАЕТСЯ подключать кэш при несовпадении; ветка рецепта напоминает запустить
его вручную. **Разница значения в любом поле идентичности (включая строку dtype) —
это БЕЗОПАСНЫЙ промах кэша** — хэш namespace меняется, и два пути просто перестают
делить закэшированные блоки. Они никогда не читают неверный KV; они просто
перестают переиспользовать. Если хотите переиспользование между обоими путями —
держите значения одинаковыми.

Отключение / откат

Удалите строку KV_PERSIST=1 (или поставьте 0) и перезапустите. Это весь откат: рецепт по дизайну не тронут, а закэшированные данные на NVMe просто игнорируются при выключенном переключателе.

Порядок запуска

Сервис кэша должен работать ДО подключения лаунчера. Порядок: сначала start-cache.sh, затем лаунчер рецепта. Если сервис не запущен к моменту старта vLLM — уберите KV_PERSIST=1 и используйте обычный рецепт (или запустите кэш и перезапустите) — никогда не оставляйте vLLM ретраящим мёртвый коннектор в продакшене.

Какой лаунчер выбрать

Лаунчер Когда
run-tp4-uva.sh UVA-базлайн (проверенный рабочий путь рецепта)
run-tp4-hotsplit.sh разделение горячих/холодных экспертов (динамический/статический режимы)
kv-persistence/scripts/run-vllm-with-persist.sh когда нужен автоматический гейт идентичности и полный инструментарий kv-persistence (preflight, benchmark, test-recovery)

Все три принимают одни и те же ручки KV-PERSIST (специализированный лаунчер читает их из собственного конфига kv-persistence). Используйте тот, который запускаете сегодня.

Как тестируется блок лаунчера

Контрактные тесты (текстовые проверки) плюс ПОВЕДЕНЧЕСКИЕ тесты в sikkatu/recipes/tests/test_kv_persist_behaviour.py: оба лаунчера реально ВЫПОЛНЯЮТСЯ со стабами docker/nvidia-smi/curl/python3, а стаб python3 записывает полученные от блока KVP_* переопределения. Покрыто: namespace следует реальным аргументам движка (fp8 и bfloat16 дают разные namespace), auto резолвится в эффективный dtype модели, ошибка CLI прерывает запуск с реальной причиной (без тихого fallback), override KV_PERSIST_NAMESPACE соблюдается, обычный запуск (KV_PERSIST=0) ничего не выводит, KV_PERSIST_BLOCK_SIZE доходит и до CLI, и до --block-size, а префикс model_name стабилен между лаунчерами (mimo-pro/<hash> на обоих путях). В kv-persistence дополнительно есть tests/unit/test_launcher_namespace_coherence.py, который исполняет реальную строку дефолтного выражения run-vllm-with-persist.sh — регрессия к basename $MODEL_DIR валит тест.

Чего в рецепте НЕТ

Сам сервер кэша, политика ёмкости, пины идентичности и административные инструменты живут в kv-persistence; его wiki — справочник по настройке, проверке персистентности и откату. Обратите внимание, что приёмочный прогон восстановления (scripts/test-recovery.sh) всё ещё требует запуска на GPU-хосте — честный статус см. в kv-persistence docs/final-report.md. Контрактные тесты рецепта проверяют, что лаунчер содержит механизм; сами по себе они не доказывают реальное восстановление с NVMe.

Clone this wiki locally