Skip to content

Conversation

@slavonnet
Copy link

Добавлена поддержка мультиканальной транскрибации с диаризацией

Описание

Добавлена функциональность для транскрибации мультиканального аудио с автоматической диаризацией (разделением по каналам/спикерам). Метод корректно обрабатывает перекрывающуюся речь и сортирует результаты по времени, обеспечивая правильное чередование реплик между каналами.

Разделение спикеров по каналам (или отдельным аудио файлам) применяется в колл-центрах, чтобы не терять качество разбора когда обе стороны высказываются одновременно.

Основные изменения

Новые функции и методы

  1. GigaAMASR.transcribe_multichannel() — метод для транскрибации мультиканального аудио

    • Поддерживает стерео/многоканальные файлы или список отдельных файлов
    • Автоматическая сегментация с использованием VAD (pyannote.audio)
    • Батчинг для эффективной обработки
    • Результаты сортируются по времени и чередуются между каналами
  2. load_multichannel_audio() в preprocess.py — загрузка мультиканального аудио

    • Поддержка стерео/многоканальных файлов (через torchaudio)
    • Поддержка списка отдельных моно файлов
    • Автоматическое выравнивание длин каналов
  3. segment_multichannel_audio() в vad_utils.py — сегментация мультиканального аудио

    • VAD сегментация для каждого канала
    • Группировка сегментов по каналам с учетом пауз
    • Объединение сегментов с ограничением по длительности для модели
    • Оптимизированная работа с GPU (тензоры обрабатываются в памяти)

Тесты

Добавлен файл tests/test_multichannel.py с тестами:

  • Транскрибация стерео файла, созданного из моно
  • Транскрибация списка отдельных файлов
  • Проверка правильности идентификации каналов
  • Проверка сортировки результатов по времени

Документация

  • Обновлены README.md и README_ru.md с примерами использования мультиканальной транскрибации

Технические детали

Алгоритм работы

  1. Загрузка аудио: Загружаются все каналы (из одного файла или списка файлов)
  2. VAD сегментация: Для каждого канала применяется VAD модель для обнаружения речевых сегментов
  3. Группировка: Сегменты группируются по каналам с учетом пауз (pause_threshold)
  4. Сортировка: Все сегменты сортируются по времени начала (global_start, затем start_time)
  5. Объединение: Сегменты одного канала объединяются в окна до strict_limit_duration
  6. Транскрибация: Сегменты обрабатываются батчами независимо от канала
  7. Результат: Возвращается список с информацией о канале, транскрипции и временных границах

Оптимизации

  • Все операции с аудио выполняются на GPU в памяти (без сохранения на диск)
  • Эффективная работа с тензорами (клонирование сегментов для освобождения памяти)
  • Батчинг для ускорения обработки модели
  • Использование itertools.groupby и map для функционального стиля обработки

Ограничения

  • Требуется установка pyannote.audio и токен Hugging Face для доступа к модели VAD
  • Максимальная длительность сегмента для модели: 30 секунд (настраивается через strict_limit_duration)

Примеры использования

import gigaam
import os

# Настройка токена для pyannote.audio
os.environ["HF_TOKEN"] = "<ваш HF токен>"

# Загрузка модели
model = gigaam.load_model("v3_e2e_rnnt")

# Вариант 1: Стерео файл
results = model.transcribe_multichannel("conversation_stereo.wav")

# Вариант 2: Список отдельных файлов
results = model.transcribe_multichannel(
    ["channel_0.wav", "channel_1.wav"],
    batch_size=4,
    pause_threshold=2.0,
    strict_limit_duration=30.0
)

# Вывод результатов
for seg in results:
    channel = seg["channel"]
    transcription = seg["transcription"]
    start, end = seg["boundaries"]
    print(f"[{start:.2f}s - {end:.2f}s] Канал {channel}: {transcription}")

Совместимость

  • ✅ Все существующие методы остались без изменений
  • ✅ Базовые функции проекта не изменены
  • ✅ Обратная совместимость сохранена
  • ✅ Все существующие тесты проходят

Файлы изменений

  • gigaam/model.py — добавлен метод transcribe_multichannel()
  • gigaam/preprocess.py — добавлена функция load_multichannel_audio()
  • gigaam/vad_utils.py — добавлена функция segment_multichannel_audio()
  • gigaam/__init__.py — экспорт новых функций
  • tests/test_multichannel.py — новые тесты
  • README.md, README_ru.md — обновлена документация

Тестирование

Все тесты проходят успешно:

pytest tests/test_multichannel.py -v
# 4 passed

Зависимости

Требуется установка дополнительных зависимостей для мультиканальной транскрибации:

pip install pyannote.audio huggingface_hub

…ic diarization (channel/speaker separation). The method correctly processes overlapping speech and sorts the results by time, ensuring the correct alternation of cues between channels.
@slavonnet
Copy link
Author

Test 194 секунды разговора колл центра. 2 моно файла по для каждой стороны.

RTX 5060 Ti 16Gb,
Win11,
Core i7 Gen3

Результаты:
Загрузка аудио: 0.01s
VAD сегментация: 0.95s (68 маленьких сегментов)
Объединение сегментов: 0.003s (26 финальных сегментов)
Транскрибация: 11.29s
Общее время: 12.73s

Узкие места:
Декодирование (6.44s) занимает ~61% времени транскрибации

…=160, win_length=320, window=torch.cuda.FloatTensor{[320]}, normalized=0, onesided=1, return_complex=1, align_to_window=None) : expected 0 < n_fft < 270, but got n_fft=320
@slavonnet
Copy link
Author

slavonnet commented Jan 14, 2026

При запуске на коллекции звонков за год в одном месте ошибка проскочила, исправил что размер аулио в батче не может быть меньше 320

@slavonnet
Copy link
Author

slavonnet commented Jan 22, 2026

я так использую

def do_process(t, r):
    try:
        with torch.no_grad():
            results = model.transcribe_multichannel(
                [t, r],  # Список файлов: [агент, клиент]
                batch_size=4,
                pause_threshold=0.5,
                strict_limit_duration=30.0

хирый хак есть чтобы когда два канала одновременно говорят правильно раскидывало и сортировало результат -pause_threshold за это отвечает.
Как бы долепляет хвост к тому каналу который первый начал говорить до срабатывания pause_threshold.
Тем самым нет проблемы что по одному слову на канал левый и правый проскакивает и результат читаем как адекватный диалог

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant