Установка и настройка голосового робота Эра (SecondChain)
Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:
- Подготовка — Docker, PostgreSQL, настройки в системе телефонии.
- Установка сервисов инференса — ASR, LLM, TTS. Опционально, только для развёртывания на собственном сервере с GPU.
- Настройка .env — параметры подключения.
- Запуск контейнера и создание робота — старт сервиса и конфигурация робота.
Глоссарий
Модель — обученная нейросеть, задающая соответствие между входом и выходом (текст -> текст, звук -> текст и т.д.). Модель определяется архитектурой и набором весов, полученных при обучении. В стеке робота их четыре: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, поэтому на картах с ограниченным объёмом его сокращают.
Этап 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) | 11 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 lighttts-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
docker logs -f lighttts
После запуска сервис скомпилирует веса, по аналогии с T-One. После завершения подготовки в логах будут следующие строки:
///////////////////////
Проверка: TTS слушает порт 8080, потребление VRAM — 11 GB:
docker ps | grep lighttts
nvidia-smi
2.6. Итоговая карта портов
| Сервис | Контейнер | Внешний порт |
|---|---|---|
| ASR (Triton HTTP) | tone-triton |
8000 |
| ASR (Triton gRPC) | tone-triton |
8001 |
| LLM (vLLM) | vllm-qwen35-moe |
16080 |
| TTS (LightTTS) | lighttts |
8080 |
2.7. Финальная проверка стека
docker ps # все три контейнера (ASR / vLLM / TTS) в статусе Up
После проверки выполняется подключение пайплайна PjSIP → VAD → ASR → LLM → TTS с указанием эндпоинтов в конфигурации: ASR — :8000/:8001, LLM — :16080, TTS — :8080.
Этап 3. Настройка .env
Базовые параметры:
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]
А также настройки 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. Осуществить звонок
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.