Решения

Диааризация на GPU: метрики и пайплайны

Задача страницы. Инженерный гид по построению диааризации (кто говорил и когда) на GPU: real‑time для звонков/совещаний и батч‑диааризация архивов, поддержка перекрывающейся речи (OSD), оценка качества (DER/JER), экономическая модель и операционные метрики. Ориентир: локальный NVMe‑кэш, режимы On‑Demand и Interruptible, контейнеризация и стриминг (SSE/WebSocket), интеграция с ASR/энхансментом.

TL;DR

  • Режимы:
    • On‑Demand (реал‑тайм): слайдинг‑окна, онлайн‑кластеризация, OSD; буфер 200–500 мс, минимальная задержка.
    • Interruptible (батчи): сегментация→эмбеддинги→кластеризация (AHC/VBx/PLDA)→ресегментация→отчёты.
  • Пайплайн: AEC/денойз (опц.) → VAD → сегментация (win/hop) → эмбеддинги спикера (GPU)кластеризация → [OSD/ресегментация] → пост‑процесс → JSON/RTTM.
  • Метрики качества: DER = Miss + False Alarm + Confusion; JER; параметры оценки: collar (обычно 0.2–0.5 с), учёт overlap.
  • Ключевые латентные/производственные метрики: RTF_diar, TTFA_diar, p50/p95 latency, speaker‑turn latency, overlap coverage, GPU util/HBM.
  • Экономика: Cost_per_min = (c_gpu × RTF_diar / U) / 60; RTF_diar ≈ RTF_vad + RTF_embed + RTF_cluster + RTF_osd.
  • Тюнинг: FP16/BF16 для эмбеддеров, pinned/zero‑copy, кэш сегментов/эмбеддингов на NVMe, микробатчинг в батче. См. https://cloudcompute.ru/solutions/performance-tuning/, https://cloudcompute.ru/solutions/fp8-bf16/, https://cloudcompute.ru/solutions/throughput-vs-latency/
  • Интеграции: ASR (слова + спикеры), энхансмент/сепарация до эмбеддингов. См. https://cloudcompute.ru/solutions/asr-whisper/, https://cloudcompute.ru/solutions/speech-enhancement/

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

  • Колл‑центры/контроль качества: кто говорит, длительность, перерывания, перекрытия, доли времени по ролям.
  • Совещания/протоколы: автоматическая расклейка реплик по спикерам, интеграция с ASR и саблайнами.
  • Медиа/архивы: батч‑диааризация выпусков/подкастов/лекций, подготовка для поиска по спикерам.
  • Комплаенс/безопасность: контроль один‑на‑один/много участников, детект перекрытий и «фоновых» голосов.
  • Предобработчик пайплайнов: улучшение точности ASR/VC/TTS за счёт чистых спикерских интервалов.

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

1) Реал‑тайм диааризация (низкая латентность, SSE/WebSocket)

				
					Audio In (Mic/WebRTC/RTSP)
  └─> [Optional] AEC/Denoise  ─┐
       └─> VAD (pad 100–200 ms) ├─> Segmenter (win 1.5 s, hop 0.5 s)
                                 └─> GPU: Speaker Embedder (FP16/BF16)
                                      └─> Online Clustering (centroid/adapt PLDA)
                                           └─> OSD (overlap speech detect)
                                                └─> Post (hysteresis/smoothing)
                                                     └─> Stream Out (SSE/WebSocket JSON)


				
			

Особенности: speaker‑turn latency управляется длиной окна/хопа и сглаживанием; OSD для разметки одновременных спикеров; бэктрек‑коррекции в пределах 1–2 окон.

2) Батч‑диааризация (качество, отчётность)

				
					Object Storage ─┬─> Preprocess (resample, enh)
                 ├─> Segmentation (win/hop, VAD thresholds)
                 ├─> GPU Embeddings (batch)
                 ├─> Clustering (AHC/VBx/PLDA thresholds)
                 ├─> Resegmentation (Viterbi/HMM, overlap handling)
                 └─> Writer (RTTM/JSON, per‑speaker WAV)
                      └─> Metrics (DER/JER) + QA reports
				
			

