Решения

Улучшение речи на GPU: шумоподавление и сепарация

Задача страницы. Практический гид по построению сервисов speech enhancement на GPU: шумоподавление (denoise), подавление эха (AEC), дереверберация (dereverb) и разделение источников (source separation) в real‑time и батч‑режимах. Дадим пайплайны (стриминг и офлайн), sizing по профилям 24/48/80 ГБ, конфиги (Docker/K8s/YAML), метрики (RTF/TTFA/p95), экономику и траблшутинг. Рекомендуется локальный NVMe‑кэш, режимы On‑Demand и Interruptible, контейнеризация и стриминг через SSE/WebSocket.

TL;DR

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

  • Звонки/контакт‑центры/видеоконференции: подавление фонового шума, клавиатуры, кондиционеров, эха помещений.
  • Медиа‑продакшен/подкасты: офлайн очистка дорожек, дереверберация, выравнивание громкости.
  • ASR‑препроцессинг: повышение точности распознавания на сложном фоне (см. https://cloudcompute.ru/solutions/asr-whisper/).
  • Разделение источников: выделение голоса диктора от музыки/шумов; извлечение N спикеров для дальнейшей обработки/диаризации.
  • Edge/мультимик: кардиоидные массивы, beamforming (MVDR/GEV) перед нейронным denoise.

Архитектуры и пайплайны

1) Real‑time enhancement (низкая латентность, SSE/WebSocket)

				
					Audio In (Mic/WebRTC/RTSP)
  └─> AEC (опц, ref from device)
       └─> Beamforming (опц, multichannel)
            └─> VAD (pad=100–200 ms)
                 └─> Ring Buffer (200–500 ms)
                      └─> GPU: Denoise + Dereverb (FP16/BF16)
                           └─> [Optional] GPU: Separation (N speakers)
                                └─> Post-process (AGC/loudness)
                                     └─> Stream Out (PCM/Opus via SSE/WebSocket)

				
			

Особенности: TTFA_enh ≤ 150–300 мс, стабильный RTF_enh < 1, кросс‑фейд 5–10 мс между блоками, backpressure и drop‑политики.

2) Батчи (массовая очистка/сепарация)

				
					Object Storage ─┬─> Sharder (≤120 s, overlap 0.2–0.5 s)
                 ├─> Work Queue (prio, retries, idempotency)
                 └─> N x GPU Workers:
                       ├─> AEC/Beamform (опц.)
                       ├─> Denoise + Dereverb
                       ├─> [Optional] Separation (N)
                       └─> Merge (de-dup overlap, loudness)
                            └─> Writer (WAV/FLAC + JSON stems)
                                 └─> Object Storage / DB

				
			

Особенности: NVMe‑кэш для временных WAV/спектрограмм/эмбеддингов; идемпотентные ключи; отчеты по качеству (PESQ/STOI/SI‑SDR).

3) Интеграция с ASR/TTS/VC

				
					Enhancement Service ─> Clean audio ─┬─> ASR
                                    ├─> TTS (ре‑синтез)
                                    └─> Voice Conversion

				
			

Сборка конвейера — через сервисную шину/очереди. См. хабы:
https://cloudcompute.ru/solutions/, https://cloudcompute.ru/solutions/gradio-fastapi/

GPU‑профили и ориентиры

Диапазоны для одновременных real‑time потоков при RTF_enh ≈ 0.3–0.6 (denoise/dereverb) и RTF_sep ≈ 0.2–0.5 на спикера; U≈0.7. Для батчей — масштабирование по формуле в «Экономике».

Профиль GPU

Память

Типичные стеки

Real‑time потоки*

Батчи (параллель)

Комментарии

24 ГБ (Compact)

24 ГБ

Mask‑U‑Net‑класс denoise + лёгкий dereverb

1–3

2–6

Базовая очистка звонков/микрофона, SR 16–24 кГц.

48 ГБ (Balanced)

48 ГБ

Denoise + dereverb + Separation (2ch)

3–6

6–12

Баланс качества/латентности; устойчивые p95.

80 ГБ (HQ)

