Открыть меню
Платформа Эра. Документация
Toggle preferences menu
Открыть персональное меню
Вы не представились системе
Your IP address will be publicly visible if you make any edits.

Установка сервисов голосового робота

Материал из Платформа Эра. Документации

Общая информация

Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:

  1. Подготовка — Docker, PostgreSQL, настройки в системе телефонии.
  2. Установка сервисов инференса — ASR, LLM, TTS. Опционально, только для развёртывания на собственном сервере с GPU.
  3. Настройка .env — параметры подключения.
  4. Запуск контейнера и создание робота — старт сервиса и конфигурация робота.

Глоссарий

Модель — обученная нейросеть, задающая соответствие между входом и выходом (текст -> текст, звук -> текст и т.д.). Модель определяется архитектурой и набором весов, полученных при обучении. В стеке робота их четыре:VAD (детекция голосовой активности), ASR (распознавание речи), LLM (генерация ответа), TTS (синтез речи).

Веса — числовые параметры модели, полученные при обучении. Именно они хранятся в файлах модели и загружаются в VRAM при старте. «Загрузка весов» в логах vLLM — это чтение этих файлов с диска в память GPU.

Инференс — использование готовой модели для получения ответа на новый вход («прогон» данных через веса). В отличие от обучения, веса не меняются. Сервисы инференса в статье — Triton, vLLM, LightTTS.

Triton (NVIDIA Triton Inference Server) — сервер инференса от NVIDIA, обслуживающий модели по gRPC и HTTP. В стеке на нём крутится ASR-модель T-one.

TensorRT — библиотека NVIDIA для оптимизации моделей под конкретный GPU: она компилирует модель в специализированный «движок» ради ускорения инференса. Сборка такого движка — разовая операция под железо, поэтому в LightTTS и T-One Triton она выполняется на первой фазе и коммитится в образ.

vLLM — движок инференса для больших языковых моделей (LLM), оптимизированный на пропускную способность и эффективную работу с памятью. Предоставляет OpenAI-совместимый API.

nvidia-smi (NVIDIA System Management Interface) — консольная утилита для просмотра состояния GPU: модель карты, версия драйвера, загрузка, потребление VRAM, запущенные процессы. Используется для проверки, что драйвер установлен и GPU виден (в т.ч. изнутри контейнера).

KV-Cache (кэш ключей и значений) — память, где LLM хранит промежуточные представления уже обработанных токенов, чтобы не пересчитывать их при генерации каждого нового токена. Ускоряет генерацию ценой VRAM. В конфиге ограничен параметром --kv-cache-memory (3 GiB). Растёт с числом сессий и длиной контекста — поэтому его размер критичен на картах с малым запасом VRAM.

LightTTS — движок инференса для TTS-моделей (синтеза речи). В стеке запускает модель CosyVoice3, слушает порт 8080.

Токен —В контексте LLM — единица текста, которой оперирует модель (примерно часть слова / слово / знак). Именно в токенах измеряются окно контекста и объём генерации.

Окно контекста — максимальное количество токенов, которое LLM может учитывать за один запрос (вход + генерируемый ответ вместе). Чем больше окно, тем больше VRAM уходит под KV-Cache, поэтому на картах с ограниченным объёмом его сокращают.

Compute — Вычислительные ресурсы GPU. Абстрактный ресурс видеоускорителя, аналог CPU Time при обычных расчетах. Измеряется в GFLOP/TFLOP (операциях в секунду)

Требования к оборудованию, нагрузка и мастштабирование

Микросервисы робота и их нагрузка

Робот функционирует на базе 4 микросервисов, каждый из которых может быть вынесен на отдельный сервер, или исполняться на общем сервере.

Микросервисы робота
Название Назначение Ключевые ресурсы Минимальное потребление VRAM Дополнительное потребление VRAM из расчета на 1 сессию Условное потребление Compute на 1 сессию
secondchain Инференс модели VAD (CPU), логика робота, голосовой pipeline, работа с сессиями, SIP-клиент CPU, RAM - - -
vLLM (qwen3.5-35b-a3b-INT4)

Данные указаны с окном контекста 8192 токена.

Инференс больших языковых моделей (LLM) VRAM, Compute 22gb 0.25gb ~3 GFLOP/токен
T-one (Triton Inference Server) Инференс T-One speech-to-text Compute 600mb 10mb ~1-3 GFLOP/секунда речи
LightTTS Инференс CosyVoice3 TTS Compute, VRAM 8gb 0.3gb ~120GFLOP/секунда генерируемоей речи

