Перевод голосовых сообщений в текст — задача, с которой сталкивается каждый, кто ведёт 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, можно построить эффективного бота для расшифровки голосовых на одном ядре. Код проекта открыт, что позволяет адаптировать его под свои нужды.