Перенос моделей Hugging Face в локальное S3 для запуска vLLM в закрытом контуре
Инструкция описывает загрузку модели с Hugging Face на машину с доступом в Интернет, перенос полного снапшота модели в закрытый контур и загрузку его в локальное S3-совместимое хранилище. После этого vLLM запускается внутри закрытого контура и получает модель из локального S3 либо из предварительно загруженного каталога на PVC.
Когда это пригодится
- В закрытом контуре без доступа к сети Интернет необходимо запустить инференс модели через
vLLM - Требуется контролируемая поставка моделей: фиксация версии, контроль целостности, исключение обращений к внешним ресурсам
- Требуется развернуть модель в Kubernetes-кластере с GPU-нодами, где модель хранится в локальном S3
Основной сценарий:
INTERNET
│
▼
┌───────────────────┐
│ Internet Host │
│ Hugging Face │
│ huggingface_hub │
└─────────┬─────────┘
│ download
▼
┌───────────────────┐
│ Model Package │
│ config.json │
│ tokenizer.* │
│ *.safetensors │
│ generation_config │
└─────────┬─────────┘
│ SHA256
▼
┌───────────────────┐
│ Transfer Package │
└─────────┬─────────┘
│ USB / SSD / контролируемый канал
▼
┌───────────────────┐
│ Air-gapped Host │
└─────────┬─────────┘
│ upload
▼
┌───────────────────┐
│ Local S3 │
│ s3://models/... │
└─────────┬─────────┘
▼
┌───────────────────┐
│ Kubernetes / vLLM │
│ model from S3 │
└───────────────────┘
Обозначения в документе
| Плейсхолдер | Значение |
|---|---|
<COMMIT-SHA> |
SHA-1 коммита модели в репозитории Hugging Face; фиксируется на шаге 1 и используется как immutable-префикс в S3 |
s3.example.local |
Адрес S3-совместимого хранилища в закрытом контуре |
registry.example.local |
Адрес локального container registry в закрытом контуре |
Qwen/Qwen3-8B |
Пример репозитория модели; заменяйте на вашу модель |
vllm.example.local |
Адрес сервиса vLLM для проверки API |
Предварительные требования
Internet-хост (машина с доступом к Hugging Face):
- Python 3
- Пакет
huggingface_hub(CLIhf) - Токен Hugging Face для gated/private-моделей (для публичных моделей не требуется)
- Опционально: GPU для полной проверки модели через
vLLMдо переноса
Закрытый контур:
- S3-совместимое хранилище: endpoint, bucket, credentials
- Kubernetes-кластер с GPU-нодами (см. GPU-оператор Metax)
vLLM-образ в локальном registryStorageClassиPVCдля хранения модели (см. Longhorn и Velero — контекст S3-хранилищ)- Достаточный объём VRAM и дискового пространства под модель
Быстрый путь: минимальный вариант для разовой поставки
Если требуется максимально простой сценарий без полных проверок — выполните следующее. Детальный сценарий с фиксацией commit SHA, inventory, контрольными суммами и промышленной схемой описан в шагах 1–5.
На Internet-хосте:
Проверьте структуру:
Создайте контрольные суммы:
Заархивируйте и посчитайте SHA-256 архива:
Перенесите архив на USB.
В закрытом контуре:
Загрузите в S3:
aws s3 sync \
Qwen3-8B/ \
s3://models/qwen/Qwen3-8B/<COMMIT-SHA>/ \
--endpoint-url https://s3.example.local
Проверьте содержимое:
aws s3 ls \
s3://models/qwen/Qwen3-8B/<COMMIT-SHA>/ \
--recursive \
--endpoint-url https://s3.example.local
После этого модель можно использовать для vLLM deployment.
Ограничения быстрого пути
В быстром пути не фиксируются commit SHA модели, inventory и контрольные суммы файлов до переноса, не проверяется повторно целостность после загрузки в S3. Для воспроизводимой и проверяемой поставки используйте шаги 1–5.
Шаг 1. Скачивание снапшота модели на Internet-хосте
1.1. Подготовка Internet-хоста
Проверьте Python и установите huggingface_hub:
Проверьте CLI. В современных версиях huggingface_hub основным CLI является hf:
1.2. Авторизация в Hugging Face
Для публичной модели авторизация может не потребоваться. Для gated/private-моделей необходим токен:
Введите Hugging Face Access Token. Проверьте авторизацию:
1.3. Создание рабочего каталога
Результат:
1.4. Фиксация модели: repository, revision, commit SHA
Не используйте только имя репозитория (Qwen/Qwen3-8B) как идентификатор поставки — ветка main может измениться. Фиксируйте три параметра:
| Параметр | Значение |
|---|---|
| Repository | Qwen/Qwen3-8B |
| Revision | main |
| Commit SHA | <COMMIT-SHA> |
Commit SHA однозначно идентифицирует состояние модели.
1.5. Получение информации о модели
Посмотрите, какие файлы будут скачаны, и оцените размер:
Для конкретного revision:
1.6. Скачивание снапшота целиком
Скачивайте снапшот целиком, а не только веса
vLLM требуется как минимум config.json + веса + tokenizer. В зависимости от модели могут понадобиться generation_config.json, tokenizer_config.json, special_tokens_map.json, chat_template.jinja, индекс весов (model.safetensors.index.json) и custom-код модели. Правильная единица поставки — весь снапшот (Model Release), а не отдельные *.safetensors.
Используйте --local-dir, а не стандартный cache ~/.cache/huggingface/: модель сразу лежит в самостоятельном каталоге, который можно проверить, заархивировать, посчитать checksum и перенести.
Почему нельзя скачать только *.safetensors
Распространённая ошибка — «мне нужны веса модели, скачаю `*.safetensors`». Для `vLLM` этого недостаточно: без `config.json` и `tokenizer` модель не загрузится. Правильная единица поставки — Model Release, а не `model.safetensors`.1.7. Проверка снапшота на Internet-хосте
Проверьте структуру и размер:
Пример вывода:
Проверьте обязательные файлы — конфигурацию, токенизатор и веса:
find "$WORKDIR/models/Qwen3-8B" \
-type f \
\( -name '*.safetensors' -o -name '*.bin' -o -name '*.pt' \)
Посмотрите содержимое config.json — особенно поля architectures, model_type, torch_dtype, hidden_size, num_hidden_layers, num_attention_heads:
jq '{ architectures, model_type, torch_dtype, hidden_size, num_hidden_layers, num_attention_heads }' \
"$WORKDIR/models/Qwen3-8B/config.json"
Убедитесь, что снапшот корректно загружается через Transformers. Установите зависимости:
Выполните тест офлайн-загрузки:
from transformers import AutoTokenizer, AutoConfig
path = "/opt/model-transfer/models/Qwen3-8B"
config = AutoConfig.from_pretrained(
path,
local_files_only=True
)
tokenizer = AutoTokenizer.from_pretrained(
path,
local_files_only=True
)
print(config)
print(tokenizer)
local_files_only=True
Параметр local_files_only=True гарантирует, что библиотека не попытается скачать недостающие файлы из Интернета. Используйте его во всех офлайн-проверках.
Если на Internet-хосте есть GPU, выполните полный тест vLLM до переноса:
Зафиксируйте версии окружения (vLLM, CUDA, NVIDIA driver, PyTorch, архитектура модели и GPU) — они понадобятся для environment manifest.
Если Internet Host не имеет GPU
Это не проблема: можно проверить tokenizer, config и файлы модели офлайн. Полный тест `vLLM` выполните уже в закрытом контуре.1.8. Особенности отдельных моделей
- Квантованные модели. Если модель квантована (
AWQ,GPTQ,GGUF,FP8,INT8), явно отразите это в manifest:Qwen3-8BиQwen3-8B-AWQ— разные артефакты, нельзя считать их одной моделью. - Custom-код. Некоторые модели требуют дополнительных Python-файлов в снапшоте (
modeling_xxx.py,configuration_xxx.py,tokenization_xxx.py). Эти файлы должны быть перенесены вместе со снапшотом.
trust_remote_code
Флаг --trust-remote-code означает выполнение кода, поставляемого вместе с моделью. В защищённом контуре включайте его только для заранее проверенных и утверждённых моделей.
- Python-зависимости. Custom-код может требовать пакеты (
einops,sentencepiece,protobuf,tiktokenи др.). В air-gapped среде они тоже должны быть доступны — при необходимости перенесите их в локальный PyPI/package repository. - Токенизатор. Проверьте наличие файлов токенизатора — в зависимости от модели это
tokenizer.json,tokenizer.model,vocab.json,merges.txt,special_tokens_map.json,tokenizer_config.json:
- Chat template. Для instruct/chat-моделей важен
chat_template.jinja(или chat template внутриtokenizer_config.json). Без него модель может технически загрузиться, но поведение chat API будет отличаться от ожидаемого. Chat template — часть Model Release.
Шаг 2. Фиксация версии и подготовка transfer package
2.1. Получение commit SHA
Зафиксируйте commit SHA модели через Python:
Или для конкретной revision:
from huggingface_hub import model_info
info = model_info(
"Qwen/Qwen3-8B",
revision="main"
)
print(info.sha)
Сохраните результат в manifests/model-revision.txt:
2.2. Inventory и контрольные суммы
Создайте inventory всех файлов модели:
find \
"$WORKDIR/models/Qwen3-8B" \
-type f \
-printf '%P\n' \
| sort \
> "$WORKDIR/manifests/model-files.txt"
Посчитайте SHA-256 каждого файла:
cd "$WORKDIR/models/Qwen3-8B"
find . \
-type f \
-exec sha256sum {} \; \
> "$WORKDIR/checksums/model-SHA256SUMS"
Проверьте контрольные суммы:
Все файлы должны вернуть OK.
Сохраните размер и количество файлов:
2.3. Model manifest
Пример manifests/model.yaml:
model:
name: Qwen3-8B
repository: Qwen/Qwen3-8B
revision: main
commit: "<COMMIT-SHA>"
files:
count: 42
size_bytes: 123456789012
format:
weights: safetensors
source:
type: huggingface
url: https://huggingface.co/Qwen/Qwen3-8B
target:
storage: s3
bucket: models
prefix: qwen/Qwen3-8B/<COMMIT-SHA>/
2.4. Сборка transfer package
Рекомендуемая структура пакета:
Qwen3-8B-<COMMIT-SHA>/
├── README.md
├── manifest.yaml
├── model/
│ ├── config.json
│ ├── generation_config.json
│ ├── tokenizer.json
│ ├── tokenizer_config.json
│ ├── model-00001-of-00004.safetensors
│ └── ...
├── manifests/
│ ├── model-files.txt
│ ├── model-revision.txt
│ ├── model-size.txt
│ └── environment.txt
└── checksums/
└── model-SHA256SUMS
Соберите пакет:
mkdir -p "$WORKDIR/package"
cp -r "$WORKDIR/models/Qwen3-8B" "$WORKDIR/package/model"
cp -r "$WORKDIR/manifests" "$WORKDIR/package/"
cp -r "$WORKDIR/checksums" "$WORKDIR/package/"
Положите в пакет README.txt с информацией о модели:
Model: Qwen3-8B
Hugging Face repository: Qwen/Qwen3-8B
Revision: main
Commit: <COMMIT-SHA>
Download date: 2026-08-31
Weight format: safetensors
Total size: XX GB
Files: XX
SHA256: checksums/model-SHA256SUMS
2.5. Создание архива и его SHA-256
tar \
-czf \
Qwen3-8B-<COMMIT-SHA>-airgap.tar.gz \
-C "$WORKDIR/package" \
model \
manifests \
checksums
gzip для больших моделей
Сжатие safetensors обычно даёт небольшой выигрыш — веса уже не являются хорошо сжимаемыми текстовыми данными. Для моделей на десятки-сотни гигабайт используйте обычный tar без сжатия:
tar \
-cf \
Qwen3-8B-<COMMIT-SHA>-airgap.tar \
-C "$WORKDIR/package" \
model \
manifests \
checksums
Можно переносить каталог и без архива, если транспорт это позволяет.
Создайте SHA-256 архива:
2.6. Перенос через USB
cp Qwen3-8B-<COMMIT-SHA>-airgap.tar /media/usb/
cp Qwen3-8B-<COMMIT-SHA>-airgap.tar.sha256 /media/usb/
sync
umount /media/usb
Шаг 3. Проверка и распаковка в закрытом контуре
3.1. Проверка SHA-256 архива
После подключения USB в закрытом контуре:
Ожидаемый результат:
НЕ ПРОДОЛЖАТЬ ИМПОРТ
Если checksum не совпадает — не продолжайте импорт. Повторите перенос или разберитесь с причиной повреждения до загрузки в S3.
3.2. Распаковка
Результат:
3.3. Повторная проверка checksum файлов
Все файлы должны пройти проверку.
Шаг 4. Загрузка модели в локальное S3
4.1. Подготовка AWS CLI и credentials
Пример параметров:
- Endpoint:
https://s3.example.local - Bucket:
models
Проверьте наличие AWS CLI:
Настройте credentials:
Укажите:
Для S3-совместимого хранилища endpoint задаётся отдельно через --endpoint-url.
4.2. Проверка доступа к S3
Проверьте bucket:
4.3. Если используется внутренний CA
Если S3 использует сертификат внутреннего CA — не отключайте проверку TLS.
Не используйте --no-verify-ssl в production
Флаг --no-verify-ssl отключает проверку TLS. В production вместо него установите внутренний CA:
(или соответствующий путь для конкретной ОС). После этого проверьте доступ:
4.4. Выбор immutable prefix
Рекомендуемый префикс:
Не перезаписывайте существующую модель
Не загружайте новую версию поверх s3://models/qwen/Qwen3-8B/. Используйте immutable prefix <COMMIT-SHA> — это позволяет хранить несколько релизов модели (Model Release 1/2/3) и выполнять rollback.
Почему в S3 лучше использовать commit SHA
Хранение только по имени модели (`s3://models/qwen/Qwen3-8B/`) не позволяет отличить версии. Префикс с commit SHA — неизменяемый артефакт. Для нескольких моделей структура выглядит так: При необходимости можно вести логический alias `current`: `current` — логический alias на утверждённую версию, а не единственное хранилище модели.4.5. Загрузка модели в S3
aws s3 sync \
/opt/model-import/model/ \
s3://models/qwen/Qwen3-8B/<COMMIT-SHA>/ \
--endpoint-url https://s3.example.local
AWS CLI рекурсивно загрузит весь каталог.
4.6. Проверка содержимого S3
aws s3 ls \
s3://models/qwen/Qwen3-8B/<COMMIT-SHA>/ \
--recursive \
--endpoint-url https://s3.example.local
Должны присутствовать config.json, tokenizer.json, tokenizer_config.json, *.safetensors и остальные файлы модели.
Проверьте, что количество файлов совпадает. Локально:
В S3:
aws s3 ls \
s3://models/qwen/Qwen3-8B/<COMMIT-SHA>/ \
--recursive \
--endpoint-url https://s3.example.local \
| wc -l
Количество должно совпадать.
Проверьте размер. Локально:
В S3:
aws s3 ls \
s3://models/qwen/Qwen3-8B/<COMMIT-SHA>/ \
--recursive \
--summarize \
--human-readable \
--endpoint-url https://s3.example.local
Сравните общий размер.
4.7. Строгая проверка: повторная SHA-256 из S3
Количество файлов и размер — недостаточная проверка: содержимое могло измениться. Скачайте модель из S3 во временный каталог и сверьте SHA-256:
mkdir -p /tmp/model-verification
aws s3 sync \
s3://models/qwen/Qwen3-8B/<COMMIT-SHA>/ \
/tmp/model-verification/ \
--endpoint-url https://s3.example.local
Если все файлы вернули OK — модель успешно перенесена в S3.
ETag ≠ MD5
Не используйте ETag == MD5 как универсальную проверку целостности: для multipart-загрузки ETag обычно не является простым MD5 всего файла. Источник истины — собственные SHA-256 из checksums/model-SHA256SUMS.
Шаг 5. Подготовка PVC и запуск vLLM
5.1. Рекомендуемая схема: initContainer + PVC
Для production Kubernetes модель загружается из S3 в PVC через initContainer:
S3 используется как master storage, PVC — как локальный cache. Это удобно для моделей размером 10–500 ГБ.
Не используйте emptyDir для больших моделей
При использовании emptyDir модель исчезает при пересоздании Pod — при каждом рестарте пришлось бы скачивать модель заново:
Используйте PVC как cache: S3 → PVC → vLLM.
Альтернатива: скачать модель на PVC заранее
Можно один раз вручную скопировать модель из S3 на PVC (без initContainer). Этот вариант проще, но обновление модели требует ручных операций.5.2. Credentials и права доступа
Не прописывайте AWS_ACCESS_KEY_ID и AWS_SECRET_ACCESS_KEY непосредственно в Deployment. Создайте Secret:
kubectl create secret generic s3-model-credentials \
--from-literal=AWS_ACCESS_KEY_ID='...' \
--from-literal=AWS_SECRET_ACCESS_KEY='...' \
-n inference
Отдельный пользователь S3
Для vLLM/model downloader не используйте административный S3-аккаунт. Создайте отдельного пользователя vllm-model-reader с правами только s3:GetObject и s3:ListBucket на models/qwen/Qwen3-8B/*. Запретите PutObject и DeleteObject.
Модель — immutable-артефакт: после утверждения s3://models/qwen/Qwen3-8B/<COMMIT-SHA>/ vLLM имеет доступ только на чтение (READ, не WRITE). Это разделяет процессы загрузки (Model ingestion) и обслуживания (Model serving) модели.
5.3. Манифест Deployment
Простой манифест для проверки работоспособности:
apiVersion: apps/v1
kind: Deployment
metadata:
name: vllm-qwen3-8b
namespace: inference
spec:
replicas: 1
selector:
matchLabels:
app: vllm-qwen3-8b
template:
metadata:
labels:
app: vllm-qwen3-8b
spec:
initContainers:
- name: model-download
image: registry.example.local/tools/aws-cli:latest
command:
- /bin/sh
- -c
- |
aws s3 sync \
s3://models/qwen/Qwen3-8B/<COMMIT-SHA>/ \
/models/Qwen3-8B \
--endpoint-url https://s3.example.local
envFrom:
- secretRef:
name: s3-model-credentials
volumeMounts:
- name: model
mountPath: /models
containers:
- name: vllm
image: registry.example.local/vllm/vllm-openai:<VERSION>
command: ["vllm", "serve"]
args:
- /models/Qwen3-8B
- --served-model-name
- qwen3-8b
env:
- name: HF_HUB_OFFLINE
value: "1"
volumeMounts:
- name: model
mountPath: /models
volumes:
- name: model
persistentVolumeClaim:
claimName: qwen3-8b-model
Запрос GPU-ресурсов (resources.limits) задаётся в соответствии с установленным GPU-оператором — см. GPU-оператор Metax.
Не используйте latest в production
Образ registry.example.local/tools/aws-cli:latest может измениться в любой момент. В production используйте конкретную версию (registry.example.local/tools/aws-cli:<VERSION>), а лучше — digest (registry.example.local/tools/aws-cli@sha256:<DIGEST>).
Отличия от минимального варианта:
- Образы initContainer и vLLM зафиксированы по digest:
- Credentials берутся из Secret
s3-model-credentials(см. шаг 5.2), у S3-пользователя только права на чтение. HF_HUB_OFFLINE=1в контейнере vLLM (см. шаг 5.5).- Сетевой доступ ограничен NetworkPolicy: разрешены только S3, DNS и внутренние сервисы, Интернет запрещён:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: vllm-egress
namespace: inference
spec:
podSelector:
matchLabels:
app: vllm-qwen3-8b
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: <S3_CIDR> # адреса локального S3
ports:
- protocol: TCP
port: 443
- to:
- namespaceSelector: {} # DNS
ports:
- protocol: UDP
port: 53
Подставьте реальные CIDR под вашу инфраструктуру.
5.4. Запуск vLLM
После того как модель появилась на PVC (/models/Qwen3-8B), vLLM запускается обычным образом:
В Kubernetes аргументы задаются в манифесте Deployment (см. шаг 5.3).
5.5. Офлайн-режим и сетевая изоляция
vLLM должен запускаться без доступа к huggingface.co, github.com, pypi.org, docker.io. Если модель полностью локальная, vllm serve /models/Qwen3-8B не должен обращаться к Hugging Face.
HF_HUB_OFFLINE=1
Переменная HF_HUB_OFFLINE=1 запрещает Hugging Face Hub client обращаться в Интернет за отсутствующими файлами. Задайте её в контейнере:
Это особенно полезно для тестирования air-gapped-развёртывания.
Не полагайтесь только на переменные окружения: ограничьте сетевой доступ namespace/Pod через NetworkPolicy (см. шаг 5.3, промышленный вариант).
Промышленный вариант: рекомендуемая архитектура
Для production рекомендуемая архитектура:
INTERNET
│
▼
┌──────────────────┐
│ Model Collector │ huggingface_hub
└────────┬─────────┘
▼
┌──────────────────┐
│ Model Validator │ commit SHA, SHA256, inventory, tokenizer, config
└────────┬─────────┘
▼
┌──────────────────┐
│ Transfer Package │
└────────┬─────────┘
USB
▼
┌──────────────────┐
│ Airgap Importer │
└────────┬─────────┘
▼
┌──────────────────┐
│ Local S3 │ model releases
└────────┬─────────┘
read-only access
▼
┌──────────────────┐
│ Model Downloader │ initContainer
└────────┬─────────┘
▼
┌──────────────────┐
│ PersistentVolume │
└────────┬─────────┘
▼
┌──────────────────┐
│ vLLM (GPU) │
└────────┬─────────┘
▼
OpenAI-compatible API
Главная идея: Hugging Face — внешний источник модели, S3 — внутренний master storage, PVC — локальный cache для inference, а vLLM не должен знать о существовании Интернета.
Единица поставки — Model Release, а не отдельный файл весов:
Qwen3-8B Model Release
├── Hugging Face repository
├── Commit SHA
├── Model configuration
├── Tokenizer
├── Chat template
├── Weight files
├── Weight index
├── Generation configuration
├── Custom code
├── Python dependencies
├── File inventory
├── SHA256
└── Validation information
После импорта модель живёт в S3 с immutable prefix:
s3://models/
└── qwen/
└── Qwen3-8B/
└── <COMMIT-SHA>/
├── config.json
├── tokenizer.json
├── tokenizer_config.json
├── model-00001-of-00004.safetensors
├── ...
└── model.safetensors.index.json
Сохраните также environment manifest — сведения об окружении, на котором модель проверялась:
Python: 3.x
huggingface_hub: x.y.z
transformers: x.y.z
torch: x.y.z
vLLM: x.y.z
CUDA: 12.x
NVIDIA Driver: xxx.xx
Это позволит через год ответить на вопрос: «На каком окружении эта модель была проверена?»
Проверка результата
После загрузки модели в S3 и запуска Deployment выполните итоговые проверки.
- Целостность архива и файлов — шаги 3.1 и 3.3:
sha256sum -cдля архива и для файлов модели. - Повторная SHA-256 из S3 — шаг 4.7: скачайте модель из S3 и сверьте контрольные суммы.
- Запуск vLLM:
- Проверка API vLLM. Список моделей:
Ожидаемый ответ:
Тестовый запрос:
curl http://vllm.example.local/v1/chat/completions \
-H 'Content-Type: application/json' \
-d '{
"model": "qwen3-8b",
"messages": [
{
"role": "user",
"content": "Hello"
}
]
}'
- Тест air-gap: запустите vLLM, убедитесь, что модель загружается, полностью запретите Интернет, перезапустите Pod и убедитесь, что vLLM снова успешно стартует. Если это работает — deployment действительно независим от Интернета.
Частые ошибки
| Симптом | Вероятная причина | Решение |
|---|---|---|
| vLLM не загружает модель, ошибка на старте | Перенесены только веса, отсутствует tokenizer или config.json |
Скачивайте снапшот целиком (шаг 1.6), проверяйте обязательные файлы (шаг 1.7) |
| vLLM обращается в Интернет при старте | Не задан HF_HUB_OFFLINE, нет NetworkPolicy |
Задайте HF_HUB_OFFLINE=1 и ограничьте сеть (шаг 5.5) |
| В S3 новая версия модели перезаписала старую | Нарушение immutable: загрузка без префикса <COMMIT-SHA> |
Всегда используйте immutable prefix (шаг 4.4) |
| Проверка целостности по ETag даёт неверный результат | Для multipart-upload ETag ≠ MD5 всего файла | Используйте собственные SHA-256 (шаг 4.7) |
| initContainer не скачивает модель | Неверные credentials, endpoint или права пользователя S3 | Проверьте Secret, --endpoint-url, права s3:GetObject/s3:ListBucket (шаг 5.2) |
| Модель скачивается заново при каждом рестарте Pod | Используется emptyDir вместо PVC |
Используйте PVC как cache (шаг 5.1) |
| Не воспроизводимый образ initContainer | Используется latest-тег |
Зафиксируйте версию или digest образа (шаг 5.3) |
| Модель с custom code не запускается в закрытом контуре | Не перенесены Python-зависимости | Перенесите зависимости в локальный PyPI (шаг 1.8) |
Приложения
Контрольный чек-лист перед переносом
- Hugging Face repository зафиксирован
- Revision зафиксирован
- Commit SHA получен
- Snapshot скачан целиком
-
config.jsonприсутствует - tokenizer присутствует
- все weight-файлы присутствуют
-
index.jsonприсутствует, если необходим -
generation_configпроверен - chat template проверен
- custom code проверен
- Python dependencies определены
- модель локально загружается
- file inventory создан
- SHA256 создан
- transfer package создан
- SHA256 package создан
Контрольный чек-лист после переноса
- SHA256 transfer package совпадает
- SHA256 файлов модели совпадает
- количество файлов совпадает
- размер модели совпадает
- manifest проверен
- S3 bucket доступен
- модель загружена в правильный prefix
- количество S3-объектов совпадает
- размер S3-объектов совпадает
- повторная SHA256-проверка прошла
- S3 prefix сделан immutable
- credentials имеют только необходимые права
- PVC создан
- model downloader работает
- vLLM стартует
- vLLM не обращается в Интернет
- API
/v1/modelsработает - inference request работает