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

Сравнение GigaAM v3 и Whisper на процессоре

Первое, что нужно решить — какую модель распознавания речи использовать. Whisper от OpenAI — популярный выбор, но на CPU он может быть медленным и требовательным к памяти. GigaAM v3 — российская разработка, оптимизированная для работы на слабом железе. В ходе тестов на одном ядре GigaAM v3 показала сравнимую точность на русскоязычных записях при меньшем времени обработки. Whisper же лучше справляется с шумными записями и акцентами, но требует больше ресурсов.

Критерии выбора:

  • Язык: для русского GigaAM v3 часто точнее и быстрее.
  • Ресурсы: если сервер слабый, GigaAM v3 предпочтительнее.
  • Шум: Whisper устойчивее к фоновому шуму.
  • Размер модели: GigaAM v3 имеет компактные версии, что важно для ограниченной памяти.

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

Нарезка длинных записей по паузам без отдельной модели

Длинные аудио (например, подкасты или кружки) нельзя подавать в модель целиком — это переполнит память и замедлит обработку. Вместо использования отдельной модели для детекции голосовой активности (VAD) можно применить простой алгоритм нарезки по паузам. Суть в том, чтобы анализировать амплитуду сигнала и находить участки тишины длительностью более 300–500 мс. Эти участки становятся границами сегментов.

Шаги реализации:

  • Разбить аудио на фреймы по 20–30 мс.
  • Вычислить энергию каждого фрейма.
  • Определить порог тишины (например, ниже 10% от максимальной энергии).
  • Найти последовательности фреймов тишины длиннее заданного порога.
  • Нарезать аудио по серединам этих пауз.

Такой подход не требует дополнительных моделей и работает быстро. Главное — не нарезать слишком короткие сегменты (менее 1 секунды), иначе модель будет часто ошибаться.

Круговая очередь для справедливой обработки

Когда бот обрабатывает несколько запросов одновременно, важно, чтобы короткое голосовое сообщение не ждало в очереди за длинным подкастом. Решение — круговая очередь (round-robin). Вместо того чтобы обрабатывать задачи в порядке поступления, бот выделяет каждому пользователю квант времени (например, 10 секунд) и переключается между задачами. Это гарантирует, что все пользователи получат ответ примерно за одинаковое время.

Реализация на одном ядре:

  • Использовать асинхронный цикл с переключением контекста.
  • Хранить очередь активных задач.
  • По таймеру прерывать текущую задачу и переходить к следующей.
  • Сохранять состояние каждой задачи (например, текущую позицию в аудио).

Важно правильно выбрать квант времени: слишком маленький увеличит накладные расходы, слишком большой приведёт к задержкам для коротких записей. Оптимально — 5–15 секунд.

Свой сервер Bot API для файлов до 2 ГБ

Стандартный Telegram Bot API имеет ограничение на размер файла — 20 МБ для скачивания. Для голосовых сообщений этого обычно достаточно, но если нужно обрабатывать длинные аудио, придётся поднять собственный сервер Bot API. Это позволяет принимать файлы до 2 ГБ. Процесс установки описан в документации Telegram, но есть нюансы: требуется выделенный сервер с достаточным диском и настроенный SSL.

Шаги:

  • Арендовать VPS с 2 ГБ RAM и 20 ГБ диска.
  • Установить Docker и запустить контейнер с Bot API.
  • Настроить Nginx как reverse proxy с SSL-сертификатом.
  • Указать в боте URL вашего сервера вместо api.telegram.org.

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

В итоге, комбинируя GigaAM v3, нарезку по паузам, круговую очередь и собственный Bot API, можно построить эффективного бота для расшифровки голосовых на одном ядре. Код проекта открыт, что позволяет адаптировать его под свои нужды.