Особенности: overlapped‑aware ресегментация; параметризация порогов под домен; отчёты DER/JER по корпусам.

3) ASR + Диааризация (слово‑точные подписи спикеров)

				
					Clean Audio ─> Diarization (segments) ─┬─> ASR (words + ts)
                                       └─> Alignment Mapper
                                            └─> Speaker‑labeled words (JSON/SRT/VTT)


				
			

Интеграция с ASR‑гайдом: https://cloudcompute.ru/solutions/asr-whisper/

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

Одновременные real‑time потоки при U≈0.7, win=1.5 с/hop=0.5 с, OSD включён. Для батчей масштабируйте по «Экономике».

Профиль GPU

Память

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

Real‑time потоки*

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

Комментарии

24 ГБ (Compact)

24 ГБ

VAD + эмбеддер (ECAPA/SSL‑класс) + онлайн‑кластер

3–8

6–16

Базовый контакт‑центр/митинги, моно 16–24 кГц.

48 ГБ (Balanced)

48 ГБ

Усиленные эмбеддеры + OSD + ресегментация

8–16

16–32

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

80 ГБ (HQ)

80 ГБ

Мультиканал/beamforming + OSD HQ + VBx

16–32

32–64

Сложные домены/перекрытия, длинные сессии.

* Зависит от частоты/канальности, доли перекрытий, сложности OSD/ресегментации и I/O.
Тюнинг и профилировка: https://cloudcompute.ru/solutions/performance-tuning/, https://cloudcompute.ru/solutions/throughput-vs-latency/, https://cloudcompute.ru/solutions/fp8-bf16/

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

Docker Compose (real‑time + batch)

				
					version: "3.9"

x-common-env: &env
  MODELS_DIR: /models
  CACHE_DIR: /var/cache/diar
  SAMPLE_RATE: "16000"
  FRAME_MS: "20"
  EMBED_PRECISION: "fp16"      # bf16|fp16
  WIN_S: "1.5"
  HOP_S: "0.5"
  VAD_THRESHOLD: "0.6"
  OSD_ENABLE: "true"
  CLUSTER_METHOD: "online"     # online|ahc|vbx
  CLUSTER_THRESHOLD: "0.35"

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

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


				
			

K8s (скелет, 1 GPU/под)

				
					apiVersion: apps/v1
kind: Deployment
metadata:
  name: diar-realtime
spec:
  replicas: 2
  selector: { matchLabels: { app: diar-realtime } }
  template:
    metadata:
      labels: { app: diar-realtime }
    spec:
      containers:
        - name: diar
          image: cloudcompute/diarization:latest
          ports: [{ containerPort: 8040 }]
          env:
            - { name: EMBED_PRECISION, value: "fp16" }
            - { name: WIN_S, value: "1.5" }
            - { name: HOP_S, value: "0.5" }
            - { name: OSD_ENABLE, value: "true" }
          volumeMounts:
            - { name: models, mountPath: /models }
            - { name: cache,  mountPath: /var/cache/diar }
          resources:
            limits:
              nvidia.com/gpu: 1
              memory: "24Gi"
              cpu: "4"
      volumes:
        - name: models
          hostPath: { path: /nvme/models }
        - name: cache
          hostPath: { path: /nvme/diar-cache }


				
			

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

				
					pipeline:
  input:
    sample_rate: 16000
    channels: 1
  preprocess:
    denoise: false
    aec: false
  vad:
    threshold: 0.6
    pad_ms: 150
  segmentation:
    win_s: 1.5
    hop_s: 0.5
    min_speech_s: 0.3
    min_silence_s: 0.2
  embeddings:
    model: "ecapa_like"      # или ssl_spk_like
    precision: "fp16"
    l2_normalize: true
    batch_size: 128          # для батча
  osd:
    enabled: true
    overlap_min_s: 0.2
  clustering:
    method: "vbx"            # online|ahc|vbx
    threshold: 0.35
    max_speakers: 8
  resegmentation:
    enabled: true
    hysteresis_ms: 200
    smoothing_ms: 150
  output:
    formats: [json, rttm]

				
			