При высокой конкуренции за Compute, увеличиваются задержки на каждом из этапов инференса. Самым чувствительным компонентом, при этом, является LightTTS - из-за архитектурных особенностей. TTS требует много вычислительных ресурсов, и большое количество параллельных генераций могут значительно увеличивать задержку. В случае использования нескольких серверов рекомендуется первично выносить на отдельный сервер либо LightTTS, либо vLLM (для высвобождения Compute).

Архитектурно при этом, робот устроен таким образом, чтобы минимизировать инференс LightTTS при возможности (агрессивное кеширование результатов TTS).

Нюансы подбора GPU

паывпывапва

Анизотропность нагрузки

пывпаывпыва

Приблизительный расчет требуемых мощностей

паывпывапыв

Масштабирование сервиса

авыфаывафыв

Этап 1. Подготовка

Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.

1.1. Установка Docker

Установка самого Docker:

apt install ca-certificates curl
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc

sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF

sudo apt update

sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Установка Nvidia Container Toolkit (только для серверов с GPU):

# репозиторий
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg

curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
  sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list

sudo apt update
sudo apt install -y nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker

1.2. Создать БД в PostgreSQL

Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.

Пример с Docker:

docker run -d \
  --name postgres \
  --network host \
  -e POSTGRES_USER=secondchain \
  -e POSTGRES_PASSWORD=changeme \
  -e POSTGRES_DB=secondchain \
  -v pgdata:/var/lib/postgresql/data \
  postgres:17

1.3. Настройка проброса заголовка в B2B

Мастер-домен → приложение Настройки. В конфигурации, в нодах B2B добавить проброс заголовка X-Robot-Session:

"fwd_headers": ["X-Robot-Session"],

Активировать новую конфигурацию.

1.4. Создать абонента для робота

Проектный домен → приложение Настройки. Создать нового абонента, под которым будет регистрироваться робот.

Робот будет использовать данную учетную запись для приема звонков.

1.5. Создать канал интеграции для робота

Проектный домен → приложение Настройки. Создать новый канал интеграции:

  • Тип — Подписчик
  • Праваai_admin, ai_voicebot_admin
  • Режим активности — постоянный

1.6. Создать движок в приложении ИИ

Задать произвольные название и код. В поле Номер телефона указать внутренний номер абонента, созданного на шаге 1.4.

Количество сессий по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.


Этап 2. Установка сервисов инференса (опционально)

Инструкция для Ubuntu Server 24.04. Стек: ASR (T-one/Triton) → LLM (Qwen3.5-35B-A3B на vLLM) → TTS (LightTTS + CosyVoice3).

Целевая машина — сервер с GPU: RTX PRO 5000 (48GB) или RTX PRO 6000 Blackwell (96GB).

2.1. Предварительные требования

Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:

nvidia-smi                          # драйвер и GPU видны
docker --version                    # Docker установлен
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер

Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.

Бюджет VRAM

Компонент VRAM
ASR (T-one/Triton) 600–800 MB
LLM (Qwen3.5-35B-A3B) 24–48 GB (зависит от числа сессий и длины контекста)
TTS (LightTTS/CosyVoice3) 10 GB

Суммарное потребление в пике — ~36–60 GB.

RTX PRO 6000 (96GB): объёма достаточно с большим запасом. Допустимо использование максимального числа сессий и длинного контекста.

RTX PRO 5000 (48GB): запас минимальный. Фиксированная сумма ASR (~0.8 GB) и TTS (11 GB) составляет ~12 GB, на LLM остаётся ~36 GB. Это покрывает только нижнюю границу диапазона LLM (24 GB). Требуется ограничение параметров --max-num-seqs и --max-model-len во избежание ошибки OOM. Значение --gpu-memory-utilization 0.50 (~24 GB на карте 48GB) для данного сценария допустимо при условии, что ASR и TTS инициализированы до старта LLM.

Объем оперативной памяти не может быть меньше, чем VRAM, так как в процессе запуска веса моделей помещаются сначала в оперативную память, и только затем в VRAM.

2.2. Порядок запуска

Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: ASR → LLM → TTS.

Компиляция моделей может занимать больше VRAM, чем запущенный сервис, поэтому в случае дефицита видеопамяти, рекомендуется временно отключать свеже созданные контейнеры, собирать их по одному, после чего запускать по очереди уже в собранном виде.

2.3. ASR (T-one на Triton Inference Server)

Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.

