Чанкинг аудио для STT: Silero VAD, диаризация, overlap | Гайд 2026 | AiManual
AiManual Logo Ai / Manual.
14 Мар 2026 Гайд

Методы чанкинга для STT: как разбивать длинные аудио без потери точности транскрипции

Как разбивать длинные аудиофайлы для распознавания речи. Практическое руководство по чанкингу с Silero VAD, диаризацией и перекрывающимися чанками. Примеры кода

Почему ваш STT падает на длинных аудио и как это исправить

Вы загружаете часовую запись совещания в Whisper или Parakeet Multitalk и получаете мешанину из слов. Или модель просто выдает ошибку памяти. Знакомо? Это не баг, это фича всех современных STT-моделей. У них есть ограничение контекста — обычно от 10 до 30 секунд.

Просто резать файл на равные 30-секундные куски — самый быстрый путь к катастрофе. Слова обрываются на полуслове, контекст теряется, имена собственные превращаются в абракадабру. Точность падает на 15-40% в зависимости от аудио.

Как НЕ делать: никогда не используйте np.array_split() для аудио. Вы получите чанки, которые режут слова пополам. Модель не поймет «ин-вести-ции» и превратит это в «инвестиции» (что, впрочем, иногда и правильно).

Метод 1: Silero VAD — режем по тишине

Детектор речевой активности — ваш лучший друг. Он находит моменты, когда люди действительно говорят, и режет там. Silero VAD (актуальная версия 4.0 на март 2026) работает локально, быстро и на удивление точно даже в шумных условиях.

import torch
import numpy as np
from silero_vad import load_silero_vad, get_speech_timestamps

def chunk_by_silero_vad(audio_numpy, sample_rate=16000):
    """Разбивает аудио по речевым сегментам."""
    model = load_silero_vad()  # Загружаем последнюю версию
    timestamps = get_speech_timestamps(
        audio_numpy,
        model,
        sampling_rate=sample_rate,
        threshold=0.5,  # Чувствительность
        min_speech_duration_ms=300,
        min_silence_duration_ms=500
    )
    
    chunks = []
    for ts in timestamps:
        start = int(ts['start'] / sample_rate * 1000)  # в мс
        end = int(ts['end'] / sample_rate * 1000)
        chunk = audio_numpy[ts['start']:ts['end']]
        chunks.append((chunk, start, end))
    return chunks

Почему это работает? Потому что естественная речь состоит из пауз. Даже самый болтливый менеджер делает вдох. VAD ловит эти моменты и создает чанки, которые соответствуют речевым фразам, а не произвольным временным интервалам.

1 Настройка порога чувствительности

Самая частая ошибка — оставить threshold=0.5 для всех сценариев. В шумном кафе повышайте до 0.7. Для студийной записи можно 0.3. Проверяйте визуально:

# Визуализация чанков
import matplotlib.pyplot as plt

def plot_chunks(audio, chunks):
    plt.figure(figsize=(12, 4))
    plt.plot(audio, alpha=0.5)
    for chunk, start, end in chunks:
        plt.axvspan(start, end, alpha=0.3, color='red')
    plt.show()

Метод 2: Диаризация — когда говорят несколько человек

Если в аудио несколько голосов, VAD не поможет. Он создаст один длинный чанк, где два человека перебивают друг друга. Нужна диаризация — разделение по говорящим. Здесь все сложно. Классический pyannote.audio (который в 2026 году сломан на перекрывающейся речи), но есть альтернативы.

# Используем SpeechBrain для диаризации (актуально на 2026)
from speechbrain.inference import SpeakerRecognition
from speechbrain.inference import SepformerSeparation as Separator
import torchaudio

def diarize_chunks(audio_path):
    # Загружаем модель разделения речи
    separator = Separator.from_hparams(
        source="speechbrain/sepformer-wsj02mix",
        savedir="tmp"
    )
    # Разделяем каналы если есть
    est_sources = separator.separate_file(audio_path)
    # Дальше кластеризация по голосам
    # (Это упрощенный пример, реальный код на 30 строк дольше)
    return separated_chunks

Диаризация жрет ресурсы как не в себя. На час аудио может уйти 30 минут на GPU. Но для расшифровки интервью или судебных заседаний — это единственный способ.

💡
Если у вас медицинские записи с несколькими врачами, посмотрите исследование 26 STT-моделей на медицинских диалогах. Там есть специфика по терминам и перекрытиям.

Метод 3: Overlap chunking — перекрываемся для контекста

Самый элегантный метод. Мы режем аудио на чанки с перекрытием (overlap). Например, чанк 30 секунд, overlap 5 секунд. Почему? Потому что контекст. Слово, которое попало на стык, будет обработано дважды, и модель сможет использовать контекст из предыдущего чанка.