FastAPI: стриминг спикерских смен (SSE)

				
					from fastapi import FastAPI
from sse_starlette.sse import EventSourceResponse
import json, asyncio

app = FastAPI()

async def diar_stream(audio_iter):
    async for turn in online_diarize(audio_iter):
        # turn: {"spk":"SPEAKER_01","ts_start":12.34,"ts_end":13.80,"overlap":["SPEAKER_02"]}
        yield json.dumps(turn)

@app.post("/diar/stream")
async def diar_stream_endpoint():
    async def event_gen():
        async for evt in diar_stream(audio_source()):
            yield {"event": "turn", "data": evt}
        yield {"event": "done", "data": "{}"}
    return EventSourceResponse(event_gen())


				
			

Ресегментация и сглаживание (псевдокод)

				
					def smooth_and_hysteresis(segments, hys_ms=200, smooth_ms=150):
    # объединяет короткие "микро-реплики" и стабилизирует границы
    ...

def overlap_infer(segments, osd_events):
    # помечает перекрывающуюся речь на основе OSD
    ...

def finalize(segments):
    segments = smooth_and_hysteresis(segments)
    segments = overlap_infer(segments, osd_events=[])
    return segments


				
			

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

Latency/Perf:

  • diar_ttfa_seconds{mode=rt} — время до первой разметки (p95 ≤ 0.3–0.5 с).
  • diar_rtft_proc / t_audio (real‑time цель p95 < 0.7).
  • diar_turn_latency_seconds — задержка реакции на смену спикера.
  • diar_gpu_utilization, diar_gpu_mem_peak_bytes, diar_nvme_read_mb_s.

Quality:

  • diar_der (общий/по сессиям), diar_jer, diar_miss, diar_fa, diar_confusion.
  • diar_overlap_coverage — доля корректно размеченной перекрывающейся речи.
  • diar_speakers_estimate_error — ошибка оценки числа спикеров.

