Реал‑тайм стриминг на GPU: низкая латентность

Задача страницы. Инженерный гид по построению низколатентных потоковых аудио‑сервисов на GPU: приём WebRTC/RTSP/микрофон, буферизация и стриминг частичных результатов (SSE/WebSocket), управление jitter/underruns, адаптивный размер блока и backpressure, микробатчинг без срыва SLA, наблюдаемость и экономика. Материалы применимы к ASR/TTS/Voice Conversion/Enhancement/Диааризации и музыкальным моделям; ссылки на профильные страницы — в конце.

TL;DR

Сценарии (когда это нужно)

Архитектуры и пайплайны 1) Единый потоковый конвейер (низкая латентность)

Client (WebRTC/Mic/RTSP)
 └─> Ingress (WS/SSE, UDP->PCM, resample 16–48 kHz)
 └─> Ring Buffer (200–500 ms) + VAD (опц.)
 └─> GPU Stage A (Enhance/VC/TTS block)
 └─> GPU Stage B (ASR/TTS/Align)
 └─> Post-process (punct/AGC/loudness)
 └─> Stream Out (SSE/WS partials)

Особенности: CHUNK_MS=20–40, RING_MS=300–500, ограничение очередей (HWM/LWM), кросс‑фейд 5–10 мс для бесшовности.

2) Агрегатор потоков (мульти‑тенант)

Ingress ─> Auth ─> Router(by tenant/model/lang) ─> Low-latency GPU Pool
 └> HQ GPU Pool (offload/align)
 └> Autoscaler (U, RTF, queue_len)

Отдельные пулы на 24/48/80 ГБ и разные SLA. См. https://cloudcompute.ru/solutions/multi-gpu/

3) Видеопоток → аудио → ASR/TTS (опционально)

RTSP/HTTP Video ─> NVDEC ─> Audio Demux/Resample ─> [Enhance] ─> ASR/TTS/VC ─> Stream Out

Профили GPU и ориентиры

Оценка по количеству одновременных реал‑тайм потоков при целевом U≈0.7 и RTF p95 из диапазона в таблице. Для батчей используйте формулы в «Экономике».

**Профиль GPU** **Память** **Типовой стек** **Целевой RTF (p95)** **Реал‑тайм потоки\*** **Комментарии**
24 ГБ (Compact) 24 ГБ Лёгкий Enhance → ASR **или** TTS LL 0.3–0.5 2–6 Короткие окна, стабильный TTFA; mono 16–24 кГц.
48 ГБ (Balanced) 48 ГБ Enhance → ASR/TTS/VC (средний стек) 0.4–0.6 6–12 Баланс качества/латентности, OSD/доп. пост‑проц.
80 ГБ (HQ) 80 ГБ Сложные пайплайны (VC+ASR, HQ TTS, демикс) 0.5–0.7 12–24 HQ‑режимы, многоканальность, большие словари/модели.

* Диапазон зависит от частоты дискретизации, сложности модели, VAD/OSD, сетевых условий и I/O. Тюнинг — в https://cloudcompute.ru/solutions/performance-tuning/ и https://cloudcompute.ru/solutions/throughput-vs-latency/

Конфиги (YAML) и скелеты кода

Docker Compose: универсальный стриминг‑сервис (SSE/WS)

version: "3.9"
x-env: &env
 MODELS_DIR: /models
 CACHE_DIR: /var/cache/rt
 SAMPLE_RATE: "24000"
 CHUNK_MS: "20" # 20–40
 RING_MS: "300" # 200–500
 PRECISION: "fp16" # bf16|fp16
 TRANSPORT: "sse" # sse|ws
 BACKPRESSURE_HWM: "8" # макс. блоков в очереди
 BACKPRESSURE_LWM: "4"
 DROP_OLD_CHUNKS: "true"
 MAX_CONCURRENCY: "4" # локальная параллельность GPU-ядра
 PARTIALS_EVERY_MS: "100" # частота отдачи частичных результатов
services:
 rt-gateway:
 image: cloudcompute/realtime-streaming:latest
 environment: *env
 deploy:
 resources:
 reservations:
 devices: [{ capabilities: ["gpu"] }]
 ports: ["8088:8088"]
 volumes:
 - /nvme/models:/models
 - /nvme/rt-cache:/var/cache/rt
 command: ["python", "serve.py", "--host=0.0.0.0", "--port=8088"]

