Хранилище и модели¶
Страница для тех, кто настраивает сервер: где лежат записи звонков, как подключить S3, как устроен забор файлов из бакета, какая модель распознаёт речь и сколько памяти и процессора ей нужно.
Где хранится звук¶
За хранение отвечает одна переменная STORAGE_KIND. Тексты, оценки и настройки лежат в PostgreSQL независимо от неё.
local (по умолчанию) |
s3 |
|
|---|---|---|
| Где лежат файлы | том Docker audio-data, внутри контейнера tgt-api каталог /data/audio |
бакет S3-совместимого хранилища |
| Ключ файла | ГГГГ/ММ/ДД/<uuid>.<расширение> |
<S3_UPLOAD_PREFIX>ГГГГ/ММ/ДД/<uuid>.<расширение> |
| Что в резервной копии | нужна копия тома audio-data |
звук уже вне сервера, включите версионирование бакета, если провайдер даёт |
| Занимает диск сервера | да, растёт с числом записей | нет, только временные файлы загрузки |
Дата в ключе указана по UTC, имя файла остаётся только в базе. Какой вид хранилища работает сейчас, видно в «Настройки → Система → Технические сведения → Хранилище аудио».
Внимание
Смена STORAGE_KIND не переносит файлы. Записи, оставшиеся на локальном диске, потеряют звук и сохранят расшифровки. Переключайте вид хранилища до появления настоящих данных или когда текущие записи уже расшифрованы.
Загружаемый файл сначала попадает во временную папку контейнера tgt-api и затем переносится в хранилище; файлы, которые так и не были перенесены, удаляются при запуске API, если старше суток. Файлы, скачиваемые по ссылке, пишутся в хранилище потоком.
Подключение S3¶
- Создайте бакет и ключ доступа у провайдера (или добавьте MinIO сервисом Coolify). Ключу нужны права
s3:ListBucketна бакет иs3:GetObject,s3:PutObject,s3:AbortMultipartUploadиs3:DeleteObjectна объекты. Для префикса, из которого файлы только забираются, достаточно чтения: забранные файлы платформа никогда не меняет и не удаляет. - В переменных окружения задайте
STORAGE_KIND=s3,S3_BUCKET,S3_ACCESS_KEY_IDиS3_SECRET_ACCESS_KEY. Провайдеру, отличному от AWS, нужны ещёS3_ENDPOINT_URLиS3_REGION(например, для Yandex Object Storage этоhttps://storage.yandexcloud.netиru-central1). Для AWS адрес не нужен, нужен настоящий регион иS3_FORCE_PATH_STYLE=false; MinIO и большинство других провайдеров работают со значением по умолчаниюtrue. - Чтобы платформа забирала файлы, которые кладёт в бакет кто-то другой, задайте ещё
INGESTION_SOURCE=s3иS3_INGEST_PREFIX(папка видаcalls/; пусто означает весь бакет, кромеS3_UPLOAD_PREFIX). Префиксы не должны пересекаться:S3_INGEST_PREFIXне может лежать внутриS3_UPLOAD_PREFIX, иначе сервер не запустится. - Перезапустите приложение. Проверьте, что «Хранилище аудио» показывает «S3» и что загруженный файл появился в бакете.
Без обязательной переменной tgt-api не запускается и называет её в сообщении. Сочетание INGESTION_SOURCE=s3 требует STORAGE_KIND=s3, а local-inbox требует local.
Откуда приходят записи¶
| Путь | Что запускает | Что ограничивает |
|---|---|---|
| Автоматический режим | сам берёт новые звонки менеджеров продаж из Битрикс24 по расписанию | включается владельцем; берёт не больше, чем помещается в очередь, и не глубже семи суток |
| Вручную | кнопка «Загрузить файл» в «Звонки», ссылка или POST /v1/recordings |
вход владельца или ключ API |
| Загрузка истории | «Загрузить историю» в «Настройки → Автоматика → Дополнительно» | период, оценка числа звонков и подтверждение; не больше свободного места в очереди |
| Событие Битрикс24 | исходящий вебхук «звонок завершён» | переключатель «Автозабор записей» |
| Старый забор из хранилища | файлы, которые появились в папке inbox или в бакете |
переключатель «Автозабор записей» и четыре ограничения |
Старый забор из хранилища¶
Он нужен, когда записи кладёт в папку или бакет внешняя система. Он выключен по умолчанию и ограничен: у сервера немного ресурсов, а в бакете может лежать архив за годы. Поэтому забор не берёт ничего старше выбранной даты, работает партиями и только пока в очереди есть место, а включение никогда не поставит в очередь весь бакет сразу. Раздел виден только владельцу, в «Настройки → Система → Старый забор записей из хранилища», и показывается, только пока источник настроен или переключатель включён.
| Ограничение | Поле в интерфейсе | По умолчанию | Диапазон |
|---|---|---|---|
| Самая ранняя дата | «Забирать записи не раньше» | момент включения | дата |
| Размер очереди | «Максимум в очереди» | 50 | 1-10 000 |
| Размер партии | «Записей за один запуск» | 20 | 1-500 |
| Пауза между запусками | «Интервал, секунд» | 60 | 10-86 400 |
Как это работает:
- Берутся только файлы, изменённые позже выбранной даты. Если включить без даты, дата ставится равной текущему моменту. Смена даты начинает просмотр с неё.
- Пока в очереди столько записей или больше, сколько указано в «Максимум в очереди», ничего не берётся (результат «Очередь заполнена»).
- За один запуск регистрируется не больше «Записей за один запуск» (и не больше свободного места в очереди).
- Файлы регистрируются на месте: платформа их не копирует, не переименовывает и не удаляет, а уже известные пропускает. Подходят файлы с расширениями
mp3,wav,ogg,oga,opus,m4a,mp4,aac,flac,webm,amr. Пустые объекты пропускаются; в локальной папкеinboxещё пропускаются скрытые файлы (имя с точки) и файлы, изменённые меньше 5 секунд назад. - Каждый запуск просматривает весь префикс: один запрос к S3 на каждую тысячу объектов. Для большого бакета увеличьте «Интервал, секунд».
- Лимит «Максимум в очереди» общий: по нему же ждут автоматическая проверка новых звонков и загрузка истории из Битрикс24.
Результат последнего запуска виден в карточке «Состояние забора»: «Записи забраны», «Новых записей нет», «Забор выключен», «Очередь заполнена», «Источник не настроен» или «Ошибка забора» с сообщением.
Модель распознавания¶
Речь распознаёт модель T-one: потоковая CTC-модель, обученная на телефонных разговорах. Она работает на процессоре, без видеокарты и без обращений к внешним сервисам. Русский язык, звук приводится к 8 кГц моно. Принимаются распространённые форматы: wav, mp3, ogg/opus, m4a, flac, webm и другие контейнеры из закреплённого списка; побитые файлы разбираются до места обрыва. Самый длинный принимаемый звонок: 10 800 секунд (три часа); более длинный получает ошибку «Запись длиннее, чем принимает сервис, повтор не поможет».
Распознаватель tgt-asr это внутренний сервис: у него нет публичного адреса, страница /docs отключена, он не хранит бизнес-данных. API обращается к нему по секрету ASR_API_KEY.
Декодер: greedy или beam_search¶
greedy |
beam_search (по умолчанию в docker-compose.yml) |
|
|---|---|---|
| Что использует | только акустическую модель | акустическую модель и языковую модель KenLM (kenlm.bin) |
| Файлы моделей | model.onnx и model.fp32.onnx |
те же и kenlm.bin |
| Размер скачиваемого | около 0,4 ГБ | около 5,9 ГБ |
| Что делает | быстрый, без поправок | исправляет слова, которых не бывает в русском языке |
- Декодер сервиса задаёт
DECODER. Читается при старте: переключение это перезапуск без пересборки, нужные файлы докачиваются сами. - Запись может попросить декодер при загрузке по API (поле
decoder). Сервис, запущенный сgreedy, отвечает своим декодером, а в расшифровке всегда указано, каким она получена. - По умолчанию вычисления идут в fp32: результат не зависит от процессора (на странице «Технические сведения» поле «Вычисления» показывает
fp32). ПеременнаяFP32_COMPUTE=falseотключает это и нужна только для отладки; вdocker-compose.ymlеё нет.
Память и параллельность¶
| Настройка | Где | Что делает | По умолчанию |
|---|---|---|---|
ASR_MAX_CONCURRENCY (в сервисе MAX_CONCURRENCY) |
tgt-asr |
сколько файлов обрабатывается одновременно, остальные ждут | 2 |
TRANSCRIPTION_CONCURRENCY |
tgt-api |
сколько записей API передаёт распознавателю одновременно (1-8). Держите не больше ASR_MAX_CONCURRENCY |
2 |
ASR_MEMORY_LIMIT |
контейнер tgt-asr |
лимит памяти | 3g |
WEB_CONCURRENCY |
tgt-asr |
число процессов распознавателя; у каждого своя копия модели и свои слоты | 1, задано в файле |
ORT_THREADS |
tgt-asr |
потоков вычислений на один файл | 1 (в файле не задана) |
Что нужно знать:
- По умолчанию на один файл идёт один поток вычислений (
ORT_THREADS), поэтому одна расшифровка занимает примерно одно ядро. Число одновременных расшифровок выбирайте по числу свободных ядер сервера и измеряйте скорость на своём сервере: в карточке «Сейчас расшифровывается» на странице очереди показана скорость. - По измерениям разработчиков на Linux файл языковой модели отображается в память, поэтому почти вся память под него это кэш файла, который ядро вытесняет при нехватке памяти. Процесс держит около 0,6 ГБ обычной памяти; при маленьком кэше расшифровка идёт медленнее, но результат тот же. Сервис работал и при лимите 1,5 ГБ.
WEB_CONCURRENCYувеличивает потребление памяти кратно числу процессов, поэтому для ускорения увеличивайтеASR_MAX_CONCURRENCY, а не число процессов.- Скачивание моделей идёт потоком прямо в файл на диске и не требует памяти под весь файл.
Почему образ небольшой, а модели лежат в томе¶
Модели не входят в образ tgt-asr. Они скачиваются при первом запуске в том asr-models (/models/t-one) и переиспользуются при каждом следующем. Так образ остаётся небольшим, каждое развёртывание не копирует почти 6 ГБ, а очистка кэша сборки Docker не заставляет скачивать модели заново.
Что делает распознаватель при запуске:
- Проверяет, каких файлов не хватает для выбранного декодера, и берёт блокировку, чтобы несколько процессов не скачивали одно и то же.
- Проверяет свободное место (нужно примерно в 1,2 раза больше размера недостающих файлов) и, если места мало, останавливается с понятным сообщением.
- Скачивает файлы с Hugging Face прямо на место назначения: файл появляется под своим именем, только когда он полный, а после обрыва скачивание продолжается.
- Один раз строит из
model.onnxкопиюmodel.fp32.onnxдля вычислений в fp32.
Том asr-models не нужно копировать в резервную копию: он скачивается заново. Том audio-data нужен в копии, если звук хранится локально.
Распознаватель можно развернуть и отдельно от платформы, например как общий сервис: тогда ему нужны API_KEYS (секрет), DECODER, MAX_CONCURRENCY, постоянный том в /models и порт 8000. Для работы платформы это не требуется.
См. также¶
- Развёртывание: переменные окружения и первый запуск.
- Эксплуатация: что делать, если S3 недоступен или распознаватель не отвечает.
- Подключение Битрикс24: автоматический режим и загрузка записей из портала.