Repository navigation
Troubleshooting.ru
Сначала посмотрите три вещи:
bash scripts/budget-report.sh status # занято, пространства, диск
tail -n 100 "$KVP_CACHE_ROOT/lmcache-server.log" # сервис кэша
docker logs --tail 100 mimo-pro-tp4-kvp # движок (лаунчер kv-persistence)(KVP_CACHE_ROOT задаётся в configs/generic/cache.env.local.)
-
KVP_MODEL_REVISION must be a full 40-hex SHA— вставьте SHA коммита, а не имя ветки (см. шаг 3 Быстрого старта). -
KVP_CHAT_TEMPLATE_DIGEST must be 64 hex— выполните preflight один раз сKVP_MODEL_DIR="$HOME/models/MiMo-V2.6-Pro-MOPD"; скопируйте напечатанное значение.
ERROR: lmcache CLI missing — установите по шагу 4 Быстрого старта. Если
import lmcache падает с ошибками неопределённых символов, pip-wheel собран под
другой стек PyTorch/CUDA. Запасной путь — сервер прямо из production-образа:
docker run --rm --entrypoint lmcache "$IMAGE" server --helpЕсли так работает — подправьте строку запуска в scripts/start-cache.sh под
docker run с теми же аргументами (порты/пути не меняются).
- Порядок старта:
start-cache.shДО лаунчера vLLM (run-vllm-with-persist.shиначе отказывается стартовать). - Смотрите строку ошибки в логе сервиса; оба процесса используют одну host-сеть — не переносите порт запросов без правки обеих сторон.
- С интеграцией рецепта (
KV_PERSIST=1): лаунчер печатаетKV_PERSIST=1: attaching LMCache connector …— нет строки = ручка не дошла до лаунчера (проверьтеtp4.envи экспортированы ли переменные).
Проверяйте по порядку:
-
cached_tokensв ответе > 0. -
grep -c Retrieved "$KVP_CACHE_ROOT/lmcache-server.log"растёт во время запроса; строки после перезапуска — это доказательство дискового восстановления. -
used_bytesНЕ выросло, пересоздавая те же данные (bash scripts/budget-report.sh statusдо/после). - Идентичность не менялась — повторите
scripts/preflight.sh; смена ревизии/ dtype/шаблона молча переводит в НОВОЕ пространство (по дизайну). -
KVP_PERSIST_ENABLEDравенtrue(иначеstart-cache.shпредупреждает).
free_bytes: 0 в отчёте либо адаптер пишет отказ на жёстком лимите — поднимите
KVP_CACHE_BUDGET_GB или явно подчистите старые пространства
(purge --namespace=NAME --yes, имена — из status). Жёсткий лимит — это
max_capacity_gb в адаптере L2: при его достижении новые записи отклоняются
(сервис продолжает работать без новых записей в кэш). Эвикция на мягком пороге
(90 %) обычно освобождает место раньше, но это НЕ гарантия от заполнения самого
ДИСКА — реальная граница: свободное место на томе с KVP_CACHE_ROOT (на
эталонном хосте этот же том держит Docker, модель и ОС). Держите запас
свободного места и снижайте бюджет, если диск заканчивается. Не удаляйте
отдельные файлы внутри корня кэша, пока сервис работает.
Поднимите KVP_EVICT_TRIGGER_WATERMARK (начинать позже) или отрегулируйте
KVP_EVICT_RATIO (больше возврата за цикл). Проверяйте на маленьком изолированном
бюджете, прежде чем ждать эффектов в масштабе 1.5 ТБ. Фактический режим виден по
счётчикам evictions/reclaimed_bytes в отчёте.
Измерьте, какая часть промпта реально стабильна:
python3 "$REPO/implementation/prompt_probe.py" --tokenizer "$MODEL_DIR" \
--request-file a.json --request-file b.jsonс двумя реальными телами запросов, выгруженными из клиента. Мало
stable_prefix_tokens — динамические значения (временные метки, id tool-вызовов)
ломают префикс: лечите сериализацию на источнике либо принимайте ограничение.
Обрезать историю ради кэша запрещено.
Повреждения терпимы: промах просто пересчитывает. Для очистки вручную: остановите
сервис кэша, bash scripts/budget-report.sh purge --all --yes, запустите снова.
Автоматически никогда. Фреймы lossless-кодека дополнительно несут CRC32: битый
или усечённый фрейм обнаруживается при чтении и трактуется как промах кэша —
никогда не возвращается как неверный KV.
-
CodecError: zstandard/lz4 python bindings not installed— ВЫБРАННОМУ кодеку нужен Python-пакет (zstd→zstandard,lz4→lz4). Установите его в venv lmcache или откатитесь наLMCACHE_L2_SERDE=none(байт-точный сырой режим, без зависимостей вообще). Проверка идёт до старта сервера и никогда не требует неиспользуемый кодек: кэшуnoneпакеты сжатия не нужны. -
LMCACHE_L2_SERDE=... is LOSSY and is not supported— ожидаемо: проект lossless-only. Используйтеnone,zstdилиlz4. - Сменили кодек и исчезли cache hit — ожидаемо и безопасно: кодек входит в namespace идентичности, старые чанки становятся промахом. Пересохраните их (или верните кодек) — никогда не неверное чтение.
- Сжатые чанки не меньше на диске — кодек сжимает только сжимаемое; несжимаемые блоки хранятся сырыми с паддингом до 4 КиБ. На крошечных чанках доминирует заголовок (28 Б).
После жёсткого убийства (SIGKILL, OOM, отключение питания) адаптер может
оставить <final>.bin.tmp.<uuid> — файлы, не успевшие атомарно переименоваться.
Upstream вычищает их только при ЧИСТОЙ остановке. Проверьте
bash scripts/budget-report.sh status (поля tmp_files / tmp_files_bytes),
удалите через purge --tmp --yes (только мусор) или purge --all --yes.
Обе команды защищают идущие записи реестром активных записей
(kvpersist.tmp_guard): каждая запись регистрирует маркер до создания tmp-файла
и снимает его после атомарного rename. Живость работает в ОБОИХ режимах запуска
(раунд 18):
-
host-режим — маркер хранит
(pid, время старта процесса), писатель жив, пока существует именно этот процесс (/proc/<pid>+ время старта защищает от повторного использования PID); -
docker-режим (
KVP_LAUNCH_MODE=docker, без--pid=host) — маркер хранит ID PID-неймспейса писателя; если маркер принадлежит чужому неймспейсу, CLI на хосте не может проверить его PID, поэтому живость определяется по HEARTBEAT самого маркера (работающая запись освежает его каждые 30 с): маркер, тронутый за последние 2 минуты — живой, старше — остаток краша. Если живость определить вообще нельзя (нет /proc, нечитаемый маркер) — маркер сохраняется: лучше держать лишний tmp-файл, чем удалить файл живой записи. Маркеры, чей писатель доказанно завершился, вычищаются через час. Второй механизм — страховка для писателей без реестра (например, голыйlmcache server): файлы*.tmp.*, изменённые за последние 15 минут, пропускаются — это окно ЭВРИСТИКА, а не абсолютная защита.
Стек пассивен до пуша телеметрии. Запустите кэш с USE_OBSERVABILITY=1 (или
KVP_OTLP_ENDPOINT=http://localhost:4320) и проверьте лог на баннер [kvp].
В docker-режиме start-cache.sh сам переписывает localhost на
host.docker.internal. Все порты стека — только 127.0.0.1 (loopback-контракт).
Изменение ЛЮБОГО поля идентичности меняет пространство имён: старые записи кэша не удаляются, но становятся недостижимыми — это выглядит как "кэш сломан", хотя работает механизм изоляции. Каждая строка ниже инвалидирует ВСЕ ранее закэшированные KV-блоки этого деплоя:
| Вы изменили... | Влияние на namespace | Переиспользование старого кэша? |
|---|---|---|
| веса модели (подмена содержимого, даже при тех же именах) | SHA-256 байт шарда меняется | НЕТ |
| ревизию модели (HF SHA) | меняется | НЕТ |
| токенизатор (tokenizer.json / tokenizer_config.json) | меняется | НЕТ |
| chat_template / chat_template.jinja | digest меняется | НЕТ |
--kv-cache-dtype (bfloat16 -> float16 и т.п.) |
меняется | НЕТ |
--max-model-len |
меняется | НЕТ |
--tensor-parallel-size |
меняется | НЕТ |
| конфигурацию KV-геометрии в config.json | меняется | НЕТ |
| сборку vLLM / версию LMCache-коннектора (KVP_CONNECTOR_VERSION) | меняется | НЕТ |
--enforce-eager / прочие флаги движка, меняющие порядок KV-вычислений |
может менять раскладку блоков → меняется | НЕТ |
| дайджест Docker-образа (другая сборка vLLM) | меняется | НЕТ |
Практически: фиксируйте KVP_MODEL_REVISION выводом setup-identity.sh и
сохраняйте identity.env.local рядом с каждым деплоем; ожидайте смену namespace
при любом изменении аргументов движка и воспринимайте "кэш холодный после правки"
как корректное ожидаемое поведение, а не ошибку.