Гибридные пайплайны: CV+LLM, DIFF+LLM и ETL+ML
Задача страницы. Инженерный гид по проектированию и эксплуатации смешанных пайплайнов на GPU: — CV+LLM (детекция/сегментация/ОCR → рассуждение/инструкции), — DIFF+LLM (идеация/контроль генерации/оценка качества), — ETL+ML (GPU‑ETL → обучение/инференс). Разберём архитектуры, очереди и backpressure, микробатчинг, профилирование, экономику и устойчивость. Сосредоточимся на GPU‑эффективности, наблюдаемости и чётких SLA.
TL;DR
- Архитектура как граф задач: декомпозируйте на независимые стадии (CV/LLM/DIFF/ETL/Rank), связывайте через очереди с HWM/LWM и явными таймаутами/ретраями.
- Латентность vs throughput: для интерактива держите U≈0.6–0.75, маленькие батчи (≤ 4) и микрошаги 20–40 мс; для батчей — укрупняйте батчи и используйте Interruptible. См. https://cloudcompute.ru/solutions/throughput-vs-latency/ и https://cloudcompute.ru/solutions/interruptible-patterns/
- GPU‑упаковка: лёгкие микросервисы (эмбеддинги, OCR, детекторы) выгодно сажать на MIG; тяжёлые LLM/диффузию — на цельные GPU. См. https://cloudcompute.ru/solutions/mig/
- Кэш и артефакты: веса/токенайзеры/тайлы — на NVMe с прогревом; фичи/эмбеддинги — в локальный кэш. См. https://cloudcompute.ru/solutions/storage-data/
- Наблюдаемость: E2E p95, stage_*_latency, queue_depth, drop/timeout, gpu_util/HBM, дешборды для деградаций/фоллбэков. См. https://cloudcompute.ru/solutions/llm-inference/observability/
- Экономика: Cost_request = Σ (c_stage × t_stage / U_stage). Узкое место определяет throughput; оптимизация — балансировка и фьюзинг препроцесса.
- Безопасность: PII/маскирование, guardrails перед LLM‑вызовами, версионирование промптов/моделей. См. https://cloudcompute.ru/solutions/security/ и https://cloudcompute.ru/solutions/llm-inference/observability/
Сценарии (когда это нужно)
- CV+LLM: визуальный поиск и описания, чек‑листы качества, извлечение структур из документов (det→OCR→LLM), VQA, анализ производственных дефектов.
- DIFF+LLM: генерация изображений по брифу с итеративным «критиком» (LLM), автокоррекция промптов, ControlNet/последующий апскейл.
- ETL+ML: RAPIDS/Spark RAPIDS‑подготовка фичей → обучение (cuML/torch) → сервинг (Triton), RAG‑обогащение метаданными.
- Композиты: видео‑аналитика + субтитры + LLM‑резюмирование; ASR→LLM→TTS для «голосовых ассистентов». См. https://cloudcompute.ru/solutions/realtime-streaming/
Архитектуры и пайплайны A) CV + LLM (Perception → Reasoning → Action)
Ingress (HTTP/WS)
└─> Preprocess (resize/normalize, NVJPEG/NVDEC)
└─> CV Stage(s): Detector/Segmenter/OCR (GPU)
└─> Feature Join (embeddings/text, NVMe cache)
└─> LLM Reasoner (prompt+context, stream partials)
└─> Guardrails/Policies
└─> Response (JSON/SSE)
Особенности: для OCR/детектора используйте микробатч ≤ 4, для LLM — стриминг частичных токенов. Фичи и вырезки храните на NVMe.
B) DIFF + LLM (Ideation → Generation → Review)
Brief/Prompt ─> LLM Prompt Crafter ─> Diffusion (SD/Control) ─> LLM Critic (score/tags)
└─> If score < τ → Re-prompt (N iters)
└─> If ok → Upscale/Refine → Deliver
Особенности: вынесите LLM‑критика на отдельный GPU/MIG, лимитируйте число итераций и общий бюджет времени.
C) ETL + ML (Features → Train/Score)
Object/NVMe ─> RAPIDS/Spark RAPIDS (read→join→agg→encode)
└─> Feature Store (Parquet/partitions)
├─> Train (cuML/torch) → Checkpoints
└─> Triton Serving (GPU) → Online scoring/embeddings
Особенности: тяжёлые шифлы и обучение — в Interruptible, онлайн‑скоринг — в On‑Demand. См. https://cloudcompute.ru/solutions/rapids/, https://cloudcompute.ru/solutions/spark-rapids/, https://cloudcompute.ru/solutions/triton-inference-server/
Профили GPU и ориентиры
Инженерные диапазоны для онлайн пайплайнов при U≈0.7. Реальные цифры зависят от моделей/разрешений/промптов и I/O.
| **Профиль GPU** | **Память** | **CV+LLM (запросы/с)\*** | **DIFF+LLM (изобр/мин)\*\*** | **ETL+ML (онлайн RPS)\*\*\*** | **Комментарии** |
| 24 ГБ (Compact) | 24 ГБ | 10–30 | 2–6 | 100–300 | Лёгкие детекторы/OCR/эмбеддинги; LLM — малый/квантованный. |
| 48 ГБ (Balanced) | 48 ГБ | 30–70 | 6–12 | 300–700 | Баланс качества/латентности; LLM средний; DIFF с малым шагом. |
| 80 ГБ (HQ) | 80 ГБ | 70–150 | 12–25 | 700–1500 | Тяжёлые промпты/больше токенов; DIFF с Control/апскейлом. |
* CV детект + OCR + LLM‑ответ p95 ≤ 1–2 с. ** Один проход генерации (≤ 30–60 шагов) + оценка «критиком». *** Ранкер/скора, без тяжёлых фичей. Для батч‑ETL см. страницы RAPIDS/Spark RAPIDS.
Конфиги и скелеты
Docker Compose: оркестратор + три воркера (CV / LLM / DIFF)
version: "3.9"
x-env: &env
CACHE_DIR: /var/cache/hybrid
PRECISION: "fp16"
MAX_MICROBATCH: "4"
HWM: "128" # High-watermark очереди
LWM: "64"
services:
orchestrator:
image: cloudcompute/hybrid-orchestrator:latest
environment: *env
ports: ["8088:8088"] # HTTP/SSE API
volumes:
- /nvme/hybrid:/var/cache/hybrid
depends_on: [cv-worker, llm-worker, diff-worker]
command: ["python","serve.py","--host=0.0.0.0","--port=8088"]
cv-worker:
image: cloudcompute/cv-serving:latest
environment: { PRECISION: "fp16", MAX_MICROBATCH: "4" }
deploy: { resources: { reservations: { devices: [{ capabilities: ["gpu"] }] } } }
volumes: ["/nvme/models:/models", "/nvme/hybrid:/var/cache/hybrid"]
llm-worker:
image: cloudcompute/llm-serving:latest
environment: { PRECISION: "fp16", MAX_TOKENS: "256", STREAM: "true" }
deploy: { resources: { reservations: { devices: [{ capabilities: ["gpu"] }] } } }
volumes: ["/nvme/models:/models", "/nvme/hybrid:/var/cache/hybrid"]
diff-worker:
image: cloudcompute/diffusion-serving:latest
environment: { STEPS: "30", UPSCALE: "true", PRECISION: "fp16" }
deploy: { resources: { reservations: { devices: [{ capabilities: ["gpu"] }] } } }
volumes: ["/nvme/models:/models", "/nvme/hybrid:/var/cache/hybrid"]
K8s: разные пулы под стадии (онлайн SLA)
apiVersion: apps/v1
kind: Deployment
metadata: { name: llm-worker }
spec:
replicas: 3
selector: { matchLabels: { app: llm-worker } }
template:
metadata: { labels: { app: llm-worker } }
spec:
containers:
- name: llm
image: cloudcompute/llm-serving:latest
ports: [{ containerPort: 9090 }]
env:
- { name: PRECISION, value: "fp16" }
- { name: MAX_TOKENS, value: "256" }
resources:
limits: { nvidia.com/gpu: 1, cpu: "4", memory: "32Gi" }
nodeSelector: { pool: on-demand }
---
apiVersion: apps/v1
kind: Deployment
metadata: { name: diff-worker }
spec:
replicas: 2
selector: { matchLabels: { app: diff-worker } }
template:
metadata: { labels: { app: diff-worker } }
spec:
containers:
- name: diff
image: cloudcompute/diffusion-serving:latest
resources:
limits: { nvidia.com/gpu: 1, cpu: "4", memory: "32Gi" }
nodeSelector: { pool: interruptible } # офлайн/полуонлайн
Конфиг пайплайна (YAML): граф, SLA, фоллбэки
dag:
nodes:
- id: preprocess ; type: cv_pre
- id: detector ; type: cv_model ; model: "detector_x"
- id: ocr ; type: cv_ocr ; model: "ocr_small"
- id: llm_reason ; type: llm ; model: "llm_medium" ; stream: true
- id: critic ; type: llm ; model: "llm_small"
- id: diffusion ; type: diff ; steps: 30 ; upscale: true
edges:
- [preprocess, detector]
- [detector, ocr]
- [ocr, llm_reason]
- [llm_reason, diffusion, { optional: true, when: "request.mode == 'generate'" }]
- [diffusion, critic]
sla:
e2e_ms: 1500
stage:
detector_ms: 150
ocr_ms: 120
llm_reason_ms: 800
diffusion_ms: 600
queue:
hwm: 128
lwm: 64
drop_policy: "oldest" # для интерактива
fallbacks:
- when: "llm_reason_timeout" ; action: "short_answer"
- when: "diffusion_timeout" ; action: "skip_upscale"
FastAPI (скелет): оркестратор с очередями и таймаутами
from fastapi import FastAPI, Body
from sse_starlette.sse import EventSourceResponse
import asyncio, time, json, uuid
app = FastAPI()
Q = { "cv": asyncio.Queue(maxsize=128),
"llm": asyncio.Queue(maxsize=128),
"diff": asyncio.Queue(maxsize=64) }
async def call_worker(kind, payload, timeout_ms):
q = Q[kind]; req_id = str(uuid.uuid4())
fut = asyncio.get_running_loop().create_future()
await q.put((req_id, payload, fut))
try:
return await asyncio.wait_for(fut, timeout=timeout_ms/1000)
except asyncio.TimeoutError:
return {"timeout": True}
@app.post("/cv-llm")
async def cv_llm(payload: dict = Body(...)):
t0 = time.time()
r1 = await call_worker("cv", {"op":"detector+ocr", "img":payload["img"]}, 300)
if r1.get("timeout"): return {"ok": False, "error":"cv_timeout"}
r2 = await call_worker("llm", {"op":"reason", "text":r1["text"]}, 900)
if r2.get("timeout"): r2 = {"text":"(краткий ответ без контекста)"}
return {"ok": True, "t_ms": int((time.time()-t0)*1000), "answer": r2["text"]}
Привязку к реальным моделям/бэкендам (Triton/vLLM/TGI/ComfyUI) делайте через адаптеры; для UI/демо — см. https://cloudcompute.ru/solutions/gradio-fastapi/ ## Наблюдаемость, метрики, алерты
E2E и стадии:
- hyb_e2e_seconds (p50/p95), hyb_stage_latency_seconds{stage=cv|ocr|llm|diff}, hyb_tokens_per_s, hyb_images_per_min.
- hyb_queue_depth{stage=...}, hyb_drop_total, hyb_timeout_total.
GPU/IO:
- gpu_utilization{stage=...}, gpu_mem_peak_bytes, gpu_copy_util, nvme_{read,write}_mb_s, model_cache_hit.
Качество:
- CV: map@mAP, OCR: cer/wer, DIFF: critic_score, LLM: halluc_rate (проксими), финальные accept_rate.
Алерты (примеры):
- hyb_e2e_p95 > SLA — сократить токены/шаги DIFF, включить деградацию, расширить GPU/профиль.
- gpu_copy_util≈100% при низком SM — упор в копировщики/PCIe → пиннинг, фьюзинг препроцесса, уменьшить параллельность.
- hyb_queue_depth↑ и drop_total↑ — узкое место стадии; добавить воркеры/увеличить профиль/перестроить DAG.
- gpu_mem_peak/HBM > 0.9 — уменьшить batch/размеры картинок/токенов, FP16/BF16, выгрузка неисп. тензоров.
Детальнее: https://cloudcompute.ru/solutions/monitoring-logging/ • https://cloudcompute.ru/solutions/llm-inference/observability/
Экономика и формулы
Пусть для этапа k: цена c_k (за GPU‑час), целевая загрузка U_k, среднее время обработки t_k.
- **Стоимость запроса: Cost_request ≈ Σ_k ( c_k × t_k / U_k ).
- **Throughput (ограничение узким местом): TPS ≈ min_k ( 1 / t_k_effective ), где t_k_effective учитывает очередь и микробатчинг.
- **Стадия DIFF с N итерациями: t_diff ≈ N × t_step + t_upscale, ограничивайте N и шаги апскейла по SLA.
- **Кэш‑экономия: Вероятность хита p_hit даёт: Δt ≈ p_hit × (t_load - t_cache) и ΔCost ≈ Σ (c_k × Δt / U_k).
- **On‑Demand vs Interruptible: Для смешанных пайплайнов: CV/LLM — On‑Demand, DIFF/обучение/ETL — Interruptible. Итоговая стоимость = сумма по пулам. См. https://cloudcompute.ru/solutions/cost-planner/ и https://cloudcompute.ru/solutions/interruptible-patterns/
Безопасность и политики
- PII/контент: маскирование идентификаторов, фильтры изображений/текста, безопасное логирование (без сырья). См. https://cloudcompute.ru/solutions/security/
- Guardrails LLM: валидация промптов/ответов, whitelists/blacklists, лимиты на токены и цепочки.
- Секреты и ключи: только Secret‑хранилища/ENV, ротация.
- Ретеншн: TTL на временные артефакты/рендеры/эмбеддинги; манифесты версий моделей/промптов.
- Изоляция: раздельные пулы (On‑Demand/Interruptible), MIG‑профили для мелких сервисов. См. https://cloudcompute.ru/solutions/mig/
Траблшутинг
| **Симптом** | **Возможная причина** | **Решение** |
| E2E p95 вышел за SLA | Узкое место (LLM/DIFF) или очереди | Урезать токены/шаги, включить деградации, добавить воркеры/профили, повысить U осторожно |
| Пики VRAM/CUDA OOM | Размеры изображений/батчи/активации | FP16/BF16, лимит разрешений, микробатч ≤ 4, выгрузка лишних тензоров |
| Падение качества OCR/детекта | Слишком агрессивный resize/сжатие | Балансировать препроцесс, повысить качество, адаптивные пороги |
| «Галлюцинации» LLM | Недостаточный контекст/guardrails | Добавить RAG/кастомные промпты, валидацию выходов, пост‑правила |
| Диффузия «залипает» | Вытянутые промпты/слишком много итераций | Ограничить N, LLM‑редактор промптов, ранний останов по «critic\_score» |
| Очереди растут волнообразно | Несогласованный микробатчинг стадий | Синхронизировать MAX\_MICROBATCH, задать HWM/LWM, включить backpressure |
| GPU простаивает | Узкое место в I/O/CPU | Пиннинг/zero‑copy, NVMe‑кэш, фьюзинг препроцесса, выделенные CPU лимиты |
| Нестабильный прод | Канарейки/версии конфликтуют | Версионирование моделей/промптов, canary/rollback, контракт схем |
Как запустить в cloudcompute.ru
- Откройте Шаблоны запусков: https://cloudcompute.ru/solutions/templates/ — выберите Hybrid Orchestrator и профильные темплейты (CV Serving / LLM Serving / Diffusion Serving / RAPIDS).
- Разведите пулы: On‑Demand (CV/LLM/онлайн‑ранкинг) и Interruptible (DIFF/обучение/ETL).
- Смонтируйте NVMe: /nvme/models, /nvme/hybrid (кэш/артефакты).
- Заполните dag.yaml (стадии, таймауты, деградации) и переменные (микробатч, HWM/LWM).
- Поднимиe наблюдаемость: дешборды E2E/стадий, алерты p95/queue/HBM, трассировка запросов.
- Канареечный деплой и нагрузочный прогон ≥ 30 мин под целевым трафиком.
Чек‑лист перед продом
- Заданы SLA: E2E и по стадиям; реализованы деградации/фоллбэки.
- Настроены очереди HWM/LWM, микробатчинг и backpressure.
- Прогреты модели/артефакты на NVMe; кэш‑хитрейт измерен.
- Дашборды и алерты: hyb_e2e_p95, stage_*_latency, queue_depth, HBM, copy_util.
- Политики PII/guardrails/ретеншн включены; секреты — через Secret‑хранилище.
- Пулы On‑Demand/Interruptible и/или MIG‑раскладка согласованы.
- Резервные сценарии (rollbacks/канарейки) протестированы.
Навигация
- Хаб «Решения»: https://cloudcompute.ru/solutions/
- Шаблоны запусков: https://cloudcompute.ru/solutions/templates/
- Throughput vs Latency: https://cloudcompute.ru/solutions/throughput-vs-latency/
- Interruptible‑паттерны: https://cloudcompute.ru/solutions/interruptible-patterns/
- MIG‑партиционирование: https://cloudcompute.ru/solutions/mig/
- RAPIDS (cuDF/cuML): https://cloudcompute.ru/solutions/rapids/
- Spark RAPIDS: https://cloudcompute.ru/solutions/spark-rapids/
- Triton Inference Server: https://cloudcompute.ru/solutions/triton-inference-server/
- Производительность и тюнинг: https://cloudcompute.ru/solutions/performance-tuning/
- Хранилища и данные: https://cloudcompute.ru/solutions/storage-data/
- Наблюдаемость инференса: https://cloudcompute.ru/solutions/llm-inference/observability/
- Мониторинг и логи: https://cloudcompute.ru/solutions/monitoring-logging/
- Gradio + FastAPI: https://cloudcompute.ru/solutions/gradio-fastapi/
- CI/CD контейнеров: https://cloudcompute.ru/solutions/containers-ci-cd/
Готовы запустить?
Запустить GPU-сервер