80 ГБ

Demucs‑класс / Conv‑TasNet‑класс + HQ dereverb

6–12

12–24

Высокое качество, многоканальность, N≥2 спикеров.

* Зависит от частоты дискретизации, каналов, силы шума/реверберации, включённой сепарации и пост‑процесса.
Тюнинг: https://cloudcompute.ru/solutions/performance-tuning/, https://cloudcompute.ru/solutions/fp8-bf16/, https://cloudcompute.ru/solutions/throughput-vs-latency/

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

Docker Compose (real‑time + batch)

				
					version: "3.9"

x-common-env: &env
  MODELS_DIR: /models
  CACHE_DIR: /var/cache/enh
  SAMPLE_RATE: "24000"
  FRAME_MS: "20"
  PRECISION: "fp16"          # bf16|fp16
  STREAM_CODEC: "pcm_s16le"  # или opus
  ENABLE_AEC: "false"
  ENABLE_BEAMFORM: "false"
  ENABLE_SEPARATION: "false" # true для N спикеров
  N_SPEAKERS: "2"

services:
  enh-realtime:
    image: cloudcompute/speech-enhancement:latest
    environment:
      <<: *env
      SERVICE_MODE: "realtime"
      TTFA_TARGET_MS: "200"
    deploy:
      resources:
        reservations:
          devices: [{ capabilities: ["gpu"] }]
    ports: ["8070:8070"]
    volumes:
      - /nvme/models:/models
      - /nvme/enh-cache:/var/cache/enh
    command: ["python", "serve_realtime.py", "--host=0.0.0.0", "--port=8070"]

  enh-batch:
    image: cloudcompute/speech-enhancement:latest
    environment:
      <<: *env
      SERVICE_MODE: "batch"
      MAX_CHUNK_SECONDS: "120"
      OVERLAP_SECONDS: "0.3"
    deploy:
      resources:
        reservations:
          devices: [{ capabilities: ["gpu"] }]
    volumes:
      - /nvme/models:/models
      - /nvme/enh-cache:/var/cache/enh
      - /mnt/audio-in:/data/in
      - /mnt/audio-out:/data/out
    command: ["python", "run_batch.py", "--input=/data/in", "--output=/data/out"]


				
			

K8s (1 GPU/под)

				
					apiVersion: apps/v1
kind: Deployment
metadata:
  name: enh-realtime
spec:
  replicas: 2
  selector: { matchLabels: { app: enh-realtime } }
  template:
    metadata:
      labels: { app: enh-realtime }
    spec:
      containers:
        - name: enh
          image: cloudcompute/speech-enhancement:latest
          ports: [{ containerPort: 8070 }]
          env:
            - { name: PRECISION, value: "fp16" }
            - { name: SAMPLE_RATE, value: "24000" }
            - { name: FRAME_MS, value: "20" }
            - { name: ENABLE_SEPARATION, value: "false" }
          volumeMounts:
            - { name: models, mountPath: /models }
            - { name: cache,  mountPath: /var/cache/enh }
          resources:
            limits:
              nvidia.com/gpu: 1
              memory: "24Gi"
              cpu: "4"
      volumes:
        - name: models
          hostPath: { path: /nvme/models }
        - name: cache
          hostPath: { path: /nvme/enh-cache }


				
			

Конфиг пайплайна (YAML)

				
					pipeline:
  input:
    sample_rate: 24000
    channels: 1
  aec:
    enabled: false
    tail_ms: 128
  beamforming:
    enabled: false
    method: mvdr    # mvdr|gev|cardioid
  vad:
    enabled: true
    threshold: 0.6
    pad_ms: 150
  denoise:
    model: "mask_unet_like"
    precision: "fp16"
    strength: 0.7       # 0..1
  dereverb:
    enabled: true
    method: "wpe_like"
    strength: 0.5
  separation:
    enabled: false
    type: "demucs_like" # или conv_tasnet_like
    speakers: 2
  post:
    agc: true
    loudness_target_lufs: -23.0
  output:
    codec: "pcm_s16le"
    stream_chunk_ms: 40
    formats: [wav, stems_json]


				
			

