8(800) 222 32 56
Панель управления
Инфраструктура

Кэш весов LLM на NVMe: OCI-артефакты и быстрый старт в Kubernetes

Кэш весов LLM на NVMe: OCI-артефакты и быстрый старт в Kubernetes
Подберите идеальное решение для ваших задач:
в России, США и Нидерландах обеспечат максимальную скорость. Воспользуйтесь всеми преимуществами надежного оборудования. Базовая помощь и техническое обслуживание входят в пакет услуг.

GPU уже выделен, pod запланирован, а endpoint всё ещё не принимает запросы: десятки гигабайт весов едут по сети, распаковываются и только потом попадают в память ускорителя. В таком сценарии autoscaling увеличивает не производительность, а очередь холодных реплик. Проблему обычно лечат не ещё одной GPU, а управляемой доставкой модели: неизменяемой версией, локальным NVMe-кэшем и понятным правилом прогрева. Разберём рабочую схему для Kubernetes, где веса можно хранить в OCI-реестре или объектном хранилище, а inference-поды стартуют предсказуемо.

Готовы перейти на современную серверную инфраструктуру?

В King Servers мы предлагаем серверы как на AMD EPYC, так и на Intel Xeon, с гибкими конфигурациями под любые задачи — от виртуализации и веб-хостинга до S3-хранилищ и кластеров хранения данных.

  • S3-совместимое хранилище для резервных копий
  • Панель управления, API, масштабируемость
  • Поддержку 24/7 и помощь в выборе конфигурации

Создайте аккаунт

Быстрая регистрация для доступа к инфраструктуре

Разложите холодный старт на измеримые этапы

Первый шаг — перестать называть всё время до первого ответа «запуском модели». Оно складывается из ожидания узла и GPU, получения весов, чтения их с диска и инициализации runtime с переносом тензоров в VRAM. Если смотреть только на Ready у Pod, причины сливаются, и команда оптимизирует не тот участок.

Зафиксируйте временные метки в одном deployment-id: когда workload создан, назначен узел, началась и завершилась доставка модели, процесс открыл файлы, создан GPU-контекст и health endpoint впервые вернул успех. Для vLLM, TGI или собственного сервера названия метрик различаются, но логика одна. Проверяли ли вы, сколько времени GPU уже зарезервирована, но ещё не обслуживает трафик? Этот интервал превращается в прямую инфраструктурную потерю.

Практический пример: новая реплика ждёт две минуты. Без разбиения команда заказывает более быстрый канал. После разметки выясняется, что сеть заняла двадцать секунд, распаковка слоя — сорок, а чтение множества мелких файлов с сетевого тома — оставшуюся минуту. Здесь поможет иной формат артефакта или локальный SSD, а не увеличение bandwidth.

  • T-schedule: создание Pod — назначение узла;
  • T-fetch: получение и проверка байтов;
  • T-disk: открытие и чтение файлов;
  • T-runtime: процессы, CUDA-контекст и размещение весов;
  • T-ready: успешная проба и первый реальный запрос.

Контекст по очередям и ускорителям есть в материале KingServers о GPU scheduling между inference, training и batch-задачами. Здесь мы оставляем общее планирование за скобками и оптимизируем путь весов после выбора узла.

Выберите источник весов и границы кэша

Единственного правильного хранилища нет. Объектное хранилище удобно как исходный репозиторий: оно отделено от кластера, версионируется и подходит для больших файлов. OCI-реестр полезен, когда команда уже умеет зеркалировать, подписывать и продвигать artifacts между средами. Общий PVC проще внедрить, но задержка зависит от backend, числа читателей и поведения файловой системы.

Заранее определите, где заканчивается источник истины и начинается расходный кэш. Источник хранит конкретную ревизию модели, tokenizer, шаблон диалога и адаптеры. Локальный NVMe — ускоритель доставки, а не единственная копия. Потеря узла не должна означать потерю модели; очистка кэша не должна менять результат повторного развёртывания.

Для пула из двух GPU-серверов разумен простой вариант: модель лежит в объектном хранилище по версии, DaemonSet переносит её на NVMe, а inference-поды монтируют read-only путь. Для десятков nodes пригодится декларативный контроллер. KServe Local Model Cache решает эту задачу, но его CRD остаются в serving.kserve.io/v1alpha1; схему нужно считать развивающейся и проверять на staging.

