ГлавнаяБлог → Как повысить точность распознавания речи: восемь рабочих приёмов

Как повысить точность распознавания речи: восемь рабочих приёмов

Опубликовано 2026-08-18 · 7 мин чтения

«Распознаёт плохо» — это не диагноз. Почти в каждом реальном случае проблема качества сводится к одной из нескольких конкретных причин, и большинство из них устраняются на вашей стороне, ещё до того как звук ушёл с сервера. Вот они — в том порядке, в котором их стоит пробовать.

Сначала измерьте, а не гадайте

Без числа любое изменение — вопрос вкуса. Возьмите 20–30 записей, похожих на ваш реальный поток, выпишите, что было сказано на самом деле, и посчитайте долю ошибок: замены плюс пропуски плюс вставки, делённые на число произнесённых слов.

pip install jiwer
from jiwer import wer

score = wer(reference_text, recognised_text)
print(f"WER: {score:.1%}")

Две вещи важнее самого значения. Во-первых, измеряйте на своём звуке, а не на публичном бенчмарке. Во-вторых, взвешивайте по тому, что вам нужно: если бизнесу важны номера заказов, 5% ошибок со сплошь перевранными цифрами — провал, а 15% с чистыми цифрами — успех.

Приём 1. Дайте модели чистый звук

Модели распознавания работают внутри с моно 16 кГц. Всё, что выше, отбрасывается, всё, что ниже, потеряно навсегда:

ffmpeg -i input.wav -ac 1 -ar 16000 -b:a 64k clean.mp3

Агрессивное шумоподавление — то самое исключение, которое обычно вредит: жёсткие фильтры съедают согласные, и распознавание становится хуже, а не лучше. Шум разумнее лечить на микрофоне.

Приём 2. Скажите, какой это язык

Автоопределение почти не ошибается на длинных записях и заметно чаще промахивается на трёхсекундных. Если поток заведомо одноязычный, так и скажите:

r = client.audio.transcriptions.create(
    model="whisper-1", file=f, language="ru",
)

Это убирает целый класс сбоев, когда короткая фраза опознаётся как другой язык и возвращается бессмыслицей. Заодно обработка чуть ускоряется — проход определения языка пропускается.

Приём 3. Передайте свой словарь через prompt

Самый ценный параметр — и самый часто забываемый. prompt не появляется в ответе, он смещает распознавание в сторону перечисленных слов:

r = client.audio.transcriptions.create(
    model="whisper-1", file=f,
    prompt="Продукты: Кестрел, Кестрел Про, Хокнест. Менеджеры: Дуарте, Иванова, Скворцова.",
)

Держите подсказку короткой и конкретной. Список из 20–40 реально встречающихся терминов работает, абзац общих описаний — нет. Меняйте список под контекст: очередь обращений по счетам требует других слов, чем очередь по оборудованию.

Подсказка передаёт ещё и стиль. Если вам нужны расшифровки с пунктуацией и заглавными буквами, напишите подсказку правильно оформленным предложением — модель склонна продолжать в том стиле, который ей задали.

Приём 4. Вырежьте тишину

Длинные молчаливые куски — источник «галлюцинаций»: распознавать нечего, и модель способна выдать пустой текст-заполнитель. Они же стоят денег, потому что оплата идёт за минуты аудио.

ffmpeg -i input.mp3 -af silenceremove=start_periods=1:stop_periods=-1:stop_duration=2:stop_threshold=-45dB out.mp3

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

Приём 5. Режьте по паузам, а не по часам

Длинные записи всё равно приходится резать, чтобы уложиться в 25 МБ. Важно, где именно проходит разрез: граница посреди предложения съедает слова с обеих сторон.

# ищем паузы вместо резки по фиксированной минуте
ffmpeg -i long.mp3 -af silencedetect=noise=-40dB:d=0.7 -f null - 2> pauses.txt

Найденные паузы используйте как кандидаты на точки разреза, а куски держите в диапазоне 5–20 минут. Более короткие теряют контекст на стыках, заметно более длинные не дают выигрыша.

Приём 6. Запрашивайте формат, который несёт уверенность

verbose_json возвращает не только текст, но и сегменты, и определённый язык с вероятностью. Это сырьё для автоматического контроля качества:

r = client.audio.transcriptions.create(
    model="whisper-1", file=f, response_format="verbose_json",
)

if r.language_probability < 0.6:
    queue_for_review(r)          # подозрительная запись — посмотреть глазами

Отправка сомнительных нескольких процентов на ручную проверку поднимает качество всего конвейера гораздо дешевле, чем попытки выжать последний процент из самого распознавания.

Приём 7. Правьте текст, а не распознавайте заново

Часть ошибок систематична: одно и то же название продукта каждый раз перевирается одинаково. Словарь замен чинит это одной строкой и ничего не стоит:

FIXES = {"кастрел": "Кестрел", "хок нест": "Хокнест"}

for wrong, right in FIXES.items():
    text = text.replace(wrong, right)

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

Приём 8. Ловите пустой и выдуманный вывод

Два сценария стоит обрабатывать в коде явно: пустой результат и результат, подозрительно похожий на шаблонную фразу. Фильтры «галлюцинаций» отсекают классику вроде титров и благодарностей за просмотр, поэтому пустая строка честно означает, что речи не было.

text = r.text.strip()
if not text:
    return None            # тишина, а не ошибка — повторять не нужно

Повторная отправка пустой записи только тратит минуты. Запишите в журнал, пропустите, идите дальше.

Что не поможет

Попробуйте на своих записях. Регистрация занимает минуту, бесплатных минут хватает, чтобы оценить качество.

Получить ключ бесплатно

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

Какой доли ошибок ожидать?

На чистой речи в хорошо поддержанном языке нормой считаются единицы процентов. Телефонный звук, шум, перебивания и сильный акцент поднимают её. Измеряйте на своих записях: публичный бенчмарк ничего не говорит о вашем потоке.

Параметр prompt действительно что-то меняет?

Да, и это самое дешёвое улучшение из доступных. Короткий список имён, продуктов и кодов, встречающихся в вашем аудио, заметно снижает ошибки ровно на тех словах, которые важнее всего.

Указывать язык или доверить автоопределению?

Указывайте, когда поток одноязычный, особенно на коротких записях. Оставляйте автоопределение, если сообщения действительно приходят на разных языках.

Стоит ли чистить шум перед отправкой?

Лёгкая нормализация помогает, агрессивное шумоподавление обычно вредит, потому что портит согласные. Если шум сильный, дешевле починить условия записи, чем подбирать фильтр.

Какого размера делать куски длинной записи?

От пяти до двадцати минут, с разрезами по паузам, а не по фиксированным интервалам. Так предложения остаются целыми, а запрос укладывается в лимит 25 МБ.

Читайте также