Ops:

  • diar_segments_count, diar_avg_segment_len, diar_cluster_switch_rate.
  • Версионирование: diar_model_version, diar_threshold_profile.

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

  • diar_der_p95 > target — калибровать пороги/ресегментацию, улучшить VAD/OSD/денойз (см. https://cloudcompute.ru/solutions/speech-enhancement/).
  • diar_turn_latency_p95 > SLA — уменьшить hop_s, увеличить буфер, упростить OSD.
  • gpu_mem_peak/HBM > 0.9 — уменьшить batch/окна, FP16/BF16, разделить сервисы.

Дополнительно: https://cloudcompute.ru/solutions/monitoring-logging/https://cloudcompute.ru/solutions/llm-inference/observability/

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

Обозначения: c_gpu — цена/час, U — целевая загрузка GPU, RTF_diar = t_proc / t_audio.

  • Сколько GPU для онлайна:
    GPU_count = ceil( (Σ RTF_diar_streams) / U ).
  • Стоимость минуты аудио:
    Cost_per_min = (c_gpu × RTF_diar / U) / 60.
  • Декомпозиция RTF:
    RTF_diar ≈ RTF_vad + RTF_embed + RTF_cluster + RTF_osd (+ RTF_preproc).
  • Батчи (время партии):
    T_batch ≈ (RTF_diar × L_audio_total) / (GPU_count × U).

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

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

  • Биометрия/PII: спикер‑эмбеддинги — чувствительные данные; хранение с шифрованием «на диске» и «в канале», доступ по ролям.
  • Минимизация: храните эмбеддинги и метки, сырое аудио — по строгому TTL; логи без аудио.
  • Версионирование: фиксируйте версии эмбеддера/кластера/порогов в метаданных.
  • Изоляция: раздельные GPU‑пулы и бакеты по тенантам/регионам; контроль копирования/экспорта.

Подробнее: https://cloudcompute.ru/solutions/security/https://cloudcompute.ru/solutions/storage-data/

Траблшутинг

Симптом

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

Решение

Завышенный DER за счёт Miss

Жёсткий VAD/слишком длинный hop

Понизить VAD_THRESHOLD, уменьшить hop_s, включить ресегментацию

Много False Alarm

Шум/эхо/нет энхансмента

Включить денойз/AEC, поднять VAD_THRESHOLD, добавить пост‑фильтры

Частые «дребезги» спикеров

Нет гистерезиса/слишком мелкие окна

hysteresis_ms ≥ 150–250, win_s ≥ 1.5, сглаживание границ

Путает спикеров (Confusion)

Слабые эмбеддинги/порог кластера

Усиленный эмбеддер, тюнинг CLUSTER_THRESHOLD, VBx/PLDA

Плохая работа на overlap

OSD отключён/порог высок

Включить OSD, калибровать overlap_min_s, использовать overlap‑aware ресег

Высокая turn‑latency

Крупный hop/буфер

Уменьшить hop_s до 0.25–0.5 с, баланс с качеством/RTF

VRAM OOM

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

FP16/BF16, уменьшить batch, разделить сервисы по пулам

Нестабильный DER между релизами

Дрифт моделей/порогов

Версионирование, канареечный деплой, контрольные корпуса/пороговые тесты

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

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

  1. Откройте Шаблоны запусков: https://cloudcompute.ru/solutions/templates/
    Выберите Diarization (Real‑time) или Diarization (Batch).
  2. Профиль GPU: 24/48/80 ГБ — по частоте/перекрытиям/канальности и SLA.
  3. Диски/кэш: смонтируйте /nvme/models, /nvme/diar-cache; для батчей — /mnt/audio и /mnt/labels.
  4. Настройте параметры пайплайна по docker-compose.yml: WIN_S/HOP_S, VAD_THRESHOLD, CLUSTER_METHOD/THRESHOLD, OSD/ресегментация.
  5. Для продакшна: автоскейл по U/RTF/queue, дашборды и алерты (DER/JER/turn‑latency/GPU HBM), канареечный деплой.

Дополнительно:
https://cloudcompute.ru/solutions/asr-whisper/ — слово‑точные подписи по спикерам.
https://cloudcompute.ru/solutions/speech-enhancement/ — очистка аудио перед эмбеддингами.
https://cloudcompute.ru/solutions/triton-inference-server/ — сервинг моделей.
https://cloudcompute.ru/solutions/gradio-fastapi/ — быстрые эндпойнты/демо.
https://cloudcompute.ru/solutions/containers-ci-cd/ — сборка/выкладка.

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

  • Замерены TTFA_diar p50/p95, RTF_diar p50/p95, turn‑latency.
  • Целевые DER/JER достигнуты на контрольном корпусе; пороги зафиксированы.
  • Включён OSD и overlap‑aware ресегментация при необходимости.
  • Выбран профиль GPU (24/48/80 ГБ) с запасом по U ≥ 0.2.
  • NVMe‑кэш и каталоги примонтированы; прогрев эмбеддеров.
  • Настроены алерты: DER/JER/turn‑latency/GPU HBM/queue length.
  • Политики PII/биометрии и ретеншна внедрены; шифрование и роли.
  • Interruptible‑джобы идемпотентны; чанк ≤ 120 с; ретраи.
  • Нагрузочный прогон ≥ 30 мин на целевом профиле с реальными звонками.

Навигация