FastAPI: стриминг очищенного аудио (SSE + base64 фреймы)

				
					from fastapi import FastAPI, Body
from sse_starlette.sse import EventSourceResponse
import base64, asyncio

app = FastAPI()

async def enhance_stream(audio_iter, cfg):
    async for frame in process_blocks(audio_iter, cfg):  # 20–40 мс PCM16LE
        yield base64.b64encode(frame).decode("ascii")

@app.post("/enh/stream")
async def enh_stream_endpoint(payload: dict = Body(...)):
    cfg = payload.get("config", {})
    async def event_gen():
        async for b64_chunk in enhance_stream(audio_source(), cfg):
            yield {"event": "audio", "data": b64_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


				
			

Overlap‑Add для батчей (псевдокод)

				
					import numpy as np

def split_with_overlap(x, sr, win_s=1.2, hop_s=1.0):
    win = int(win_s * sr); hop = int(hop_s * sr)
    windows = [x[i:i+win] for i in range(0, max(len(x)-win, 0)+1, hop)]
    return windows, win, hop

def overlap_add(chunks, win, hop):
    out = np.zeros(hop*(len(chunks)-1)+win, dtype=chunks[0].dtype)
    window = np.hanning(win)
    for idx, c in enumerate(chunks):
        i = idx*hop
        out[i:i+win] += c[:win] * window
    return out

				
			

Наблюдаемость/метрики/алерты

Метрики (Prometheus‑стиль):

  • RTF_enh: enh_rtf{mode=rt|batch}t_proc / t_audio. Цель p95 < 0.7 для интерактива.
  • TTFA_enh: enh_ttfa_seconds{mode=rt} — время до первого аудиофрейма (p95 ≤ 0.3 с).
  • Latency: enh_latency_seconds{phase=aec|beamform|denoise|dereverb|separation|post} (p50/p95).
  • Quality: enh_pesq, enh_stoi, enh_sisdr, enh_snri.
  • Stability: enh_jitter_ms, enh_buffer_underrun_total, enh_drop_rate.
  • GPU: enh_gpu_utilization, enh_gpu_memory_bytes, enh_gpu_mem_peak_bytes.
  • I/O: enh_nvme_read_mb_s, enh_nvme_write_mb_s, hit‑rate кэша.

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

  • enh_ttfa_p95 > 0.5s — увеличить ring‑buffer, уменьшить stream_chunk_ms, включить подогрев модели.
  • enh_rtf_p95 > 0.8 — деградация; снизить силу эффектов/частоту дискретизации/сложность сепарации.
  • enh_sisdr_p50 < 8 dB или enh_snri_p50 < 5 dB — качество ниже целевого; пересобрать профиль/модель.
  • gpu_mem_peak / HBM > 0.9 — уменьшить размер блоков, включить offload, снизить число параллельных потоков.

Подробнее: https://cloudcompute.ru/solutions/monitoring-logging/https://cloudcompute.ru/solutions/llm-inference/observability/

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

Обозначения: c_gpu — цена GPU/час, U — целевая загрузка, RTF_enht_proc / t_audio, RTF_sep — на каждого спикера.

  • Сколько GPU для стриминга:
    GPU_count = ceil( (Σ (RTF_enh + N_speakers×RTF_sep) ) / U )
    Пример: 8 потоков, RTF_enh=0.35, RTF_sep=0.25, N=2, U=0.7
    ceil( 8×(0.35+0.5)/0.7 ) = ceil( 8×0.85/0.7 ) = ceil(9.71) = 10 GPU.
  • Стоимость минуты аудио:
    Cost_per_min = (c_gpu × (RTF_enh + N_speakers×RTF_sep) / U) / 60.
  • Батчи (время партии):
    T_batch ≈ ( (RTF_enh + N_speakers×RTF_sep) × L_audio_total ) / (GPU_count × U ).

Оптимизация расходов: микс профилей (24/48/80 ГБ) под разную сложность, offload тяжелых стадий, батчирование и кэширование. См. https://cloudcompute.ru/solutions/cost-planner/ и https://cloudcompute.ru/solutions/throughput-vs-latency/

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

  • PII/биометрия: логируйте только агрегаты/метрики; не храните сырые дорожки без необходимости.
  • Ретеншн: временные WAV/чанки/спектры — авто‑очистка по TTL; артефакты — на NVMe.
  • Ключи/токены: только Secret‑хранилища/переменные окружения; ротация.
  • Изоляция: раздельные GPU‑пулы по тенантам/профилям; доступ к бакетам по ролям.
  • Потоки/стримы: защита каналов, ограничение доступа к «референс‑треку» для AEC.

См. также: https://cloudcompute.ru/solutions/security/https://cloudcompute.ru/solutions/storage-data/

Траблшутинг

Симптом

Возможная причина

Решение

«Металл/пампинг» после denoise

Слишком агрессивные маски/низкий SR

Снизить strength, повысить SR до 24 кГц, мягкий пост‑фильтр

Щелчки/швы между блоками

Несогласованные границы блоков

Кросс‑фейд 5–10 мс, увеличить pad_ms, корректный overlap‑add

Высокий TTFA

Ленивая инициализация

Подогрев моделей, увеличить ring‑buffer, уменьшить stream_chunk_ms

RTF_enh ≈ 1 и выше

Перегрузка GPU/включена сепарация

FP16/BF16, отключить HQ‑dereverb, уменьшить N спикеров или добавить GPU

Плохая разборчивость (низкий STOI)

Удаление полезной речи с шумом

Снизить силу denoise, донастройка VAD/beamforming

Эхо не уходит

Нет/неверный AEC ref

Подключить правильный reference, увеличить tail_ms

Дубли/фантомы в разделении

Недостаточный контекст/плохой merge

Увеличить окно, улучшить post‑merge, калибровать модели

VRAM OOM

Большие блоки/много потоков

Уменьшить размер блоков, включить offload, разделить сервисы по пулам

Underruns в стриме

Низкий буфер/нет backpressure

Ring‑buffer 300–500 мс, контроль скорости выдачи, закрепление потоков

См. также: https://cloudcompute.ru/solutions/interruptible-patterns/https://cloudcompute.ru/solutions/performance-tuning/

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

  1. Откройте Шаблоны запусков: https://cloudcompute.ru/solutions/templates/
    Выберите Speech Enhancement (Real‑time) или Speech Enhancement (Batch).
  2. Выберите профиль GPU: 24/48/80 ГБ — в зависимости от включенных стадий (dereverb/separation) и SLA.
  3. Подключите диски: /nvme/models, /nvme/enh-cache; для батчей — /mnt/audio-in, /mnt/audio-out.
  4. Настройте переменные окружения по docker-compose.yml (AEC/beamforming, сила denoise/dereverb, включение separation, частоты).
  5. Для продакшна: автоскейл по U/RTF, раздельные пулы low‑latency и HQ, мониторинг/алерты и канареечный деплой.

Дополнительно:
https://cloudcompute.ru/solutions/triton-inference-server/ — сервинг через Triton/ONNX/TensorRT.
https://cloudcompute.ru/solutions/gradio-fastapi/ — быстрый UI/эндпойнты/демо.
https://cloudcompute.ru/solutions/containers-ci-cd/ — сборка и выкладка.

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

  • Замерены TTFA_enh p50/p95, RTF_enh/RTF_sep p50/p95, jitter.
  • Определены целевые PESQ/STOI/SI‑SDR/SNRi и проверки качества на корпусе.
  • Выбран профиль GPU, запас по U ≥ 0.2; протестирован автоскейл.
  • NVMe‑кэш подключен; настроен overlap‑add и merge без швов.
  • Настроены алерты по TTFA/RTF/HBM/underruns/quality.
  • Политики PII/ретеншна внедрены; логи без сырого аудио.
  • Interruptible‑джобы идемпотентны; чанк ≤ 120 с; ретраи.
  • Нагрузочный прогон ≥ 30 мин с целевыми p95.