K8s (1 GPU/под, явные лимиты и readiness)

apiVersion: apps/v1
kind: Deployment
metadata:
 name: realtime-streaming
spec:
 replicas: 2
 selector: { matchLabels: { app: rt-stream } }
 template:
 metadata: { labels: { app: rt-stream } }
 spec:
 containers:
 - name: gateway
 image: cloudcompute/realtime-streaming:latest
 ports: [{ containerPort: 8088 }]
 env:
 - { name: CHUNK_MS, value: "20" }
 - { name: RING_MS, value: "300" }
 - { name: PRECISION, value: "fp16" }
 - { name: TRANSPORT, value: "sse" }
 readinessProbe:
 httpGet: { path: /healthz, port: 8088 }
 initialDelaySeconds: 3
 periodSeconds: 5
 resources:
 limits: { nvidia.com/gpu: 1, memory: "24Gi", cpu: "4" }
 nodeSelector:
 nvidia.com/gpu.present: "true"

FastAPI: SSE + WebSocket, адаптивный микробатчинг (≤ 4 блока)

from fastapi import FastAPI, WebSocket
from sse_starlette.sse import EventSourceResponse
import asyncio, time, json, base64, collections
app = FastAPI()
HWM, LWM = 8, 4
CHUNK_MS = 20
async def gpu_infer(blocks: list[bytes]) -> list[bytes]:
 # Единичный вызов модели над 1–4 блоками: FP16/BF16, zero-copy
 await asyncio.sleep(0) # имитация
 return blocks # заглушка
async def process_stream(frame_iter):
 q = collections.deque()
 last_emit = 0
 async def producer():
 async for frame in frame_iter: # PCM блоками 20–40 мс
 q.append(frame)
 if len(q) > HWM and DROP_OLD_CHUNKS:
 q.popleft() # backpressure: сброс старых блоков
 await asyncio.sleep(0)
 async def consumer():
 nonlocal last_emit
 while True:
 if not q:
 await asyncio.sleep(0.001); continue
 batch = []
 while q and len(batch) < 4: # микробатчинг до 4 блоков
 batch.append(q.popleft())
 out = await gpu_infer(batch)
 now = time.time()
 for chunk in out:
 if (now - last_emit) * 1000 >= 100: # PARTIALS_EVERY_MS
 last_emit = now
 yield base64.b64encode(chunk).decode("ascii")
 await asyncio.sleep(0)
 return producer, consumer
@app.post("/sse")
async def sse_endpoint():
 async def event_gen():
 producer, consumer = await process_stream(audio_source())
 asyncio.create_task(producer())
 async for b64 in consumer():
 yield {"event": "audio", "data": b64}
 yield {"event": "done", "data": "{}"}
 return EventSourceResponse(event_gen())
@app.websocket("/ws")
async def ws_endpoint(ws: WebSocket):
 await ws.accept()
 producer, consumer = await process_stream(websocket_audio_source(ws))
 asyncio.create_task(producer())
 async for b64 in consumer():
 await ws.send_text(b64)
 await ws.close()
# Заглушки источников аудио:
async def audio_source():
 while True:
 frame = await next_pcm_frame_or_none(CHUNK_MS)
 if frame is None: break
 yield frame
async def websocket_audio_source(ws: WebSocket):
 while True:
 msg = await ws.receive_text()
 yield base64.b64decode(msg)
