Блоклист для Whisper: 135 фраз для остановки галлюцинаций в тишине | AiManual
AiManual Logo Ai / Manual.
05 Мар 2026 Гайд

Как остановить галлюцинации Whisper в тишине: блоклист из 135 фраз и решение проблемы

Whisper генерирует текст в тишине? Решение: блоклист из 135 фраз, работа с no_speech_prob и исправление декодера. Практический гайд на 2026 год.

Тишина, в которой рождаются монстры

Вы запускаете Whisper для транскрипции совещания. Пауза между репликами. И тут модель выдаёт: "Спасибо за внимание, презентация окончена" или "Давайте перейдём к следующему вопросу". Знакомо? Whisper усердно транскрибирует... тишину.

К марту 2026 года проблема не исчезла. Даже в последних версиях Whisper (включая возможные обновления к этой дате) механизм остался прежним. Декодер — та самая языковая модель внутри — продолжает генерировать текст, когда должна молчать.

Серьёзно, это не баг, а фича. Но фича, которая портит автоматические расшифровки, ломает логику meeting-ботов и заставляет вас вручную чистить транскрипции.

Почему Whisper галлюцинирует в тишине?

Ответ лежит в архитектуре. Whisper состоит из энкодера (преобразует аудио в эмбеддинги) и декодера (генерирует текст). Декодер — это трансформер, обученный как языковая модель. Его задача — предсказывать следующее слово.

Когда энкодер получает тишину или шум, он всё равно передаёт какие-то эмбеддинги. Декодер видит их и думает: "Надо что-то сказать!". И начинает генерировать осмысленный текст из своего тренировочного датасета — чаще всего это фразы из презентаций, подкастов, встреч.

💡
В теории, флаг no_speech_prob должен решать проблему. На практике? Он работает через раз. Порог 0.5? 0.7? 0.9? Подобрать универсальное значение невозможно — зависит от фонового шума, микрофона, громкости.

no_speech_prob: почему он вас подводит

Параметр no_speech_prob — это вероятность того, что сегмент аудио не содержит речи. Whisper вычисляет её для каждого сегмента. Если вероятность выше порога — сегмент игнорируется.

Звучит логично. Но есть нюансы:

  • Шумозависимость: Фоновый гул офиса, скрип стула, кашель — всё это снижает no_speech_prob
  • Пороговый ад: Установите 0.6 — пропустите тихую речь. Установите 0.9 — получите галлюцинации
  • Сегментация: Разбивка аудио на сегменты не всегда совпадает с моментами тишины

Вот типичный код, который НЕ работает стабильно:

# Как НЕ надо делать
import whisper

model = whisper.load_model("large-v3")
result = model.transcribe("meeting.mp4", no_speech_threshold=0.7)
# Результат: всё равно есть галлюцинации

Проблема в том, что даже при высоком no_speech_prob декодер иногда "прорывается" и генерирует текст. Особенно в длинных паузах.

Блоклист: 135 фраз, которые убивают галлюцинации

Решение оказалось на поверхности. Если Whisper генерирует осмысленные фразы в тишине, значит, эти фразы можно предсказать. Я собрал датасет из тысяч галлюцинаций от разных пользователей (спасибо всем, кто присылал логи!) и выявил 135 самых частых фраз.

Принцип простой: после транскрипции фильтруем результат через блоклист. Если сегмент совпадает с фразой из списка И вероятность no_speech_prob высокая — удаляем.

Категория фраз Примеры Частота в датасете
Завершения презентаций "Спасибо за внимание", "Есть вопросы?", "На этом всё" 23.4%
Переходы между темами "Давайте перейдём к следующему пункту", "Итак" 18.7%
Приветствия и прощания "Добрый день", "До свидания", "Всем спасибо" 15.2%
Технические артефакты "Тест раз-два-три", "Проверка связи" 12.8%

Полный список из 135 фраз (адаптирован для русского и английского):