def overlap_chunk(audio_numpy, sample_rate, chunk_duration_sec=30, overlap_sec=5):
    """Создает перекрывающиеся чанки."""
    chunk_samples = chunk_duration_sec * sample_rate
    overlap_samples = overlap_sec * sample_rate
    step_samples = chunk_samples - overlap_samples
    
    chunks = []
    for start in range(0, len(audio_numpy), step_samples):
        end = start + chunk_samples
        chunk = audio_numpy[start:end]
        if len(chunk) < chunk_samples * 0.5:  # Пропускаем слишком маленькие обрезки
            continue
        chunks.append({
            'audio': chunk,
            'start_ms': int(start / sample_rate * 1000),
            'end_ms': int(min(end, len(audio_numpy)) / sample_rate * 1000)
        })
    return chunks

После транскрипции нужно склеить результаты, убрав дублирующиеся перекрывающиеся части. Это отдельная задача, но решаемая.

Метод Точность Скорость Когда использовать
Silero VAD Высокая (если паузы есть) Быстрая Монологи, лекции, подкасты
Диаризация Средняя (зависит от модели) Очень медленная Интервью, совещания, диалоги
Overlap chunking Высокая Быстрая Любое длинное аудио, где важна связность

Собираем пайплайн: от аудио до текста

Теперь соединим все вместе. Идеальный пайплайн для 2026 года выглядит так:

1 Предобработка аудио

Приводим все к 16 кГц, моно. Убираем шум простым фильтром, если нужно.

import librosa
def preprocess_audio(file_path):
    audio, sr = librosa.load(file_path, sr=16000, mono=True)
    # Простой noise reduction (спектральное вычитание)
    from scipy import signal
    # ... код шумоподавления
    return audio, sr

2 Адаптивный выбор метода чанкинга

Определяем, есть ли несколько голосов. Если да — диаризация + overlap. Если нет — VAD.

def detect_speaker_count(audio, sr):
    """Простая оценка количества говорящих через спектральные особенности."""
    # Используем кепстральный анализ
    # Если находим резкие изменения в характеристиках — несколько голосов
    return count

3 Транскрипция чанков

Подаем каждый чанк в STT-модель. Лучше использовать локальные модели, если конфиденциальность важна. Как выбрать? Читайте полный гайд по выбору STT-модели в 2025 (актуально и для 2026).

from transformers import pipeline
# Используем актуальную на 2026 модель, например, Whisper-large-v4
stt = pipeline("automatic-speech-recognition",
               model="openai/whisper-large-v4",
               device="cuda")

def transcribe_chunks(chunks):
    transcripts = []
    for chunk in chunks:
        result = stt(chunk['audio'])
        transcripts.append({
            'text': result['text'],
            'start': chunk['start_ms'],
            'end': chunk['end_ms']
        })
    return transcripts

4 Склейка и постобработка

Убираем дубли из overlap, соединяем тексты, добавляем пунктуацию (если модель не сделала).

Что сломается и как избежать

  • Тишина в студии. VAD может не найти пауз и создать один чанк на 2 часа. Решение: принудительно резать каждые 60 секунд, если сегмент речи длиннее порога.
  • Фоновый шум. Гул кондиционера принимается за речь. Повышайте порог VAD до 0.6-0.7.
  • Перекрывающаяся речь. Два человека говорят одновременно. Диаризация падает. Здесь поможет только специальная обработка перекрытий.
  • Разные языки в одном аудио. STT-модель нужно переключать. Детектируйте язык каждые 10 секунд.

Частые вопросы

Какой overlap оптимальный?

5-10% от длины чанка. Для 30-секундных чанков overlap 2-3 секунды. Меньше — рискуете потерять контекст, больше — удваиваете работу.

Можно ли комбинировать VAD и overlap?

Да, и это даст лучший результат. Сначала режем по VAD, затем если чанк длиннее 30 секунд, применяем overlap внутри него.

Какая STT-модель лучше для чанкованного аудио?

Модели с большим контекстом (Whisper, Parakeet) справляются лучше. Но если вы работаете с медицинскими или юридическими текстами, смотрите специализированные сравнения.

Что будет дальше?

К 2027 году STT-модели научатся обрабатывать контекст в несколько часов без чанкинга. Но пока мы застряли в эпохе патчей. Мой совет: не экономьте на overlap. Лучше потратить лишние 10% вычислений, чем потом вручную склеивать обрывки фраз. И проверяйте чанки визуально — иногда простой график спасет вас от часов отладки.

Если делаете автосекретаря, посмотрите как собрать систему с субсекундной задержкой. Там чанкинг нужен, но совсем другой.

Подписаться на канал