AZykov (обсуждение | вклад) |
AZykov (обсуждение | вклад) |
||
| Строка 14: | Строка 14: | ||
'''Инференс''' — использование готовой модели для получения ответа на новый вход («прогон» данных через веса). В отличие от обучения, веса не меняются. Сервисы инференса в статье — Triton, vLLM, LightTTS. | '''Инференс''' — использование готовой модели для получения ответа на новый вход («прогон» данных через веса). В отличие от обучения, веса не меняются. Сервисы инференса в статье — Triton, vLLM, LightTTS. | ||
'''LLM''' — Большая языковая модель. Класс моделей text-to-text, обученных на больших объемах мультиязычных и мультидоменных данных. | |||
'''Triton''' (NVIDIA Triton Inference Server) — сервер инференса от NVIDIA, обслуживающий модели по gRPC и HTTP. В стеке на нём крутится ASR-модель T-one. | '''Triton''' (NVIDIA Triton Inference Server) — сервер инференса от NVIDIA, обслуживающий модели по gRPC и HTTP. В стеке на нём крутится ASR-модель T-one. | ||
| Строка 26: | Строка 28: | ||
'''LightTTS''' — движок инференса для TTS-моделей (синтеза речи). В стеке запускает модель CosyVoice3, слушает порт 8080. | '''LightTTS''' — движок инференса для TTS-моделей (синтеза речи). В стеке запускает модель CosyVoice3, слушает порт 8080. | ||
'''Промпт''' — Инструкция, которой следует большая языковая модель. | |||
'''Токен''' —В ''контексте LLM'' — единица текста, которой оперирует модель (примерно часть слова / слово / знак). Именно в токенах измеряются окно контекста и объём генерации. | '''Токен''' —В ''контексте LLM'' — единица текста, которой оперирует модель (примерно часть слова / слово / знак). Именно в токенах измеряются окно контекста и объём генерации. | ||
| Строка 86: | Строка 90: | ||
Следует также учитывать высокие темпы развития архитектур GPU. Производительная карта шестилетней давности может уступать современному решению среднего уровня как по вычислительной мощности, так и — что существенно в данном случае — по набору поддерживаемых типов данных. Например, NVIDIA V100 (Volta, 2017), несмотря на наличие NVLink и памяти HBM, не поддерживает аппаратное ускорение FP8 и Int4 на тензорных ядрах. Между тем рассматриваемый стек существенно опирается на эти форматы: Qwen в квантизации GPTQ-Int4 с fp8 KV-cache, T-one в TensorRT, TTS с int8-квантизацией. На оборудовании предыдущих поколений соответствующие операции либо неработоспособны в требуемых форматах, либо выполняются с существенным замедлением за счёт программной эмуляции. | Следует также учитывать высокие темпы развития архитектур GPU. Производительная карта шестилетней давности может уступать современному решению среднего уровня как по вычислительной мощности, так и — что существенно в данном случае — по набору поддерживаемых типов данных. Например, NVIDIA V100 (Volta, 2017), несмотря на наличие NVLink и памяти HBM, не поддерживает аппаратное ускорение FP8 и Int4 на тензорных ядрах. Между тем рассматриваемый стек существенно опирается на эти форматы: Qwen в квантизации GPTQ-Int4 с fp8 KV-cache, T-one в TensorRT, TTS с int8-квантизацией. На оборудовании предыдущих поколений соответствующие операции либо неработоспособны в требуемых форматах, либо выполняются с существенным замедлением за счёт программной эмуляции. | ||
С практической точки зрения приоритеты при выборе оборудования под данный пайплайн выстраиваются следующим образом: в первую очередь — поколение архитектуры (Ada, Hopper, Blackwell — ввиду поддержки FP8 и Int4 на тензорных ядрах), далее — пропускная способность памяти, и лишь затем — объём VRAM, поскольку последний в рамках данной задачи практически всегда достаточен. | С практической точки зрения приоритеты при выборе оборудования под данный пайплайн выстраиваются следующим образом: в первую очередь — поколение архитектуры (Ada, Ampere, Hopper, Blackwell — ввиду поддержки FP8 и Int4 на тензорных ядрах), далее — пропускная способность памяти, и лишь затем — объём VRAM, поскольку последний в рамках данной задачи практически всегда достаточен. | ||
Робот тестировался преимущественно на картах поколения Blackwell: | Робот тестировался преимущественно на картах поколения Blackwell: | ||
| Строка 94: | Строка 98: | ||
* '''RTX PRO 6000''' 96gb | * '''RTX PRO 6000''' 96gb | ||
Однако проводились также тесты на картах архитектуры Ampere. Результат можно считать удовлетворительным, особенно для организации тестовых и демо-сред без постоянной большой нагрузки. | Однако проводились также тесты на картах архитектуры '''Ampere'''. Результат можно считать удовлетворительным, особенно для организации тестовых и демо-сред без постоянной большой нагрузки. | ||
Отдельно хочется сказать про ускорители других производителей (AMD, Intel): | Отдельно хочется сказать про ускорители других производителей (AMD, Intel): | ||
| Строка 101: | Строка 105: | ||
=== Анизотропность нагрузки === | === Анизотропность нагрузки === | ||
Из-за логики работы голосового робота, нагрузка на его компоненты в рамках одной сессии достаточно неравномерна. Большинство моделей включаются последовательно после завершения инференса модели на предыдущем шаге: | |||
* VAD (детектирование голосовой активности) - работает всегда (но не вносит существенной нагрузки) | |||
* ASR (распознавание речи) - запускается при срабатывании триггера VAD (окончание реплики) | |||
* LLM - запускается после завершения работы ASR | |||
* TTS - запускается во время / после завершения работы ASR (LLM возвращает текст в потоковом режиме. Текст разбивается на предложения и передается TTS в реальном времени) | |||
Кроме того, архитектурные особенности робота позволяют избегать шага вызова TTS для всех реплик, которые уже были сгенерированы ранее и помещены в кеш. Получается, что если инструкция робота задана таким образом, чтобы его реплики были "статичны" от сессии к сессии, получается экономить значительное количество ресурсов, переиспользуя уже существующие генерации. | |||
Свои оптимизации есть и на стороне инференса LLM: | |||
В команду запуска vLLM по-умолчанию включен режим prefix caching. Данный механизм позволяет кешировать системный промпт и переиспользовать ранее произведенные вычисления для новых запросов. Включение prefix caching позволяет экономить compute для однотипных запросов, а также уменьшить скорость отклика. | |||
Поскольку в рамках голосового робота все запросы (к конкретной конфигурации) используют один системный промпт, это позволяет серьезно экономить. | |||
Данный механизм теряет свою эффективность, к одной LLM будет обращаться большое число роботов с существенно отличающимися системными промптами (50+, точное количество зависит от доступного объема VRAM и настроек vLLM). Также механизм будет мешать, если LLM используется для каких-либо других задач, кроме работы голосового робота. | |||
=== Приблизительный расчет требуемых мощностей === | === Приблизительный расчет требуемых мощностей === | ||
| Строка 107: | Строка 126: | ||
=== Масштабирование сервиса === | === Масштабирование сервиса === | ||
При масштабировании голосового робота существует три подхода: | |||
* Использование дополнительных GPU, либо переход на сервер с более производительным GPU | |||
* Использование нескольких серверов с GPU для балансировки нагрузки | |||
* Использование нескольких экземпляров робота (движков) | |||
На текущий момент наиболее удобным вариантом масштабирования является второй. Наиболее нагруженные сервисы | |||
__TOC__ | __TOC__ | ||
Версия от 10:51, 7 июля 2026
Общая информация

Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:
- Подготовка — Docker, PostgreSQL, настройки в системе телефонии.
- Установка сервисов инференса — ASR, LLM, TTS. Опционально, только для развёртывания на собственном сервере с GPU.
- Настройка .env — параметры подключения.
- Запуск контейнера и создание робота — старт сервиса и конфигурация робота.
Глоссарий
Модель — обученная нейросеть, задающая соответствие между входом и выходом (текст -> текст, звук -> текст и т.д.). Модель определяется архитектурой и набором весов, полученных при обучении. В стеке робота их четыре:VAD (детекция голосовой активности), ASR (распознавание речи), LLM (генерация ответа), TTS (синтез речи).
Веса — числовые параметры модели, полученные при обучении. Именно они хранятся в файлах модели и загружаются в VRAM при старте. «Загрузка весов» в логах vLLM — это чтение этих файлов с диска в память GPU.
Инференс — использование готовой модели для получения ответа на новый вход («прогон» данных через веса). В отличие от обучения, веса не меняются. Сервисы инференса в статье — Triton, vLLM, LightTTS.
LLM — Большая языковая модель. Класс моделей text-to-text, обученных на больших объемах мультиязычных и мультидоменных данных.
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.3gb | ~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
При подборе GPU под данный стек объём VRAM не является определяющим критерием. Веса любой из трёх моделей помещаются в память практически любой современной карты (уровня 5090 или выше), тогда как реальными ограничивающими факторами выступают пропускная способность памяти на этапе декодирования LLM и вычислительная нагрузка DiT-декодера в TTS. Соответственно, при выборе оборудования следует ориентироваться в первую очередь на memory bandwidth и на аппаратную поддержку современных типов данных, а не на номинальный объём видеопамяти.
Отдельного внимания заслуживает интерфейс межкарточного взаимодействия. Потребительские карты рассчитаны преимущественно на одиночную эксплуатацию: в актуальных линейках Blackwell и Ada поддержка NVLink отсутствует, и обмен между несколькими GPU на одном сервере осуществляется исключительно через PCIe (Gen4/Gen5). При использовании tensor parallelism это создаёт заметные накладные расходы на межкарточную коммуникацию, что становится ощутимым при высокой конкурентной нагрузке. Дата-центровые решения (H100, H200, а также RTX PRO 6000 в соответствующем сегменте) либо предоставляют NVLink с пропускной способностью в сотни ГБ/с, либо обладают достаточным объёмом памяти для размещения моделей на одной карте, что позволяет полностью исключить tensor parallelism и связанные с ним издержки.
Следует также учитывать высокие темпы развития архитектур GPU. Производительная карта шестилетней давности может уступать современному решению среднего уровня как по вычислительной мощности, так и — что существенно в данном случае — по набору поддерживаемых типов данных. Например, NVIDIA V100 (Volta, 2017), несмотря на наличие NVLink и памяти HBM, не поддерживает аппаратное ускорение FP8 и Int4 на тензорных ядрах. Между тем рассматриваемый стек существенно опирается на эти форматы: Qwen в квантизации GPTQ-Int4 с fp8 KV-cache, T-one в TensorRT, TTS с int8-квантизацией. На оборудовании предыдущих поколений соответствующие операции либо неработоспособны в требуемых форматах, либо выполняются с существенным замедлением за счёт программной эмуляции.
С практической точки зрения приоритеты при выборе оборудования под данный пайплайн выстраиваются следующим образом: в первую очередь — поколение архитектуры (Ada, Ampere, Hopper, Blackwell — ввиду поддержки FP8 и Int4 на тензорных ядрах), далее — пропускная способность памяти, и лишь затем — объём VRAM, поскольку последний в рамках данной задачи практически всегда достаточен.
Робот тестировался преимущественно на картах поколения Blackwell:
- RTX5090 (использовалась другая LLM меньшего размера)
- RTX PRO 5000 48gb
- RTX PRO 6000 96gb
Однако проводились также тесты на картах архитектуры Ampere. Результат можно считать удовлетворительным, особенно для организации тестовых и демо-сред без постоянной большой нагрузки.
Отдельно хочется сказать про ускорители других производителей (AMD, Intel):
К большому сожалению, большая часть инфраструктурного софта оптимизируется в первую очередь под ускорители NVIDIA. В связи с этим даже более производительные карты AMD "на бумаге", по факту показывают значительно меньшие скорости при реальных задачах. Некоторые же библиотеки и компоненты (TensorRT, Triton Inference Server и т.д.) вообще являются проприетарными разработками NVIDIA и не поддерживают работу с ускорителями других производителей.
Анизотропность нагрузки
Из-за логики работы голосового робота, нагрузка на его компоненты в рамках одной сессии достаточно неравномерна. Большинство моделей включаются последовательно после завершения инференса модели на предыдущем шаге:
- VAD (детектирование голосовой активности) - работает всегда (но не вносит существенной нагрузки)
- ASR (распознавание речи) - запускается при срабатывании триггера VAD (окончание реплики)
- LLM - запускается после завершения работы ASR
- TTS - запускается во время / после завершения работы ASR (LLM возвращает текст в потоковом режиме. Текст разбивается на предложения и передается TTS в реальном времени)
Кроме того, архитектурные особенности робота позволяют избегать шага вызова TTS для всех реплик, которые уже были сгенерированы ранее и помещены в кеш. Получается, что если инструкция робота задана таким образом, чтобы его реплики были "статичны" от сессии к сессии, получается экономить значительное количество ресурсов, переиспользуя уже существующие генерации.
Свои оптимизации есть и на стороне инференса LLM:
В команду запуска vLLM по-умолчанию включен режим prefix caching. Данный механизм позволяет кешировать системный промпт и переиспользовать ранее произведенные вычисления для новых запросов. Включение prefix caching позволяет экономить compute для однотипных запросов, а также уменьшить скорость отклика.
Поскольку в рамках голосового робота все запросы (к конкретной конфигурации) используют один системный промпт, это позволяет серьезно экономить.
Данный механизм теряет свою эффективность, к одной LLM будет обращаться большое число роботов с существенно отличающимися системными промптами (50+, точное количество зависит от доступного объема VRAM и настроек vLLM). Также механизм будет мешать, если LLM используется для каких-либо других задач, кроме работы голосового робота.
Приблизительный расчет требуемых мощностей
паывпывапыв
Масштабирование сервиса
При масштабировании голосового робота существует три подхода:
- Использование дополнительных GPU, либо переход на сервер с более производительным GPU
- Использование нескольких серверов с 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. Осуществить звонок
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.