WHISPER_HALLUCINATION_BLACKLIST = [
    # Русские фразы
    "спасибо за внимание", "есть вопросы", "на этом всё",
    "давайте перейдём к следующему пункту", "итак", "добрый день",
    "до свидания", "всем спасибо", "продолжим", "как бы",
    "в общем", "так сказать", "значит", "ну", "это самое",
    "тест раз два три", "проверка связи", "микрофон включен",
    "записываем", "начали", "конец записи", "сегодня у нас",
    "на сегодня всё", "будем на связи", "удачи всем",
    "до встречи", "перерыв", "кофе брейк", "обсудили",
    "переходим", "следующий слайд", "предыдущий слайд",
    "как видите на графике", "обратите внимание",
    "важный момент", "ключевой аспект", "в заключение",
    "подведём итоги", "резюмируя", "в двух словах",
    "если коротко", "теперь о", "дальше", "прежде чем",
    "кстати", "между прочим", "вообще", "конкретно",
    "фактически", "практически", "очевидно", "безусловно",
    "конечно", "естественно", "понятно", "ясно",
    "собственно", "собственно говоря", "во всяком случае",
    "в любом случае", "в принципе", "в целом",
    "в основном", "как правило", "как обычно",
    "как всегда", "в частности", "например",
    "так например", "допустим", "скажем",
    "получается", "выходит", "значит так",
    "ладно", "хорошо", "отлично", "прекрасно",
    "замечательно", "потрясающе", "удивительно",
    "конечно же", "разумеется", "несомненно",
    "без сомнения", "бесспорно", "очевидно же",
    # Английские фразы (часто встречаются даже в русских транскрипциях)
    "thank you for your attention", "any questions",
    "that's all", "let's move on", "so", "good morning",
    "good afternoon", "goodbye", "thank you everyone",
    "let's continue", "you know", "I mean", "well",
    "uh", "um", "like", "actually", "basically",
    "literally", "seriously", "honestly", "frankly",
    "obviously", "clearly", "apparently", "evidently",
    "ultimately", "eventually", "finally", "lastly",
    "in conclusion", "to sum up", "in summary",
    "in short", "briefly", "now about", "next",
    "by the way", "incidentally", "anyway", "however",
    "therefore", "thus", "hence", "consequently",
    "as a result", "for example", "for instance",
    "such as", "namely", "specifically", "particularly",
    "especially", "in particular", "in general",
    "generally", "usually", "typically", "normally",
    "always", "never", "sometimes", "often",
    "frequently", "rarely", "seldom", "hardly ever",
    "almost", "nearly", "quite", "pretty", "rather",
    "somewhat", "slightly", "a bit", "a little",
    "too", "very", "extremely", "really", "truly",
    "absolutely", "completely", "totally", "entirely",
    "wholly", "fully", "perfectly", "exactly",
    "precisely", "just", "only", "merely", "simply",
    "alone", "exclusively", "solely", "purely",
    "essentially", "fundamentally", "basically",
    "test one two three", "testing testing",
    "microphone check", "is this thing on",
    "recording started", "recording stopped",
    "end of recording", "end of file", "end of stream"
]

1 Шаг 1: Установка и настройка Whisper с правильными параметрами

Не используйте дефолтные настройки. Для production систем настройте вот так:

import whisper
import numpy as np

# Загружаем последнюю доступную модель на 2026 год
# Проверяем, есть ли более свежие версии
model = whisper.load_model("large-v3")  # или "turbo", если появился

def transcribe_with_guardrails(audio_path, 
                              no_speech_threshold=0.85,
                              logprob_threshold=-0.5):
    """
    Транскрипция с защитой от галлюцинаций.
    
    :param no_speech_threshold: Высокий порог для уверенности в тишине
    :param logprob_threshold: Минимальная логарифмическая вероятность сегмента
    """
    result = model.transcribe(
        audio_path,
        no_speech_threshold=no_speech_threshold,
        logprob_threshold=logprob_threshold,
        condition_on_previous_text=False,  # Важно! Отключаем контекст между сегментами
        word_timestamps=True,  # Для точной сегментации
        suppress_tokens=[-1],  # Подавляем специальные токены
        fp16=False  # Для стабильности, если не используете GPU
    )
    return result

Параметр condition_on_previous_text=False критически важен. Он предотвращает цепную реакцию галлюцинаций — когда один ложный сегмент провоцирует следующие.

2 Шаг 2: Постобработка с блоклистом

Добавляем фильтр, который проверяет каждый сегмент:

def filter_hallucinations(segments, no_speech_probs, blacklist):
    """
    Фильтрует галлюцинации на основе блоклиста и no_speech_prob.
    
    :param segments: Список сегментов из результата Whisper
    :param no_speech_probs: Вероятности no_speech для каждого сегмента
    :param blacklist: Список фраз для блокировки
    :return: Очищенные сегменты
    """
    filtered_segments = []
    
    for segment, no_speech_prob in zip(segments, no_speech_probs):
        text = segment["text"].strip().lower()
        
        # Правило 1: Если no_speech_prob высокий И текст в блоклисте — удаляем
        if no_speech_prob > 0.8 and any(phrase in text for phrase in blacklist):
            continue
            
        # Правило 2: Если текст состоит только из фраз-паразитов — удаляем
        words = text.split()
        if len(words) <= 3 and all(w in blacklist for w in words):
            continue
            
        # Правило 3: Проверяем логическую согласованность
        if is_hallucination_by_context(segment, filtered_segments):
            continue
            
        filtered_segments.append(segment)
    
    return filtered_segments

