Расшифровка звонков на своём сервере через Whisper
В архиве отдела продаж лежат тысячи звонков, и переслушать их вручную нереально: аналитик физически не успеет прогнать даже неделю записей, а руководителю нужны цифры по всем менеджерам сразу. Первое, что приходит в голову — облачный сервис транскрибации: залил файл, через минуту получил текст. Проблема в том, что в этом файле — голос клиента, его имя, номер телефона, иногда паспортные данные или платёжные реквизиты, и всё это уходит на чужой сервер за пределами вашего контроля, часто ещё и за рубеж. Для колл-центра, работающего с персональными данными по 152-ФЗ, это уже не техническая деталь, а юридический риск. Решение — распознавание речи моделью Whisper прямо на своём сервере: записи не покидают инфраструктуру, а расшифровка встраивается в тот же процесс, что уже обрабатывает звонки.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Что такое Whisper и почему он подходит для расшифровки звонков
Whisper — модель распознавания речи, которую OpenAI выложила с открытыми весами ещё в 2022 году и с тех пор не переставала развивать: актуальная линейка large-v3 и её ускоренный вариант turbo уверенно держат русский язык, включая разговорную речь с перебивами, паузами-хезитациями и фоновым шумом колл-центра. Открытый вес — ключевое отличие от API-сервисов транскрибации: модель скачивается один раз и дальше работает офлайн, без единого исходящего запроса к третьей стороне. Для звонков это снимает сразу два вопроса — куда уходят записи клиентов и что будет, если провайдер транскрибации однажды поднимет цены или закроет API.
Второй практический плюс — Whisper не требует видеокарты. Оригинальная реализация OpenAI и её производные (о них ниже) прекрасно работают на CPU, пусть и медленнее GPU-инференса. Для отдела, которому нужно расшифровывать записи не в реальном времени, а пакетно — раз в сутки или раз в неделю прогонять накопившиеся звонки — обычный VPS без GPU полностью закрывает задачу, и это заметно дешевле сервера с видеокартой.
Стоит сразу разделить ожидания: Whisper — это распознавание речи в текст, а не готовая аналитика звонков. Разметку по темам, оценку менеджера, поиск ключевых фраз придётся строить поверх текста отдельно — но сам текст, полученный локально, уже можно безопасно скормить любому инструменту анализа, включая LLM на том же сервере.
Установка Whisper на VPS: faster-whisper или whisper.cpp
У задачи расшифровки звонков на CPU есть два практичных пути, и оригинальную реализацию OpenAI (пакет openai-whisper) для продакшена брать не стоит — она медленнее обеих альтернатив и не оптимизирована под инференс без GPU.
faster-whisper — переписанная реализация на движке CTranslate2. На CPU она даёт заметный выигрыш по скорости и памяти по сравнению с оригиналом за счёт квантования и более эффективного рантайма. Это разумный выбор по умолчанию для сервера с несколькими ядрами и от 4 ГБ RAM. Ставится через pip, зависимость — ffmpeg для чтения аудио и видеоформатов:
sudo apt update && sudo apt install -y ffmpeg python3-pip
pip install faster-whisper
whisper.cpp — реализация на чистом C/C++ без Python и тяжёлых зависимостей вроде PyTorch. Подходит для лёгких серверов с 1–2 vCPU и ограниченной памятью, где каждый мегабайт на счету, а также если вы предпочитаете единственный бинарник без виртуального окружения Python:
git clone https://github.com/ggerganov/whisper.cpp
cd whisper.cpp
cmake -B build && cmake --build build --config Release -j
./models/download-ggml-model.sh medium
Для сервера, который уже крутит скрипты на Python — CRM-интеграции, обработку файлов, — faster-whisper обычно удобнее: он встраивается в код одной строкой импорта. Для минимального выделенного инстанса под одну задачу whisper.cpp экономичнее по ресурсам. Разница между ними подробно разобрана в отдельном сравнении faster-whisper против whisper.cpp.
Под сам процесс расшифровки звонков достаточно обычного VPS без видеокарты — 4 vCPU и 8 ГБ RAM с запасом хватает на пакетную обработку записей в фоне, а оплатить его из России можно картой российского банка, через СБП или криптовалютой, без иностранной карты и посредников.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Развернуть WhisperКакую модель Whisper выбрать под задачу
Whisper поставляется в нескольких размерах, и выбор — это всегда компромисс между скоростью и точностью распознавания:
| Модель | Параметры | Для чего годится |
|---|---|---|
| tiny | 39M | Черновая расшифровка, поиск по ключевым словам, где ошибки не критичны |
| base | 74M | Быстрый прогон больших объёмов, тестовые прогоны перед выбором модели побольше |
| small | 244M | Разумный баланс для повседневных звонков среднего качества записи |
| medium | 769M | Рабочая лошадка для колл-центра — заметно точнее small, ещё терпимо по скорости на CPU |
| large-v3 / turbo | ~1550M | Максимальная точность, сложные записи с акцентами, наложением речи, шумом |
Честно: large точнее, но на CPU заметно медленнее — на процессорном инференсе разница в скорости между small и large может быть кратной, а не процентной. Конкретные цифры скорости и требуемой памяти сильно зависят от процессора сервера, длины записи и качества исходного звука, поэтому ориентируйтесь не на чужие бенчмарки, а на собственный тестовый прогон нескольких реальных звонков перед тем, как ставить модель в постоянную обработку. Как минимум для звонков через IP-телефонию с частым сжатием и шумом лучше не экономить и брать medium как стартовую точку, поднимаясь до large только если точности не хватает. Сколько именно памяти требует каждая модель — отдельно разобрано в материале сколько RAM нужно для Whisper по моделям.
Практический запуск: от одного файла до пакетной обработки
Расшифровка одной записи через faster-whisper — несколько строк на Python:
from faster_whisper import WhisperModel
model = WhisperModel("medium", device="cpu", compute_type="int8")
segments, info = model.transcribe("call_001.wav", language="ru")
for segment in segments:
print(f"[{segment.start:.1f}s -> {segment.end:.1f}s] {segment.text}")
compute_type="int8" здесь не опция для галочки — это квантование модели, которое на CPU ощутимо ускоряет инференс ценой небольшой просадки точности. Для звонков, где важнее общий смысл разговора, а не дословная стенограмма под протокол, это разумный размен.
На whisper.cpp тот же файл расшифровывается одной командой из терминала:
./build/bin/whisper-cli -m models/ggml-medium.bin -f call_001.wav -l ru -otxt
Флаг -otxt сохраняет результат рядом с исходным файлом как call_001.wav.txt.
Дальше — пакетная обработка папки, куда падают звонки после смены. Простой скрипт на Python обходит директорию и расшифровывает всё новое:
import os
from pathlib import Path
from faster_whisper import WhisperModel
CALLS_DIR = Path("/data/calls/incoming")
DONE_DIR = Path("/data/calls/transcribed")
model = WhisperModel("medium", device="cpu", compute_type="int8")
for audio_file in CALLS_DIR.glob("*.wav"):
segments, info = model.transcribe(str(audio_file), language="ru")
text = "\n".join(f"[{s.start:.1f}s] {s.text.strip()}" for s in segments)
out_path = DONE_DIR / f"{audio_file.stem}.txt"
out_path.write_text(text, encoding="utf-8")
audio_file.rename(DONE_DIR / audio_file.name)
print("Готово, обработано файлов:", len(list(DONE_DIR.glob('*.txt'))))
Запускать такой скрипт по расписанию через cron — рабочий вариант для небольшого объёма. Для десятков и сотен звонков в день имеет смысл держать модель в памяти постоянно и обрабатывать очередь файлов сервисом, а не перезапускать процесс на каждый файл — загрузка модели в память занимает заметное время, и на больших объёмах это существенная экономия.
Таймкоды и разделение по спикерам
Таймкоды faster-whisper отдаёт из коробки — они видны в примерах выше: каждый сегмент несёт start и end в секундах, и этого достаточно, чтобы позже прыгать по аудио к нужному месту в разговоре или подсвечивать конкретную фразу в интерфейсе прослушивания.
А вот разделение «кто говорит — менеджер или клиент» Whisper из коробки не делает — это отдельная задача, которая называется диаризацией, и решается другим инструментом поверх результата распознавания. Самый распространённый вариант — библиотека pyannote.audio: она размечает аудио на сегменты по спикерам («speaker 1», «speaker 2»), а дальше эти метки сопоставляются по таймкодам с текстом от Whisper. Стоит сказать честно: диаризация сложнее и капризнее базового распознавания речи — точность разделения сильно зависит от качества записи, перекрытия голосов и того, разведены ли собеседники по разным аудиоканалам. Если звонок записан в два канала — отдельно менеджер, отдельно клиент, как это часто настроено в IP-телефонии, — задача сильно упрощается: можно просто прогнать оба канала через Whisper по отдельности и не связываться с диаризацией вообще. Если запись одноканальная (моно), pyannote.audio — рабочий, но более трудоёмкий в настройке путь, требующий отдельного токена Hugging Face и собственной модели, которую тоже стоит гонять локально по тем же соображениям приватности.
Автоматизация: расшифровка звонков в n8n
Ручной запуск скрипта работает, пока звонков немного. Как только расшифровка становится ежедневной рутиной, её стоит встроить в автоматизацию. n8n — открытый инструмент no-code автоматизации, который тоже можно развернуть на своём сервере рядом с Whisper, и он умеет реагировать на появление нового файла в папке или на вебхук от АТС.
Типичный workflow выглядит так: триггер отслеживает папку с записями (или получает вебхук из системы телефонии сразу после завершения звонка) → нода Execute Command запускает скрипт расшифровки на Python или бинарник whisper.cpp → результат сохраняется в базу или отправляется в CRM карточкой к звонку → при необходимости текст дополнительно прогоняется через LLM на том же сервере для короткого саммари разговора. Всё это остаётся внутри одной инфраструктуры — запись, расшифровка и анализ ни разу не покидают сервер.
Пример ноды Execute Command в n8n, вызывающей скрипт пакетной обработки:
python3 /opt/whisper/transcribe_batch.py --input /data/calls/incoming --output /data/calls/transcribed
Дальше нода n8n читает получившийся .txt, добавляет его текстом в поле CRM через HTTP-запрос к её API — и на этом цепочка «звонок положили на диск → текст появился в карточке клиента» замыкается без единого ручного действия. Подробно процесс установки n8n и первые workflow разобраны в материале как поднять n8n для AI-автоматизаций на сервере, а готовый пример именно транскрибации через HTTP-эндпоинт — в статье как поднять API транскрибации звонков на сервере.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Развернуть WhisperОбсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Частые вопросы
Нужна ли видеокарта для расшифровки звонков через Whisper?
Нет, для пакетной обработки записей в фоновом режиме достаточно обычного VPS с несколькими ядрами CPU. GPU ускоряет инференс, но для задачи «расшифровать звонки за прошедшие сутки» это не обязательное условие — выигрыш по времени есть, но окупает дополнительные расходы на видеокарту не всегда.
Можно ли обрабатывать записи в реальном времени, прямо во время звонка?
Технически да, но это отдельная и более сложная задача потокового распознавания с собственными настройками буферизации и задержки. Материал выше рассчитан на пакетную расшифровку уже завершённых записей — самый частый сценарий для анализа звонков постфактум.
Whisper действительно ничего не отправляет в интернет?
Сама модель после загрузки весов работает полностью офлайн и не делает исходящих запросов на серверы OpenAI. Единственное исключение — если вы сами добавляете шаг с внешним API, например для перевода текста или дополнительного анализа. Для задачи именно распознавания речи весь процесс замкнут на вашем сервере.
Как повысить точность на записях с плохим качеством связи?
Помогает переход на модель побольше (medium вместо small, large вместо medium) и предварительная нормализация громкости через ffmpeg перед подачей в Whisper. Универсального решения нет — качество исходной записи задаёт потолок точности сильнее, чем выбор модели, и точные цифры улучшения индивидуальны для каждого набора звонков.
Нужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.