CI/CD для GPU‑нагрузок: контейнеры и пайплайны
Задача страницы. Инженерный гид по построению контейнеров и CI/CD‑пайплайнов для GPU‑нагрузок: обучение и инференс (LLM/ASR/CV/DIFF), RAPIDS‑ETL, сервисы на FastAPI/Gradio и Triton. Разберём паттерны сборки, кеши, тесты с GPU, миграцию моделей, канареечные релизы, метрики качества/латентности, экономику и безопасные практики. Соседние разделы: https://cloudcompute.ru/solutions/triton-inference-server/, https://cloudcompute.ru/solutions/gradio-fastapi/, https://cloudcompute.ru/solutions/rapids/, https://cloudcompute.ru/solutions/spark-rapids/, https://cloudcompute.ru/solutions/mig/, https://cloudcompute.ru/solutions/interruptible-patterns/, https://cloudcompute.ru/solutions/performance-tuning/, https://cloudcompute.ru/solutions/throughput-vs-latency/.
TL;DR
- Контейнеры: multi‑stage, CUDA‑совместимость, BuildKit‑кеши (--mount=type=cache), reproducible сборки (пинning по digest).
- Модели: версионируйте как артефакты (OCI‑слои / модельные пакеты) с model.yaml; прогрев на NVMe.
- CI: быстрые стадии CPU (lint/tests) → GPU‑smoke (≤ 60–120 с) → перф‑гейты (p95/throughput/VRAM headroom).
- CD: canary/blue‑green, readiness/liveness, rollback по SLO; трафик‑гейты.
- Экономика: кеши и слойность дают 2–10× экономию build‑времени; GPU‑тесты — под On‑Demand, длительные тренировки — под Interruptible.
- Наблюдаемость: build_time, image_size, cache_hit, p95_latency, gpu_util/HBM, fail_rate.
Сценарии (когда это нужно)
- Онлайн‑инференс (LLM/ASR/CV/TTS/DIFF) с FastAPI/Triton и канарейками. См. https://cloudcompute.ru/solutions/triton-inference-server/, https://cloudcompute.ru/solutions/gradio-fastapi/
- GPU‑ETL/аналитика (RAPIDS/Spark RAPIDS) — контейнеризация джоб и пайплайнов. См. https://cloudcompute.ru/solutions/rapids/, https://cloudcompute.ru/solutions/spark-rapids/
- Обучение/дообучение (LoRA/классика/графовые) — воспроизводимые тренировки и чекпоинты. См. https://cloudcompute.ru/solutions/interruptible-patterns/
- MIG‑кластер — мультисервисы на одном GPU. См. https://cloudcompute.ru/solutions/mig/
Архитектуры/пайплайны (общая схема) ```
Git push/tag └─ CI: ├─ Lint/Unit (CPU) ├─ Build Docker (BuildKit + caches) ├─ SBOM/Scan + Sign ├─ GPU-SMOKE (≤ 120 s: nvidia-smi, torch.cuda, mini batch) ├─ PERF-GATES (p95 latency, VRAM headroom, throughput) └─ Publish (registry, model artifacts) └─ CD: ├─ Staging deploy (K8s, readiness) ├─ Canary 1-5% traffic (SLO guard) ├─ Promote to 100% (blue/green) └─ Rollback on SLO breach
## **Профили GPU и ориентиры для CI‑тестов**
Оценка **smoke/perf‑гейтов** на 1 GPU при U≈0.6–0.75. Используйте минимально достаточный профиль.
<table><tbody><tr><td>**Профиль**
</td><td>**Память**
</td><td>**Smoke‑тест (сек)**
</td><td>**Перф‑замер (мин)**
</td><td>**Типовые задачи**
</td></tr><tr><td>24 ГБ (Compact)
</td><td>24 ГБ
</td><td>20–60
</td><td>2–5
</td><td>Torch/CUDA init, 1–2 микробатча LLM/CV, простые RAPIDS
</td></tr><tr><td>48 ГБ (Balanced)
</td><td>48 ГБ
</td><td>20–60
</td><td>3–8
</td><td>Средние модели (ASR/TTS), Triton model‑repo проверка
</td></tr><tr><td>80 ГБ (HQ)
</td><td>80 ГБ
</td><td>20–60
</td><td>5–10
</td><td>Крупные LLM/DIFF/батчи ETL, стабильные p95
</td></tr></tbody></table>
Подбор пула и экономику см. <https://cloudcompute.ru/solutions/throughput-vs-latency/> и <https://cloudcompute.ru/solutions/cost-planner/>
## **Контейнеры: паттерны Dockerfile**
**1) Torch/LLM Inference (multi‑stage + BuildKit кеши)**
syntax=docker/dockerfile:1.6
ARG CUDA_VER=12.4.1 ARG BASE_OS=ubuntu22.04 FROM nvidia/cuda:${CUDA_VER}-cudnn-runtime-${BASE_OS} AS base ENV DEBIAN_FRONTEND=noninteractive PIP_NO_CACHE_DIR=1 PYTHONDONTWRITEBYTECODE=1 TORCH_CUDA_ARCH_LIST="8.0;8.6;8.9" HF_HUB_DISABLE_TELEMETRY=1 RUN --mount=type=cache,target=/var/cache/apt apt-get update && apt-get install -y --no-install-recommends git curl ca-certificates python3 python3-pip libsndfile1 && rm -rf /var/lib/apt/lists/*
Wheelhouse (кешируем pip)
FROM base AS wheel COPY requirements.txt /tmp/requirements.txt RUN --mount=type=cache,target=/root/.cache/pip python3 -m pip install -U pip && pip wheel -r /tmp/requirements.txt -w /wheels
Runtime
FROM base AS runtime WORKDIR /app COPY --from=wheel /wheels /wheels RUN --mount=type=cache,target=/root/.cache/pip pip install --no-index --find-links=/wheels -r /wheels/requirements.txt COPY . /app
Неблокирующий прогрев токенайзеров/весов на NVMe (смонтируйте /nvme/models)
ENV MODELS_DIR=/nvme/models PRECISION=fp16 CMD ["python","serve.py"]
**Рекомендации:** фиксируйте **digest** базового образа, держите requirements.txt отсортированным (минимум диффа), вынесите большие зависимости в wheelhouse‑кеш.
**2) RAPIDS‑ETL job**
FROM rapidsai/rapidsai-core:24.06-cuda12.2-runtime-ubuntu22.04 ENV RMM_POOL_SIZE=70% UCX_TLS=tcp,cuda_copy,cuda_ipc WORKDIR /job COPY etl_job.py /job/etl_job.py CMD ["python","etl_job.py","--input","/data","--out","/out"]
**3) Triton model repository (минимальный runtime)**
FROM nvcr.io/nvidia/tritonserver:24.05-py3 COPY models/ /models/ # репозиторий моделей (config.pbtxt, версии) CMD ["tritonserver","--model-repository=/models","--log-verbose=0"]
Храните модели отдельно от кода, как **версионируемые артефакты**, публикуйте вместе с SBOM и метаданными:
model: name: "llm-small-ru" version: "1.4.2" format: "hf" # hf|onnx|triton precision: "fp16" files:
- path: "pytorch_model.bin"
- path: "tokenizer.json" metrics: token_rate_tok_s: 650 vram_peak_gb: 14.3 compatibility: cuda: ">=12.2" arch: ["8.0","8.6","8.9"] promote: tests:
- "smoke_llm_hello_world"
- "perf_token_rate >= 500" rollout: canary_traffic: 0.05 rollback_slo: latency_p95_ms: 1200 error_rate: 0.5
## **CI: пайплайны (GitHub Actions / GitLab CI)**
**GitHub Actions (.github/workflows/ci.yml)**
name: ci on: push: { branches: ["main"] } pull_request: jobs: lint-test: runs-on: ubuntu-22.04 steps:
- uses: actions/checkout@v4
- run: pipx install ruff && ruff check .
- run: pipx install pytest && pytest -q build-image: needs: lint-test runs-on: ubuntu-22.04 steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3 with: { registry: ${{ secrets.REGISTRY }}, username: ${{ secrets.USER }}, password: ${{ secrets.PASSWORD }} }
- name: Build & push run: | docker buildx build --push --build-arg CUDA_VER=12.4.1 --cache-to=type=registry,ref=${{ secrets.REGISTRY }}/proj/cache,mode=max --cache-from=type=registry,ref=${{ secrets.REGISTRY }}/proj/cache -t ${{ secrets.REGISTRY }}/proj/app:${{ github.sha }} . gpu-smoke: needs: build-image runs-on: self-hosted-gpu # раннер с GPU steps:
- name: Pull image run: docker pull ${{ secrets.REGISTRY }}/proj/app:${{ github.sha }}
- name: Smoke (≤120s) timeout-minutes: 5 run: | docker run --rm --gpus 1 -e MODELS_DIR=/nvme/models -v /nvme/models:/nvme/models ${{ secrets.REGISTRY }}/proj/app:${{ github.sha }} python -c "import torch; assert torch.cuda.is_available(); print(torch.cuda.get_device_name(0))" perf-gates: needs: gpu-smoke runs-on: self-hosted-gpu steps:
- name: Perf test run: | docker run --rm --gpus 1 ${{ secrets.REGISTRY }}/proj/app:${{ github.sha }} python perf_gate.py --p95-ms 1200 --vram-headroom-gb 2.0
**GitLab CI (.gitlab-ci.yml)**
stages: [lint, build, smoke, perf, deploy] lint: stage: lint image: python:3.11 script:
- pip install ruff pytest
- ruff check .
- pytest -q build: stage: build image: docker:24.0.5 services: [docker:dind] script:
- docker buildx create --use
- docker login -u "$REG_USER" -p "$REG_PASS" $REGISTRY
- docker buildx build --push -t $REGISTRY/proj/app:$CI_COMMIT_SHA . smoke: stage: smoke tags: ["gpu"] # GitLab Runner с GPU script:
- docker run --rm --gpus 1 $REGISTRY/proj/app:$CI_COMMIT_SHA python smoke.py perf: stage: perf tags: ["gpu"] script:
- docker run --rm --gpus 1 $REGISTRY/proj/app:$CI_COMMIT_SHA python perf_gate.py --p95-ms 1200
## **CD: канареечные релизы и промоушн**
**K8s Deployment (readiness/liveness + canary)**
apiVersion: apps/v1 kind: Deployment metadata: { name: llm-serving, labels: { app: llm, channel: stable } } spec: replicas: 6 selector: { matchLabels: { app: llm, channel: stable } } template: metadata: { labels: { app: llm, channel: stable } } spec: containers:
- name: api image: registry.local/proj/app:sha-abcdef ports: [{ containerPort: 9090 }] env:
- { name: PRECISION, value: "fp16" } readinessProbe: { httpGet: { path: /healthz, port: 9090 } } livenessProbe: { httpGet: { path: /livez, port: 9090 } } resources: { limits: { nvidia.com/gpu: 1, cpu: "4", memory: "32Gi" } }
apiVersion: apps/v1 kind: Deployment metadata: { name: llm-serving-canary, labels: { app: llm, channel: canary } } spec: replicas: 1 selector: { matchLabels: { app: llm, channel: canary } } template: metadata: { labels: { app: llm, channel: canary } } spec: containers:
- name: api image: registry.local/proj/app:${NEW_SHA} ports: [{ containerPort: 9090 }] env: [ { name: PRECISION, value: "fp16" } ] readinessProbe: { httpGet: { path: /healthz, port: 9090 } } resources: { limits: { nvidia.com/gpu: 1, cpu: "4", memory: "32Gi" } }
**Маршрутизация трафика** (ingress/сервис) отдаёт 1–5% на channel=canary. Гейты промоушна: latency\_p95, error\_rate, gpu\_mem\_peak/HBM, token\_rate.
**Наблюдаемость/метрики/алерты**
**CI/Build:**
- ci\_build\_time\_seconds, image\_size\_bytes, cache\_hit\_ratio, sbom\_vuln\_count, build\_fail\_rate.
- wheelhouse\_hit\_ratio, layer\_reuse\_ratio.
**GPU‑тесты/перф‑гейты:**
- gpu\_smoke\_time\_seconds, latency\_p95\_ms, token\_rate\_tok\_s/fps, vram\_peak\_gb, gpu\_utilization, gpu\_copy\_util.
- perf\_gate\_pass\_total, perf\_gate\_fail\_total.
**CD/Прод:**
- latency\_seconds{route}, timeouts\_total, errors\_total, queue\_depth, HBM\_peak, packing\_efficiency (для MIG).
**Алерты (примеры):**
- cache\_hit\_ratio < 0.6 — проверьте BuildKit‑кеш/слои, вынесите зависимости в отдельный этап.
- latency\_p95\_ms > SLO — уменьшить max\_tokens/steps, увеличить реплики/GPU, см. <https://cloudcompute.ru/solutions/throughput-vs-latency/>
- vram\_peak/HBM > 0.9 — FP16/BF16, микробатч ≤ 4, профиль побольше/MIG‑переупаковка. См. <https://cloudcompute.ru/solutions/mig/>
- sbom\_vuln\_count ↑ — обновите базу, пересоберите образ, фиксируйте digest.
- gpu\_copy\_util ≈100% при низком SM — упор в PCIe/копировщики: pinned/zero‑copy, фьюзинг препроцесса. См. <https://cloudcompute.ru/solutions/performance-tuning/>
Детали по логам и метрикам: <https://cloudcompute.ru/solutions/monitoring-logging/>, <https://cloudcompute.ru/solutions/llm-inference/observability/>
**Экономика и формулы**
Обозначения: c\_gpu — цена GPU‑часа, c\_cpu — CPU‑часа, U — целевая загрузка, t\_b — build‑время, t\_smoke, t\_perf, n\_prompts — тестовые запросы.
- **Стоимость сборки:
Cost\_build ≈ c\_cpu × t\_b\_cpu + c\_gpu × t\_b\_gpu / U. (обычно t\_b\_gpu ~ 0, если тесты отдельной стадией)
- **Стоимость тестов:
Cost\_tests ≈ c\_gpu × (t\_smoke + t\_perf) / U.
- **Экономия от кешей:
Пусть hit — доля кеш‑попаданий, t\_b0 — сборка без кеша.
t\_b ≈ t\_b0 × (1 - hit × k), где k∈\[0.5;0.9\] — «сила» кеша.
ΔCost ≈ c\_cpu × (t\_b0 - t\_b).
- **Canary‑стоимость:
При qps, доле p и времени проверки T:
Cost\_canary ≈ c\_gpu × p × qps × T × t\_infer / U.
- **On‑Demand vs Interruptible:
Онлайн‑сервисы → **On‑Demand**, офлайн‑тренировки/ETL → **Interruptible** (см. <https://cloudcompute.ru/solutions/interruptible-patterns/>). Итоговая стоимость = сумма по пулам.
Планирование бюджета: <https://cloudcompute.ru/solutions/cost-planner/>
**Безопасность/политики (supply chain)**
- **Пиннинг** базовых образов по **digest**, reproducible сборки (фиксированные версии).
- **SBOM** и скан уязвимостей на этапе CI; gate по критичности.
- **Подпись** и проверка образов при CD; политика доверенных реестров.
- **Секреты** только через секрет‑хранилища/ENV; **не** в образах.
- **Rootless/USER** невысоких привилегий; readOnlyRootFilesystem.
- **Политики PII**: без сырых данных/ключей в логах/артефактах; хранение моделей и датасетов в приватных бакетах. См. <https://cloudcompute.ru/solutions/security/>, <https://cloudcompute.ru/solutions/storage-data/>
**Траблшутинг**
<table><tbody><tr><td>**Симптом**
</td><td>**Возможная причина**
</td><td>**Решение**
</td></tr><tr><td>CUDA driver mismatch
</td><td>Драйвер на узле < runtime CUDA
</td><td>Обновить драйвер, подобрать базовый образ под версию драйвера
</td></tr><tr><td>invalid device function
</td><td>Сборка/библиотеки под другую arch
</td><td>Указать TORCH\_CUDA\_ARCH\_LIST, пересобрать/переустановить колеса
</td></tr><tr><td>PTX‑JIT задержки
</td><td>Нет SASS под вашу arch
</td><td>Предпрогреть модель, добавить целевые arch, кэш на NVMe
</td></tr><tr><td>Медленная сборка
</td><td>Отсутствие кешей/большие COPY
</td><td>BuildKit cache‑mounts, split‑слои, уменьшить контекст
</td></tr><tr><td>Большой образ
</td><td>Неочищенные apt/pip, dev‑зависимости
</td><td>\--no-install-recommends, wheelhouse + runtime layer
</td></tr><tr><td>Тесты «плавают»
</td><td>Нестабильные seeds/режимы CUDNN
</td><td>Фиксировать сиды, отключить benchmark при сравнениях SLA
</td></tr><tr><td>CUDA OOM в перф‑гейтах
</td><td>Батч/токены/разрешения
</td><td>FP16/BF16, микробатч ≤ 4, уменьшить входные размеры
</td></tr><tr><td>Triton не видит модель
</td><td>Нарушен layout model‑repo
</td><td>Проверить config.pbtxt/версии, права/пути
</td></tr><tr><td>MIG‑под не стартует
</td><td>Неверный resourceName
</td><td>Использовать nvidia.com/mig-\*.\*\*gb, проверить device‑plugin
</td></tr><tr><td>Развалился rollback
</td><td>Нет immutable‑тегов/диджестов
</td><td>Промоушн по **digest**, хранить N‑версий для отката
</td></tr></tbody></table>
**Как запустить в cloudcompute.ru**
1. Откройте **Шаблоны запусков**: <https://cloudcompute.ru/solutions/templates/> — выберите **CI/CD GPU Runner**, **Triton**, **FastAPI GPU API**, **RAPIDS job**.
2. Разведите пулы: **On‑Demand** (онлайн‑сервисы/канарейки) и **Interruptible** (тренировки/ETL). См. <https://cloudcompute.ru/solutions/interruptible-patterns/>
3. Смонтируйте **NVMe**: /nvme/models (веса), /nvme/cache (wheelhouse/артефакты).
4. Настройте BuildKit‑кеши и wheelhouse; зафиксируйте base‑image **digest**.
5. Добавьте GPU‑smoke (≤ 120 с) и перф‑гейты (p95/VRAM/token\_rate) в CI.
6. Настройте CD: readiness/liveness, canary 1–5%, автопромоушн по SLO, rollback.
7. Подключите дашборды: сборка/размер образов/кеш, прод‑метрики p95/QPS/HBM. См. <https://cloudcompute.ru/solutions/monitoring-logging/>, <https://cloudcompute.ru/solutions/llm-inference/observability/>
**Чек‑лист перед продом**
- Dockerfile: multi‑stage, BuildKit‑кеши, pinned digests, малый runtime‑слой.
- Модели как артефакты: model.yaml, версии, прогрев на NVMe.
- CI: lint/unit, build, SBOM/scan/sign, **GPU‑smoke (≤120 с)**, **перф‑гейты**.
- CD: staging → canary → promote → rollback; readiness/liveness.
- Метрики: build\_time, image\_size, cache\_hit, latency\_p95, HBM\_peak, token\_rate.
- Политики безопасности/PII/секретов; USER/rootless; приватные реестры.
- Пулы On‑Demand/Interruptible и/или MIG‑раскладка согласованы.
- Нагрузочный прогон ≥ 30 мин под целевым трафиком; план отката проверен.
**Навигация**
- Хаб «Решения»: <https://cloudcompute.ru/solutions/>
- Шаблоны запусков: <https://cloudcompute.ru/solutions/templates/>
- Triton Inference Server: <https://cloudcompute.ru/solutions/triton-inference-server/>
- Gradio + FastAPI: <https://cloudcompute.ru/solutions/gradio-fastapi/>
- RAPIDS (cuDF/cuML): <https://cloudcompute.ru/solutions/rapids/>
- Spark RAPIDS: <https://cloudcompute.ru/solutions/spark-rapids/>
- MIG‑партиционирование: <https://cloudcompute.ru/solutions/mig/>
- Interruptible‑паттерны: <https://cloudcompute.ru/solutions/interruptible-patterns/>
- Throughput vs Latency: <https://cloudcompute.ru/solutions/throughput-vs-latency/>
- Multi‑GPU/распределёнка: <https://cloudcompute.ru/solutions/multi-gpu/>
- Хранилища и данные: <https://cloudcompute.ru/solutions/storage-data/>
- Безопасность: <https://cloudcompute.ru/solutions/security/>
- Мониторинг и логи: <https://cloudcompute.ru/solutions/monitoring-logging/>
- Наблюдаемость LLM/инференса: <https://cloudcompute.ru/solutions/llm-inference/observability/>
Готовы запустить?
Запустить GPU-сервер