Не путайте кэш весов с semantic cache ответов. Первый экономит время старта и сетевой трафик при доставке модели, второй повторно использует результаты похожих запросов. У них разные ключи, риски и владельцы. Слой запросов разобран отдельно в статье про semantic cache для LLM.

Критерий воспроизводимости простой: можно ли по одной записи deployment восстановить точные байты через месяц? Если ответ зависит от mutable-тега latest, ручной папки или «актуального» snapshot без commit hash, архитектура пока не готова.

Упакуйте модель в неизменяемый OCI-артефакт

OCI полезен не потому, что модель становится контейнером. Он даёт registry, content-addressed слои, digest, стандартные credentials и зеркалирование. Весам не нужен процесс внутри артефакта; это набор файлов, который runtime видит в определённом каталоге. Разделение образа сервера и модели позволяет обновлять vLLM независимо от десятков гигабайт параметров.

Зафиксируйте структуру: веса, tokenizer, конфигурацию генерации, лицензию и manifest с source revision. Не добавляйте токены доступа, временные логи и локальный cache metadata. Credential нужен на этапе получения исходников или pull, но не внутри артефакта.

dockerfileDockerfile.model
FROM scratch
COPY model/ /models/
LABEL org.opencontainers.image.title="company-llm"
LABEL org.opencontainers.image.revision="MODEL_COMMIT_SHA"
Минимальная упаковка файлов модели в OCI-образ

Тег удобен человеку, digest — системе. В production используйте registry.example.com/ai/model@sha256:.... Тогда rollout не изменится из-за повторно опубликованного тега, а подпись относится к конкретным байтам. Типичная ловушка — один гигантский слой: изменение tokenizer заставляет передавать всё. Если toolchain позволяет, отделяйте редко меняющиеся веса от небольших конфигурационных слоёв, но проверяйте материализацию runtime.

KServe называет OCI-модель Modelcar и развивает native-режим через Kubernetes ImageVolume. Modelcar подходит для поддерживаемых версий KServe, а native volume уменьшает число служебных контейнеров там, где Kubernetes и runtime готовы. Официальная документация описывает подготовку OCI model data.

Проверяйте артефакт до inference: pull по digest, список файлов, checksums конфигураций и отсутствие секретов. Такой smoke test дешевле, чем после бронирования GPU обнаружить отсутствие tokenizer.json.

Подключите веса через Kubernetes ImageVolume

Kubernetes ImageVolume монтирует OCI image или artifact как read-only volume. Функция появилась в Kubernetes 1.31, а актуальная документация отмечает stable с версии 1.36 и включение по умолчанию. Нужен совместимый container runtime; версии API server недостаточно. Проверяйте поддержку на реальном worker image и конкретной версии containerd или CRI-O.

Минимальный Pod отделяет runtime image от model artifact. IfNotPresent использует уже имеющийся объект на узле, но не гарантирует вечный кэш: image garbage collection может удалить слои. Для воспроизводимости указывайте digest и используйте image pull secrets.

yamlinference-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: llm-inference
spec:
  containers:
    - name: server
      image: registry.example.com/ai/vllm-runtime:stable
      args: ["--model", "/models"]
      volumeMounts:
        - name: model
          mountPath: /models
          readOnly: true
  volumes:
    - name: model
      image:
        reference: registry.example.com/ai/model@sha256:REPLACE_ME
        pullPolicy: IfNotPresent
Read-only модель из OCI-артефакта через ImageVolume

Пример намеренно не содержит GPU resources, probes и securityContext: добавьте их по правилам кластера. До rollout создайте Pod без GPU, смонтируйте volume и проверьте каталог. Так вы отделите registry/CRI от CUDA. Если Pod завис в ContainerCreating, смотрите kubelet и runtime events, а не логи ещё не запущенного контейнера.

ImageVolume хорош для единого OCI-транспорта. Он хуже, если нужна явная политика «держать модель на каждом узле этой группы», квоты и состояние прогрева до workload. Там нужен controller или KServe LocalModel. IfNotPresent не решает prewarming: он лишь определяет pull при уже известном reference.

Источник истины по feature state — страница Kubernetes Use an Image Volume With a Pod. Сверяйте её с документацией своей minor-версии, особенно при смешанном пуле узлов.