``` **Наблюдаемость/метрики/алерты**

**Latency/Perf (Prometheus):**

- rt\_ttfa\_seconds{service=...} — **время до первого ответа** (цель p95: ASR/VC ≈ 0.3–0.6 с; TTS ≈ 0.2–0.3 с; diffusion‑music ≈ 1–2 с).
- rt\_rtf{service=...} — t\_proc / t\_audio (цель p95 &lt; 0.7).
- rt\_queue\_depth, rt\_queue\_wait\_ms — глубина и ожидание в очереди.
- rt\_jitter\_ms — отклонение межкадрового интервала.
- rt\_underrun\_total, rt\_drop\_total — недогруз/сброс блоков.
- gpu\_utilization, gpu\_memory\_bytes, gpu\_mem\_peak\_bytes.
- nvme\_read\_mb\_s, nvme\_write\_mb\_s.

**Quality/UX:**

- audio\_clipping\_rate, audio\_loudness\_lufs, stream\_gap\_ms\_p95.
- asr\_partial\_to\_final\_ratio, tts\_buffer\_level\_ms, vc\_artifacts\_score — опционально по доменам.

**Алерты (примеры):**

- rt\_ttfa\_p95 &gt; SLA — включить «подогрев», снизить CHUNK\_MS, увеличить RING\_MS.
- rt\_rtf\_p95 &gt; 0.8 — упростить стек/precision, уменьшить микробатч, добавить GPU.
- rt\_jitter\_ms\_p95 &gt; 30 — увеличить ring‑buffer, включить pace‑контроль на клиенте.
- gpu\_mem\_peak/HBM &gt; 0.9 — уменьшить размер блоков/параллельность, FP16/BF16.

Подробно о наблюдаемости и логировании:
[ https://cloudcompute.ru/solutions/monitoring-logging/](https://cloudcompute.ru/solutions/monitoring-logging/) • <https://cloudcompute.ru/solutions/llm-inference/observability/>

## **Экономика и формулы**

Обозначения: c\_gpu — цена GPU/час, U — целевая загрузка GPU, RTF — t\_proc / t\_audio, λ — входной поток (потоков/сек), S — среднее время обслуживания блока.

- **Сколько GPU для онлайна:
 GPU\_count = ceil( (Σ RTF\_streams) / U ).
- **Стоимость минуты аудио:
 Cost\_per\_min = (c\_gpu × RTF / U) / 60.
- **Время до первого блока (оценка):
 TTFA ≈ t\_init + RING\_MS + t\_first\_kernel. Уменьшаем t\_init за счёт прогрева и закрепления графа, RING\_MS — компромисс с jitter.
- **Пропускная способность очереди (приближение по Литтлу):
 WIP ≈ λ × W, где W — среднее время в системе (очередь + обработка). Удерживайте U ≤ 0.7–0.8 для стабильного p95.

Разбор компромиссов: <https://cloudcompute.ru/solutions/throughput-vs-latency/> • Планирование: <https://cloudcompute.ru/solutions/cost-planner/>

**Безопасность/политики**

- **PII/биометрия:** аудио‑потоки и частичные результаты — чувствительные данные; шифрование «в канале», редактируемый ретеншн (**TTL** на NVMe‑кэше).
- **Секреты/ключи:** только Secret‑хранилища/переменные окружения, **ротация**. См. <https://cloudcompute.ru/solutions/security/>
- **Изоляция:** пулы GPU по тенантам/языкам/профилям, rate‑limit/quotas на Ingress.
- **Гарды контента:** фильтры микрофона/промптов/референсов; маскирование PII в логах.
- **Наблюдаемость:** без хранения сырого аудио; логи — агрегаты/метрики.

**Траблшутинг**

<table><tbody><tr><td>**Симптом**

</td><td>**Возможная причина**

</td><td>**Решение**

</td></tr><tr><td>**Подлагивания/«ступеньки» звука**

</td><td>Малый буфер, высокий jitter сети

</td><td>Увеличить RING\_MS до 300–500 мс, включить pace‑контроль, кросс‑фейд 5–10 мс

</td></tr><tr><td>**TTFA «прыгает»**

</td><td>Холодный старт/инициализация модели

</td><td>Прогрев графа/кеша, pin‑threads, уменьшить CHUNK\_MS

</td></tr><tr><td>**RTF p95 → 1**

</td><td>Перегрузка GPU/большой микробатч

</td><td>FP16/BF16, ограничить микробатч ≤ 2–4, упростить стек или добавить GPU

</td></tr><tr><td>**Underruns**

</td><td>Быстрый потребитель, медленный продюсер

</td><td>Повысить RING\_MS, понизить частоту отдачи partials, включить backpressure

</td></tr><tr><td>**Overruns/рост задержки**

</td><td>Медленный консьюмер/узкий I/O

</td><td>Ограничить TOP‑K/пост‑проц, ускорить NVMe/сеть, уменьшить RING\_MS

</td></tr><tr><td>**Щелчки/швы**

</td><td>Несогласованные границы блоков

</td><td>Кросс‑фейд, баланс CHUNK\_MS/PARTIALS\_EVERY\_MS, выравнивание по нулям

</td></tr><tr><td>**Всплески HBM**

</td><td>Параллельные сессии + большие блоки

</td><td>Снизить MAX\_CONCURRENCY, уменьшить размер блоков, offload

</td></tr><tr><td>**Разрыв WS/SSE**

</td><td>Прокси/таймауты

</td><td>Keep‑alive, ping/pong, переключение SSE↔WS, дробление крупных сообщений

</td></tr><tr><td>**ASR «глотает» начало**

</td><td>Агрессивный VAD/мало паддинга

</td><td>pad\_ms ≥ 150–200, пред‑буферизация первых блоков

</td></tr></tbody></table>

**Как запустить в cloudcompute.ru**

1. Откройте **Шаблоны запусков**: <https://cloudcompute.ru/solutions/templates/> — выберите **Real‑time Streaming Gateway** или профильный темплейт (ASR/TTS/VC/Enh/Диааризация).
2. Выберите профиль GPU: **24/48/80 ГБ** — по стеку и SLA.
3. Подключите диски: /nvme/models, /nvme/rt-cache.
4. Установите переменные окружения из docker-compose.yml (CHUNK\_MS, RING\_MS, PRECISION, BACKPRESSURE).
5. Для продакшна: автоскейл по U/RTF, дашборды и алерты, раздельные пулы **On‑Demand** и **Interruptible**, канареечный деплой.

Дополнительно по сервингу:
[ https://cloudcompute.ru/solutions/triton-inference-server/](https://cloudcompute.ru/solutions/triton-inference-server/) — сервинг моделей и динамический batching.
[ https://cloudcompute.ru/solutions/containers-ci-cd/](https://cloudcompute.ru/solutions/containers-ci-cd/) — сборка и выкладка контейнеров.

**Чек‑лист перед продом**

- Замерены TTFA p50/p95, RTF p50/p95, jitter\_ms, queue\_wait\_ms.
- Конфигурированы CHUNK\_MS, RING\_MS, HWM/LWM, **drop‑политики**.
- Параметры точности/скорости (FP16/BF16, микробатч) подобраны под SLA.
- Дашборды/алерты: TTFA/RTF/jitter/HBM/underrun/queue.
- Пулы On‑Demand/Interruptible разведены; автоскейл по U/очереди.
- Политики PII/ретеншна внедрены; секреты и роли настроены.
- Нагрузочный прогон ≥ 30 мин на целевом профиле/сети; канареечный релиз готов.

**Навигация**

- Хаб «Решения»: <https://cloudcompute.ru/solutions/>
- ASR (Whisper/WhisperX): <https://cloudcompute.ru/solutions/asr-whisper/>
- TTS: <https://cloudcompute.ru/solutions/tts/>
- Voice Conversion: <https://cloudcompute.ru/solutions/voice-conversion/>
- Улучшение речи (denoise/сепарация): <https://cloudcompute.ru/solutions/speech-enhancement/>
- Диааризация: <https://cloudcompute.ru/solutions/diarization/>
- Музыкальные модели: <https://cloudcompute.ru/solutions/music-ml/>
- Аудио‑эмбеддинги: <https://cloudcompute.ru/solutions/audio-embeddings/>
- Планирование стоимости: <https://cloudcompute.ru/solutions/cost-planner/>
- Производительность и тюнинг: <https://cloudcompute.ru/solutions/performance-tuning/>
- Throughput vs Latency: <https://cloudcompute.ru/solutions/throughput-vs-latency/>
- FP8/BF16: <https://cloudcompute.ru/solutions/fp8-bf16/>
- 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/>
- Наблюдаемость инференса: <https://cloudcompute.ru/solutions/llm-inference/observability/>
- Interruptible‑паттерны: <https://cloudcompute.ru/solutions/interruptible-patterns/>
- Triton Inference Server: <https://cloudcompute.ru/solutions/triton-inference-server/>
- Gradio + FastAPI: <https://cloudcompute.ru/solutions/gradio-fastapi/>
- CI/CD контейнеров: <https://cloudcompute.ru/solutions/containers-ci-cd/>

Готовы запустить?

Запустить GPU-сервер