For clean Markdown content of this page, append .md to this URL. For the complete documentation index, see https://docs.nvidia.com/dynamo/llms.txt. For full content including API reference and SDK examples, see https://docs.nvidia.com/dynamo/llms-full.txt.
Кэширование моделей
Скачивание больших языковых моделей может занимать минуты. Без кэширования каждый pod загружает всю модель независимо, что расходует полосу пропускания и задерживает запуск. Dynamo поддерживает простой путь через общее хранилище и путь через ModelExpress для более быстрой доставки весов в крупных кластерах.
Вариант 1: PVC + Job для загрузки (рекомендуется)
Самый простой подход: создайте общий PVC, один раз запустите Job для скачивания модели, затем примонтируйте PVC в ваш DynamoGraphDeployment.
Именно этот шаблон сегодня используют все рецепты Dynamo.
Шаг 1: создайте общий PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: model-cache
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 100Gi
Режим доступа ReadWriteMany нужен, чтобы несколько pod'ов могли одновременно монтировать PVC. Убедитесь, что ваш storage class поддерживает RWX (например, NFS, CephFS или общие файловые системы от облачного провайдера).
Шаг 2: скачайте модель
apiVersion: batch/v1
kind: Job
metadata:
name: model-download
spec:
template:
spec:
restartPolicy: Never
containers:
- name: downloader
image: python:3.12-slim
command: ["sh", "-c"]
args:
- |
pip install huggingface_hub hf_transfer
HF_HUB_ENABLE_HF_TRANSFER=1 huggingface-cli download \
$MODEL_NAME --revision $MODEL_REVISION
env:
- name: MODEL_NAME
value: "Qwen/Qwen3-0.6B"
- name: MODEL_REVISION
value: "main"
- name: HF_HOME
value: /cache/huggingface
envFrom:
- secretRef:
name: hf-token-secret
volumeMounts:
- name: model-cache
mountPath: /cache/huggingface
volumes:
- name: model-cache
persistentVolumeClaim:
claimName: model-cache
Найдите путь к snapshot
После завершения Job модель хранится в структуре кэша Hugging Face:
hub/models--<org>--<model>/snapshots/<commit-hash>/
Например, meta-llama/Llama-3.1-70B-Instruct превращается в:
hub/models--meta-llama--Llama-3.1-70B-Instruct/snapshots/9d3b8e0f71f8c1e0f9b7c2a3d4e5f6a7b8c9d0e1/
Чтобы найти точный commit hash после завершения Job загрузки:
kubectl run find-snapshot --rm -it --image=busybox --restart=Never \
--overrides='{
"spec": {
"volumes": [{"name": "c", "persistentVolumeClaim": {"claimName": "model-cache"}}],
"containers": [{
"name": "f", "image": "busybox",
"command": ["find", "/c/hub", "-mindepth", "3", "-maxdepth", "3", "-type", "d"],
"volumeMounts": [{"name": "c", "mountPath": "/c"}]
}]
}
}'
Либо посмотрите commit hash на странице модели в HuggingFace Hub в разделе Files and versions.
Этот путь нужен для поля pvcModelPath в спецификации DGDR (см. Model Deployment Guide — Model Caching).
Шаг 3: примонтируйте в DynamoGraphDeployment
apiVersion: nvidia.com/v1alpha1
kind: DynamoGraphDeployment
metadata:
name: my-deployment
spec:
pvcs:
- create: false
name: model-cache
services:
VllmWorker:
volumeMounts:
- name: model-cache
mountPoint: /home/dynamo/.cache/huggingface
Все pod'ы VllmWorker, которые монтируют model-cache, теперь читают из общего кэша, а не скачивают модель отдельно для каждого pod'а. Если нужно, чтобы frontend тоже переиспользовал tokenizer и config-файлы, примонтируйте туда тот же PVC.
Кэш компиляции
Для vLLM можно также кэшировать скомпилированные артефакты (CUDA graphs и т. п.) во втором PVC:
spec:
pvcs:
- create: false
name: model-cache
- create: false
name: compilation-cache
services:
VllmWorker:
volumeMounts:
- name: model-cache
mountPoint: /home/dynamo/.cache/huggingface
- name: compilation-cache
mountPoint: /home/dynamo/.cache/vllm
Вариант 2: ModelExpress (P2P distribution)
ModelExpress - это сервис распределения весов модели, который интегрируется с pipeline загрузки весов vLLM. Он может публиковать веса модели с одного worker'а и позволять последующим worker'ам забирать эти тензоры из памяти GPU по NIXL/RDMA вместо повторной полной загрузки из хранилища.
ModelExpress также может использовать ModelStreamer как стратегию загрузки. ModelStreamer передаёт safetensors напрямую из object storage или локального пути файловой системы в память GPU через пакет runai-model-streamer. В такой схеме первый worker может стримить данные из хранилища, а затем публиковать метаданные ModelExpress, чтобы последующие worker'ы могли использовать P2P-путь.
Используйте этот путь, когда время запуска или время раскатки модели на весь флот важнее простоты общего PVC.
Как это работает
- Сервер ModelExpress работает в кластере и хранит метаданные о доступных источниках.
- Worker'ы vLLM используют загрузчик ModelExpress (
--load-format mxв новых образах ModelExpress илиmx-source/mx-targetв старых split-loader-образах). - Если совместимый источник уже обслуживает модель, новый worker забирает тензоры модели у этого источника по NIXL/RDMA.
- Если источник недоступен, worker откатывается к хранилищу. При общей файловой системе (RWX PVC, NFS, hostPath) worker читает напрямую из кэша сервера. Без общей файловой системы задайте
MODEL_EXPRESS_NO_SHARED_STORAGE=1, чтобы клиент стримил файлы с сервера по gRPC; см. ниже Streaming Without Shared Storage. Когда заданMX_MODEL_URI, ModelStreamer может стримить safetensors из S3, GCS, Azure Blob Storage или локального пути. - Kubernetes operator может внедрять
MODEL_EXPRESS_URLво все pod'ы Dynamo на основе настройки платформыmodelExpressURL.
Что настроить
| Layer | What to configure | Notes |
|---|---|---|
| Runtime image | Включите пакет Python modelexpress, а для ModelStreamer - runai-model-streamer и зависимости для object storage. | Dynamo или vLLM выдаёт ошибку импорта, если worker использует формат загрузки ModelExpress, а пакет отсутствует. |
| Сервер ModelExpress | Разверните сервер с Redis или backend метаданных на базе Kubernetes CRD. | См. ModelExpress deployment guide. |
| Платформа Dynamo | Задайте dynamo-operator.modelExpressURL. | Оператор внедрит MODEL_EXPRESS_URL в pod'ы. |
| Worker vLLM | Задайте формат загрузки ModelExpress и укажите сервер. | Новые образы ModelExpress используют --load-format mx; старые образы Dynamo могут использовать mx-source / mx-target. |
| ModelStreamer | Задайте MX_MODEL_URI для пути к хранилищу. | Поддерживаются URI вида s3://..., gs://..., az://..., абсолютный локальный путь или ID модели Hugging Face, разрешаемый из локального кэша. |
Настройка
Установка с Dynamo Platform:
helm install dynamo-platform dynamo-platform-${RELEASE_VERSION}.tgz \
--namespace ${NAMESPACE} \
--set "dynamo-operator.modelExpressURL=http://model-express-server.model-express.svc.cluster.local:8080"
Настройка worker'ов на использование ModelExpress:
services:
VllmWorker:
extraPodSpec:
mainContainer:
image: <vllm-runtime-image-with-modelexpress>
command: ["python3", "-m", "dynamo.vllm"]
args:
- --model
- meta-llama/Llama-3.1-70B-Instruct
- --load-format
- mx
- --model-express-url
- http://model-express-server.model-express.svc.cluster.local:8080
env:
- name: VLLM_PLUGINS
value: modelexpress
Когда MODEL_EXPRESS_URL настроен в операторе, он автоматически внедряется как переменная окружения во все pod'ы компонентов. Передавать --model-express-url явно по-прежнему полезно в примерах, потому что worker проверяет наличие URL сервера при использовании старых форматов загрузки mx-source / mx-target.
Используйте формат загрузки, поддерживаемый вашим runtime image. В ModelExpress v0.3 и новее описан единый загрузчик mx. Некоторые образы Dynamo всё ещё используют старые раздельные имена загрузчиков mx-source и mx-target; им нужен тот же URL сервера, но отдельные роли source и target.
Стриминг без общего хранилища
Если кэш сервера ModelExpress находится на неразделяемом томе (например, ReadWriteOnce PVC, развёртывание между namespace'ами или любая топология, где worker pod'ы не могут смонтировать ту же файловую систему, что и сервер), режим shared-storage по умолчанию ломается: сервер сообщает, что модель скачана, и возвращает свой локальный путь, worker не может прочитать этот путь изнутри своего pod'а, а загрузка незаметно откатывается к прямой загрузке из HuggingFace, сводя на нет смысл использования ModelExpress.
Задайте MODEL_EXPRESS_NO_SHARED_STORAGE=1 в каждом worker pod'е, чтобы переключить клиент ModelExpress в режим gRPC-стриминга. Тогда сервер будет отправлять файлы модели клиенту по существующему gRPC-каналу, а worker запишет их в свой локальный кэш.
services:
VllmWorker:
extraPodSpec:
mainContainer:
image: <vllm-runtime-image-with-modelexpress>
command: ["python3", "-m", "dynamo.vllm"]
args:
- --model
- meta-llama/Llama-3.1-70B-Instruct
- --load-format
- mx
env:
- name: VLLM_PLUGINS
value: modelexpress
- name: MODEL_EXPRESS_NO_SHARED_STORAGE
value: "1"
MODEL_EXPRESS_URL автоматически внедряется оператором (dynamo-operator.modelExpressURL); здесь задавать его явно не нужно. В этом режиме worker pod'ам не требуется volume mount для кэша ModelExpress.
Используйте этот путь, когда:
- Сервер работает с RWO PVC или в namespace, отличном от worker'ов.
- В кластере нет RDMA / InfiniBand fabric, поэтому P2P через NIXL невозможен.
- Вы хотите, чтобы ModelExpress работал как централизованный сервер загрузки и кэширования (один pull из HuggingFace, затем рассылка по gRPC многим worker'ам) без развёртывания object storage и
MX_MODEL_URI.
Режим с общей файловой системой всё равно быстрее, если он доступен, поэтому предпочитайте RWX PVC, смонтированный и на сервере, и на worker'ах, когда storage class это поддерживает. Полный разбор компромиссов и настроек (размер chunk'ов и т. п.) см. в ModelExpress storage access modes documentation.
ModelStreamer из object storage
Задайте MX_MODEL_URI, когда первый worker должен стримить safetensors напрямую из хранилища, а не читать их из PVC или полагаться на предыдущий source-worker.
services:
VllmWorker:
extraPodSpec:
mainContainer:
image: <vllm-runtime-image-with-modelexpress-and-modelstreamer>
command: ["python3", "-m", "dynamo.vllm"]
args:
- --model
- meta-llama/Llama-3.1-70B-Instruct
- --load-format
- mx
- --model-express-url
- http://model-express-server.model-express.svc.cluster.local:8080
env:
- name: VLLM_PLUGINS
value: modelexpress
- name: MX_MODEL_URI
value: s3://my-model-bucket/meta-llama/Llama-3.1-70B-Instruct
- name: RUNAI_STREAMER_CONCURRENCY
value: "8"
ModelStreamer использует учётные данные базового cloud SDK:
| Backend хранилища | Пример MX_MODEL_URI | Варианты учётных данных |
|---|---|---|
| S3 or S3-compatible storage | s3://bucket/path/to/model | IRSA / workload identity, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN, AWS_DEFAULT_REGION и необязательный AWS_ENDPOINT_URL |
| Google Cloud Storage | gs://bucket/path/to/model | GKE Workload Identity, Application Default Credentials или GOOGLE_APPLICATION_CREDENTIALS |
| Azure Blob Storage | az://container/path/to/model | Managed Identity, переменные окружения service principal или AZURE_ACCOUNT_NAME / AZURE_ACCOUNT_KEY |
| Local filesystem or PVC | /models/meta-llama/Llama-3.1-70B-Instruct | Примонтируйте путь в worker pod |
Учётные данные используются storage SDK в worker pod'е. Через сервер ModelExpress они не проходят.
Связь с Shadow Engine Failover
ModelExpress и ModelStreamer - это пути загрузки и распределения модели. Они не требуются для Shadow Engine Failover, и их включение не создаёт standby engines.
Используйте Shadow Engine Failover только тогда, когда вам действительно нужна active/shadow topology восстановления на базе GPU Memory Service (GMS), DRA и backend load format вроде --load-format gms. Держите конфигурацию ModelExpress / ModelStreamer отдельно, если только вы не проверили комбинированный workflow для вашего runtime image и кластера.
Когда использовать ModelExpress
| Scenario | Recommended Approach |
|---|---|
| Малый кластер, простая настройка | PVC + Job для загрузки |
| Большой кластер, много узлов | ModelExpress P2P |
| Модели уже лежат в общем хранилище (NFS) | PVC |
| Модели в S3, GCS, Azure Blob Storage или локальных safetensors-путях | ModelExpress + ModelStreamer |
| Частые обновления модели по всему флоту | ModelExpress P2P, при необходимости дополненный ModelStreamer |
| Сервер ModelExpress с неразделяемым хранилищем (RWO PVC, cross-namespace) | ModelExpress с MODEL_EXPRESS_NO_SHARED_STORAGE=1 |
See Also
- Managing Models with DynamoModel — declarative CRD для управления моделями
- Detailed Installation Guide — конфигурация Helm chart, включая ModelExpress
- Shadow Engine Failover — active/shadow recovery на базе GMS, отдельно от распределения моделей
- ModelExpress deployment guide — конфигурация сервера, P2P и ModelStreamer
- LoRA Adapters — динамическая загрузка адаптеров (отдельно от кэширования базовой модели)