Организуйте локальный NVMe-кэш на GPU-узлах

Локальный NVMe сокращает сетевой путь, но переносит ответственность на node lifecycle. Нужно знать, какой диск выделен под модели, кто создаёт каталоги, какие права у downloader и inference-пода, сколько места можно занять и что удалять первым. Папка /models без лимита закончится DiskPressure в неудобный момент.

Разделите capacity на рабочий запас и eviction budget. Суммируйте размеры одновременно нужных ревизий, добавьте место для временной загрузки и резерв системе. Номинальный размер модели неточен: формат, shard-файлы и материализация OCI-слоёв меняют расход. Измеряйте bytes on disk после реального pull.

Hugging Face Hub хранит файлы в content-addressed blobs и связывает их со snapshots. Путь переносится через HF_HOME или HF_HUB_CACHE. Это удобно, но cache layout — не контракт deployment: ссылайтесь на конкретный snapshot. Официальная схема описана в Hugging Face Local Cache.

KServe LocalModelCache добавляет ресурсы для группы узлов и local PV. Важная деталь: local.path в PV должен совпадать с hostPath agent DaemonSet. Иначе агент не увидит скачанную модель и повторит jobs. HostPath также не применяет fsGroup так, как ожидают многие команды; права готовьте на узле.

Представьте четыре GPU-nodes и две версии во время canary. Если cache рассчитан на одну, обновление вытеснит предыдущую до проверки. Rollback снова станет cold deployment. Держите текущую и предыдущую подтверждённую ревизии до конца окна отката.

Свяжите прогрев кэша с планированием

Кэш полезен только на том узле, куда попадёт workload. Если scheduler выбирает любой GPU, а прогрев был на соседнем сервере, система создаст ещё одну холодную копию. Свяжите модель, node group и readiness: label или resource status должны отражать подтверждённое наличие digest, а не намерение скачать.

Для статичного пула подойдёт DaemonSet с nodeSelector и tolerations. Для нескольких моделей лучше controller, который создаёт jobs по группам и публикует status. Inference допускайте на узел через affinity после проверки cache. Downloader не должен конкурировать с production inference за весь NVMe bandwidth.

bashcheck-cache.sh
kubectl get localmodelcache -o wide
kubectl get localmodelnode -o wide
kubectl get jobs -n kserve-localmodel-jobs
kubectl get events --sort-by=.lastTimestamp | tail -n 50
Проверка статуса локального кэша перед rollout

KServe использует cluster-scoped LocalModelCache, namespace-scoped LocalModelNamespaceCache, группы узлов и node status. API v1alpha1 требует осторожности: закрепляйте chart, храните CRD с конфигурацией и тестируйте upgrade. Функция по умолчанию отключена.

Не связывайте readiness с одним файлом-флагом, созданным до fsync. Проверяйте digest/manifest и набор файлов, затем запускайте runtime. Job может иметь Completed, а модель не читаться из-за прав, пути или неполного snapshot.

Как KServe, GPU Operator и очереди соединяются в общий контур, разобрано в статье Kubernetes для AI inference. Cache readiness дополняет autoscaling и не даёт масштабироваться на неподготовленные nodes.

Обновляйте модель по digest и оставляйте путь назад

Обновление весов — полноценный release. Новый digest появляется в registry, проходит проверку состава и подписи, затем прогревается на ограниченной группе. Только после этого создавайте canary и отправляйте малую долю трафика. Mutable-тег удобен в CI, но production deployment фиксирует разрешённый digest.

Разделяйте три проверки. Транспортная подтверждает байты. Runtime-проверка запускает модель и выполняет smoke набор. Прикладная оценка сравнивает качество, latency и ошибки на репрезентативных запросах. Быстрый старт бесполезен, если tokenizer не соответствует весам.

Rollback готовят до rollout: предыдущий manifest хранится в Git, прошлый digest разрешён, а cache не удаляется до конца окна наблюдения. Тогда откат — смена ссылки и маршрутизации. Если диска хватает на одну ревизию, зафиксируйте увеличенное recovery time в SLO.

Мини-кейс: quantized checkpoint даёт больше ошибок на длинном контексте. Digest возвращает прежние байты, только если tokenizer и generation config входили в release bundle. Иначе «старая модель» окажется смесью версий. Это часть общего процесса LLMOps и жизненного цикла модели.

