Полнофункциональное решение для автоматической аннотации телефонных разговоров в контейнере Docker под python:3.11-slim-bullseye.
CallAnnotate предоставляет разработчикам и системным администраторам гибкий серверный компонент с WebSocket и REST/JSON API, способный асинхронно обрабатывать аудиозаписи любой длительности и сложности, используя ресурсы CPU или при необходимости GPU.
- Требуемая версия Python: 3.11
- Docker-образ на базе python:3.11-slim-bullseye CallAnnotate создаёт лёгкий и безопасный контейнер, готовый к развёртыванию на любых серверах и облачных платформах, поддерживающих Docker.
- Универсальные интерфейсы API
- WebSocket позволяет устанавливать постоянное соединение для потоковой передачи аудио и мгновенного получения результатов.
- REST/JSON интерфейс предназначен для пакетной обработки задач: отправьте запрос с файлом, получите полную аннотацию в ответе.
- Асинхронная архитектура обработки Все задачи помещаются в очередь и обрабатываются асинхронно, что исключает блокировку сервера. CallAnnotate может распределять нагрузку между ядрами CPU и, при наличии поддерживаемого оборудования, GPU-ускорителем.
- Этапная архитектура обработки аудио (preprocess → diarization → transcription → recognition → carddav)
- Предобработка аудио (SoX, RNNoise, DeepFilterNet)
- Диаризация говорящих Алгоритмы выделения сегментов аудио автоматически распознают смены говорящих, разделяют файл на спикер-ориентированные блоки и сохраняют таймкоды каждого участка.
- Распознавание известных голосов Согласно конфигурации контейнера, CallAnnotate загружает заранее сформированные голосовые эмбеддинги и сопоставляет их с поступающими фрагментами. Это позволяет автоматически отмечать в аннотации имена участников, чьи голоса уже известны системе.
- Идентификация новых записей через CardDAV При встрече незнакомого голоса CallAnnotate выполняет запросы к CardDAV-серверу, чтобы найти совпадения по контактам пользователя. Если совпадений не обнаружено, система аккуратно помечает фрагмент как «неизвестный спикер».
- Транскрипция с многослойной разметкой Используя современные движки ASR, CallAnnotate переводит аудио в текст и структурирует результат по уровням (схоже с системой ELAN):
- отдельное слово и его начало/конец
- предложения и абзацы
- метки спикеров
- Готовая аннотация в одном JSON По окончании обработки API возвращает полный объём метаданных:
- сегментация по спикерам и таймкоды
- идентификаторы и имена найденных голосов
- ссылки на источники эмбеддингов
- транскрипция с выделением уровней
- при необходимости — URL для скачивания аудиофрагментов
В config/default.yaml в разделе preprocess:
preprocess: model: "DeepFilterNet2" device: "cpu" chunk_duration: 2.0 overlap: 0.5 target_rms: -20.0 Этап transcription осуществляет пакетную транскрипцию аудио с помощью OpenAI Whisper.
Конфигурация этапа в config/default.yaml:
transcription: model: "openai/whisper-small" \# размер модели Whisper device: "cpu" \# вычислительное устройство language: "ru" \# язык транскрипции ("auto" — автоопределение) batch_size: 16 \# размер пакета фрагментов task: "transcribe" \# "transcribe" или "translate" curl -X POST http://localhost:8000/api/v1/jobs \ -F "file=@recording.wav" При получении результата через GET /api/v1/jobs/{job_id}/result возвращается JSON, содержащий, среди прочего, поле transcription:
"transcription": { "full_text": "[speaker_01]: Здравствуйте!\n[speaker_02]: Привет!", "confidence": 0.93, "language": "ru", "segments": [ { "start": 0.000, "end": 3.500, "text": "Здравствуйте!", "speaker": "speaker_01", "speaker_confidence": 1.000, "no_speech_prob": 0.001, "avg_logprob": -0.25 } ], "words": [ { "start": 0.000, "end": 0.500, "word": "Здравствуйте!", "probability": 0.98, "speaker": "speaker_01" } ] } - preprocess
- diarization
- transcription
- recognition
- carddav
Проект распространяется под лицензией Apache License 2.0. Подробности — в файлах LICENSE и NOTICE.