Полнофункциональное решение для автоматической аннотации телефонных разговоров в контейнере 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.