Ограничьте pull нужными ServiceAccount, проверяйте подписи на admission или CI и не передавайте token в аргументах. Read-only mount защищает от случайной модификации, но узел и привилегированные workloads остаются в доверенной границе.

Наблюдайте не pod, а весь путь модели

Успешный Pod — слабый сигнал. Нужны cache hit по digest, переданные байты, длительность pull, скорость чтения диска, runtime initialization, свободное место, eviction и возраст последнего прогрева. Добавляйте модель и ревизию, но не полный digest в высококардинальную метку: хватит короткого id плюс ссылка в metadata.

Стройте SLO вокруг готовности обслужить запрос. Следите за долей реплик, готовых в пределах cold-start budget, и долей запусков с cache hit. Порог выбирается из требований продукта, а не чужого benchmark. Универсальных секунд нет: модель, storage, runtime и GPU дают разные профили.

Трассировка должна связать controller, downloader, kubelet и inference server: scheduler выбрал node, cache miss создал job, registry ответил, файлы материализовались, runtime открыл их, probe прошла. Без цепочки инцидент распадается между platform и ML-командами.

  • alert на заполнение cache volume и прогноз;
  • alert на повторные jobs одного digest;
  • alert на рост T-fetch при стабильном размере;
  • alert на GPU allocated, но endpoint not ready дольше budget;
  • распределение cold start по hit и miss;
  • проверка доступности rollback digest локально и в registry.

Может ли дежурный за пять минут сказать, сеть, диск или runtime задержали реплику? Если нет, общий график CPU не поможет. Нужны границы этапов и одинаковая версия во всех логах.

Соберите production-runbook и критерии готовности

Начните с одного GPU-узла и некритичной модели. Измерьте baseline без прогрева, затем повторите с локальными байтами. Сравнивайте этапы. После этого отключите registry: прогретая модель должна запускаться по выбранной политике, непрогретая — завершаться понятной ошибкой, а не зависать.

Следующий тест — нехватка диска. Заполните cache до eviction threshold, запросите новую ревизию и убедитесь, что активная и rollback-модель сохраняются. Перезагрузите node, удалите Pod и проверьте status после рестарта. Проведите mixed-version upgrade: ImageVolume зависит от CRI на каждом worker.

  • модель и конфигурации закреплены по digest или commit;
  • источник истины переживает потерю node;
  • cache directory, права и лимиты описаны как код;
  • prewarm status отражает проверенные файлы;
  • scheduler выбирает узлы с нужной ревизией;
  • probes разделяют materialization и runtime;
  • предыдущая версия хранится до конца rollback window;
  • dashboard показывает T-schedule, T-fetch, T-disk, T-runtime и T-ready;
  • runbook покрывает registry outage, DiskPressure и permission denied.

Для private AI API дисциплина особенно важна: одна модель обслуживает нескольких клиентов, и cold start становится общей деградацией. Контекст gateway, квот и доступа есть в материале о Private AI API на своих серверах.

Главная мысль проста: веса LLM доставляют как версионируемый production-артефакт, а локальный диск считают управляемым кэшем. Начните с разметки холодного старта, закрепите модель по digest и прогоните отказ registry на тестовом GPU-узле. Когда маршрут воспроизводим, масштабирование перестаёт быть лотереей, а команда выбирает OCI ImageVolume, KServe LocalModel или собственную схему по наблюдаемым ограничениям. Для пилота заранее согласуйте профиль NVMe, сети и окно прогрева — это часто полезнее ещё одного autoscaler.

Proxmox VE на выделенном сервере: как собрать частное облако для бизнеса в 2026 году
Proxmox

Proxmox VE на выделенном сервере: как собрать частное облако для бизнеса в 2026 году

Практический гид по Proxmox VE на выделенном сервере: выбор железа, ZFS и Ceph, сеть, кластер, HA, backup и безопасность.

CXL Memory Expansion для AI inference: больше RAM без иллюзии «дополнительной VRAM»
AI

CXL Memory Expansion для AI inference: больше RAM без иллюзии «дополнительной VRAM»

Как использовать CXL Type-3 memory expansion в AI inference: Linux, NUMA, vLLM offload, memory pooling, ограничения и практический чек-лист.