Распознавание речи на GPU: Whisper и WhisperX
Задача страницы. Практический гид по запуску и масштабированию ASR на базе Whisper/WhisperX для двух режимов — real‑time (интерактив) и батчи (офлайн), с голосовой активностью (VAD), таймкодами и выравниванием (alignment). Дадим типовые пайплайны, sizing по GPU, конфиги (Docker/K8s/FastAPI SSE), метрики и экономику. Все примеры ориентированы на инфраструктуру с локальным NVMe‑кэшем и режимами On‑Demand/Interruptible.
TL;DR
- **Два режима: On‑Demand — низкая латентность (стриминг SSE/WebSocket). Interruptible — массивные батчи с чанкованием ≤ 120 с и ретраями.
- Пайплайн: Resample→VAD→ASR (Whisper)→[опц.] WhisperX Align→Post‑process→Форматы (JSON/SRT/VTT/TSV).
- Хранение: NVMe для весов/артефактов/временных чанков; объектное хранилище для исходников и результатов. См. https://cloudcompute.ru/solutions/storage-data/
- Тюнинг: FP16/BF16, pinned/zero‑copy, батчирование в батч‑режиме, минимизация копий аудио между CPU/GPU. См. https://cloudcompute.ru/solutions/performance-tuning/ и https://cloudcompute.ru/solutions/fp8-bf16/
- Наблюдаемость: RTF, p50/p95 латентности, GPU util/HBM, drop‑rate VAD/буферов. См. https://cloudcompute.ru/solutions/monitoring-logging/ и https://cloudcompute.ru/solutions/llm-inference/observability/
- Экономика: GPU_count ≈ ceil(Σ RTF / U); Cost_per_min = (c_gpu * RTF / U) / 60. См. https://cloudcompute.ru/solutions/cost-planner/ и https://cloudcompute.ru/solutions/throughput-vs-latency/
- Безопасность: маскирование PII, шифрование артефактов, минимальный ретеншн. См. https://cloudcompute.ru/solutions/security/ и https://cloudcompute.ru/solutions/llm-inference/guardrails/
Когда это нужно (сценарии)
- Реал‑тайм стенография и ассистенты: звонки, колл‑центры, совещания, субтитры в прямом эфире, интерактивные демо.
- Пакетная расшифровка медиаархивов: подкасты, вебинары, лекции, медиатеки, телеконтент.
- RTSP/стримы с VAD: автоматическое включение распознавания на голосовой активности с паддингами.
- Пост‑обработка: нормализация, пунктуация, сплит по спикерам, WhisperX‑выравнивание для покадровых субтитров.
- ML‑пайплайны: поиск по речи, индексирование, RAG по транскриптам, автозаголовки/теги.
Архитектуры и пайплайны 1) Real‑time (низкая латентность, SSE/WebSocket)
Audio In (Mic/WebRTC/RTSP)
└─> Resample (16 kHz mono) ──> VAD (thresholds, pad)
└─> Ring Buffer (200–500 ms)
└─> GPU: Whisper (stream decode, FP16/BF16)
└─> [Optional] WhisperX Align (post)
└─> Post-process (punct/normalize)
└─> Stream out (SSE/WebSocket JSON chunks)
Особенности: короткие окна, стабильная RTF<1, backpressure, drop‑политики буфера, прогрессивные таймкоды, обрезка «щелчков» на границах VAD.
2) Батчи (массовая обработка, Interruptible) ``` Object Storage ─┬─> Sharder (≤120 s, overlap=0.2–0.5 s) │ ├─> Work Queue (priority, retries) │ └─> N x GPU Workers (batch inference, AMP) └─> Merge Segments (de-dup via overlap) └─> [Optional] WhisperX Align + Diarization └─> Writer (JSON/SRT/VTT/TSV) └─> Object Storage / DB
Особенности: чанк ≤120 с, оверлап 0.2–0.5 с для стыков, ретраи при прерывании, NVMe‑кэш для временных WAV/мел‑спектрограмм.
**3) Сервисная шина (мульти‑тенант)**
Ingress ─> Auth ─> Topic/Queue ─> GPU Pools (by profile) ─> Results Store └> Autoscaler (U target)
Разнесите модели/языки по пулам «24/48/80 ГБ», включите авто‑скейл по U и RTF.
## **GPU‑профили и ориентиры**
Базовый ориентир по одновременным потокам real‑time при RTF\_target ≈ 0.5 и целевой загрузке U ≈ 0.7. Для батчей масштабируйте по формуле в разделе «Экономика».
<table><tbody><tr><td>**Профиль GPU**
</td><td>**Память**
</td><td>**Типичные модели**
</td><td>**Real‑time потоки\***
</td><td>**Батчи (параллель)**
</td><td>**Комментарии**
</td></tr><tr><td>24 ГБ (Compact)
</td><td>24 ГБ
</td><td>Whisper **Small/Base**
</td><td>1–3
</td><td>2–6
</td><td>Легкие языковые модели, хороший интерактив в моно 16 кГц.
</td></tr><tr><td>48 ГБ (Balanced)
</td><td>48 ГБ
</td><td>Whisper **Medium**
</td><td>3–6
</td><td>6–12
</td><td>Баланс точности/скорости; устойчивый RTF для многоязычия.
</td></tr><tr><td>80 ГБ (HQ)
</td><td>80 ГБ
</td><td>Whisper **Large**
</td><td>6–12
</td><td>12–24
</td><td>Крупные модели, сложные домены, выравнивание + пост‑проц.
</td></tr></tbody></table>
\* Диапазоны зависят от аудио‑битрейта, языка, шумов, пост‑процесса и I/O. Для точного sizing снимайте RTF на своем корпусе.
См. тюнинг и профилировку: <https://cloudcompute.ru/solutions/performance-tuning/> • <https://cloudcompute.ru/solutions/throughput-vs-latency/> • <https://cloudcompute.ru/solutions/fp8-bf16/>
## **Конфиги и скелеты кода**
**Docker Compose (реал‑тайм + батчи + выравнивание)**
version: "3.9" x-common-env: &common_env CACHE_DIR: /var/cache/asr MODELS_DIR: /models SAMPLE_RATE: "16000" CHANNELS: "1" VAD_THRESHOLD: "0.6" VAD_MIN_SPEECH_MS: "300" VAD_PAD_MS: "150" WHISPER_MODEL: "medium" # small|base|medium|large WHISPER_PRECISION: "fp16" # bf16|fp16 ALIGN_ENABLE: "true" # WhisperX LANG: "auto" # или ru|en|... services: asr-realtime: image: cloudcompute/asr-whisper:latest environment: <<: *common_env SERVICE_MODE: "realtime" deploy: resources: reservations: devices: [{ capabilities: ["gpu"] }] ports: ["8080:8080"] volumes:
- /nvme/asr-cache:/var/cache/asr
- /nvme/models:/models command: ["python", "serve_realtime.py", "--host=0.0.0.0", "--port=8080"] asr-batch: image: cloudcompute/asr-whisper:latest environment: <<: *common_env SERVICE_MODE: "batch" MAX_CHUNK_SECONDS: "120" OVERLAP_SECONDS: "0.3" deploy: resources: reservations: devices: [{ capabilities: ["gpu"] }] volumes:
- /nvme/asr-cache:/var/cache/asr
- /nvme/models:/models
- /mnt/media:/data # аудио архива command: ["python", "run_batch.py", "--input=/data/in/", "--output=/data/out/"] aligner: image: cloudcompute/whisperx-align:latest environment: MODELS_DIR: /models deploy: resources: reservations: devices: [{ capabilities: ["gpu"] }] volumes:
- /nvme/models:/models
- /mnt/media:/data command: ["python", "align.py", "--input=/data/out/", "--write-word-timestamps"]
**K8s (скелет деплоймента под 1 GPU)**
apiVersion: apps/v1 kind: Deployment metadata: name: asr-realtime spec: replicas: 2 selector: { matchLabels: { app: asr-realtime } } template: metadata: labels: { app: asr-realtime } spec: containers:
- name: asr image: cloudcompute/asr-whisper:latest ports: [{ containerPort: 8080 }] env:
- { name: WHISPER_MODEL, value: "medium" }
- { name: WHISPER_PRECISION, value: "fp16" }
- { name: SAMPLE_RATE, value: "16000" }
- { name: VAD_THRESHOLD, value: "0.6" } volumeMounts:
- { name: models, mountPath: /models }
- { name: cache, mountPath: /var/cache/asr } resources: limits: nvidia.com/gpu: 1 memory: "24Gi" cpu: "4" volumes:
- name: models hostPath: { path: /nvme/models }
- name: cache hostPath: { path: /nvme/asr-cache }
**Конфиг пайплайна (YAML)**
pipeline: resample: sample_rate: 16000 channels: 1 vad: enabled: true threshold: 0.6 min_speech_ms: 300 pad_ms: 150 whisper: model: medium precision: fp16 # bf16|fp16 language: auto beam_size: 5 no_speech_threshold: 0.6 alignment: enabled: true word_timestamps: true output: formats: [json, srt, vtt] timestamps: segment_and_word
**FastAPI + SSE (стриминг частичных результатов)**
from fastapi import FastAPI, BackgroundTasks from fastapi.responses import StreamingResponse from sse_starlette.sse import EventSourceResponse import asyncio, json app = FastAPI() async def stream_transcribe(audio_iter):
audio_iter -> async generator of PCM frames @16kHz mono
async for partial in asr_infer(audio_iter):
partial: {"text": "...", "ts_start": 12.34, "ts_end": 13.20, "confidence": 0.92}
yield json.dumps(partial) @app.post("/stream") async def stream_endpoint(): async def event_gen(): async for chunk in stream_transcribe(audio_source()): yield {"event": "partial", "data": chunk} yield {"event": "done", "data": "{}"} return EventSourceResponse(event_gen())
Заглушки под аудио и инференс:
async def audio_source(): while True: frame = await next_pcm_frame_or_none() if frame is None: break yield frame async def asr_infer(audio_iter):
VAD + ring buffer + whisper decode (FP16/BF16), progressive timestamps
async for seg in decode_with_vad(audio_iter): yield seg
**Пакетная обработка (псевдокод)**
from pathlib import Path from concurrent.futures import ThreadPoolExecutor def shard_audio(wav_path, max_chunk=120.0, overlap=0.3):
вернёт список чанков (start, end)
... def transcribe_chunk(wav_path, t0, t1):
вырезать в tmp, подать в модель, вернуть сегменты с локальными ts
... def merge_segments(list_of_segments, overlap=0.3):
склеить и удалить дубли из оверлапа
... def batch_job(input_dir, output_dir): for wav in Path(input_dir).glob("*.wav"): chunks = shard_audio(wav) with ThreadPoolExecutor(max_workers=GPU_PARALLEL) as ex: parts = list(ex.map(lambda c: transcribe_chunk(wav, *c), chunks)) segments = merge_segments(parts) if ALIGN_ENABLE: segments = whisperx_align(segments, wav) write_outputs(segments, output_dir, wav.stem, formats=["json","srt","vtt"])
Ключевые метрики (Prometheus‑стиль):
- **RTF**: asr\_rtf{mode=rt|batch} — real‑time factor (GPU\_secs/audio\_secs), цель < 1.0 для интерактива.
- **Latency**: asr\_latency\_seconds{phase=enqueue|infer|align|post}, следим за p50/p95.
- **Throughput**: asr\_segments\_per\_sec, asr\_tokens\_per\_sec.
- **Quality**: asr\_confidence\_avg, asr\_vad\_drop\_rate, asr\_overlap\_fixups.
- **GPU**: asr\_gpu\_utilization, asr\_gpu\_memory\_bytes, asr\_gpu\_mem\_peak\_bytes.
- **I/O**: asr\_nvme\_read\_mb\_s, asr\_nvme\_write\_mb\_s.
Алерты (пример):
- RTF\_p95 > 0.9 в течение 3 мин — масштабируем пул или упрощаем пост‑процесс.
- GPU\_mem\_peak\_bytes / HBM > 0.9 — снизить размер батча/модель/включить offload.
- asr\_vad\_drop\_rate > 0.05 — пересмотреть пороги VAD/буферы.
См. хабы: <https://cloudcompute.ru/solutions/monitoring-logging/> • <https://cloudcompute.ru/solutions/llm-inference/observability/>
## **Экономика и формулы**
Обозначения: c\_gpu — цена GPU/час, U — целевая загрузка GPU (0–1), RTF — real‑time factor.
- **Сколько GPU нужно (стриминг):
GPU\_count = ceil( (Σ RTF\_streams) / U )
Пример: 8 потоков, каждый RTF≈0.4, U=0.7 → ceil( (8×0.4)/0.7 ) = ceil(4.57) = 5 GPU.
- **Стоимость минуты аудио:
Cost\_per\_min = (c\_gpu \* RTF / U) / 60.
- **Батчи:
Время партии T\_batch ≈ (RTF × L\_audio\_total) / (GPU\_count × U).
Cost\_total ≈ c\_gpu × GPU\_count × T\_batch.
См. калькулятор и подходы:
[ https://cloudcompute.ru/solutions/cost-planner/](https://cloudcompute.ru/solutions/cost-planner/) • <https://cloudcompute.ru/solutions/throughput-vs-latency/>
## **Безопасность и политики**
- **PII и чувствительные данные:** включайте маскирование в пост‑процессе (телефоны, карты, e‑mail), храните оригиналы минимально.
- **Ретеншн:** временные WAV/чанки на NVMe — авто‑очистка по TTL; логирование без сырого аудио.
- **Ключи/токены:** секреты только через переменные окружения/Secret‑хранилища.
- **Изоляция:** раздельные пулы GPU по тенантам/языкам, контроль доступа к бакетам.
Подробнее: <https://cloudcompute.ru/solutions/security/> • <https://cloudcompute.ru/solutions/llm-inference/guardrails/>
**Траблшутинг**
<table><tbody><tr><td>**Симптом**
</td><td>**Возможная причина**
</td><td>**Решение**
</td></tr><tr><td>«Глотает» начало фраз
</td><td>VAD/буфер слишком агрессивны
</td><td>Увеличить VAD\_PAD\_MS и размер ring‑buffer
</td></tr><tr><td>Задержка скачет
</td><td>I/O перегрузка, маленький буфер
</td><td>NVMe‑кэш, увеличить буферы, ограничить конкуренцию
</td></tr><tr><td>VRAM OOM
</td><td>Слишком крупная модель/батч
</td><td>Понизить модель/батч, FP16/BF16, offload промежуточных тензоров
</td></tr><tr><td>RTF ≈ 1 и выше
</td><td>Перегрузка GPU/пост‑процесс
</td><td>Упростить beam, снять выравнивание в онлайне, добавить GPU
</td></tr><tr><td>Дубли на стыках чанков
</td><td>Недостаточный overlap/merge
</td><td>Увеличить overlap до 0.3–0.5 с, dedup по логитам/ts
</td></tr><tr><td>Плохая пунктуация
</td><td>Шум, неверный язык
</td><td>Фильтрация шума, зафиксировать LANG, пост‑проц NORM
</td></tr><tr><td>«Щелчки» в конце сегментов
</td><td>Обрезка VAD без паддинга
</td><td>VAD\_PAD\_MS ≥ 100–200 мс
</td></tr><tr><td>Сбои на Interruptible
</td><td>Нет ретраев/идемпотентности
</td><td>Очередь с ретраями, idempotent‑ключи, чанк ≤120 с
</td></tr><tr><td>Падает выравнивание
</td><td>Нечеткие сегменты
</td><td>Запуск Align в батче после merge, калибровка порогов
</td></tr><tr><td>Высокий CPU
</td><td>Ресемплинг/декодинг на CPU
</td><td>Библиотеки с SIMD, групповой ресемплинг, закрепление потоков
</td></tr></tbody></table>
См. тюнинг: <https://cloudcompute.ru/solutions/performance-tuning/> • <https://cloudcompute.ru/solutions/interruptible-patterns/>
## **Как запустить в cloudcompute.ru**
1. Зайдите в **Шаблоны запусков**: <https://cloudcompute.ru/solutions/templates/>
Выберите темплейт **ASR Whisper (Real‑time)** или **ASR Whisper (Batch)**.
2. Укажите профиль GPU: **24 ГБ / 48 ГБ / 80 ГБ** и включите NVMe‑диск под /nvme.
3. Смонтируйте каталоги:
/nvme/models — веса, /nvme/asr-cache — кэш, /mnt/media — вход/выход батчей.
4. Настройте переменные окружения из примеров docker-compose.yml (модель, язык, пороги VAD, формат вывода).
5. Для продакшна рекомендованы: автоскейл по U/RTF, отдельные пулы по языкам/моделям, мониторинг/алерты.
Дополнительно:
[ https://cloudcompute.ru/solutions/triton-inference-server/](https://cloudcompute.ru/solutions/triton-inference-server/) — если хотите сервировать через Triton/ONNX/TensorRT.
[ https://cloudcompute.ru/solutions/gradio-fastapi/](https://cloudcompute.ru/solutions/gradio-fastapi/) — быстрый UI/эндпойнты.
[ https://cloudcompute.ru/solutions/containers-ci-cd/](https://cloudcompute.ru/solutions/containers-ci-cd/) — сборка и выкладка контейнеров.
**Чек‑лист перед продом**
- Замерены RTF p50/p95 под целевой корпус (язык/шум/битрейт).
- Выбран профиль GPU (24/48/80 ГБ) с запасом по U ≥ 0.2.
- NVMe‑кэш и каталоги корректно примонтированы.
- Пороговые параметры VAD\_THRESHOLD/PAD согласованы с UX.
- Форматы вывода (JSON/SRT/VTT) валидируются на примерах.
- Алерты по RTF/GPU‑HBM/дропам на месте.
- Политики PII и ретеншна внедрены; логи без сырого аудио.
- Interruptible‑джобы имеют ретраи и идемпотентные ключи.
- Автоскейл проверен (нагрузочный прогон ≥ 30 мин).
- Канареечный деплой и откат готовы.
**Навигация**
- Хаб «Решения»: <https://cloudcompute.ru/solutions/>
- Шаблоны запусков: <https://cloudcompute.ru/solutions/templates/>
- Планирование стоимости: <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-сервер