wget https://ai02.era-platform.ru/tone-triton.tar.gz

docker load < tone-triton.tar.gz

docker run -d --name tone-triton --gpus all --restart unless-stopped \
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \
    -v tone-engine:/models/streaming_acoustic/1 \
    tone-triton:dist-trt-b32

docker logs -f tone-triton

После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:

I0706 22:41:02.484518 1 grpc_server.cc:2562] "Started GRPCInferenceService at 0.0.0.0:8001"
I0706 22:41:02.484664 1 http_server.cc:4832] "Started HTTPService at 0.0.0.0:8000"
I0706 22:41:02.525792 1 http_server.cc:358] "Started Metrics Service at 0.0.0.0:8002"

Проверка: после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — 600–800 MB. Статус контейнера:

docker ps | grep -i tone

2.4. LLM (Qwen3.5-35B-A3B на vLLM)

Установка выполняется из Docker Hub, следующей командой:

docker run -d \
  --name vllm-qwen35-moe \
  --gpus all \
  --ipc=host \
  -v /path/to/cache:/root/.cache \
  -p 16080:8000 \
  vllm/vllm-openai:cu130-nightly \
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \
  --served-model-name qwen35-35b-a3b \
  --quantization moe_wna16 \
  --max-num-seqs 6 \
  --max-model-len 4096 \
  --kv-cache-memory 3221225472 \
  --gpu-memory-utilization 0.50 \
  --enable-prefix-caching \
  --host 0.0.0.0 --port 8000 \
  --reasoning-parser qwen3 \
  --enable-auto-tool-choice \
  --tool-call-parser qwen3_coder \
  --language-model-only


docker logs vllm-qwen35-moe -f

Ключевые параметры:

  • --max-model-len 8192 — максимальное окно контекста в токенах.
  • --max-num-seqs 6 — максимум одновременно обрабатываемых запросов.
  • --gpu-memory-utilization 0.50 — 50% VRAM выделено под LLM.
  • --kv-cache-memory 3221225472 — 3 GiB под KV-кэш.
  • /path/to/cache — директория хост-машины, где будет храниться кеш весов модели (24gb)

Минимальный объём VRAM для запуска — 24 GB. Фактическое потребление — 24–48 GB в зависимости от числа допустимых сессий (--max-num-seqs) и длины контекста (--max-model-len).

После запуска vllm скачает веса модели для запуска (24gb). После завершения запуска и загрузки весов в логах можно наблюдать следующие строки:

(APIServer pid=1) INFO:     Started server process [1]
(APIServer pid=1) INFO:     Waiting for application startup.
(APIServer pid=1) INFO:     Application startup complete.

Как только они появятся, можно переходить к следующему шагу.

Проверка: после загрузки весов проверить OpenAI-совместимый эндпоинт на порту 16080. Первый запрос к модели будет занимать достаточно много времени:

docker logs -f vllm-qwen35-moe        # ожидать "Application startup complete"

curl http://localhost:16080/v1/models

curl http://localhost:16080/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen35-35b-a3b",
    "messages": [{"role": "user", "content": "Привет"}],
    "chat_template_kwargs": {"enable_thinking": false}
  }'

2.5. TTS (LightTTS + CosyVoice3)

По аналогии с T-One, установка выполняется из образа docker-контейнера

wget https://ai02.era-platform.ru/lightts-weights.tar.gz

docker load -i lightts-weights.tar.gz

docker run -d --gpus all -p 8080:8080 --shm-size 4g \
  --restart unless-stopped --name lighttts \
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \
  lighttts/light-tts:weights \
  python -m light_tts.server.api_server \
    --model_dir /opt/models/Fun-CosyVoice3-0.5B \
    --data_type float16 \
    --load_trt True \
    --host 0.0.0.0

docker logs -f lighttts

После запуска сервис скомпилирует веса, по аналогии с T-One. После завершения подготовки в логах будут следующие строки:

INFO 07-06 23:16:49.963 [server/api_http.py:391]  Startup health check passed!
INFO 07-06 23:16:49.963 [server/api_http.py:395]  Application ready! Server is now accepting requests
INFO 07-06 23:16:49.963 [server/api_http.py:396] 🌐 Listening at: http://localhost:8080

Проверка: TTS слушает порт 8080, потребление VRAM — 10 GB:

docker ps | grep lighttts
nvidia-smi

2.6. Итоговая карта портов