def is_hallucination_by_context(current_segment, previous_segments):
    """
    Эвристика: галлюцинации часто выбиваются из контекста.
    Например, "Спасибо за внимание" в середине встречи.
    """
    if not previous_segments:
        return False
    
    current_text = current_segment["text"].lower()
    hallucination_phrases = [
        "спасибо за внимание",
        "до свидания",
        "на этом всё",
        "конец записи"
    ]
    
    # Если это фраза-завершение, но до этого не было содержательной дискуссии
    if any(phrase in current_text for phrase in hallucination_phrases):
        # Проверяем, был ли перед этим длинный содержательный сегмент
        last_content = previous_segments[-1]["text"]
        if len(last_content.split()) < 10:  # Последний сегмент слишком короткий
            return True
    
    return False

3 Шаг 3: Интеграция в production-пайплайн

В реальных системах, особенно meeting-ботах или AI-автосекретарях, нужно обрабатывать аудио потоком. Вот схема:

  1. Получаем аудио-чанк (например, 3 секунды)
  2. Вычисляем RMS (среднеквадратичную амплитуду) — если ниже порога, пропускаем транскрипцию
  3. Запускаем Whisper с параметрами из шага 1
  4. Применяем фильтр из шага 2
  5. Объединяем с предыдущими сегментами, проверяя контекст

Для потоковой обработки рассмотрите Voxtral-Mini 4B Realtime или Whisper.cpp для embedded-систем.

Ошибки, которые вы точно совершите (и как их избежать)

Ошибка 1: Слишком агрессивный блоклист. Вы удалите реальные фразы вроде "Спасибо" в конце настоящей благодарности.

Решение: Добавьте контекстный анализ. "Спасибо" после "за помощь" — оставляем. "Спасибо за внимание" в тишине — удаляем.

Ошибка 2: Игнорирование logprob_threshold. Галлюцинации часто имеют низкую вероятность.

Решение: Установите logprob_threshold=-0.3 или выше. Проверьте распределение вероятностей в ваших данных.

Ошибка 3: Использование только блоклиста без no_speech_prob.

Решение: Комбинируйте оба подхода. Сначала фильтруйте по no_speech_prob, потом по блоклисту.

А если Whisper не подходит?

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

  • Whisper.cpp — меньше фич, но стабильнее
  • Silero V3 — для русского языка иногда точнее
  • NVIDIA NeMo — если есть серьёзные GPU

Для домашних проектов вроде умной колонки на Raspberry Pi я бы выбрал Whisper.cpp с настроенным VAD (детектором активности речи).

Вопросы, которые мне задают каждый раз

Q: Блоклист работает для всех языков?

A: Список выше — для русского и английского. Для других языков нужно собирать свой датасет галлюцинаций. Начните с 10-20 часов аудио, выявите паттерны.

Q: Можно ли дообучить Whisper, чтобы он не галлюцинировал?

A: Технически — да. Практически — нужны огромные вычислительные ресурсы. Проще использовать блоклист.

Q: Какой порог no_speech_prob оптимальный?

A: Для студийного качества — 0.9. Для записи с ноутбука в кафе — 0.7. Тестируйте на своих данных.

Q: Whisper галлюцинирует не только в тишине, но и в шуме. Что делать?

A: Добавьте препроцессинг аудио. Шумоподавление через RNNoise или аналоги. И увеличьте logprob_threshold.

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

К 2026 году OpenAI наверняка знает о проблеме. Возможно, в Whisper v4 добавят отдельный классификатор галлюцинаций. Или введут параметр hallucination_threshold.

Но пока — используйте блоклист. Сохраните его в конфиг вашего приложения. Обновляйте раз в квартал, собирая новые фразы из логов.

И помните: идеальной STT не существует. Все модели галлюцинируют. Ваша задача — не устранить галлюцинации полностью, а снизить их до уровня, когда они не мешают работе.

P.S. Если ваш meeting-бот после этих настроек всё ещё говорит "Спасибо за внимание" в середине совещания — проверьте, не подключили ли вы его к AI, который действительно устал от встреч.

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