Сервис Контейнер Внешний порт
ASR (Triton HTTP) tone-triton 17000
ASR (Triton gRPC) tone-triton 17001
LLM (vLLM) vllm-qwen35-moe 16080
TTS (LightTTS) lighttts 8080

2.7. Финальная проверка стека

docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up

Этап 3. Настройка .env

Необходимо переименовать файл example.env в .env и изменить в нём следующие параметры:

EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]

POSTGRES_HOST=[хост postgresql]
POSTGRES_PORT=5432
POSTGRES_USER=[логин postgresql]
POSTGRES_PASSWORD=[пароль postgresql]
POSTGRES_DB=[имя БД, если укзаанная БД отсутствует - она будет автоматически создана]

CONCURRENT_SESSIONS=[Жесткое ограничение количества одновременных сессий]

SIP_SERVER=[адрес Эры]
SIP_PORT=[порт SIP]
SIP_USERNAME=[Имя учетной записи абонента из пункта 1.4]
SIP_PASSWORD=[Пароль учетной записи абонента из пункта 1.4]
SIP_DOMAIN=[Полное имя домена, например robot.era-platform.ru]
#Детальные настройки SIP-клиента. В случае необходимости обхода NAT
SIP_TRANSPORT=udp
# NAT Traversal
SIP_STUN_SERVER=stun.l.google.com:19302
SIP_USE_ICE=false


LLM_MODE=openai_api
#В случае использования сервиса инфереса vLLM на другом хосте, необходимо изменить адрес/порт
LLM_OPENAI_API_BASE=http://localhost:16080/v1 
LLM_OPENAI_MODEL=qwen35-35b-a3b


ASR_MODE=triton
#В случае использования сервиса инфереса tone-triton на другом хосте, необходимо изменить адреса/порты
ASR_TRITON_URL=http://localhost:17000
ASR_TRITON_GRPC=localhost:17001
ASR_TRITON_MODEL=streaming_acoustic
ASR_TRITON_TIMEOUT=10
ASR_DECODER_TYPE=beam_search


TTS_PROVIDER=lighttts
#В случае использования сервиса инфереса LightTTS на другом хосте, необходимо изменить адрес/порт
LIGHTTTS_URL=http://localhost:8080/
LIGHTTTS_SAMPLE_RATE=24000
LIGHTTTS_STREAMING=false
LIGHTTTS_CONCURRENCY=4

А также настройки Postgres (из шага 1.2) и подключения SIP к учётной записи абонента (из шага 1.4).


Этап 4. Запуск контейнера и создание робота

4.1. Загрузка образа и запуск контейнера

Скопировать на сервер архив с образом контейнера и файл .env в одну директорию.

wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz
docker load -i secondchain-1.0.3a-cpu.tar.gz
mkdir -p ./logs
docker run -d --name secondchain \
  --network host \
  --env-file .env \
  --restart unless-stopped \
  -v secondchain-data:/data \
  -v ./logs:/app/logs \
  secondchain:1.0.3a-cpu

docker logs secondchain -f

Когда сервис загрузится и проинициализируется, в консоли появится сообщение:

Registration: OK (code=200)    [pjsip.account]
[info     ] SIP client registered successfully [voip.sip]
[info     ] VoIP health monitor started    [src.api.app]
[info     ] SecondChain started successfully [src.api.app]
[info     ] Application startup complete.  [uvicorn.error]
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)

4.2. Создать робота в приложении ИИ

Загрузить голос

Необходим аудиофайл .mp3 или .wav длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).

Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).

Создать инструменты

Базовые инструменты работы со звонком.

drop_call

Параметр Значение
Имя drop_call
Код drop_call
description Завершение звонка по инициативе робота
toolType callManagement
callAction drop
enabled Да

transfer_call

Параметр Значение
Имя transfer_call
Код transfer_call
description Перевод звонка на оператора
toolType callManagement
callAction transfer
transferDestination Короткий номер для перевода звонков (например, номер очереди)
enabled Да

Создать робота

Импортировать шаблон (Роботы.json). На вкладке Инструкции изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.

4.3. Проверить создание пользователя

После создания робота должен автоматически создаться пользователь Робот_имяРобота.

4.4. Проверить и установить статус пользователя

Приложение Супервизор контакт-центра → раздел Операторы → Текущие статусы. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус Готов. При необходимости установить этот статус.

4.5. Добавить робота в очередь

Приложение Администратор контакт-центра → добавить робота как участника очереди. Тип участника = Робот. В остальном настройки идентичны.

4.6. Осуществить звонок

Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.

Содержание