<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>https://wiki.era-platform.ru/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=AZykov</id>
	<title>Платформа Эра. Документация - Вклад [ru]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.era-platform.ru/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=AZykov"/>
	<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/AZykov"/>
	<updated>2026-07-31T04:36:09Z</updated>
	<subtitle>Вклад</subtitle>
	<generator>MediaWiki 1.42.3</generator>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2458</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2458"/>
		<updated>2026-07-08T15:20:22Z</updated>

		<summary type="html">&lt;p&gt;AZykov: /* 4.1. Загрузка образа и запуск контейнера */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Общая информация =&lt;br /&gt;
[[Файл:Архитектура голосового робота.png|центр|безрамки|763x763пкс]]&lt;br /&gt;
= Глоссарий =&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Модель.&#039;&#039;&#039; Обученная нейросеть, задающая соответствие между входом и выходом (текст -&amp;gt; текст, звук -&amp;gt; текст и т.д.). Модель определяется архитектурой и набором весов, полученных при обучении. В стеке робота их четыре: VAD (детекция голосовой активности), ASR (распознавание речи), LLM (генерация ответа), TTS (синтез речи).&lt;br /&gt;
* &#039;&#039;&#039;Веса.&#039;&#039;&#039; Числовые параметры модели, полученные при обучении. Именно они хранятся в файлах модели и загружаются в VRAM при старте. «Загрузка весов» в логах vLLM — это чтение этих файлов с диска в память GPU.&lt;br /&gt;
* &#039;&#039;&#039;Инференс.&#039;&#039;&#039; Использование готовой модели для получения ответа на некий набор входных данных (&amp;quot;прогон&amp;quot; данных через веса). В отличие от обучения, веса не меняются. Сервисы инференса в статье — Triton, vLLM, LightTTS.&lt;br /&gt;
* &#039;&#039;&#039;LLM.&#039;&#039;&#039; Большая языковая модель. Класс моделей text-to-text, обученных на больших объемах мультиязычных и мультидоменных данных.&lt;br /&gt;
* &#039;&#039;&#039;Triton&#039;&#039;&#039; (NVIDIA Triton Inference Server). Сервер инференса от NVIDIA, обслуживающий модели по gRPC и HTTP. В стеке на нём крутится ASR-модель T-one.&lt;br /&gt;
* &#039;&#039;&#039;TensorRT.&#039;&#039;&#039; Библиотека NVIDIA для оптимизации моделей под конкретный GPU: она компилирует модель в специализированный «движок» ради ускорения инференса. Сборка такого движка — разовая операция под железо, поэтому в LightTTS и T-One Triton она выполняется на первой фазе и коммитится в образ.&lt;br /&gt;
* &#039;&#039;&#039;vLLM.&#039;&#039;&#039; Движок инференса для больших языковых моделей (LLM), оптимизированный на пропускную способность и эффективную работу с памятью. Предоставляет OpenAI-совместимый API.&lt;br /&gt;
* &#039;&#039;&#039;nvidia-smi&#039;&#039;&#039; (NVIDIA System Management Interface). Консольная утилита для просмотра состояния GPU: модель карты, версия драйвера, загрузка, потребление VRAM, запущенные процессы. Используется для проверки, что драйвер установлен и GPU виден (в т.ч. изнутри контейнера).&lt;br /&gt;
* &#039;&#039;&#039;KV-Cache&#039;&#039;&#039; (кэш ключей и значений). Память, где LLM хранит промежуточные представления уже обработанных токенов, чтобы не пересчитывать их при генерации каждого нового токена. Ускоряет генерацию ценой VRAM. В конфиге ограничен параметром &amp;lt;code&amp;gt;--kv-cache-memory&amp;lt;/code&amp;gt; (3 GiB). Растёт с числом сессий и длиной контекста — поэтому его размер критичен на картах с малым запасом VRAM.&lt;br /&gt;
* &#039;&#039;&#039;LightTTS.&#039;&#039;&#039; Движок инференса для TTS-моделей (синтеза речи). В стеке запускает модель CosyVoice3, слушает порт 8080.&lt;br /&gt;
* &#039;&#039;&#039;Промпт.&#039;&#039;&#039; Инструкция, которой следует большая языковая модель.&lt;br /&gt;
* &#039;&#039;&#039;Токен.&#039;&#039;&#039; В &#039;&#039;контексте LLM&#039;&#039; это единица текста, которой оперирует модель (примерно часть слова / слово / знак). В токенах измеряются окно контекста и объём генерации.&lt;br /&gt;
* &#039;&#039;&#039;Окно контекста.&#039;&#039;&#039; Максимальное количество токенов, которое LLM может учитывать за один запрос (вход + генерируемый ответ вместе). Чем больше окно, тем больше VRAM уходит под KV-Cache, поэтому на картах с ограниченным объёмом его сокращают.&lt;br /&gt;
* &#039;&#039;&#039;Compute.&#039;&#039;&#039; Вычислительные ресурсы GPU. Абстрактный ресурс видеоускорителя. Измеряется в GFLOP/TFLOP (операциях в секунду)&lt;br /&gt;
&lt;br /&gt;
= Требования к оборудованию, нагрузка и мастштабирование =&lt;br /&gt;
&lt;br /&gt;
=== Микросервисы робота и их ресурсы ===&lt;br /&gt;
Робот функционирует на базе 4 микросервисов, каждый из которых может быть вынесен на отдельный сервер, или исполняться на общем сервере. &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Микросервисы робота&lt;br /&gt;
!Название&lt;br /&gt;
!Назначение&lt;br /&gt;
!Ключевые ресурсы&lt;br /&gt;
!Минимальное потребление VRAM&lt;br /&gt;
!Дополнительное потребление VRAM из расчета на 1 сессию&lt;br /&gt;
!Условное потребление Compute на 1 сессию&lt;br /&gt;
|-&lt;br /&gt;
|secondchain&lt;br /&gt;
|Инференс модели VAD (CPU), логика робота, голосовой pipeline, работа с сессиями, SIP-клиент&lt;br /&gt;
|CPU, RAM&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
|vLLM (qwen3.5-35b-a3b-INT4)&lt;br /&gt;
Данные указаны с окном контекста 8192 токена.&lt;br /&gt;
|Инференс больших языковых моделей (LLM)&lt;br /&gt;
|VRAM, Compute&lt;br /&gt;
|22gb&lt;br /&gt;
|0.3gb&lt;br /&gt;
|~3 GFLOP/токен&lt;br /&gt;
|-&lt;br /&gt;
|T-one (Triton Inference Server)&lt;br /&gt;
|Инференс T-One speech-to-text&lt;br /&gt;
|Compute&lt;br /&gt;
|600mb&lt;br /&gt;
|10mb&lt;br /&gt;
|~1-3 GFLOP/секунда речи&lt;br /&gt;
|-&lt;br /&gt;
|LightTTS&lt;br /&gt;
|Инференс CosyVoice3 TTS&lt;br /&gt;
|Compute, VRAM&lt;br /&gt;
|8gb&lt;br /&gt;
|0.3gb&lt;br /&gt;
|~120GFLOP/секунда генерируемоей речи&lt;br /&gt;
|}&lt;br /&gt;
При высокой конкуренции за Compute, увеличиваются задержки на каждом из этапов инференса. Самым чувствительным компонентом, при этом, является LightTTS - из-за архитектурных особенностей. TTS требует много вычислительных ресурсов, и большое количество параллельных генераций могут значительно увеличивать задержку. В случае использования нескольких серверов рекомендуется первично выносить на отдельный сервер либо LightTTS, либо vLLM (для высвобождения Compute).&lt;br /&gt;
&lt;br /&gt;
Архитектурно при этом, робот устроен таким образом, чтобы минимизировать инференс LightTTS при возможности (агрессивное кеширование результатов TTS). &lt;br /&gt;
&lt;br /&gt;
=== Нюансы подбора GPU ===&lt;br /&gt;
При подборе GPU под данный стек объём VRAM не является определяющим критерием. Веса любой из трёх моделей помещаются в память практически любой современной карты (уровня 5090 или выше), тогда как реальными ограничивающими факторами выступают пропускная способность памяти на этапе декодирования LLM и вычислительная нагрузка DiT-декодера в TTS. Соответственно, при выборе оборудования следует ориентироваться в первую очередь на memory bandwidth и на аппаратную поддержку современных типов данных, а не на номинальный объём видеопамяти.&lt;br /&gt;
&lt;br /&gt;
Отдельного внимания заслуживает интерфейс межкарточного взаимодействия. Потребительские карты рассчитаны преимущественно на одиночную эксплуатацию: в актуальных линейках Blackwell и Ada поддержка NVLink отсутствует, и обмен между несколькими GPU на одном сервере осуществляется исключительно через PCIe (Gen4/Gen5). При использовании tensor parallelism это создаёт заметные накладные расходы на межкарточную коммуникацию, что становится ощутимым при высокой конкурентной нагрузке. Дата-центровые решения (H100, H200, а также RTX PRO 6000 в соответствующем сегменте) либо предоставляют NVLink с пропускной способностью в сотни ГБ/с, либо обладают достаточным объёмом памяти для размещения моделей на одной карте, что позволяет полностью исключить tensor parallelism и связанные с ним издержки.&lt;br /&gt;
&lt;br /&gt;
Следует также учитывать высокие темпы развития архитектур GPU. Производительная карта шестилетней давности может уступать современному решению среднего уровня как по вычислительной мощности, так и — что существенно в данном случае — по набору поддерживаемых типов данных. Например, NVIDIA V100 (Volta, 2017), несмотря на наличие NVLink и памяти HBM, не поддерживает аппаратное ускорение FP8 и Int4 на тензорных ядрах. Между тем рассматриваемый стек существенно опирается на эти форматы: Qwen в квантизации GPTQ-Int4 с fp8 KV-cache, T-one в TensorRT, TTS с int8-квантизацией. На оборудовании предыдущих поколений соответствующие операции либо неработоспособны в требуемых форматах, либо выполняются с существенным замедлением за счёт программной эмуляции.&lt;br /&gt;
&lt;br /&gt;
С практической точки зрения приоритеты при выборе оборудования под данный пайплайн выстраиваются следующим образом: в первую очередь — поколение архитектуры (Ada, Ampere, Hopper, Blackwell — ввиду поддержки FP8 и Int4 на тензорных ядрах), далее — пропускная способность памяти, и лишь затем — объём VRAM, поскольку последний в рамках данной задачи практически всегда достаточен.&lt;br /&gt;
&lt;br /&gt;
Робот тестировался преимущественно на картах поколения Blackwell:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;RTX5090&#039;&#039;&#039; (использовалась другая LLM меньшего размера)&lt;br /&gt;
* &#039;&#039;&#039;RTX PRO 5000&#039;&#039;&#039; 48gb&lt;br /&gt;
* &#039;&#039;&#039;RTX PRO 6000&#039;&#039;&#039; 96gb&lt;br /&gt;
&lt;br /&gt;
Однако проводились также тесты на картах архитектуры &#039;&#039;&#039;Ampere&#039;&#039;&#039;. Результат можно считать удовлетворительным, особенно для организации тестовых и демо-сред без постоянной большой нагрузки.&lt;br /&gt;
&lt;br /&gt;
Отдельно хочется сказать про ускорители других производителей (AMD, Intel):&lt;br /&gt;
&lt;br /&gt;
К большому сожалению, большая часть инфраструктурного софта оптимизируется в первую очередь под ускорители NVIDIA. В связи с этим даже более производительные карты AMD &amp;quot;на бумаге&amp;quot;, по факту показывают значительно меньшие скорости при реальных задачах. Некоторые же библиотеки и компоненты (TensorRT, Triton Inference Server и т.д.) вообще являются проприетарными разработками NVIDIA и не поддерживают работу с ускорителями других производителей.&lt;br /&gt;
&lt;br /&gt;
=== Анизотропность нагрузки ===&lt;br /&gt;
Из-за логики работы голосового робота, нагрузка на его компоненты в рамках одной сессии достаточно неравномерна. Большинство моделей включаются последовательно после завершения инференса модели на предыдущем шаге:&lt;br /&gt;
&lt;br /&gt;
* VAD (детектирование голосовой активности) - работает всегда (но не вносит существенной нагрузки)&lt;br /&gt;
* ASR (распознавание речи) - запускается при срабатывании триггера VAD (окончание реплики)&lt;br /&gt;
* LLM - запускается после завершения работы ASR&lt;br /&gt;
* TTS - запускается во время / после завершения работы ASR (LLM возвращает текст в потоковом режиме. Текст разбивается на предложения и передается TTS в реальном времени)&lt;br /&gt;
&lt;br /&gt;
Кроме того, архитектурные особенности робота позволяют избегать шага вызова TTS для всех реплик, которые уже были сгенерированы ранее и помещены в кеш. Получается, что если инструкция робота задана таким образом, чтобы его реплики были &amp;quot;статичны&amp;quot; от сессии к сессии, получается экономить значительное количество ресурсов, переиспользуя уже существующие генерации.&lt;br /&gt;
&lt;br /&gt;
Свои оптимизации есть и на стороне инференса LLM:&lt;br /&gt;
&lt;br /&gt;
В команду запуска vLLM по-умолчанию включен режим prefix caching. Данный механизм позволяет кешировать системный промпт и переиспользовать ранее произведенные вычисления для новых запросов. Включение prefix caching позволяет экономить compute для однотипных запросов, а также уменьшить скорость отклика.&lt;br /&gt;
&lt;br /&gt;
Поскольку в рамках голосового робота все запросы (к конкретной конфигурации) используют один системный промпт, это позволяет серьезно экономить.&lt;br /&gt;
&lt;br /&gt;
Данный механизм теряет свою эффективность, к одной LLM будет обращаться большое число роботов с существенно отличающимися системными промптами (50+, точное количество зависит от доступного объема VRAM и настроек vLLM). Также механизм будет мешать, если LLM используется для каких-либо других задач, кроме работы голосового робота.&lt;br /&gt;
&lt;br /&gt;
=== Приблизительный расчет требуемых мощностей ===&lt;br /&gt;
Рекомендуемой конфигурацией является следующая:&lt;br /&gt;
&lt;br /&gt;
CPU 8x&lt;br /&gt;
&lt;br /&gt;
RAM 64gb DDR5&lt;br /&gt;
&lt;br /&gt;
300gb SSD &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Сравнение ускорителей&lt;br /&gt;
!Ускоритель&lt;br /&gt;
!Архитектура&lt;br /&gt;
!VRAM&lt;br /&gt;
!Bandwith&lt;br /&gt;
!Compute (INT8)&lt;br /&gt;
!Приблизительное количество параллельных сессий&lt;br /&gt;
|-&lt;br /&gt;
|RTX PRO 5000&lt;br /&gt;
|Blackwell&lt;br /&gt;
|48gb&lt;br /&gt;
|1.34TB/s&lt;br /&gt;
|516 TOPS&lt;br /&gt;
|30-40&lt;br /&gt;
|-&lt;br /&gt;
|RTX PRO 6000&lt;br /&gt;
|Blackwell&lt;br /&gt;
|96gb&lt;br /&gt;
|1.79TB/s&lt;br /&gt;
|1000 TOPS&lt;br /&gt;
|50-70&lt;br /&gt;
|-&lt;br /&gt;
|RTX 4090/48&lt;br /&gt;
|Ada&lt;br /&gt;
|48gb&lt;br /&gt;
|1TB/s&lt;br /&gt;
|660 TOPS&lt;br /&gt;
|25-30&lt;br /&gt;
|-&lt;br /&gt;
|2x RTX 5090&lt;br /&gt;
|Blackwell&lt;br /&gt;
|2x32gb&lt;br /&gt;
|1.79TB/s&lt;br /&gt;
|828 TOPS&lt;br /&gt;
|30-40&lt;br /&gt;
|-&lt;br /&gt;
|2x RTX 4090/24&lt;br /&gt;
|Ada&lt;br /&gt;
|2x24gb&lt;br /&gt;
|1TB/s&lt;br /&gt;
|660 TOPS&lt;br /&gt;
|10-20&lt;br /&gt;
|-&lt;br /&gt;
|A100/40&lt;br /&gt;
|Ampere&lt;br /&gt;
|40gb&lt;br /&gt;
|1.56TB/s&lt;br /&gt;
|624 TOPS&lt;br /&gt;
|18-23&lt;br /&gt;
|-&lt;br /&gt;
|A100/80&lt;br /&gt;
|Ampere&lt;br /&gt;
|80gb&lt;br /&gt;
|2TB/s&lt;br /&gt;
|624 TOPS&lt;br /&gt;
|55-75&lt;br /&gt;
|-&lt;br /&gt;
|H100&lt;br /&gt;
|Hopper&lt;br /&gt;
|80gb&lt;br /&gt;
|3.35TB/s&lt;br /&gt;
|990 TOPS&lt;br /&gt;
|70-100&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
При использовании конфигураций из двух карт с небольшим объемом VRAM (24, 32gb) будет происходить проблема дисбаланса:&lt;br /&gt;
&lt;br /&gt;
Одну из карт будет полностью занимать LLM (22gb базовых весов), а другую карту будут занимать другие модели. При этом в случае 2x24gb VRAM, для LLM будет оставаться крайне мало памяти на активные сессии, что будет являться главным ограничителем. Использовать память или compute соседней карты невозможно без NVLINK, а в потребительских картах он отсутствует.&lt;br /&gt;
&lt;br /&gt;
Таким образом вариант 2x4090/24 может использовать только для ненагруженных систем - демо стендов или сред разработки. Для такой конфигурации возможно заменить вторую карту на более простую, например 4080, так как TTS + ASR не реализуют 24gb vram.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем оперативной памяти не может быть меньше, чем 32gb, так как в процессе запуска веса моделей помещаются сначала в оперативную память, и только затем в VRAM.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Масштабирование сервиса ===&lt;br /&gt;
При масштабировании голосового робота существует три подхода:&lt;br /&gt;
&lt;br /&gt;
* Использование дополнительных GPU, либо переход на сервер с более производительным GPU&lt;br /&gt;
* Использование нескольких серверов с GPU для балансировки нагрузки&lt;br /&gt;
* Использование нескольких экземпляров робота (движков)&lt;br /&gt;
&lt;br /&gt;
На текущий момент наиболее удобным вариантом масштабирования является второй. Наиболее нагруженные сервисы vLLM и LightTTS можно выносить на отдельные сервера. При этом, например, для LightTTS не требуется большой объем VRAM, и он может качественно работать на сравнительно недорогих потребительских ускорителях (4090, 5080). &lt;br /&gt;
&lt;br /&gt;
Отдельно стоит упомянуть вынесение на отдельный сервер ASR. Данный компонент работает в потоковом режиме по протоколу gRPC, и не рекомендуется вынесение его на другие площадки с высокой задержкой. Остальные компоненты (за исключением VAD, который работает на CPU в составе главного сервиса secondchain), не чувствительны к дополнительным задержкам (в рамках разумного, до 50-70мс).&lt;br /&gt;
&lt;br /&gt;
=== Запуск робота с использованием облачных сервисов инференса ===&lt;br /&gt;
В случае, когда проектные требования позволяют использовать облачную инфраструктуру, нет необходимости полного разворота всех сервисов локально. Можно использовать ресурсы облачных провайдеров и ресурсы, предоставляемые командой платформы.&lt;br /&gt;
&lt;br /&gt;
Сервис поддерживает наиболее популярные API для работы с облачными моделями:&lt;br /&gt;
&lt;br /&gt;
* OpenAI-like формат для LLM. Позволяет подключать к роботу любые из современных передовых языковых моделей.&lt;br /&gt;
* OpenAI-like transcription формат для распознавания речи.&lt;br /&gt;
* LightTTS API формат для генерации речи&lt;br /&gt;
&lt;br /&gt;
Часто, экономически эффективным может быть использование только облачной LLM, так как она требует большого объема VRAM и дорогих ускорителей. При этом остальные модели запускаются локально, на более простой карте.&lt;br /&gt;
&lt;br /&gt;
При выборе облачной LLM критичными показателями являются следующие:&lt;br /&gt;
&lt;br /&gt;
* Метрика TTFT (Time To First Token). Время отклика модели до пересылки первых токенов ответа. Должна быть &amp;lt;=300мс, включая сетевые задержки;&lt;br /&gt;
* Поддержка streaming (SSE/chunked) ответов;&lt;br /&gt;
* Возможность отключения режима thinking/reasoning; &lt;br /&gt;
* Скорость генерации ответа &amp;gt;30 токенов/сек.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Популярные подписки на современные модели по типу &amp;quot;Token Plan&amp;quot;, которые предлагают использование с ограничением на количество запросов, а не тарификацию по токенам, зачастую непригодны для использования с роботом. Данные подписки используются в агентских системах, где время отклика не является целевой метрикой, а запросы инференса с таких подписок, как правило обрабатываются облачными сервисами с меньшим приоритетом.&amp;lt;/blockquote&amp;gt;При использовании всех облачных сервисов инференса, локально разворачивается только главный контейнер - secondchain. Рекомендуемые требования к серверу для такой среды:&lt;br /&gt;
&lt;br /&gt;
4x CPU&lt;br /&gt;
&lt;br /&gt;
8gb RAM&lt;br /&gt;
&lt;br /&gt;
80gb SSD&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
Установка самого Docker:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установка Nvidia Container Toolkit (только для серверов с GPU):&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# репозиторий&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \&lt;br /&gt;
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \&lt;br /&gt;
  sed &#039;s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g&#039; | \&lt;br /&gt;
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-container-toolkit&lt;br /&gt;
sudo nvidia-ctk runtime configure --runtime=docker&lt;br /&gt;
sudo systemctl restart docker&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (только для серверов с GPU) =&lt;br /&gt;
&lt;br /&gt;
Инструкция написана для Unbuntu 24.04.&lt;br /&gt;
&lt;br /&gt;
При написании и проверке данной инструкции использовался сервер с RTX PRO 5000 48gb.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Компиляция моделей может занимать больше VRAM, чем запущенный сервис, поэтому в случае дефицита видеопамяти, рекомендуется временно отключать свеже созданные контейнеры, собирать их по одному, после чего запускать по очереди уже в собранном виде.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton Inference Server) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
I0706 22:41:02.484518 1 grpc_server.cc:2562] &amp;quot;Started GRPCInferenceService at 0.0.0.0:8001&amp;quot;&lt;br /&gt;
I0706 22:41:02.484664 1 http_server.cc:4832] &amp;quot;Started HTTPService at 0.0.0.0:8000&amp;quot;&lt;br /&gt;
I0706 22:41:02.525792 1 http_server.cc:358] &amp;quot;Started Metrics Service at 0.0.0.0:8002&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
Установка выполняется из Docker Hub, следующей командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
* &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; — директория хост-машины, где будет храниться кеш весов модели (24gb)&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
После запуска vllm скачает веса модели для запуска (24gb). После завершения запуска и загрузки весов в логах можно наблюдать следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
(APIServer pid=1) INFO:     Started server process [1]&lt;br /&gt;
(APIServer pid=1) INFO:     Waiting for application startup.&lt;br /&gt;
(APIServer pid=1) INFO:     Application startup complete.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Как только они появятся, можно переходить к следующему шагу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080.&#039;&#039;&#039; Первый запрос к модели будет занимать достаточно много времени (холодный старт):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}],&lt;br /&gt;
    &amp;quot;chat_template_kwargs&amp;quot;: {&amp;quot;enable_thinking&amp;quot;: false}&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load -i lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights \&lt;br /&gt;
  python -m light_tts.server.api_server \&lt;br /&gt;
    --model_dir /opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
    --data_type float16 \&lt;br /&gt;
    --load_trt True \&lt;br /&gt;
    --host 0.0.0.0&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;После запуска сервис скомпилирует веса, по аналогии с T-One. После завершения подготовки в логах будут следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:391] ✅ Startup health check passed!&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:395] ✅ Application ready! Server is now accepting requests&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:396] 🌐 Listening at: http://localhost:8080&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — 10 &#039;&#039;&#039;GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 17000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 17001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Контейнеры сервисов инференса голосового робота.png|центр|безрамки|1067x1067пкс]]&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
Для упрощения работы с настройкой робота, нами был подготовлен набор демо-ресурсов:&lt;br /&gt;
&lt;br /&gt;
[[:Файл:Демо ресурсы для голосового робота.zip]]&lt;br /&gt;
&lt;br /&gt;
Он включает файл голоса, example.env и файлы для импорта в разделы приложения ИИ с готовым настроенным роботом.&lt;br /&gt;
&lt;br /&gt;
Необходимо переименовать файл example.env в .env и изменить в нём следующие параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&lt;br /&gt;
POSTGRES_HOST=[хост postgresql]&lt;br /&gt;
POSTGRES_PORT=5432&lt;br /&gt;
POSTGRES_USER=[логин postgresql]&lt;br /&gt;
POSTGRES_PASSWORD=[пароль postgresql]&lt;br /&gt;
POSTGRES_DB=[имя БД, если укзаанная БД отсутствует - она будет автоматически создана]&lt;br /&gt;
&lt;br /&gt;
CONCURRENT_SESSIONS=[Жесткое ограничение количества одновременных сессий]&lt;br /&gt;
&lt;br /&gt;
SIP_SERVER=[адрес Эры]&lt;br /&gt;
SIP_PORT=[порт SIP]&lt;br /&gt;
SIP_USERNAME=[Имя учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_PASSWORD=[Пароль учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_DOMAIN=[Полное имя домена, например robot.era-platform.ru]&lt;br /&gt;
#Детальные настройки SIP-клиента. В случае необходимости обхода NAT&lt;br /&gt;
SIP_TRANSPORT=udp&lt;br /&gt;
# NAT Traversal&lt;br /&gt;
SIP_STUN_SERVER=stun.l.google.com:19302&lt;br /&gt;
SIP_USE_ICE=false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
LLM_MODE=openai_api&lt;br /&gt;
#В случае использования сервиса инфереса vLLM на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LLM_OPENAI_API_BASE=http://localhost:16080/v1 &lt;br /&gt;
LLM_OPENAI_MODEL=qwen35-35b-a3b&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ASR_MODE=triton&lt;br /&gt;
#В случае использования сервиса инфереса tone-triton на другом хосте, необходимо изменить адреса/порты&lt;br /&gt;
ASR_TRITON_URL=http://localhost:17000&lt;br /&gt;
ASR_TRITON_GRPC=localhost:17001&lt;br /&gt;
ASR_TRITON_MODEL=streaming_acoustic&lt;br /&gt;
ASR_TRITON_TIMEOUT=10&lt;br /&gt;
ASR_DECODER_TYPE=beam_search&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
TTS_PROVIDER=lighttts&lt;br /&gt;
#В случае использования сервиса инфереса LightTTS на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LIGHTTTS_URL=http://localhost:8080/&lt;br /&gt;
LIGHTTTS_SAMPLE_RATE=24000&lt;br /&gt;
LIGHTTTS_STREAMING=false&lt;br /&gt;
LIGHTTTS_CONCURRENCY=4&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
= Этап 4. Запуск контейнера secondchain и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
Ссылка на загрузку контейнера secondchain предоставляется менеджером по запросу.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
docker load -i secondchain.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
Для упрощения работы с настройкой робота, нами был подготовлен набор демо-ресурсов:&lt;br /&gt;
&lt;br /&gt;
[[:Файл:Демо ресурсы для голосового робота.zip]]&lt;br /&gt;
&lt;br /&gt;
Он включает файл голоса, example.env и файлы для импорта в разделы приложения ИИ с готовым настроенным роботом.&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
[[Файл:Голос робота в приложении ИИ.png|мини]]&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
[[Файл:Инструменты робота.png|мини]]&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
[[Файл:Пример робота в приложении ИИ.png|мини]]&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
Системный промпт задаёт поведение робота, а промпт пост-обработки позволяет после окончания диалога проанализировать его и сохранить в сессии бизнес-результат (удобнее всего, в формате JSON).&lt;br /&gt;
&lt;br /&gt;
При составлении собственного системного важным эффектом является &amp;quot;внимательность&amp;quot; (attention) больших языковых моделей. Они более строго следуют инструкциям, написанным в начале и конце промпта. Поэтому данные области рекомендуется оставлять для строгих ограничений.&lt;br /&gt;
&lt;br /&gt;
Для построения надежных роботов с повторяемой эффективностью, рекомендуется использовать подход с описанием строгих шагов диалога.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
[[Файл:Статус робота.png|мини]]&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
[[Файл:Робот в очереди.png|мини]]&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2457</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2457"/>
		<updated>2026-07-07T12:19:35Z</updated>

		<summary type="html">&lt;p&gt;AZykov: /* Микросервисы робота и их нагрузка */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Общая информация =&lt;br /&gt;
[[Файл:Архитектура голосового робота.png|центр|безрамки|763x763пкс]]&lt;br /&gt;
= Глоссарий =&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Модель.&#039;&#039;&#039; Обученная нейросеть, задающая соответствие между входом и выходом (текст -&amp;gt; текст, звук -&amp;gt; текст и т.д.). Модель определяется архитектурой и набором весов, полученных при обучении. В стеке робота их четыре: VAD (детекция голосовой активности), ASR (распознавание речи), LLM (генерация ответа), TTS (синтез речи).&lt;br /&gt;
* &#039;&#039;&#039;Веса.&#039;&#039;&#039; Числовые параметры модели, полученные при обучении. Именно они хранятся в файлах модели и загружаются в VRAM при старте. «Загрузка весов» в логах vLLM — это чтение этих файлов с диска в память GPU.&lt;br /&gt;
* &#039;&#039;&#039;Инференс.&#039;&#039;&#039; Использование готовой модели для получения ответа на некий набор входных данных (&amp;quot;прогон&amp;quot; данных через веса). В отличие от обучения, веса не меняются. Сервисы инференса в статье — Triton, vLLM, LightTTS.&lt;br /&gt;
* &#039;&#039;&#039;LLM.&#039;&#039;&#039; Большая языковая модель. Класс моделей text-to-text, обученных на больших объемах мультиязычных и мультидоменных данных.&lt;br /&gt;
* &#039;&#039;&#039;Triton&#039;&#039;&#039; (NVIDIA Triton Inference Server). Сервер инференса от NVIDIA, обслуживающий модели по gRPC и HTTP. В стеке на нём крутится ASR-модель T-one.&lt;br /&gt;
* &#039;&#039;&#039;TensorRT.&#039;&#039;&#039; Библиотека NVIDIA для оптимизации моделей под конкретный GPU: она компилирует модель в специализированный «движок» ради ускорения инференса. Сборка такого движка — разовая операция под железо, поэтому в LightTTS и T-One Triton она выполняется на первой фазе и коммитится в образ.&lt;br /&gt;
* &#039;&#039;&#039;vLLM.&#039;&#039;&#039; Движок инференса для больших языковых моделей (LLM), оптимизированный на пропускную способность и эффективную работу с памятью. Предоставляет OpenAI-совместимый API.&lt;br /&gt;
* &#039;&#039;&#039;nvidia-smi&#039;&#039;&#039; (NVIDIA System Management Interface). Консольная утилита для просмотра состояния GPU: модель карты, версия драйвера, загрузка, потребление VRAM, запущенные процессы. Используется для проверки, что драйвер установлен и GPU виден (в т.ч. изнутри контейнера).&lt;br /&gt;
* &#039;&#039;&#039;KV-Cache&#039;&#039;&#039; (кэш ключей и значений). Память, где LLM хранит промежуточные представления уже обработанных токенов, чтобы не пересчитывать их при генерации каждого нового токена. Ускоряет генерацию ценой VRAM. В конфиге ограничен параметром &amp;lt;code&amp;gt;--kv-cache-memory&amp;lt;/code&amp;gt; (3 GiB). Растёт с числом сессий и длиной контекста — поэтому его размер критичен на картах с малым запасом VRAM.&lt;br /&gt;
* &#039;&#039;&#039;LightTTS.&#039;&#039;&#039; Движок инференса для TTS-моделей (синтеза речи). В стеке запускает модель CosyVoice3, слушает порт 8080.&lt;br /&gt;
* &#039;&#039;&#039;Промпт.&#039;&#039;&#039; Инструкция, которой следует большая языковая модель.&lt;br /&gt;
* &#039;&#039;&#039;Токен.&#039;&#039;&#039; В &#039;&#039;контексте LLM&#039;&#039; это единица текста, которой оперирует модель (примерно часть слова / слово / знак). В токенах измеряются окно контекста и объём генерации.&lt;br /&gt;
* &#039;&#039;&#039;Окно контекста.&#039;&#039;&#039; Максимальное количество токенов, которое LLM может учитывать за один запрос (вход + генерируемый ответ вместе). Чем больше окно, тем больше VRAM уходит под KV-Cache, поэтому на картах с ограниченным объёмом его сокращают.&lt;br /&gt;
* &#039;&#039;&#039;Compute.&#039;&#039;&#039; Вычислительные ресурсы GPU. Абстрактный ресурс видеоускорителя. Измеряется в GFLOP/TFLOP (операциях в секунду)&lt;br /&gt;
&lt;br /&gt;
= Требования к оборудованию, нагрузка и мастштабирование =&lt;br /&gt;
&lt;br /&gt;
=== Микросервисы робота и их ресурсы ===&lt;br /&gt;
Робот функционирует на базе 4 микросервисов, каждый из которых может быть вынесен на отдельный сервер, или исполняться на общем сервере. &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Микросервисы робота&lt;br /&gt;
!Название&lt;br /&gt;
!Назначение&lt;br /&gt;
!Ключевые ресурсы&lt;br /&gt;
!Минимальное потребление VRAM&lt;br /&gt;
!Дополнительное потребление VRAM из расчета на 1 сессию&lt;br /&gt;
!Условное потребление Compute на 1 сессию&lt;br /&gt;
|-&lt;br /&gt;
|secondchain&lt;br /&gt;
|Инференс модели VAD (CPU), логика робота, голосовой pipeline, работа с сессиями, SIP-клиент&lt;br /&gt;
|CPU, RAM&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
|vLLM (qwen3.5-35b-a3b-INT4)&lt;br /&gt;
Данные указаны с окном контекста 8192 токена.&lt;br /&gt;
|Инференс больших языковых моделей (LLM)&lt;br /&gt;
|VRAM, Compute&lt;br /&gt;
|22gb&lt;br /&gt;
|0.3gb&lt;br /&gt;
|~3 GFLOP/токен&lt;br /&gt;
|-&lt;br /&gt;
|T-one (Triton Inference Server)&lt;br /&gt;
|Инференс T-One speech-to-text&lt;br /&gt;
|Compute&lt;br /&gt;
|600mb&lt;br /&gt;
|10mb&lt;br /&gt;
|~1-3 GFLOP/секунда речи&lt;br /&gt;
|-&lt;br /&gt;
|LightTTS&lt;br /&gt;
|Инференс CosyVoice3 TTS&lt;br /&gt;
|Compute, VRAM&lt;br /&gt;
|8gb&lt;br /&gt;
|0.3gb&lt;br /&gt;
|~120GFLOP/секунда генерируемоей речи&lt;br /&gt;
|}&lt;br /&gt;
При высокой конкуренции за Compute, увеличиваются задержки на каждом из этапов инференса. Самым чувствительным компонентом, при этом, является LightTTS - из-за архитектурных особенностей. TTS требует много вычислительных ресурсов, и большое количество параллельных генераций могут значительно увеличивать задержку. В случае использования нескольких серверов рекомендуется первично выносить на отдельный сервер либо LightTTS, либо vLLM (для высвобождения Compute).&lt;br /&gt;
&lt;br /&gt;
Архитектурно при этом, робот устроен таким образом, чтобы минимизировать инференс LightTTS при возможности (агрессивное кеширование результатов TTS). &lt;br /&gt;
&lt;br /&gt;
=== Нюансы подбора GPU ===&lt;br /&gt;
При подборе GPU под данный стек объём VRAM не является определяющим критерием. Веса любой из трёх моделей помещаются в память практически любой современной карты (уровня 5090 или выше), тогда как реальными ограничивающими факторами выступают пропускная способность памяти на этапе декодирования LLM и вычислительная нагрузка DiT-декодера в TTS. Соответственно, при выборе оборудования следует ориентироваться в первую очередь на memory bandwidth и на аппаратную поддержку современных типов данных, а не на номинальный объём видеопамяти.&lt;br /&gt;
&lt;br /&gt;
Отдельного внимания заслуживает интерфейс межкарточного взаимодействия. Потребительские карты рассчитаны преимущественно на одиночную эксплуатацию: в актуальных линейках Blackwell и Ada поддержка NVLink отсутствует, и обмен между несколькими GPU на одном сервере осуществляется исключительно через PCIe (Gen4/Gen5). При использовании tensor parallelism это создаёт заметные накладные расходы на межкарточную коммуникацию, что становится ощутимым при высокой конкурентной нагрузке. Дата-центровые решения (H100, H200, а также RTX PRO 6000 в соответствующем сегменте) либо предоставляют NVLink с пропускной способностью в сотни ГБ/с, либо обладают достаточным объёмом памяти для размещения моделей на одной карте, что позволяет полностью исключить tensor parallelism и связанные с ним издержки.&lt;br /&gt;
&lt;br /&gt;
Следует также учитывать высокие темпы развития архитектур GPU. Производительная карта шестилетней давности может уступать современному решению среднего уровня как по вычислительной мощности, так и — что существенно в данном случае — по набору поддерживаемых типов данных. Например, NVIDIA V100 (Volta, 2017), несмотря на наличие NVLink и памяти HBM, не поддерживает аппаратное ускорение FP8 и Int4 на тензорных ядрах. Между тем рассматриваемый стек существенно опирается на эти форматы: Qwen в квантизации GPTQ-Int4 с fp8 KV-cache, T-one в TensorRT, TTS с int8-квантизацией. На оборудовании предыдущих поколений соответствующие операции либо неработоспособны в требуемых форматах, либо выполняются с существенным замедлением за счёт программной эмуляции.&lt;br /&gt;
&lt;br /&gt;
С практической точки зрения приоритеты при выборе оборудования под данный пайплайн выстраиваются следующим образом: в первую очередь — поколение архитектуры (Ada, Ampere, Hopper, Blackwell — ввиду поддержки FP8 и Int4 на тензорных ядрах), далее — пропускная способность памяти, и лишь затем — объём VRAM, поскольку последний в рамках данной задачи практически всегда достаточен.&lt;br /&gt;
&lt;br /&gt;
Робот тестировался преимущественно на картах поколения Blackwell:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;RTX5090&#039;&#039;&#039; (использовалась другая LLM меньшего размера)&lt;br /&gt;
* &#039;&#039;&#039;RTX PRO 5000&#039;&#039;&#039; 48gb&lt;br /&gt;
* &#039;&#039;&#039;RTX PRO 6000&#039;&#039;&#039; 96gb&lt;br /&gt;
&lt;br /&gt;
Однако проводились также тесты на картах архитектуры &#039;&#039;&#039;Ampere&#039;&#039;&#039;. Результат можно считать удовлетворительным, особенно для организации тестовых и демо-сред без постоянной большой нагрузки.&lt;br /&gt;
&lt;br /&gt;
Отдельно хочется сказать про ускорители других производителей (AMD, Intel):&lt;br /&gt;
&lt;br /&gt;
К большому сожалению, большая часть инфраструктурного софта оптимизируется в первую очередь под ускорители NVIDIA. В связи с этим даже более производительные карты AMD &amp;quot;на бумаге&amp;quot;, по факту показывают значительно меньшие скорости при реальных задачах. Некоторые же библиотеки и компоненты (TensorRT, Triton Inference Server и т.д.) вообще являются проприетарными разработками NVIDIA и не поддерживают работу с ускорителями других производителей.&lt;br /&gt;
&lt;br /&gt;
=== Анизотропность нагрузки ===&lt;br /&gt;
Из-за логики работы голосового робота, нагрузка на его компоненты в рамках одной сессии достаточно неравномерна. Большинство моделей включаются последовательно после завершения инференса модели на предыдущем шаге:&lt;br /&gt;
&lt;br /&gt;
* VAD (детектирование голосовой активности) - работает всегда (но не вносит существенной нагрузки)&lt;br /&gt;
* ASR (распознавание речи) - запускается при срабатывании триггера VAD (окончание реплики)&lt;br /&gt;
* LLM - запускается после завершения работы ASR&lt;br /&gt;
* TTS - запускается во время / после завершения работы ASR (LLM возвращает текст в потоковом режиме. Текст разбивается на предложения и передается TTS в реальном времени)&lt;br /&gt;
&lt;br /&gt;
Кроме того, архитектурные особенности робота позволяют избегать шага вызова TTS для всех реплик, которые уже были сгенерированы ранее и помещены в кеш. Получается, что если инструкция робота задана таким образом, чтобы его реплики были &amp;quot;статичны&amp;quot; от сессии к сессии, получается экономить значительное количество ресурсов, переиспользуя уже существующие генерации.&lt;br /&gt;
&lt;br /&gt;
Свои оптимизации есть и на стороне инференса LLM:&lt;br /&gt;
&lt;br /&gt;
В команду запуска vLLM по-умолчанию включен режим prefix caching. Данный механизм позволяет кешировать системный промпт и переиспользовать ранее произведенные вычисления для новых запросов. Включение prefix caching позволяет экономить compute для однотипных запросов, а также уменьшить скорость отклика.&lt;br /&gt;
&lt;br /&gt;
Поскольку в рамках голосового робота все запросы (к конкретной конфигурации) используют один системный промпт, это позволяет серьезно экономить.&lt;br /&gt;
&lt;br /&gt;
Данный механизм теряет свою эффективность, к одной LLM будет обращаться большое число роботов с существенно отличающимися системными промптами (50+, точное количество зависит от доступного объема VRAM и настроек vLLM). Также механизм будет мешать, если LLM используется для каких-либо других задач, кроме работы голосового робота.&lt;br /&gt;
&lt;br /&gt;
=== Приблизительный расчет требуемых мощностей ===&lt;br /&gt;
Рекомендуемой конфигурацией является следующая:&lt;br /&gt;
&lt;br /&gt;
CPU 8x&lt;br /&gt;
&lt;br /&gt;
RAM 64gb DDR5&lt;br /&gt;
&lt;br /&gt;
300gb SSD &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Сравнение ускорителей&lt;br /&gt;
!Ускоритель&lt;br /&gt;
!Архитектура&lt;br /&gt;
!VRAM&lt;br /&gt;
!Bandwith&lt;br /&gt;
!Compute (INT8)&lt;br /&gt;
!Приблизительное количество параллельных сессий&lt;br /&gt;
|-&lt;br /&gt;
|RTX PRO 5000&lt;br /&gt;
|Blackwell&lt;br /&gt;
|48gb&lt;br /&gt;
|1.34TB/s&lt;br /&gt;
|516 TOPS&lt;br /&gt;
|30-40&lt;br /&gt;
|-&lt;br /&gt;
|RTX PRO 6000&lt;br /&gt;
|Blackwell&lt;br /&gt;
|96gb&lt;br /&gt;
|1.79TB/s&lt;br /&gt;
|1000 TOPS&lt;br /&gt;
|50-70&lt;br /&gt;
|-&lt;br /&gt;
|RTX 4090/48&lt;br /&gt;
|Ada&lt;br /&gt;
|48gb&lt;br /&gt;
|1TB/s&lt;br /&gt;
|660 TOPS&lt;br /&gt;
|25-30&lt;br /&gt;
|-&lt;br /&gt;
|2x RTX 5090&lt;br /&gt;
|Blackwell&lt;br /&gt;
|2x32gb&lt;br /&gt;
|1.79TB/s&lt;br /&gt;
|828 TOPS&lt;br /&gt;
|30-40&lt;br /&gt;
|-&lt;br /&gt;
|2x RTX 4090/24&lt;br /&gt;
|Ada&lt;br /&gt;
|2x24gb&lt;br /&gt;
|1TB/s&lt;br /&gt;
|660 TOPS&lt;br /&gt;
|10-20&lt;br /&gt;
|-&lt;br /&gt;
|A100/40&lt;br /&gt;
|Ampere&lt;br /&gt;
|40gb&lt;br /&gt;
|1.56TB/s&lt;br /&gt;
|624 TOPS&lt;br /&gt;
|18-23&lt;br /&gt;
|-&lt;br /&gt;
|A100/80&lt;br /&gt;
|Ampere&lt;br /&gt;
|80gb&lt;br /&gt;
|2TB/s&lt;br /&gt;
|624 TOPS&lt;br /&gt;
|55-75&lt;br /&gt;
|-&lt;br /&gt;
|H100&lt;br /&gt;
|Hopper&lt;br /&gt;
|80gb&lt;br /&gt;
|3.35TB/s&lt;br /&gt;
|990 TOPS&lt;br /&gt;
|70-100&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
При использовании конфигураций из двух карт с небольшим объемом VRAM (24, 32gb) будет происходить проблема дисбаланса:&lt;br /&gt;
&lt;br /&gt;
Одну из карт будет полностью занимать LLM (22gb базовых весов), а другую карту будут занимать другие модели. При этом в случае 2x24gb VRAM, для LLM будет оставаться крайне мало памяти на активные сессии, что будет являться главным ограничителем. Использовать память или compute соседней карты невозможно без NVLINK, а в потребительских картах он отсутствует.&lt;br /&gt;
&lt;br /&gt;
Таким образом вариант 2x4090/24 может использовать только для ненагруженных систем - демо стендов или сред разработки. Для такой конфигурации возможно заменить вторую карту на более простую, например 4080, так как TTS + ASR не реализуют 24gb vram.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем оперативной памяти не может быть меньше, чем 32gb, так как в процессе запуска веса моделей помещаются сначала в оперативную память, и только затем в VRAM.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Масштабирование сервиса ===&lt;br /&gt;
При масштабировании голосового робота существует три подхода:&lt;br /&gt;
&lt;br /&gt;
* Использование дополнительных GPU, либо переход на сервер с более производительным GPU&lt;br /&gt;
* Использование нескольких серверов с GPU для балансировки нагрузки&lt;br /&gt;
* Использование нескольких экземпляров робота (движков)&lt;br /&gt;
&lt;br /&gt;
На текущий момент наиболее удобным вариантом масштабирования является второй. Наиболее нагруженные сервисы vLLM и LightTTS можно выносить на отдельные сервера. При этом, например, для LightTTS не требуется большой объем VRAM, и он может качественно работать на сравнительно недорогих потребительских ускорителях (4090, 5080). &lt;br /&gt;
&lt;br /&gt;
Отдельно стоит упомянуть вынесение на отдельный сервер ASR. Данный компонент работает в потоковом режиме по протоколу gRPC, и не рекомендуется вынесение его на другие площадки с высокой задержкой. Остальные компоненты (за исключением VAD, который работает на CPU в составе главного сервиса secondchain), не чувствительны к дополнительным задержкам (в рамках разумного, до 50-70мс).&lt;br /&gt;
&lt;br /&gt;
=== Запуск робота с использованием облачных сервисов инференса ===&lt;br /&gt;
В случае, когда проектные требования позволяют использовать облачную инфраструктуру, нет необходимости полного разворота всех сервисов локально. Можно использовать ресурсы облачных провайдеров и ресурсы, предоставляемые командой платформы.&lt;br /&gt;
&lt;br /&gt;
Сервис поддерживает наиболее популярные API для работы с облачными моделями:&lt;br /&gt;
&lt;br /&gt;
* OpenAI-like формат для LLM. Позволяет подключать к роботу любые из современных передовых языковых моделей.&lt;br /&gt;
* OpenAI-like transcription формат для распознавания речи.&lt;br /&gt;
* LightTTS API формат для генерации речи&lt;br /&gt;
&lt;br /&gt;
Часто, экономически эффективным может быть использование только облачной LLM, так как она требует большого объема VRAM и дорогих ускорителей. При этом остальные модели запускаются локально, на более простой карте.&lt;br /&gt;
&lt;br /&gt;
При выборе облачной LLM критичными показателями являются следующие:&lt;br /&gt;
&lt;br /&gt;
* Метрика TTFT (Time To First Token). Время отклика модели до пересылки первых токенов ответа. Должна быть &amp;lt;=300мс, включая сетевые задержки;&lt;br /&gt;
* Поддержка streaming (SSE/chunked) ответов;&lt;br /&gt;
* Возможность отключения режима thinking/reasoning; &lt;br /&gt;
* Скорость генерации ответа &amp;gt;30 токенов/сек.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Популярные подписки на современные модели по типу &amp;quot;Token Plan&amp;quot;, которые предлагают использование с ограничением на количество запросов, а не тарификацию по токенам, зачастую непригодны для использования с роботом. Данные подписки используются в агентских системах, где время отклика не является целевой метрикой, а запросы инференса с таких подписок, как правило обрабатываются облачными сервисами с меньшим приоритетом.&amp;lt;/blockquote&amp;gt;При использовании всех облачных сервисов инференса, локально разворачивается только главный контейнер - secondchain. Рекомендуемые требования к серверу для такой среды:&lt;br /&gt;
&lt;br /&gt;
4x CPU&lt;br /&gt;
&lt;br /&gt;
8gb RAM&lt;br /&gt;
&lt;br /&gt;
80gb SSD&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
Установка самого Docker:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установка Nvidia Container Toolkit (только для серверов с GPU):&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# репозиторий&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \&lt;br /&gt;
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \&lt;br /&gt;
  sed &#039;s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g&#039; | \&lt;br /&gt;
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-container-toolkit&lt;br /&gt;
sudo nvidia-ctk runtime configure --runtime=docker&lt;br /&gt;
sudo systemctl restart docker&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (только для серверов с GPU) =&lt;br /&gt;
&lt;br /&gt;
Инструкция написана для Unbuntu 24.04.&lt;br /&gt;
&lt;br /&gt;
При написании и проверке данной инструкции использовался сервер с RTX PRO 5000 48gb.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Компиляция моделей может занимать больше VRAM, чем запущенный сервис, поэтому в случае дефицита видеопамяти, рекомендуется временно отключать свеже созданные контейнеры, собирать их по одному, после чего запускать по очереди уже в собранном виде.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton Inference Server) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
I0706 22:41:02.484518 1 grpc_server.cc:2562] &amp;quot;Started GRPCInferenceService at 0.0.0.0:8001&amp;quot;&lt;br /&gt;
I0706 22:41:02.484664 1 http_server.cc:4832] &amp;quot;Started HTTPService at 0.0.0.0:8000&amp;quot;&lt;br /&gt;
I0706 22:41:02.525792 1 http_server.cc:358] &amp;quot;Started Metrics Service at 0.0.0.0:8002&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
Установка выполняется из Docker Hub, следующей командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
* &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; — директория хост-машины, где будет храниться кеш весов модели (24gb)&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
После запуска vllm скачает веса модели для запуска (24gb). После завершения запуска и загрузки весов в логах можно наблюдать следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
(APIServer pid=1) INFO:     Started server process [1]&lt;br /&gt;
(APIServer pid=1) INFO:     Waiting for application startup.&lt;br /&gt;
(APIServer pid=1) INFO:     Application startup complete.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Как только они появятся, можно переходить к следующему шагу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080.&#039;&#039;&#039; Первый запрос к модели будет занимать достаточно много времени (холодный старт):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}],&lt;br /&gt;
    &amp;quot;chat_template_kwargs&amp;quot;: {&amp;quot;enable_thinking&amp;quot;: false}&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load -i lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights \&lt;br /&gt;
  python -m light_tts.server.api_server \&lt;br /&gt;
    --model_dir /opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
    --data_type float16 \&lt;br /&gt;
    --load_trt True \&lt;br /&gt;
    --host 0.0.0.0&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;После запуска сервис скомпилирует веса, по аналогии с T-One. После завершения подготовки в логах будут следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:391] ✅ Startup health check passed!&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:395] ✅ Application ready! Server is now accepting requests&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:396] 🌐 Listening at: http://localhost:8080&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — 10 &#039;&#039;&#039;GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 17000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 17001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Контейнеры сервисов инференса голосового робота.png|центр|безрамки|1067x1067пкс]]&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
Для упрощения работы с настройкой робота, нами был подготовлен набор демо-ресурсов:&lt;br /&gt;
&lt;br /&gt;
[[:Файл:Демо ресурсы для голосового робота.zip]]&lt;br /&gt;
&lt;br /&gt;
Он включает файл голоса, example.env и файлы для импорта в разделы приложения ИИ с готовым настроенным роботом.&lt;br /&gt;
&lt;br /&gt;
Необходимо переименовать файл example.env в .env и изменить в нём следующие параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&lt;br /&gt;
POSTGRES_HOST=[хост postgresql]&lt;br /&gt;
POSTGRES_PORT=5432&lt;br /&gt;
POSTGRES_USER=[логин postgresql]&lt;br /&gt;
POSTGRES_PASSWORD=[пароль postgresql]&lt;br /&gt;
POSTGRES_DB=[имя БД, если укзаанная БД отсутствует - она будет автоматически создана]&lt;br /&gt;
&lt;br /&gt;
CONCURRENT_SESSIONS=[Жесткое ограничение количества одновременных сессий]&lt;br /&gt;
&lt;br /&gt;
SIP_SERVER=[адрес Эры]&lt;br /&gt;
SIP_PORT=[порт SIP]&lt;br /&gt;
SIP_USERNAME=[Имя учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_PASSWORD=[Пароль учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_DOMAIN=[Полное имя домена, например robot.era-platform.ru]&lt;br /&gt;
#Детальные настройки SIP-клиента. В случае необходимости обхода NAT&lt;br /&gt;
SIP_TRANSPORT=udp&lt;br /&gt;
# NAT Traversal&lt;br /&gt;
SIP_STUN_SERVER=stun.l.google.com:19302&lt;br /&gt;
SIP_USE_ICE=false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
LLM_MODE=openai_api&lt;br /&gt;
#В случае использования сервиса инфереса vLLM на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LLM_OPENAI_API_BASE=http://localhost:16080/v1 &lt;br /&gt;
LLM_OPENAI_MODEL=qwen35-35b-a3b&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ASR_MODE=triton&lt;br /&gt;
#В случае использования сервиса инфереса tone-triton на другом хосте, необходимо изменить адреса/порты&lt;br /&gt;
ASR_TRITON_URL=http://localhost:17000&lt;br /&gt;
ASR_TRITON_GRPC=localhost:17001&lt;br /&gt;
ASR_TRITON_MODEL=streaming_acoustic&lt;br /&gt;
ASR_TRITON_TIMEOUT=10&lt;br /&gt;
ASR_DECODER_TYPE=beam_search&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
TTS_PROVIDER=lighttts&lt;br /&gt;
#В случае использования сервиса инфереса LightTTS на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LIGHTTTS_URL=http://localhost:8080/&lt;br /&gt;
LIGHTTTS_SAMPLE_RATE=24000&lt;br /&gt;
LIGHTTTS_STREAMING=false&lt;br /&gt;
LIGHTTTS_CONCURRENCY=4&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
= Этап 4. Запуск контейнера и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
docker load -i secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
Для упрощения работы с настройкой робота, нами был подготовлен набор демо-ресурсов:&lt;br /&gt;
&lt;br /&gt;
[[:Файл:Демо ресурсы для голосового робота.zip]]&lt;br /&gt;
&lt;br /&gt;
Он включает файл голоса, example.env и файлы для импорта в разделы приложения ИИ с готовым настроенным роботом.&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
[[Файл:Голос робота в приложении ИИ.png|мини]]&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
[[Файл:Инструменты робота.png|мини]]&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
[[Файл:Пример робота в приложении ИИ.png|мини]]&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
Системный промпт задаёт поведение робота, а промпт пост-обработки позволяет после окончания диалога проанализировать его и сохранить в сессии бизнес-результат (удобнее всего, в формате JSON).&lt;br /&gt;
&lt;br /&gt;
При составлении собственного системного важным эффектом является &amp;quot;внимательность&amp;quot; (attention) больших языковых моделей. Они более строго следуют инструкциям, написанным в начале и конце промпта. Поэтому данные области рекомендуется оставлять для строгих ограничений.&lt;br /&gt;
&lt;br /&gt;
Для построения надежных роботов с повторяемой эффективностью, рекомендуется использовать подход с описанием строгих шагов диалога.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
[[Файл:Статус робота.png|мини]]&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
[[Файл:Робот в очереди.png|мини]]&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2456</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2456"/>
		<updated>2026-07-07T12:19:09Z</updated>

		<summary type="html">&lt;p&gt;AZykov: /* Общая информация */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Общая информация =&lt;br /&gt;
[[Файл:Архитектура голосового робота.png|центр|безрамки|763x763пкс]]&lt;br /&gt;
= Глоссарий =&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Модель.&#039;&#039;&#039; Обученная нейросеть, задающая соответствие между входом и выходом (текст -&amp;gt; текст, звук -&amp;gt; текст и т.д.). Модель определяется архитектурой и набором весов, полученных при обучении. В стеке робота их четыре: VAD (детекция голосовой активности), ASR (распознавание речи), LLM (генерация ответа), TTS (синтез речи).&lt;br /&gt;
* &#039;&#039;&#039;Веса.&#039;&#039;&#039; Числовые параметры модели, полученные при обучении. Именно они хранятся в файлах модели и загружаются в VRAM при старте. «Загрузка весов» в логах vLLM — это чтение этих файлов с диска в память GPU.&lt;br /&gt;
* &#039;&#039;&#039;Инференс.&#039;&#039;&#039; Использование готовой модели для получения ответа на некий набор входных данных (&amp;quot;прогон&amp;quot; данных через веса). В отличие от обучения, веса не меняются. Сервисы инференса в статье — Triton, vLLM, LightTTS.&lt;br /&gt;
* &#039;&#039;&#039;LLM.&#039;&#039;&#039; Большая языковая модель. Класс моделей text-to-text, обученных на больших объемах мультиязычных и мультидоменных данных.&lt;br /&gt;
* &#039;&#039;&#039;Triton&#039;&#039;&#039; (NVIDIA Triton Inference Server). Сервер инференса от NVIDIA, обслуживающий модели по gRPC и HTTP. В стеке на нём крутится ASR-модель T-one.&lt;br /&gt;
* &#039;&#039;&#039;TensorRT.&#039;&#039;&#039; Библиотека NVIDIA для оптимизации моделей под конкретный GPU: она компилирует модель в специализированный «движок» ради ускорения инференса. Сборка такого движка — разовая операция под железо, поэтому в LightTTS и T-One Triton она выполняется на первой фазе и коммитится в образ.&lt;br /&gt;
* &#039;&#039;&#039;vLLM.&#039;&#039;&#039; Движок инференса для больших языковых моделей (LLM), оптимизированный на пропускную способность и эффективную работу с памятью. Предоставляет OpenAI-совместимый API.&lt;br /&gt;
* &#039;&#039;&#039;nvidia-smi&#039;&#039;&#039; (NVIDIA System Management Interface). Консольная утилита для просмотра состояния GPU: модель карты, версия драйвера, загрузка, потребление VRAM, запущенные процессы. Используется для проверки, что драйвер установлен и GPU виден (в т.ч. изнутри контейнера).&lt;br /&gt;
* &#039;&#039;&#039;KV-Cache&#039;&#039;&#039; (кэш ключей и значений). Память, где LLM хранит промежуточные представления уже обработанных токенов, чтобы не пересчитывать их при генерации каждого нового токена. Ускоряет генерацию ценой VRAM. В конфиге ограничен параметром &amp;lt;code&amp;gt;--kv-cache-memory&amp;lt;/code&amp;gt; (3 GiB). Растёт с числом сессий и длиной контекста — поэтому его размер критичен на картах с малым запасом VRAM.&lt;br /&gt;
* &#039;&#039;&#039;LightTTS.&#039;&#039;&#039; Движок инференса для TTS-моделей (синтеза речи). В стеке запускает модель CosyVoice3, слушает порт 8080.&lt;br /&gt;
* &#039;&#039;&#039;Промпт.&#039;&#039;&#039; Инструкция, которой следует большая языковая модель.&lt;br /&gt;
* &#039;&#039;&#039;Токен.&#039;&#039;&#039; В &#039;&#039;контексте LLM&#039;&#039; это единица текста, которой оперирует модель (примерно часть слова / слово / знак). В токенах измеряются окно контекста и объём генерации.&lt;br /&gt;
* &#039;&#039;&#039;Окно контекста.&#039;&#039;&#039; Максимальное количество токенов, которое LLM может учитывать за один запрос (вход + генерируемый ответ вместе). Чем больше окно, тем больше VRAM уходит под KV-Cache, поэтому на картах с ограниченным объёмом его сокращают.&lt;br /&gt;
* &#039;&#039;&#039;Compute.&#039;&#039;&#039; Вычислительные ресурсы GPU. Абстрактный ресурс видеоускорителя. Измеряется в GFLOP/TFLOP (операциях в секунду)&lt;br /&gt;
&lt;br /&gt;
= Требования к оборудованию, нагрузка и мастштабирование =&lt;br /&gt;
&lt;br /&gt;
=== Микросервисы робота и их нагрузка ===&lt;br /&gt;
Робот функционирует на базе 4 микросервисов, каждый из которых может быть вынесен на отдельный сервер, или исполняться на общем сервере. &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Микросервисы робота&lt;br /&gt;
!Название&lt;br /&gt;
!Назначение&lt;br /&gt;
!Ключевые ресурсы&lt;br /&gt;
!Минимальное потребление VRAM&lt;br /&gt;
!Дополнительное потребление VRAM из расчета на 1 сессию&lt;br /&gt;
!Условное потребление Compute на 1 сессию&lt;br /&gt;
|-&lt;br /&gt;
|secondchain&lt;br /&gt;
|Инференс модели VAD (CPU), логика робота, голосовой pipeline, работа с сессиями, SIP-клиент&lt;br /&gt;
|CPU, RAM&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
|vLLM (qwen3.5-35b-a3b-INT4)&lt;br /&gt;
Данные указаны с окном контекста 8192 токена.&lt;br /&gt;
|Инференс больших языковых моделей (LLM)&lt;br /&gt;
|VRAM, Compute&lt;br /&gt;
|22gb&lt;br /&gt;
|0.3gb&lt;br /&gt;
|~3 GFLOP/токен&lt;br /&gt;
|-&lt;br /&gt;
|T-one (Triton Inference Server)&lt;br /&gt;
|Инференс T-One speech-to-text&lt;br /&gt;
|Compute&lt;br /&gt;
|600mb&lt;br /&gt;
|10mb&lt;br /&gt;
|~1-3 GFLOP/секунда речи&lt;br /&gt;
|-&lt;br /&gt;
|LightTTS&lt;br /&gt;
|Инференс CosyVoice3 TTS&lt;br /&gt;
|Compute, VRAM&lt;br /&gt;
|8gb&lt;br /&gt;
|0.3gb&lt;br /&gt;
|~120GFLOP/секунда генерируемоей речи&lt;br /&gt;
|}&lt;br /&gt;
При высокой конкуренции за Compute, увеличиваются задержки на каждом из этапов инференса. Самым чувствительным компонентом, при этом, является LightTTS - из-за архитектурных особенностей. TTS требует много вычислительных ресурсов, и большое количество параллельных генераций могут значительно увеличивать задержку. В случае использования нескольких серверов рекомендуется первично выносить на отдельный сервер либо LightTTS, либо vLLM (для высвобождения Compute).&lt;br /&gt;
&lt;br /&gt;
Архитектурно при этом, робот устроен таким образом, чтобы минимизировать инференс LightTTS при возможности (агрессивное кеширование результатов TTS). &lt;br /&gt;
&lt;br /&gt;
=== Нюансы подбора GPU ===&lt;br /&gt;
При подборе GPU под данный стек объём VRAM не является определяющим критерием. Веса любой из трёх моделей помещаются в память практически любой современной карты (уровня 5090 или выше), тогда как реальными ограничивающими факторами выступают пропускная способность памяти на этапе декодирования LLM и вычислительная нагрузка DiT-декодера в TTS. Соответственно, при выборе оборудования следует ориентироваться в первую очередь на memory bandwidth и на аппаратную поддержку современных типов данных, а не на номинальный объём видеопамяти.&lt;br /&gt;
&lt;br /&gt;
Отдельного внимания заслуживает интерфейс межкарточного взаимодействия. Потребительские карты рассчитаны преимущественно на одиночную эксплуатацию: в актуальных линейках Blackwell и Ada поддержка NVLink отсутствует, и обмен между несколькими GPU на одном сервере осуществляется исключительно через PCIe (Gen4/Gen5). При использовании tensor parallelism это создаёт заметные накладные расходы на межкарточную коммуникацию, что становится ощутимым при высокой конкурентной нагрузке. Дата-центровые решения (H100, H200, а также RTX PRO 6000 в соответствующем сегменте) либо предоставляют NVLink с пропускной способностью в сотни ГБ/с, либо обладают достаточным объёмом памяти для размещения моделей на одной карте, что позволяет полностью исключить tensor parallelism и связанные с ним издержки.&lt;br /&gt;
&lt;br /&gt;
Следует также учитывать высокие темпы развития архитектур GPU. Производительная карта шестилетней давности может уступать современному решению среднего уровня как по вычислительной мощности, так и — что существенно в данном случае — по набору поддерживаемых типов данных. Например, NVIDIA V100 (Volta, 2017), несмотря на наличие NVLink и памяти HBM, не поддерживает аппаратное ускорение FP8 и Int4 на тензорных ядрах. Между тем рассматриваемый стек существенно опирается на эти форматы: Qwen в квантизации GPTQ-Int4 с fp8 KV-cache, T-one в TensorRT, TTS с int8-квантизацией. На оборудовании предыдущих поколений соответствующие операции либо неработоспособны в требуемых форматах, либо выполняются с существенным замедлением за счёт программной эмуляции.&lt;br /&gt;
&lt;br /&gt;
С практической точки зрения приоритеты при выборе оборудования под данный пайплайн выстраиваются следующим образом: в первую очередь — поколение архитектуры (Ada, Ampere, Hopper, Blackwell — ввиду поддержки FP8 и Int4 на тензорных ядрах), далее — пропускная способность памяти, и лишь затем — объём VRAM, поскольку последний в рамках данной задачи практически всегда достаточен.&lt;br /&gt;
&lt;br /&gt;
Робот тестировался преимущественно на картах поколения Blackwell:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;RTX5090&#039;&#039;&#039; (использовалась другая LLM меньшего размера)&lt;br /&gt;
* &#039;&#039;&#039;RTX PRO 5000&#039;&#039;&#039; 48gb&lt;br /&gt;
* &#039;&#039;&#039;RTX PRO 6000&#039;&#039;&#039; 96gb&lt;br /&gt;
&lt;br /&gt;
Однако проводились также тесты на картах архитектуры &#039;&#039;&#039;Ampere&#039;&#039;&#039;. Результат можно считать удовлетворительным, особенно для организации тестовых и демо-сред без постоянной большой нагрузки.&lt;br /&gt;
&lt;br /&gt;
Отдельно хочется сказать про ускорители других производителей (AMD, Intel):&lt;br /&gt;
&lt;br /&gt;
К большому сожалению, большая часть инфраструктурного софта оптимизируется в первую очередь под ускорители NVIDIA. В связи с этим даже более производительные карты AMD &amp;quot;на бумаге&amp;quot;, по факту показывают значительно меньшие скорости при реальных задачах. Некоторые же библиотеки и компоненты (TensorRT, Triton Inference Server и т.д.) вообще являются проприетарными разработками NVIDIA и не поддерживают работу с ускорителями других производителей.&lt;br /&gt;
&lt;br /&gt;
=== Анизотропность нагрузки ===&lt;br /&gt;
Из-за логики работы голосового робота, нагрузка на его компоненты в рамках одной сессии достаточно неравномерна. Большинство моделей включаются последовательно после завершения инференса модели на предыдущем шаге:&lt;br /&gt;
&lt;br /&gt;
* VAD (детектирование голосовой активности) - работает всегда (но не вносит существенной нагрузки)&lt;br /&gt;
* ASR (распознавание речи) - запускается при срабатывании триггера VAD (окончание реплики)&lt;br /&gt;
* LLM - запускается после завершения работы ASR&lt;br /&gt;
* TTS - запускается во время / после завершения работы ASR (LLM возвращает текст в потоковом режиме. Текст разбивается на предложения и передается TTS в реальном времени)&lt;br /&gt;
&lt;br /&gt;
Кроме того, архитектурные особенности робота позволяют избегать шага вызова TTS для всех реплик, которые уже были сгенерированы ранее и помещены в кеш. Получается, что если инструкция робота задана таким образом, чтобы его реплики были &amp;quot;статичны&amp;quot; от сессии к сессии, получается экономить значительное количество ресурсов, переиспользуя уже существующие генерации.&lt;br /&gt;
&lt;br /&gt;
Свои оптимизации есть и на стороне инференса LLM:&lt;br /&gt;
&lt;br /&gt;
В команду запуска vLLM по-умолчанию включен режим prefix caching. Данный механизм позволяет кешировать системный промпт и переиспользовать ранее произведенные вычисления для новых запросов. Включение prefix caching позволяет экономить compute для однотипных запросов, а также уменьшить скорость отклика.&lt;br /&gt;
&lt;br /&gt;
Поскольку в рамках голосового робота все запросы (к конкретной конфигурации) используют один системный промпт, это позволяет серьезно экономить.&lt;br /&gt;
&lt;br /&gt;
Данный механизм теряет свою эффективность, к одной LLM будет обращаться большое число роботов с существенно отличающимися системными промптами (50+, точное количество зависит от доступного объема VRAM и настроек vLLM). Также механизм будет мешать, если LLM используется для каких-либо других задач, кроме работы голосового робота.&lt;br /&gt;
&lt;br /&gt;
=== Приблизительный расчет требуемых мощностей ===&lt;br /&gt;
Рекомендуемой конфигурацией является следующая:&lt;br /&gt;
&lt;br /&gt;
CPU 8x&lt;br /&gt;
&lt;br /&gt;
RAM 64gb DDR5&lt;br /&gt;
&lt;br /&gt;
300gb SSD &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Сравнение ускорителей&lt;br /&gt;
!Ускоритель&lt;br /&gt;
!Архитектура&lt;br /&gt;
!VRAM&lt;br /&gt;
!Bandwith&lt;br /&gt;
!Compute (INT8)&lt;br /&gt;
!Приблизительное количество параллельных сессий&lt;br /&gt;
|-&lt;br /&gt;
|RTX PRO 5000&lt;br /&gt;
|Blackwell&lt;br /&gt;
|48gb&lt;br /&gt;
|1.34TB/s&lt;br /&gt;
|516 TOPS&lt;br /&gt;
|30-40&lt;br /&gt;
|-&lt;br /&gt;
|RTX PRO 6000&lt;br /&gt;
|Blackwell&lt;br /&gt;
|96gb&lt;br /&gt;
|1.79TB/s&lt;br /&gt;
|1000 TOPS&lt;br /&gt;
|50-70&lt;br /&gt;
|-&lt;br /&gt;
|RTX 4090/48&lt;br /&gt;
|Ada&lt;br /&gt;
|48gb&lt;br /&gt;
|1TB/s&lt;br /&gt;
|660 TOPS&lt;br /&gt;
|25-30&lt;br /&gt;
|-&lt;br /&gt;
|2x RTX 5090&lt;br /&gt;
|Blackwell&lt;br /&gt;
|2x32gb&lt;br /&gt;
|1.79TB/s&lt;br /&gt;
|828 TOPS&lt;br /&gt;
|30-40&lt;br /&gt;
|-&lt;br /&gt;
|2x RTX 4090/24&lt;br /&gt;
|Ada&lt;br /&gt;
|2x24gb&lt;br /&gt;
|1TB/s&lt;br /&gt;
|660 TOPS&lt;br /&gt;
|10-20&lt;br /&gt;
|-&lt;br /&gt;
|A100/40&lt;br /&gt;
|Ampere&lt;br /&gt;
|40gb&lt;br /&gt;
|1.56TB/s&lt;br /&gt;
|624 TOPS&lt;br /&gt;
|18-23&lt;br /&gt;
|-&lt;br /&gt;
|A100/80&lt;br /&gt;
|Ampere&lt;br /&gt;
|80gb&lt;br /&gt;
|2TB/s&lt;br /&gt;
|624 TOPS&lt;br /&gt;
|55-75&lt;br /&gt;
|-&lt;br /&gt;
|H100&lt;br /&gt;
|Hopper&lt;br /&gt;
|80gb&lt;br /&gt;
|3.35TB/s&lt;br /&gt;
|990 TOPS&lt;br /&gt;
|70-100&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
При использовании конфигураций из двух карт с небольшим объемом VRAM (24, 32gb) будет происходить проблема дисбаланса:&lt;br /&gt;
&lt;br /&gt;
Одну из карт будет полностью занимать LLM (22gb базовых весов), а другую карту будут занимать другие модели. При этом в случае 2x24gb VRAM, для LLM будет оставаться крайне мало памяти на активные сессии, что будет являться главным ограничителем. Использовать память или compute соседней карты невозможно без NVLINK, а в потребительских картах он отсутствует.&lt;br /&gt;
&lt;br /&gt;
Таким образом вариант 2x4090/24 может использовать только для ненагруженных систем - демо стендов или сред разработки. Для такой конфигурации возможно заменить вторую карту на более простую, например 4080, так как TTS + ASR не реализуют 24gb vram.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем оперативной памяти не может быть меньше, чем 32gb, так как в процессе запуска веса моделей помещаются сначала в оперативную память, и только затем в VRAM.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Масштабирование сервиса ===&lt;br /&gt;
При масштабировании голосового робота существует три подхода:&lt;br /&gt;
&lt;br /&gt;
* Использование дополнительных GPU, либо переход на сервер с более производительным GPU&lt;br /&gt;
* Использование нескольких серверов с GPU для балансировки нагрузки&lt;br /&gt;
* Использование нескольких экземпляров робота (движков)&lt;br /&gt;
&lt;br /&gt;
На текущий момент наиболее удобным вариантом масштабирования является второй. Наиболее нагруженные сервисы vLLM и LightTTS можно выносить на отдельные сервера. При этом, например, для LightTTS не требуется большой объем VRAM, и он может качественно работать на сравнительно недорогих потребительских ускорителях (4090, 5080). &lt;br /&gt;
&lt;br /&gt;
Отдельно стоит упомянуть вынесение на отдельный сервер ASR. Данный компонент работает в потоковом режиме по протоколу gRPC, и не рекомендуется вынесение его на другие площадки с высокой задержкой. Остальные компоненты (за исключением VAD, который работает на CPU в составе главного сервиса secondchain), не чувствительны к дополнительным задержкам (в рамках разумного, до 50-70мс).&lt;br /&gt;
&lt;br /&gt;
=== Запуск робота с использованием облачных сервисов инференса ===&lt;br /&gt;
В случае, когда проектные требования позволяют использовать облачную инфраструктуру, нет необходимости полного разворота всех сервисов локально. Можно использовать ресурсы облачных провайдеров и ресурсы, предоставляемые командой платформы.&lt;br /&gt;
&lt;br /&gt;
Сервис поддерживает наиболее популярные API для работы с облачными моделями:&lt;br /&gt;
&lt;br /&gt;
* OpenAI-like формат для LLM. Позволяет подключать к роботу любые из современных передовых языковых моделей.&lt;br /&gt;
* OpenAI-like transcription формат для распознавания речи.&lt;br /&gt;
* LightTTS API формат для генерации речи&lt;br /&gt;
&lt;br /&gt;
Часто, экономически эффективным может быть использование только облачной LLM, так как она требует большого объема VRAM и дорогих ускорителей. При этом остальные модели запускаются локально, на более простой карте.&lt;br /&gt;
&lt;br /&gt;
При выборе облачной LLM критичными показателями являются следующие:&lt;br /&gt;
&lt;br /&gt;
* Метрика TTFT (Time To First Token). Время отклика модели до пересылки первых токенов ответа. Должна быть &amp;lt;=300мс, включая сетевые задержки;&lt;br /&gt;
* Поддержка streaming (SSE/chunked) ответов;&lt;br /&gt;
* Возможность отключения режима thinking/reasoning; &lt;br /&gt;
* Скорость генерации ответа &amp;gt;30 токенов/сек.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Популярные подписки на современные модели по типу &amp;quot;Token Plan&amp;quot;, которые предлагают использование с ограничением на количество запросов, а не тарификацию по токенам, зачастую непригодны для использования с роботом. Данные подписки используются в агентских системах, где время отклика не является целевой метрикой, а запросы инференса с таких подписок, как правило обрабатываются облачными сервисами с меньшим приоритетом.&amp;lt;/blockquote&amp;gt;При использовании всех облачных сервисов инференса, локально разворачивается только главный контейнер - secondchain. Рекомендуемые требования к серверу для такой среды:&lt;br /&gt;
&lt;br /&gt;
4x CPU&lt;br /&gt;
&lt;br /&gt;
8gb RAM&lt;br /&gt;
&lt;br /&gt;
80gb SSD&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
Установка самого Docker:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установка Nvidia Container Toolkit (только для серверов с GPU):&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# репозиторий&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \&lt;br /&gt;
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \&lt;br /&gt;
  sed &#039;s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g&#039; | \&lt;br /&gt;
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-container-toolkit&lt;br /&gt;
sudo nvidia-ctk runtime configure --runtime=docker&lt;br /&gt;
sudo systemctl restart docker&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (только для серверов с GPU) =&lt;br /&gt;
&lt;br /&gt;
Инструкция написана для Unbuntu 24.04.&lt;br /&gt;
&lt;br /&gt;
При написании и проверке данной инструкции использовался сервер с RTX PRO 5000 48gb.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Компиляция моделей может занимать больше VRAM, чем запущенный сервис, поэтому в случае дефицита видеопамяти, рекомендуется временно отключать свеже созданные контейнеры, собирать их по одному, после чего запускать по очереди уже в собранном виде.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton Inference Server) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
I0706 22:41:02.484518 1 grpc_server.cc:2562] &amp;quot;Started GRPCInferenceService at 0.0.0.0:8001&amp;quot;&lt;br /&gt;
I0706 22:41:02.484664 1 http_server.cc:4832] &amp;quot;Started HTTPService at 0.0.0.0:8000&amp;quot;&lt;br /&gt;
I0706 22:41:02.525792 1 http_server.cc:358] &amp;quot;Started Metrics Service at 0.0.0.0:8002&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
Установка выполняется из Docker Hub, следующей командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
* &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; — директория хост-машины, где будет храниться кеш весов модели (24gb)&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
После запуска vllm скачает веса модели для запуска (24gb). После завершения запуска и загрузки весов в логах можно наблюдать следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
(APIServer pid=1) INFO:     Started server process [1]&lt;br /&gt;
(APIServer pid=1) INFO:     Waiting for application startup.&lt;br /&gt;
(APIServer pid=1) INFO:     Application startup complete.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Как только они появятся, можно переходить к следующему шагу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080.&#039;&#039;&#039; Первый запрос к модели будет занимать достаточно много времени (холодный старт):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}],&lt;br /&gt;
    &amp;quot;chat_template_kwargs&amp;quot;: {&amp;quot;enable_thinking&amp;quot;: false}&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load -i lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights \&lt;br /&gt;
  python -m light_tts.server.api_server \&lt;br /&gt;
    --model_dir /opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
    --data_type float16 \&lt;br /&gt;
    --load_trt True \&lt;br /&gt;
    --host 0.0.0.0&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;После запуска сервис скомпилирует веса, по аналогии с T-One. После завершения подготовки в логах будут следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:391] ✅ Startup health check passed!&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:395] ✅ Application ready! Server is now accepting requests&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:396] 🌐 Listening at: http://localhost:8080&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — 10 &#039;&#039;&#039;GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 17000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 17001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Контейнеры сервисов инференса голосового робота.png|центр|безрамки|1067x1067пкс]]&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
Для упрощения работы с настройкой робота, нами был подготовлен набор демо-ресурсов:&lt;br /&gt;
&lt;br /&gt;
[[:Файл:Демо ресурсы для голосового робота.zip]]&lt;br /&gt;
&lt;br /&gt;
Он включает файл голоса, example.env и файлы для импорта в разделы приложения ИИ с готовым настроенным роботом.&lt;br /&gt;
&lt;br /&gt;
Необходимо переименовать файл example.env в .env и изменить в нём следующие параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&lt;br /&gt;
POSTGRES_HOST=[хост postgresql]&lt;br /&gt;
POSTGRES_PORT=5432&lt;br /&gt;
POSTGRES_USER=[логин postgresql]&lt;br /&gt;
POSTGRES_PASSWORD=[пароль postgresql]&lt;br /&gt;
POSTGRES_DB=[имя БД, если укзаанная БД отсутствует - она будет автоматически создана]&lt;br /&gt;
&lt;br /&gt;
CONCURRENT_SESSIONS=[Жесткое ограничение количества одновременных сессий]&lt;br /&gt;
&lt;br /&gt;
SIP_SERVER=[адрес Эры]&lt;br /&gt;
SIP_PORT=[порт SIP]&lt;br /&gt;
SIP_USERNAME=[Имя учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_PASSWORD=[Пароль учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_DOMAIN=[Полное имя домена, например robot.era-platform.ru]&lt;br /&gt;
#Детальные настройки SIP-клиента. В случае необходимости обхода NAT&lt;br /&gt;
SIP_TRANSPORT=udp&lt;br /&gt;
# NAT Traversal&lt;br /&gt;
SIP_STUN_SERVER=stun.l.google.com:19302&lt;br /&gt;
SIP_USE_ICE=false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
LLM_MODE=openai_api&lt;br /&gt;
#В случае использования сервиса инфереса vLLM на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LLM_OPENAI_API_BASE=http://localhost:16080/v1 &lt;br /&gt;
LLM_OPENAI_MODEL=qwen35-35b-a3b&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ASR_MODE=triton&lt;br /&gt;
#В случае использования сервиса инфереса tone-triton на другом хосте, необходимо изменить адреса/порты&lt;br /&gt;
ASR_TRITON_URL=http://localhost:17000&lt;br /&gt;
ASR_TRITON_GRPC=localhost:17001&lt;br /&gt;
ASR_TRITON_MODEL=streaming_acoustic&lt;br /&gt;
ASR_TRITON_TIMEOUT=10&lt;br /&gt;
ASR_DECODER_TYPE=beam_search&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
TTS_PROVIDER=lighttts&lt;br /&gt;
#В случае использования сервиса инфереса LightTTS на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LIGHTTTS_URL=http://localhost:8080/&lt;br /&gt;
LIGHTTTS_SAMPLE_RATE=24000&lt;br /&gt;
LIGHTTTS_STREAMING=false&lt;br /&gt;
LIGHTTTS_CONCURRENCY=4&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
= Этап 4. Запуск контейнера и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
docker load -i secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
Для упрощения работы с настройкой робота, нами был подготовлен набор демо-ресурсов:&lt;br /&gt;
&lt;br /&gt;
[[:Файл:Демо ресурсы для голосового робота.zip]]&lt;br /&gt;
&lt;br /&gt;
Он включает файл голоса, example.env и файлы для импорта в разделы приложения ИИ с готовым настроенным роботом.&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
[[Файл:Голос робота в приложении ИИ.png|мини]]&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
[[Файл:Инструменты робота.png|мини]]&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
[[Файл:Пример робота в приложении ИИ.png|мини]]&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
Системный промпт задаёт поведение робота, а промпт пост-обработки позволяет после окончания диалога проанализировать его и сохранить в сессии бизнес-результат (удобнее всего, в формате JSON).&lt;br /&gt;
&lt;br /&gt;
При составлении собственного системного важным эффектом является &amp;quot;внимательность&amp;quot; (attention) больших языковых моделей. Они более строго следуют инструкциям, написанным в начале и конце промпта. Поэтому данные области рекомендуется оставлять для строгих ограничений.&lt;br /&gt;
&lt;br /&gt;
Для построения надежных роботов с повторяемой эффективностью, рекомендуется использовать подход с описанием строгих шагов диалога.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
[[Файл:Статус робота.png|мини]]&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
[[Файл:Робот в очереди.png|мини]]&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2455</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2455"/>
		<updated>2026-07-07T12:18:08Z</updated>

		<summary type="html">&lt;p&gt;AZykov: /* Глоссарий */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Общая информация =&lt;br /&gt;
[[Файл:Архитектура голосового робота.png|центр|безрамки|763x763пкс]]&lt;br /&gt;
Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 1. Подготовка|Подготовка]]&#039;&#039;&#039; — Docker, PostgreSQL, настройки в системе телефонии.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 2. Установка сервисов инференса (опционально)|Установка сервисов инференса]]&#039;&#039;&#039; — ASR, LLM, TTS. &#039;&#039;Опционально, только для развёртывания на собственном сервере с GPU.&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 3. Настройка .env|Настройка .env]]&#039;&#039;&#039; — параметры подключения.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 4. Запуск контейнера и создание робота|Запуск контейнера и создание робота]]&#039;&#039;&#039; — старт сервиса и конфигурация робота.&lt;br /&gt;
&lt;br /&gt;
= Глоссарий =&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Модель.&#039;&#039;&#039; Обученная нейросеть, задающая соответствие между входом и выходом (текст -&amp;gt; текст, звук -&amp;gt; текст и т.д.). Модель определяется архитектурой и набором весов, полученных при обучении. В стеке робота их четыре: VAD (детекция голосовой активности), ASR (распознавание речи), LLM (генерация ответа), TTS (синтез речи).&lt;br /&gt;
* &#039;&#039;&#039;Веса.&#039;&#039;&#039; Числовые параметры модели, полученные при обучении. Именно они хранятся в файлах модели и загружаются в VRAM при старте. «Загрузка весов» в логах vLLM — это чтение этих файлов с диска в память GPU.&lt;br /&gt;
* &#039;&#039;&#039;Инференс.&#039;&#039;&#039; Использование готовой модели для получения ответа на некий набор входных данных (&amp;quot;прогон&amp;quot; данных через веса). В отличие от обучения, веса не меняются. Сервисы инференса в статье — Triton, vLLM, LightTTS.&lt;br /&gt;
* &#039;&#039;&#039;LLM.&#039;&#039;&#039; Большая языковая модель. Класс моделей text-to-text, обученных на больших объемах мультиязычных и мультидоменных данных.&lt;br /&gt;
* &#039;&#039;&#039;Triton&#039;&#039;&#039; (NVIDIA Triton Inference Server). Сервер инференса от NVIDIA, обслуживающий модели по gRPC и HTTP. В стеке на нём крутится ASR-модель T-one.&lt;br /&gt;
* &#039;&#039;&#039;TensorRT.&#039;&#039;&#039; Библиотека NVIDIA для оптимизации моделей под конкретный GPU: она компилирует модель в специализированный «движок» ради ускорения инференса. Сборка такого движка — разовая операция под железо, поэтому в LightTTS и T-One Triton она выполняется на первой фазе и коммитится в образ.&lt;br /&gt;
* &#039;&#039;&#039;vLLM.&#039;&#039;&#039; Движок инференса для больших языковых моделей (LLM), оптимизированный на пропускную способность и эффективную работу с памятью. Предоставляет OpenAI-совместимый API.&lt;br /&gt;
* &#039;&#039;&#039;nvidia-smi&#039;&#039;&#039; (NVIDIA System Management Interface). Консольная утилита для просмотра состояния GPU: модель карты, версия драйвера, загрузка, потребление VRAM, запущенные процессы. Используется для проверки, что драйвер установлен и GPU виден (в т.ч. изнутри контейнера).&lt;br /&gt;
* &#039;&#039;&#039;KV-Cache&#039;&#039;&#039; (кэш ключей и значений). Память, где LLM хранит промежуточные представления уже обработанных токенов, чтобы не пересчитывать их при генерации каждого нового токена. Ускоряет генерацию ценой VRAM. В конфиге ограничен параметром &amp;lt;code&amp;gt;--kv-cache-memory&amp;lt;/code&amp;gt; (3 GiB). Растёт с числом сессий и длиной контекста — поэтому его размер критичен на картах с малым запасом VRAM.&lt;br /&gt;
* &#039;&#039;&#039;LightTTS.&#039;&#039;&#039; Движок инференса для TTS-моделей (синтеза речи). В стеке запускает модель CosyVoice3, слушает порт 8080.&lt;br /&gt;
* &#039;&#039;&#039;Промпт.&#039;&#039;&#039; Инструкция, которой следует большая языковая модель.&lt;br /&gt;
* &#039;&#039;&#039;Токен.&#039;&#039;&#039; В &#039;&#039;контексте LLM&#039;&#039; это единица текста, которой оперирует модель (примерно часть слова / слово / знак). В токенах измеряются окно контекста и объём генерации.&lt;br /&gt;
* &#039;&#039;&#039;Окно контекста.&#039;&#039;&#039; Максимальное количество токенов, которое LLM может учитывать за один запрос (вход + генерируемый ответ вместе). Чем больше окно, тем больше VRAM уходит под KV-Cache, поэтому на картах с ограниченным объёмом его сокращают.&lt;br /&gt;
* &#039;&#039;&#039;Compute.&#039;&#039;&#039; Вычислительные ресурсы GPU. Абстрактный ресурс видеоускорителя. Измеряется в GFLOP/TFLOP (операциях в секунду)&lt;br /&gt;
&lt;br /&gt;
= Требования к оборудованию, нагрузка и мастштабирование =&lt;br /&gt;
&lt;br /&gt;
=== Микросервисы робота и их нагрузка ===&lt;br /&gt;
Робот функционирует на базе 4 микросервисов, каждый из которых может быть вынесен на отдельный сервер, или исполняться на общем сервере. &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Микросервисы робота&lt;br /&gt;
!Название&lt;br /&gt;
!Назначение&lt;br /&gt;
!Ключевые ресурсы&lt;br /&gt;
!Минимальное потребление VRAM&lt;br /&gt;
!Дополнительное потребление VRAM из расчета на 1 сессию&lt;br /&gt;
!Условное потребление Compute на 1 сессию&lt;br /&gt;
|-&lt;br /&gt;
|secondchain&lt;br /&gt;
|Инференс модели VAD (CPU), логика робота, голосовой pipeline, работа с сессиями, SIP-клиент&lt;br /&gt;
|CPU, RAM&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
|vLLM (qwen3.5-35b-a3b-INT4)&lt;br /&gt;
Данные указаны с окном контекста 8192 токена.&lt;br /&gt;
|Инференс больших языковых моделей (LLM)&lt;br /&gt;
|VRAM, Compute&lt;br /&gt;
|22gb&lt;br /&gt;
|0.3gb&lt;br /&gt;
|~3 GFLOP/токен&lt;br /&gt;
|-&lt;br /&gt;
|T-one (Triton Inference Server)&lt;br /&gt;
|Инференс T-One speech-to-text&lt;br /&gt;
|Compute&lt;br /&gt;
|600mb&lt;br /&gt;
|10mb&lt;br /&gt;
|~1-3 GFLOP/секунда речи&lt;br /&gt;
|-&lt;br /&gt;
|LightTTS&lt;br /&gt;
|Инференс CosyVoice3 TTS&lt;br /&gt;
|Compute, VRAM&lt;br /&gt;
|8gb&lt;br /&gt;
|0.3gb&lt;br /&gt;
|~120GFLOP/секунда генерируемоей речи&lt;br /&gt;
|}&lt;br /&gt;
При высокой конкуренции за Compute, увеличиваются задержки на каждом из этапов инференса. Самым чувствительным компонентом, при этом, является LightTTS - из-за архитектурных особенностей. TTS требует много вычислительных ресурсов, и большое количество параллельных генераций могут значительно увеличивать задержку. В случае использования нескольких серверов рекомендуется первично выносить на отдельный сервер либо LightTTS, либо vLLM (для высвобождения Compute).&lt;br /&gt;
&lt;br /&gt;
Архитектурно при этом, робот устроен таким образом, чтобы минимизировать инференс LightTTS при возможности (агрессивное кеширование результатов TTS). &lt;br /&gt;
&lt;br /&gt;
=== Нюансы подбора GPU ===&lt;br /&gt;
При подборе GPU под данный стек объём VRAM не является определяющим критерием. Веса любой из трёх моделей помещаются в память практически любой современной карты (уровня 5090 или выше), тогда как реальными ограничивающими факторами выступают пропускная способность памяти на этапе декодирования LLM и вычислительная нагрузка DiT-декодера в TTS. Соответственно, при выборе оборудования следует ориентироваться в первую очередь на memory bandwidth и на аппаратную поддержку современных типов данных, а не на номинальный объём видеопамяти.&lt;br /&gt;
&lt;br /&gt;
Отдельного внимания заслуживает интерфейс межкарточного взаимодействия. Потребительские карты рассчитаны преимущественно на одиночную эксплуатацию: в актуальных линейках Blackwell и Ada поддержка NVLink отсутствует, и обмен между несколькими GPU на одном сервере осуществляется исключительно через PCIe (Gen4/Gen5). При использовании tensor parallelism это создаёт заметные накладные расходы на межкарточную коммуникацию, что становится ощутимым при высокой конкурентной нагрузке. Дата-центровые решения (H100, H200, а также RTX PRO 6000 в соответствующем сегменте) либо предоставляют NVLink с пропускной способностью в сотни ГБ/с, либо обладают достаточным объёмом памяти для размещения моделей на одной карте, что позволяет полностью исключить tensor parallelism и связанные с ним издержки.&lt;br /&gt;
&lt;br /&gt;
Следует также учитывать высокие темпы развития архитектур GPU. Производительная карта шестилетней давности может уступать современному решению среднего уровня как по вычислительной мощности, так и — что существенно в данном случае — по набору поддерживаемых типов данных. Например, NVIDIA V100 (Volta, 2017), несмотря на наличие NVLink и памяти HBM, не поддерживает аппаратное ускорение FP8 и Int4 на тензорных ядрах. Между тем рассматриваемый стек существенно опирается на эти форматы: Qwen в квантизации GPTQ-Int4 с fp8 KV-cache, T-one в TensorRT, TTS с int8-квантизацией. На оборудовании предыдущих поколений соответствующие операции либо неработоспособны в требуемых форматах, либо выполняются с существенным замедлением за счёт программной эмуляции.&lt;br /&gt;
&lt;br /&gt;
С практической точки зрения приоритеты при выборе оборудования под данный пайплайн выстраиваются следующим образом: в первую очередь — поколение архитектуры (Ada, Ampere, Hopper, Blackwell — ввиду поддержки FP8 и Int4 на тензорных ядрах), далее — пропускная способность памяти, и лишь затем — объём VRAM, поскольку последний в рамках данной задачи практически всегда достаточен.&lt;br /&gt;
&lt;br /&gt;
Робот тестировался преимущественно на картах поколения Blackwell:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;RTX5090&#039;&#039;&#039; (использовалась другая LLM меньшего размера)&lt;br /&gt;
* &#039;&#039;&#039;RTX PRO 5000&#039;&#039;&#039; 48gb&lt;br /&gt;
* &#039;&#039;&#039;RTX PRO 6000&#039;&#039;&#039; 96gb&lt;br /&gt;
&lt;br /&gt;
Однако проводились также тесты на картах архитектуры &#039;&#039;&#039;Ampere&#039;&#039;&#039;. Результат можно считать удовлетворительным, особенно для организации тестовых и демо-сред без постоянной большой нагрузки.&lt;br /&gt;
&lt;br /&gt;
Отдельно хочется сказать про ускорители других производителей (AMD, Intel):&lt;br /&gt;
&lt;br /&gt;
К большому сожалению, большая часть инфраструктурного софта оптимизируется в первую очередь под ускорители NVIDIA. В связи с этим даже более производительные карты AMD &amp;quot;на бумаге&amp;quot;, по факту показывают значительно меньшие скорости при реальных задачах. Некоторые же библиотеки и компоненты (TensorRT, Triton Inference Server и т.д.) вообще являются проприетарными разработками NVIDIA и не поддерживают работу с ускорителями других производителей.&lt;br /&gt;
&lt;br /&gt;
=== Анизотропность нагрузки ===&lt;br /&gt;
Из-за логики работы голосового робота, нагрузка на его компоненты в рамках одной сессии достаточно неравномерна. Большинство моделей включаются последовательно после завершения инференса модели на предыдущем шаге:&lt;br /&gt;
&lt;br /&gt;
* VAD (детектирование голосовой активности) - работает всегда (но не вносит существенной нагрузки)&lt;br /&gt;
* ASR (распознавание речи) - запускается при срабатывании триггера VAD (окончание реплики)&lt;br /&gt;
* LLM - запускается после завершения работы ASR&lt;br /&gt;
* TTS - запускается во время / после завершения работы ASR (LLM возвращает текст в потоковом режиме. Текст разбивается на предложения и передается TTS в реальном времени)&lt;br /&gt;
&lt;br /&gt;
Кроме того, архитектурные особенности робота позволяют избегать шага вызова TTS для всех реплик, которые уже были сгенерированы ранее и помещены в кеш. Получается, что если инструкция робота задана таким образом, чтобы его реплики были &amp;quot;статичны&amp;quot; от сессии к сессии, получается экономить значительное количество ресурсов, переиспользуя уже существующие генерации.&lt;br /&gt;
&lt;br /&gt;
Свои оптимизации есть и на стороне инференса LLM:&lt;br /&gt;
&lt;br /&gt;
В команду запуска vLLM по-умолчанию включен режим prefix caching. Данный механизм позволяет кешировать системный промпт и переиспользовать ранее произведенные вычисления для новых запросов. Включение prefix caching позволяет экономить compute для однотипных запросов, а также уменьшить скорость отклика.&lt;br /&gt;
&lt;br /&gt;
Поскольку в рамках голосового робота все запросы (к конкретной конфигурации) используют один системный промпт, это позволяет серьезно экономить.&lt;br /&gt;
&lt;br /&gt;
Данный механизм теряет свою эффективность, к одной LLM будет обращаться большое число роботов с существенно отличающимися системными промптами (50+, точное количество зависит от доступного объема VRAM и настроек vLLM). Также механизм будет мешать, если LLM используется для каких-либо других задач, кроме работы голосового робота.&lt;br /&gt;
&lt;br /&gt;
=== Приблизительный расчет требуемых мощностей ===&lt;br /&gt;
Рекомендуемой конфигурацией является следующая:&lt;br /&gt;
&lt;br /&gt;
CPU 8x&lt;br /&gt;
&lt;br /&gt;
RAM 64gb DDR5&lt;br /&gt;
&lt;br /&gt;
300gb SSD &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Сравнение ускорителей&lt;br /&gt;
!Ускоритель&lt;br /&gt;
!Архитектура&lt;br /&gt;
!VRAM&lt;br /&gt;
!Bandwith&lt;br /&gt;
!Compute (INT8)&lt;br /&gt;
!Приблизительное количество параллельных сессий&lt;br /&gt;
|-&lt;br /&gt;
|RTX PRO 5000&lt;br /&gt;
|Blackwell&lt;br /&gt;
|48gb&lt;br /&gt;
|1.34TB/s&lt;br /&gt;
|516 TOPS&lt;br /&gt;
|30-40&lt;br /&gt;
|-&lt;br /&gt;
|RTX PRO 6000&lt;br /&gt;
|Blackwell&lt;br /&gt;
|96gb&lt;br /&gt;
|1.79TB/s&lt;br /&gt;
|1000 TOPS&lt;br /&gt;
|50-70&lt;br /&gt;
|-&lt;br /&gt;
|RTX 4090/48&lt;br /&gt;
|Ada&lt;br /&gt;
|48gb&lt;br /&gt;
|1TB/s&lt;br /&gt;
|660 TOPS&lt;br /&gt;
|25-30&lt;br /&gt;
|-&lt;br /&gt;
|2x RTX 5090&lt;br /&gt;
|Blackwell&lt;br /&gt;
|2x32gb&lt;br /&gt;
|1.79TB/s&lt;br /&gt;
|828 TOPS&lt;br /&gt;
|30-40&lt;br /&gt;
|-&lt;br /&gt;
|2x RTX 4090/24&lt;br /&gt;
|Ada&lt;br /&gt;
|2x24gb&lt;br /&gt;
|1TB/s&lt;br /&gt;
|660 TOPS&lt;br /&gt;
|10-20&lt;br /&gt;
|-&lt;br /&gt;
|A100/40&lt;br /&gt;
|Ampere&lt;br /&gt;
|40gb&lt;br /&gt;
|1.56TB/s&lt;br /&gt;
|624 TOPS&lt;br /&gt;
|18-23&lt;br /&gt;
|-&lt;br /&gt;
|A100/80&lt;br /&gt;
|Ampere&lt;br /&gt;
|80gb&lt;br /&gt;
|2TB/s&lt;br /&gt;
|624 TOPS&lt;br /&gt;
|55-75&lt;br /&gt;
|-&lt;br /&gt;
|H100&lt;br /&gt;
|Hopper&lt;br /&gt;
|80gb&lt;br /&gt;
|3.35TB/s&lt;br /&gt;
|990 TOPS&lt;br /&gt;
|70-100&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
При использовании конфигураций из двух карт с небольшим объемом VRAM (24, 32gb) будет происходить проблема дисбаланса:&lt;br /&gt;
&lt;br /&gt;
Одну из карт будет полностью занимать LLM (22gb базовых весов), а другую карту будут занимать другие модели. При этом в случае 2x24gb VRAM, для LLM будет оставаться крайне мало памяти на активные сессии, что будет являться главным ограничителем. Использовать память или compute соседней карты невозможно без NVLINK, а в потребительских картах он отсутствует.&lt;br /&gt;
&lt;br /&gt;
Таким образом вариант 2x4090/24 может использовать только для ненагруженных систем - демо стендов или сред разработки. Для такой конфигурации возможно заменить вторую карту на более простую, например 4080, так как TTS + ASR не реализуют 24gb vram.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем оперативной памяти не может быть меньше, чем 32gb, так как в процессе запуска веса моделей помещаются сначала в оперативную память, и только затем в VRAM.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Масштабирование сервиса ===&lt;br /&gt;
При масштабировании голосового робота существует три подхода:&lt;br /&gt;
&lt;br /&gt;
* Использование дополнительных GPU, либо переход на сервер с более производительным GPU&lt;br /&gt;
* Использование нескольких серверов с GPU для балансировки нагрузки&lt;br /&gt;
* Использование нескольких экземпляров робота (движков)&lt;br /&gt;
&lt;br /&gt;
На текущий момент наиболее удобным вариантом масштабирования является второй. Наиболее нагруженные сервисы vLLM и LightTTS можно выносить на отдельные сервера. При этом, например, для LightTTS не требуется большой объем VRAM, и он может качественно работать на сравнительно недорогих потребительских ускорителях (4090, 5080). &lt;br /&gt;
&lt;br /&gt;
Отдельно стоит упомянуть вынесение на отдельный сервер ASR. Данный компонент работает в потоковом режиме по протоколу gRPC, и не рекомендуется вынесение его на другие площадки с высокой задержкой. Остальные компоненты (за исключением VAD, который работает на CPU в составе главного сервиса secondchain), не чувствительны к дополнительным задержкам (в рамках разумного, до 50-70мс).&lt;br /&gt;
&lt;br /&gt;
=== Запуск робота с использованием облачных сервисов инференса ===&lt;br /&gt;
В случае, когда проектные требования позволяют использовать облачную инфраструктуру, нет необходимости полного разворота всех сервисов локально. Можно использовать ресурсы облачных провайдеров и ресурсы, предоставляемые командой платформы.&lt;br /&gt;
&lt;br /&gt;
Сервис поддерживает наиболее популярные API для работы с облачными моделями:&lt;br /&gt;
&lt;br /&gt;
* OpenAI-like формат для LLM. Позволяет подключать к роботу любые из современных передовых языковых моделей.&lt;br /&gt;
* OpenAI-like transcription формат для распознавания речи.&lt;br /&gt;
* LightTTS API формат для генерации речи&lt;br /&gt;
&lt;br /&gt;
Часто, экономически эффективным может быть использование только облачной LLM, так как она требует большого объема VRAM и дорогих ускорителей. При этом остальные модели запускаются локально, на более простой карте.&lt;br /&gt;
&lt;br /&gt;
При выборе облачной LLM критичными показателями являются следующие:&lt;br /&gt;
&lt;br /&gt;
* Метрика TTFT (Time To First Token). Время отклика модели до пересылки первых токенов ответа. Должна быть &amp;lt;=300мс, включая сетевые задержки;&lt;br /&gt;
* Поддержка streaming (SSE/chunked) ответов;&lt;br /&gt;
* Возможность отключения режима thinking/reasoning; &lt;br /&gt;
* Скорость генерации ответа &amp;gt;30 токенов/сек.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Популярные подписки на современные модели по типу &amp;quot;Token Plan&amp;quot;, которые предлагают использование с ограничением на количество запросов, а не тарификацию по токенам, зачастую непригодны для использования с роботом. Данные подписки используются в агентских системах, где время отклика не является целевой метрикой, а запросы инференса с таких подписок, как правило обрабатываются облачными сервисами с меньшим приоритетом.&amp;lt;/blockquote&amp;gt;При использовании всех облачных сервисов инференса, локально разворачивается только главный контейнер - secondchain. Рекомендуемые требования к серверу для такой среды:&lt;br /&gt;
&lt;br /&gt;
4x CPU&lt;br /&gt;
&lt;br /&gt;
8gb RAM&lt;br /&gt;
&lt;br /&gt;
80gb SSD&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
Установка самого Docker:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установка Nvidia Container Toolkit (только для серверов с GPU):&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# репозиторий&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \&lt;br /&gt;
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \&lt;br /&gt;
  sed &#039;s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g&#039; | \&lt;br /&gt;
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-container-toolkit&lt;br /&gt;
sudo nvidia-ctk runtime configure --runtime=docker&lt;br /&gt;
sudo systemctl restart docker&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (только для серверов с GPU) =&lt;br /&gt;
&lt;br /&gt;
Инструкция написана для Unbuntu 24.04.&lt;br /&gt;
&lt;br /&gt;
При написании и проверке данной инструкции использовался сервер с RTX PRO 5000 48gb.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Компиляция моделей может занимать больше VRAM, чем запущенный сервис, поэтому в случае дефицита видеопамяти, рекомендуется временно отключать свеже созданные контейнеры, собирать их по одному, после чего запускать по очереди уже в собранном виде.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton Inference Server) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
I0706 22:41:02.484518 1 grpc_server.cc:2562] &amp;quot;Started GRPCInferenceService at 0.0.0.0:8001&amp;quot;&lt;br /&gt;
I0706 22:41:02.484664 1 http_server.cc:4832] &amp;quot;Started HTTPService at 0.0.0.0:8000&amp;quot;&lt;br /&gt;
I0706 22:41:02.525792 1 http_server.cc:358] &amp;quot;Started Metrics Service at 0.0.0.0:8002&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
Установка выполняется из Docker Hub, следующей командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
* &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; — директория хост-машины, где будет храниться кеш весов модели (24gb)&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
После запуска vllm скачает веса модели для запуска (24gb). После завершения запуска и загрузки весов в логах можно наблюдать следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
(APIServer pid=1) INFO:     Started server process [1]&lt;br /&gt;
(APIServer pid=1) INFO:     Waiting for application startup.&lt;br /&gt;
(APIServer pid=1) INFO:     Application startup complete.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Как только они появятся, можно переходить к следующему шагу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080.&#039;&#039;&#039; Первый запрос к модели будет занимать достаточно много времени (холодный старт):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}],&lt;br /&gt;
    &amp;quot;chat_template_kwargs&amp;quot;: {&amp;quot;enable_thinking&amp;quot;: false}&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load -i lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights \&lt;br /&gt;
  python -m light_tts.server.api_server \&lt;br /&gt;
    --model_dir /opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
    --data_type float16 \&lt;br /&gt;
    --load_trt True \&lt;br /&gt;
    --host 0.0.0.0&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;После запуска сервис скомпилирует веса, по аналогии с T-One. После завершения подготовки в логах будут следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:391] ✅ Startup health check passed!&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:395] ✅ Application ready! Server is now accepting requests&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:396] 🌐 Listening at: http://localhost:8080&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — 10 &#039;&#039;&#039;GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 17000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 17001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Контейнеры сервисов инференса голосового робота.png|центр|безрамки|1067x1067пкс]]&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
Для упрощения работы с настройкой робота, нами был подготовлен набор демо-ресурсов:&lt;br /&gt;
&lt;br /&gt;
[[:Файл:Демо ресурсы для голосового робота.zip]]&lt;br /&gt;
&lt;br /&gt;
Он включает файл голоса, example.env и файлы для импорта в разделы приложения ИИ с готовым настроенным роботом.&lt;br /&gt;
&lt;br /&gt;
Необходимо переименовать файл example.env в .env и изменить в нём следующие параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&lt;br /&gt;
POSTGRES_HOST=[хост postgresql]&lt;br /&gt;
POSTGRES_PORT=5432&lt;br /&gt;
POSTGRES_USER=[логин postgresql]&lt;br /&gt;
POSTGRES_PASSWORD=[пароль postgresql]&lt;br /&gt;
POSTGRES_DB=[имя БД, если укзаанная БД отсутствует - она будет автоматически создана]&lt;br /&gt;
&lt;br /&gt;
CONCURRENT_SESSIONS=[Жесткое ограничение количества одновременных сессий]&lt;br /&gt;
&lt;br /&gt;
SIP_SERVER=[адрес Эры]&lt;br /&gt;
SIP_PORT=[порт SIP]&lt;br /&gt;
SIP_USERNAME=[Имя учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_PASSWORD=[Пароль учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_DOMAIN=[Полное имя домена, например robot.era-platform.ru]&lt;br /&gt;
#Детальные настройки SIP-клиента. В случае необходимости обхода NAT&lt;br /&gt;
SIP_TRANSPORT=udp&lt;br /&gt;
# NAT Traversal&lt;br /&gt;
SIP_STUN_SERVER=stun.l.google.com:19302&lt;br /&gt;
SIP_USE_ICE=false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
LLM_MODE=openai_api&lt;br /&gt;
#В случае использования сервиса инфереса vLLM на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LLM_OPENAI_API_BASE=http://localhost:16080/v1 &lt;br /&gt;
LLM_OPENAI_MODEL=qwen35-35b-a3b&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ASR_MODE=triton&lt;br /&gt;
#В случае использования сервиса инфереса tone-triton на другом хосте, необходимо изменить адреса/порты&lt;br /&gt;
ASR_TRITON_URL=http://localhost:17000&lt;br /&gt;
ASR_TRITON_GRPC=localhost:17001&lt;br /&gt;
ASR_TRITON_MODEL=streaming_acoustic&lt;br /&gt;
ASR_TRITON_TIMEOUT=10&lt;br /&gt;
ASR_DECODER_TYPE=beam_search&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
TTS_PROVIDER=lighttts&lt;br /&gt;
#В случае использования сервиса инфереса LightTTS на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LIGHTTTS_URL=http://localhost:8080/&lt;br /&gt;
LIGHTTTS_SAMPLE_RATE=24000&lt;br /&gt;
LIGHTTTS_STREAMING=false&lt;br /&gt;
LIGHTTTS_CONCURRENCY=4&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
= Этап 4. Запуск контейнера и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
docker load -i secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
Для упрощения работы с настройкой робота, нами был подготовлен набор демо-ресурсов:&lt;br /&gt;
&lt;br /&gt;
[[:Файл:Демо ресурсы для голосового робота.zip]]&lt;br /&gt;
&lt;br /&gt;
Он включает файл голоса, example.env и файлы для импорта в разделы приложения ИИ с готовым настроенным роботом.&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
[[Файл:Голос робота в приложении ИИ.png|мини]]&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
[[Файл:Инструменты робота.png|мини]]&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
[[Файл:Пример робота в приложении ИИ.png|мини]]&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
Системный промпт задаёт поведение робота, а промпт пост-обработки позволяет после окончания диалога проанализировать его и сохранить в сессии бизнес-результат (удобнее всего, в формате JSON).&lt;br /&gt;
&lt;br /&gt;
При составлении собственного системного важным эффектом является &amp;quot;внимательность&amp;quot; (attention) больших языковых моделей. Они более строго следуют инструкциям, написанным в начале и конце промпта. Поэтому данные области рекомендуется оставлять для строгих ограничений.&lt;br /&gt;
&lt;br /&gt;
Для построения надежных роботов с повторяемой эффективностью, рекомендуется использовать подход с описанием строгих шагов диалога.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
[[Файл:Статус робота.png|мини]]&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
[[Файл:Робот в очереди.png|мини]]&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2454</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2454"/>
		<updated>2026-07-07T12:08:47Z</updated>

		<summary type="html">&lt;p&gt;AZykov: /* 4.2. Создать робота в приложении ИИ */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Общая информация =&lt;br /&gt;
[[Файл:Архитектура голосового робота.png|центр|безрамки|763x763пкс]]&lt;br /&gt;
Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 1. Подготовка|Подготовка]]&#039;&#039;&#039; — Docker, PostgreSQL, настройки в системе телефонии.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 2. Установка сервисов инференса (опционально)|Установка сервисов инференса]]&#039;&#039;&#039; — ASR, LLM, TTS. &#039;&#039;Опционально, только для развёртывания на собственном сервере с GPU.&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 3. Настройка .env|Настройка .env]]&#039;&#039;&#039; — параметры подключения.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 4. Запуск контейнера и создание робота|Запуск контейнера и создание робота]]&#039;&#039;&#039; — старт сервиса и конфигурация робота.&lt;br /&gt;
&lt;br /&gt;
= Глоссарий =&lt;br /&gt;
&#039;&#039;&#039;Модель&#039;&#039;&#039; — обученная нейросеть, задающая соответствие между входом и выходом (текст -&amp;gt; текст, звук -&amp;gt; текст и т.д.). Модель определяется архитектурой и набором весов, полученных при обучении. В стеке робота их четыре:VAD (детекция голосовой активности), ASR (распознавание речи), LLM (генерация ответа), TTS (синтез речи).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Веса&#039;&#039;&#039; — числовые параметры модели, полученные при обучении. Именно они хранятся в файлах модели и загружаются в VRAM при старте. «Загрузка весов» в логах vLLM — это чтение этих файлов с диска в память GPU.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Инференс&#039;&#039;&#039; — использование готовой модели для получения ответа на новый вход («прогон» данных через веса). В отличие от обучения, веса не меняются. Сервисы инференса в статье — Triton, vLLM, LightTTS.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;LLM&#039;&#039;&#039; — Большая языковая модель. Класс моделей text-to-text, обученных на больших объемах мультиязычных и мультидоменных данных.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Triton&#039;&#039;&#039; (NVIDIA Triton Inference Server) — сервер инференса от NVIDIA, обслуживающий модели по gRPC и HTTP. В стеке на нём крутится ASR-модель T-one.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TensorRT&#039;&#039;&#039; — библиотека NVIDIA для оптимизации моделей под конкретный GPU: она компилирует модель в специализированный «движок» ради ускорения инференса. Сборка такого движка — разовая операция под железо, поэтому в LightTTS и T-One Triton она выполняется на первой фазе и коммитится в образ.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;vLLM&#039;&#039;&#039; — движок инференса для больших языковых моделей (LLM), оптимизированный на пропускную способность и эффективную работу с памятью. Предоставляет OpenAI-совместимый API.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;nvidia-smi&#039;&#039;&#039; (NVIDIA System Management Interface) — консольная утилита для просмотра состояния GPU: модель карты, версия драйвера, загрузка, потребление VRAM, запущенные процессы. Используется для проверки, что драйвер установлен и GPU виден (в т.ч. изнутри контейнера).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;KV-Cache&#039;&#039;&#039; (кэш ключей и значений) — память, где LLM хранит промежуточные представления уже обработанных токенов, чтобы не пересчитывать их при генерации каждого нового токена. Ускоряет генерацию ценой VRAM. В конфиге ограничен параметром &amp;lt;code&amp;gt;--kv-cache-memory&amp;lt;/code&amp;gt; (3 GiB). Растёт с числом сессий и длиной контекста — поэтому его размер критичен на картах с малым запасом VRAM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;LightTTS&#039;&#039;&#039; — движок инференса для TTS-моделей (синтеза речи). В стеке запускает модель CosyVoice3, слушает порт 8080.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Промпт&#039;&#039;&#039; — Инструкция, которой следует большая языковая модель.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Токен&#039;&#039;&#039; —В &#039;&#039;контексте LLM&#039;&#039; — единица текста, которой оперирует модель (примерно часть слова / слово / знак). Именно в токенах измеряются окно контекста и объём генерации.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Окно контекста&#039;&#039;&#039; — максимальное количество токенов, которое LLM может учитывать за один запрос (вход + генерируемый ответ вместе). Чем больше окно, тем больше VRAM уходит под KV-Cache, поэтому на картах с ограниченным объёмом его сокращают.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Compute&#039;&#039;&#039; — Вычислительные ресурсы GPU. Абстрактный ресурс видеоускорителя, аналог CPU Time при обычных расчетах. Измеряется в GFLOP/TFLOP (операциях в секунду)&lt;br /&gt;
&lt;br /&gt;
= Требования к оборудованию, нагрузка и мастштабирование =&lt;br /&gt;
&lt;br /&gt;
=== Микросервисы робота и их нагрузка ===&lt;br /&gt;
Робот функционирует на базе 4 микросервисов, каждый из которых может быть вынесен на отдельный сервер, или исполняться на общем сервере. &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Микросервисы робота&lt;br /&gt;
!Название&lt;br /&gt;
!Назначение&lt;br /&gt;
!Ключевые ресурсы&lt;br /&gt;
!Минимальное потребление VRAM&lt;br /&gt;
!Дополнительное потребление VRAM из расчета на 1 сессию&lt;br /&gt;
!Условное потребление Compute на 1 сессию&lt;br /&gt;
|-&lt;br /&gt;
|secondchain&lt;br /&gt;
|Инференс модели VAD (CPU), логика робота, голосовой pipeline, работа с сессиями, SIP-клиент&lt;br /&gt;
|CPU, RAM&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
|vLLM (qwen3.5-35b-a3b-INT4)&lt;br /&gt;
Данные указаны с окном контекста 8192 токена.&lt;br /&gt;
|Инференс больших языковых моделей (LLM)&lt;br /&gt;
|VRAM, Compute&lt;br /&gt;
|22gb&lt;br /&gt;
|0.3gb&lt;br /&gt;
|~3 GFLOP/токен&lt;br /&gt;
|-&lt;br /&gt;
|T-one (Triton Inference Server)&lt;br /&gt;
|Инференс T-One speech-to-text&lt;br /&gt;
|Compute&lt;br /&gt;
|600mb&lt;br /&gt;
|10mb&lt;br /&gt;
|~1-3 GFLOP/секунда речи&lt;br /&gt;
|-&lt;br /&gt;
|LightTTS&lt;br /&gt;
|Инференс CosyVoice3 TTS&lt;br /&gt;
|Compute, VRAM&lt;br /&gt;
|8gb&lt;br /&gt;
|0.3gb&lt;br /&gt;
|~120GFLOP/секунда генерируемоей речи&lt;br /&gt;
|}&lt;br /&gt;
При высокой конкуренции за Compute, увеличиваются задержки на каждом из этапов инференса. Самым чувствительным компонентом, при этом, является LightTTS - из-за архитектурных особенностей. TTS требует много вычислительных ресурсов, и большое количество параллельных генераций могут значительно увеличивать задержку. В случае использования нескольких серверов рекомендуется первично выносить на отдельный сервер либо LightTTS, либо vLLM (для высвобождения Compute).&lt;br /&gt;
&lt;br /&gt;
Архитектурно при этом, робот устроен таким образом, чтобы минимизировать инференс LightTTS при возможности (агрессивное кеширование результатов TTS). &lt;br /&gt;
&lt;br /&gt;
=== Нюансы подбора GPU ===&lt;br /&gt;
При подборе GPU под данный стек объём VRAM не является определяющим критерием. Веса любой из трёх моделей помещаются в память практически любой современной карты (уровня 5090 или выше), тогда как реальными ограничивающими факторами выступают пропускная способность памяти на этапе декодирования LLM и вычислительная нагрузка DiT-декодера в TTS. Соответственно, при выборе оборудования следует ориентироваться в первую очередь на memory bandwidth и на аппаратную поддержку современных типов данных, а не на номинальный объём видеопамяти.&lt;br /&gt;
&lt;br /&gt;
Отдельного внимания заслуживает интерфейс межкарточного взаимодействия. Потребительские карты рассчитаны преимущественно на одиночную эксплуатацию: в актуальных линейках Blackwell и Ada поддержка NVLink отсутствует, и обмен между несколькими GPU на одном сервере осуществляется исключительно через PCIe (Gen4/Gen5). При использовании tensor parallelism это создаёт заметные накладные расходы на межкарточную коммуникацию, что становится ощутимым при высокой конкурентной нагрузке. Дата-центровые решения (H100, H200, а также RTX PRO 6000 в соответствующем сегменте) либо предоставляют NVLink с пропускной способностью в сотни ГБ/с, либо обладают достаточным объёмом памяти для размещения моделей на одной карте, что позволяет полностью исключить tensor parallelism и связанные с ним издержки.&lt;br /&gt;
&lt;br /&gt;
Следует также учитывать высокие темпы развития архитектур GPU. Производительная карта шестилетней давности может уступать современному решению среднего уровня как по вычислительной мощности, так и — что существенно в данном случае — по набору поддерживаемых типов данных. Например, NVIDIA V100 (Volta, 2017), несмотря на наличие NVLink и памяти HBM, не поддерживает аппаратное ускорение FP8 и Int4 на тензорных ядрах. Между тем рассматриваемый стек существенно опирается на эти форматы: Qwen в квантизации GPTQ-Int4 с fp8 KV-cache, T-one в TensorRT, TTS с int8-квантизацией. На оборудовании предыдущих поколений соответствующие операции либо неработоспособны в требуемых форматах, либо выполняются с существенным замедлением за счёт программной эмуляции.&lt;br /&gt;
&lt;br /&gt;
С практической точки зрения приоритеты при выборе оборудования под данный пайплайн выстраиваются следующим образом: в первую очередь — поколение архитектуры (Ada, Ampere, Hopper, Blackwell — ввиду поддержки FP8 и Int4 на тензорных ядрах), далее — пропускная способность памяти, и лишь затем — объём VRAM, поскольку последний в рамках данной задачи практически всегда достаточен.&lt;br /&gt;
&lt;br /&gt;
Робот тестировался преимущественно на картах поколения Blackwell:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;RTX5090&#039;&#039;&#039; (использовалась другая LLM меньшего размера)&lt;br /&gt;
* &#039;&#039;&#039;RTX PRO 5000&#039;&#039;&#039; 48gb&lt;br /&gt;
* &#039;&#039;&#039;RTX PRO 6000&#039;&#039;&#039; 96gb&lt;br /&gt;
&lt;br /&gt;
Однако проводились также тесты на картах архитектуры &#039;&#039;&#039;Ampere&#039;&#039;&#039;. Результат можно считать удовлетворительным, особенно для организации тестовых и демо-сред без постоянной большой нагрузки.&lt;br /&gt;
&lt;br /&gt;
Отдельно хочется сказать про ускорители других производителей (AMD, Intel):&lt;br /&gt;
&lt;br /&gt;
К большому сожалению, большая часть инфраструктурного софта оптимизируется в первую очередь под ускорители NVIDIA. В связи с этим даже более производительные карты AMD &amp;quot;на бумаге&amp;quot;, по факту показывают значительно меньшие скорости при реальных задачах. Некоторые же библиотеки и компоненты (TensorRT, Triton Inference Server и т.д.) вообще являются проприетарными разработками NVIDIA и не поддерживают работу с ускорителями других производителей.&lt;br /&gt;
&lt;br /&gt;
=== Анизотропность нагрузки ===&lt;br /&gt;
Из-за логики работы голосового робота, нагрузка на его компоненты в рамках одной сессии достаточно неравномерна. Большинство моделей включаются последовательно после завершения инференса модели на предыдущем шаге:&lt;br /&gt;
&lt;br /&gt;
* VAD (детектирование голосовой активности) - работает всегда (но не вносит существенной нагрузки)&lt;br /&gt;
* ASR (распознавание речи) - запускается при срабатывании триггера VAD (окончание реплики)&lt;br /&gt;
* LLM - запускается после завершения работы ASR&lt;br /&gt;
* TTS - запускается во время / после завершения работы ASR (LLM возвращает текст в потоковом режиме. Текст разбивается на предложения и передается TTS в реальном времени)&lt;br /&gt;
&lt;br /&gt;
Кроме того, архитектурные особенности робота позволяют избегать шага вызова TTS для всех реплик, которые уже были сгенерированы ранее и помещены в кеш. Получается, что если инструкция робота задана таким образом, чтобы его реплики были &amp;quot;статичны&amp;quot; от сессии к сессии, получается экономить значительное количество ресурсов, переиспользуя уже существующие генерации.&lt;br /&gt;
&lt;br /&gt;
Свои оптимизации есть и на стороне инференса LLM:&lt;br /&gt;
&lt;br /&gt;
В команду запуска vLLM по-умолчанию включен режим prefix caching. Данный механизм позволяет кешировать системный промпт и переиспользовать ранее произведенные вычисления для новых запросов. Включение prefix caching позволяет экономить compute для однотипных запросов, а также уменьшить скорость отклика.&lt;br /&gt;
&lt;br /&gt;
Поскольку в рамках голосового робота все запросы (к конкретной конфигурации) используют один системный промпт, это позволяет серьезно экономить.&lt;br /&gt;
&lt;br /&gt;
Данный механизм теряет свою эффективность, к одной LLM будет обращаться большое число роботов с существенно отличающимися системными промптами (50+, точное количество зависит от доступного объема VRAM и настроек vLLM). Также механизм будет мешать, если LLM используется для каких-либо других задач, кроме работы голосового робота.&lt;br /&gt;
&lt;br /&gt;
=== Приблизительный расчет требуемых мощностей ===&lt;br /&gt;
Рекомендуемой конфигурацией является следующая:&lt;br /&gt;
&lt;br /&gt;
CPU 8x&lt;br /&gt;
&lt;br /&gt;
RAM 64gb DDR5&lt;br /&gt;
&lt;br /&gt;
300gb SSD &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Сравнение ускорителей&lt;br /&gt;
!Ускоритель&lt;br /&gt;
!Архитектура&lt;br /&gt;
!VRAM&lt;br /&gt;
!Bandwith&lt;br /&gt;
!Compute (INT8)&lt;br /&gt;
!Приблизительное количество параллельных сессий&lt;br /&gt;
|-&lt;br /&gt;
|RTX PRO 5000&lt;br /&gt;
|Blackwell&lt;br /&gt;
|48gb&lt;br /&gt;
|1.34TB/s&lt;br /&gt;
|516 TOPS&lt;br /&gt;
|30-40&lt;br /&gt;
|-&lt;br /&gt;
|RTX PRO 6000&lt;br /&gt;
|Blackwell&lt;br /&gt;
|96gb&lt;br /&gt;
|1.79TB/s&lt;br /&gt;
|1000 TOPS&lt;br /&gt;
|50-70&lt;br /&gt;
|-&lt;br /&gt;
|RTX 4090/48&lt;br /&gt;
|Ada&lt;br /&gt;
|48gb&lt;br /&gt;
|1TB/s&lt;br /&gt;
|660 TOPS&lt;br /&gt;
|25-30&lt;br /&gt;
|-&lt;br /&gt;
|2x RTX 5090&lt;br /&gt;
|Blackwell&lt;br /&gt;
|2x32gb&lt;br /&gt;
|1.79TB/s&lt;br /&gt;
|828 TOPS&lt;br /&gt;
|30-40&lt;br /&gt;
|-&lt;br /&gt;
|2x RTX 4090/24&lt;br /&gt;
|Ada&lt;br /&gt;
|2x24gb&lt;br /&gt;
|1TB/s&lt;br /&gt;
|660 TOPS&lt;br /&gt;
|10-20&lt;br /&gt;
|-&lt;br /&gt;
|A100/40&lt;br /&gt;
|Ampere&lt;br /&gt;
|40gb&lt;br /&gt;
|1.56TB/s&lt;br /&gt;
|624 TOPS&lt;br /&gt;
|18-23&lt;br /&gt;
|-&lt;br /&gt;
|A100/80&lt;br /&gt;
|Ampere&lt;br /&gt;
|80gb&lt;br /&gt;
|2TB/s&lt;br /&gt;
|624 TOPS&lt;br /&gt;
|55-75&lt;br /&gt;
|-&lt;br /&gt;
|H100&lt;br /&gt;
|Hopper&lt;br /&gt;
|80gb&lt;br /&gt;
|3.35TB/s&lt;br /&gt;
|990 TOPS&lt;br /&gt;
|70-100&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
При использовании конфигураций из двух карт с небольшим объемом VRAM (24, 32gb) будет происходить проблема дисбаланса:&lt;br /&gt;
&lt;br /&gt;
Одну из карт будет полностью занимать LLM (22gb базовых весов), а другую карту будут занимать другие модели. При этом в случае 2x24gb VRAM, для LLM будет оставаться крайне мало памяти на активные сессии, что будет являться главным ограничителем. Использовать память или compute соседней карты невозможно без NVLINK, а в потребительских картах он отсутствует.&lt;br /&gt;
&lt;br /&gt;
Таким образом вариант 2x4090/24 может использовать только для ненагруженных систем - демо стендов или сред разработки. Для такой конфигурации возможно заменить вторую карту на более простую, например 4080, так как TTS + ASR не реализуют 24gb vram.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем оперативной памяти не может быть меньше, чем 32gb, так как в процессе запуска веса моделей помещаются сначала в оперативную память, и только затем в VRAM.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Масштабирование сервиса ===&lt;br /&gt;
При масштабировании голосового робота существует три подхода:&lt;br /&gt;
&lt;br /&gt;
* Использование дополнительных GPU, либо переход на сервер с более производительным GPU&lt;br /&gt;
* Использование нескольких серверов с GPU для балансировки нагрузки&lt;br /&gt;
* Использование нескольких экземпляров робота (движков)&lt;br /&gt;
&lt;br /&gt;
На текущий момент наиболее удобным вариантом масштабирования является второй. Наиболее нагруженные сервисы vLLM и LightTTS можно выносить на отдельные сервера. При этом, например, для LightTTS не требуется большой объем VRAM, и он может качественно работать на сравнительно недорогих потребительских ускорителях (4090, 5080). &lt;br /&gt;
&lt;br /&gt;
Отдельно стоит упомянуть вынесение на отдельный сервер ASR. Данный компонент работает в потоковом режиме по протоколу gRPC, и не рекомендуется вынесение его на другие площадки с высокой задержкой. Остальные компоненты (за исключением VAD, который работает на CPU в составе главного сервиса secondchain), не чувствительны к дополнительным задержкам (в рамках разумного, до 50-70мс).&lt;br /&gt;
&lt;br /&gt;
=== Запуск робота с использованием облачных сервисов инференса ===&lt;br /&gt;
В случае, когда проектные требования позволяют использовать облачную инфраструктуру, нет необходимости полного разворота всех сервисов локально. Можно использовать ресурсы облачных провайдеров и ресурсы, предоставляемые командой платформы.&lt;br /&gt;
&lt;br /&gt;
Сервис поддерживает наиболее популярные API для работы с облачными моделями:&lt;br /&gt;
&lt;br /&gt;
* OpenAI-like формат для LLM. Позволяет подключать к роботу любые из современных передовых языковых моделей.&lt;br /&gt;
* OpenAI-like transcription формат для распознавания речи.&lt;br /&gt;
* LightTTS API формат для генерации речи&lt;br /&gt;
&lt;br /&gt;
Часто, экономически эффективным может быть использование только облачной LLM, так как она требует большого объема VRAM и дорогих ускорителей. При этом остальные модели запускаются локально, на более простой карте.&lt;br /&gt;
&lt;br /&gt;
При выборе облачной LLM критичными показателями являются следующие:&lt;br /&gt;
&lt;br /&gt;
* Метрика TTFT (Time To First Token). Время отклика модели до пересылки первых токенов ответа. Должна быть &amp;lt;=300мс, включая сетевые задержки;&lt;br /&gt;
* Поддержка streaming (SSE/chunked) ответов;&lt;br /&gt;
* Возможность отключения режима thinking/reasoning; &lt;br /&gt;
* Скорость генерации ответа &amp;gt;30 токенов/сек.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Популярные подписки на современные модели по типу &amp;quot;Token Plan&amp;quot;, которые предлагают использование с ограничением на количество запросов, а не тарификацию по токенам, зачастую непригодны для использования с роботом. Данные подписки используются в агентских системах, где время отклика не является целевой метрикой, а запросы инференса с таких подписок, как правило обрабатываются облачными сервисами с меньшим приоритетом.&amp;lt;/blockquote&amp;gt;При использовании всех облачных сервисов инференса, локально разворачивается только главный контейнер - secondchain. Рекомендуемые требования к серверу для такой среды:&lt;br /&gt;
&lt;br /&gt;
4x CPU&lt;br /&gt;
&lt;br /&gt;
8gb RAM&lt;br /&gt;
&lt;br /&gt;
80gb SSD&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
Установка самого Docker:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установка Nvidia Container Toolkit (только для серверов с GPU):&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# репозиторий&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \&lt;br /&gt;
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \&lt;br /&gt;
  sed &#039;s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g&#039; | \&lt;br /&gt;
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-container-toolkit&lt;br /&gt;
sudo nvidia-ctk runtime configure --runtime=docker&lt;br /&gt;
sudo systemctl restart docker&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (только для серверов с GPU) =&lt;br /&gt;
&lt;br /&gt;
Инструкция написана для Unbuntu 24.04.&lt;br /&gt;
&lt;br /&gt;
При написании данной инструкции использовался сервер с RTX PRO 5000 48gb.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Компиляция моделей может занимать больше VRAM, чем запущенный сервис, поэтому в случае дефицита видеопамяти, рекомендуется временно отключать свеже созданные контейнеры, собирать их по одному, после чего запускать по очереди уже в собранном виде.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton Inference Server) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
I0706 22:41:02.484518 1 grpc_server.cc:2562] &amp;quot;Started GRPCInferenceService at 0.0.0.0:8001&amp;quot;&lt;br /&gt;
I0706 22:41:02.484664 1 http_server.cc:4832] &amp;quot;Started HTTPService at 0.0.0.0:8000&amp;quot;&lt;br /&gt;
I0706 22:41:02.525792 1 http_server.cc:358] &amp;quot;Started Metrics Service at 0.0.0.0:8002&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
Установка выполняется из Docker Hub, следующей командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
* &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; — директория хост-машины, где будет храниться кеш весов модели (24gb)&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
После запуска vllm скачает веса модели для запуска (24gb). После завершения запуска и загрузки весов в логах можно наблюдать следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
(APIServer pid=1) INFO:     Started server process [1]&lt;br /&gt;
(APIServer pid=1) INFO:     Waiting for application startup.&lt;br /&gt;
(APIServer pid=1) INFO:     Application startup complete.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Как только они появятся, можно переходить к следующему шагу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080.&#039;&#039;&#039; Первый запрос к модели будет занимать достаточно много времени:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}],&lt;br /&gt;
    &amp;quot;chat_template_kwargs&amp;quot;: {&amp;quot;enable_thinking&amp;quot;: false}&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load -i lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights \&lt;br /&gt;
  python -m light_tts.server.api_server \&lt;br /&gt;
    --model_dir /opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
    --data_type float16 \&lt;br /&gt;
    --load_trt True \&lt;br /&gt;
    --host 0.0.0.0&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;После запуска сервис скомпилирует веса, по аналогии с T-One. После завершения подготовки в логах будут следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:391] ✅ Startup health check passed!&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:395] ✅ Application ready! Server is now accepting requests&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:396] 🌐 Listening at: http://localhost:8080&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — 10 &#039;&#039;&#039;GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 17000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 17001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Контейнеры сервисов инференса голосового робота.png|центр|безрамки|1067x1067пкс]]&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
Для упрощения работы с настройкой робота, нами был подготовлен набор демо-ресурсов:&lt;br /&gt;
&lt;br /&gt;
[[:Файл:Демо ресурсы для голосового робота.zip]]&lt;br /&gt;
&lt;br /&gt;
Он включает файл голоса, example.env и файлы для импорта в разделы приложения ИИ с готовым настроенным роботом.&lt;br /&gt;
&lt;br /&gt;
Необходимо переименовать файл example.env в .env и изменить в нём следующие параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&lt;br /&gt;
POSTGRES_HOST=[хост postgresql]&lt;br /&gt;
POSTGRES_PORT=5432&lt;br /&gt;
POSTGRES_USER=[логин postgresql]&lt;br /&gt;
POSTGRES_PASSWORD=[пароль postgresql]&lt;br /&gt;
POSTGRES_DB=[имя БД, если укзаанная БД отсутствует - она будет автоматически создана]&lt;br /&gt;
&lt;br /&gt;
CONCURRENT_SESSIONS=[Жесткое ограничение количества одновременных сессий]&lt;br /&gt;
&lt;br /&gt;
SIP_SERVER=[адрес Эры]&lt;br /&gt;
SIP_PORT=[порт SIP]&lt;br /&gt;
SIP_USERNAME=[Имя учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_PASSWORD=[Пароль учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_DOMAIN=[Полное имя домена, например robot.era-platform.ru]&lt;br /&gt;
#Детальные настройки SIP-клиента. В случае необходимости обхода NAT&lt;br /&gt;
SIP_TRANSPORT=udp&lt;br /&gt;
# NAT Traversal&lt;br /&gt;
SIP_STUN_SERVER=stun.l.google.com:19302&lt;br /&gt;
SIP_USE_ICE=false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
LLM_MODE=openai_api&lt;br /&gt;
#В случае использования сервиса инфереса vLLM на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LLM_OPENAI_API_BASE=http://localhost:16080/v1 &lt;br /&gt;
LLM_OPENAI_MODEL=qwen35-35b-a3b&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ASR_MODE=triton&lt;br /&gt;
#В случае использования сервиса инфереса tone-triton на другом хосте, необходимо изменить адреса/порты&lt;br /&gt;
ASR_TRITON_URL=http://localhost:17000&lt;br /&gt;
ASR_TRITON_GRPC=localhost:17001&lt;br /&gt;
ASR_TRITON_MODEL=streaming_acoustic&lt;br /&gt;
ASR_TRITON_TIMEOUT=10&lt;br /&gt;
ASR_DECODER_TYPE=beam_search&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
TTS_PROVIDER=lighttts&lt;br /&gt;
#В случае использования сервиса инфереса LightTTS на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LIGHTTTS_URL=http://localhost:8080/&lt;br /&gt;
LIGHTTTS_SAMPLE_RATE=24000&lt;br /&gt;
LIGHTTTS_STREAMING=false&lt;br /&gt;
LIGHTTTS_CONCURRENCY=4&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
= Этап 4. Запуск контейнера и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
docker load -i secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
Для упрощения работы с настройкой робота, нами был подготовлен набор демо-ресурсов:&lt;br /&gt;
&lt;br /&gt;
[[:Файл:Демо ресурсы для голосового робота.zip]]&lt;br /&gt;
&lt;br /&gt;
Он включает файл голоса, example.env и файлы для импорта в разделы приложения ИИ с готовым настроенным роботом.&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
[[Файл:Голос робота в приложении ИИ.png|мини]]&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
[[Файл:Инструменты робота.png|мини]]&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
[[Файл:Пример робота в приложении ИИ.png|мини]]&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
[[Файл:Статус робота.png|мини]]&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
[[Файл:Робот в очереди.png|мини]]&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%94%D0%B5%D0%BC%D0%BE_%D1%80%D0%B5%D1%81%D1%83%D1%80%D1%81%D1%8B_%D0%B4%D0%BB%D1%8F_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0.zip&amp;diff=2453</id>
		<title>Файл:Демо ресурсы для голосового робота.zip</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%94%D0%B5%D0%BC%D0%BE_%D1%80%D0%B5%D1%81%D1%83%D1%80%D1%81%D1%8B_%D0%B4%D0%BB%D1%8F_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0.zip&amp;diff=2453"/>
		<updated>2026-07-07T12:07:05Z</updated>

		<summary type="html">&lt;p&gt;AZykov: .env файл
Запись голоса
Файлы для импорта голосового робота (Голос, инструменты, робот)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Краткое описание ==&lt;br /&gt;
.env файл&lt;br /&gt;
Запись голоса&lt;br /&gt;
Файлы для импорта голосового робота (Голос, инструменты, робот)&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2452</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2452"/>
		<updated>2026-07-07T12:02:59Z</updated>

		<summary type="html">&lt;p&gt;AZykov: /* Запуск робота с использованием облачных сервисов инференса */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Общая информация =&lt;br /&gt;
[[Файл:Архитектура голосового робота.png|центр|безрамки|763x763пкс]]&lt;br /&gt;
Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 1. Подготовка|Подготовка]]&#039;&#039;&#039; — Docker, PostgreSQL, настройки в системе телефонии.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 2. Установка сервисов инференса (опционально)|Установка сервисов инференса]]&#039;&#039;&#039; — ASR, LLM, TTS. &#039;&#039;Опционально, только для развёртывания на собственном сервере с GPU.&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 3. Настройка .env|Настройка .env]]&#039;&#039;&#039; — параметры подключения.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 4. Запуск контейнера и создание робота|Запуск контейнера и создание робота]]&#039;&#039;&#039; — старт сервиса и конфигурация робота.&lt;br /&gt;
&lt;br /&gt;
= Глоссарий =&lt;br /&gt;
&#039;&#039;&#039;Модель&#039;&#039;&#039; — обученная нейросеть, задающая соответствие между входом и выходом (текст -&amp;gt; текст, звук -&amp;gt; текст и т.д.). Модель определяется архитектурой и набором весов, полученных при обучении. В стеке робота их четыре:VAD (детекция голосовой активности), ASR (распознавание речи), LLM (генерация ответа), TTS (синтез речи).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Веса&#039;&#039;&#039; — числовые параметры модели, полученные при обучении. Именно они хранятся в файлах модели и загружаются в VRAM при старте. «Загрузка весов» в логах vLLM — это чтение этих файлов с диска в память GPU.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Инференс&#039;&#039;&#039; — использование готовой модели для получения ответа на новый вход («прогон» данных через веса). В отличие от обучения, веса не меняются. Сервисы инференса в статье — Triton, vLLM, LightTTS.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;LLM&#039;&#039;&#039; — Большая языковая модель. Класс моделей text-to-text, обученных на больших объемах мультиязычных и мультидоменных данных.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Triton&#039;&#039;&#039; (NVIDIA Triton Inference Server) — сервер инференса от NVIDIA, обслуживающий модели по gRPC и HTTP. В стеке на нём крутится ASR-модель T-one.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TensorRT&#039;&#039;&#039; — библиотека NVIDIA для оптимизации моделей под конкретный GPU: она компилирует модель в специализированный «движок» ради ускорения инференса. Сборка такого движка — разовая операция под железо, поэтому в LightTTS и T-One Triton она выполняется на первой фазе и коммитится в образ.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;vLLM&#039;&#039;&#039; — движок инференса для больших языковых моделей (LLM), оптимизированный на пропускную способность и эффективную работу с памятью. Предоставляет OpenAI-совместимый API.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;nvidia-smi&#039;&#039;&#039; (NVIDIA System Management Interface) — консольная утилита для просмотра состояния GPU: модель карты, версия драйвера, загрузка, потребление VRAM, запущенные процессы. Используется для проверки, что драйвер установлен и GPU виден (в т.ч. изнутри контейнера).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;KV-Cache&#039;&#039;&#039; (кэш ключей и значений) — память, где LLM хранит промежуточные представления уже обработанных токенов, чтобы не пересчитывать их при генерации каждого нового токена. Ускоряет генерацию ценой VRAM. В конфиге ограничен параметром &amp;lt;code&amp;gt;--kv-cache-memory&amp;lt;/code&amp;gt; (3 GiB). Растёт с числом сессий и длиной контекста — поэтому его размер критичен на картах с малым запасом VRAM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;LightTTS&#039;&#039;&#039; — движок инференса для TTS-моделей (синтеза речи). В стеке запускает модель CosyVoice3, слушает порт 8080.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Промпт&#039;&#039;&#039; — Инструкция, которой следует большая языковая модель.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Токен&#039;&#039;&#039; —В &#039;&#039;контексте LLM&#039;&#039; — единица текста, которой оперирует модель (примерно часть слова / слово / знак). Именно в токенах измеряются окно контекста и объём генерации.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Окно контекста&#039;&#039;&#039; — максимальное количество токенов, которое LLM может учитывать за один запрос (вход + генерируемый ответ вместе). Чем больше окно, тем больше VRAM уходит под KV-Cache, поэтому на картах с ограниченным объёмом его сокращают.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Compute&#039;&#039;&#039; — Вычислительные ресурсы GPU. Абстрактный ресурс видеоускорителя, аналог CPU Time при обычных расчетах. Измеряется в GFLOP/TFLOP (операциях в секунду)&lt;br /&gt;
&lt;br /&gt;
= Требования к оборудованию, нагрузка и мастштабирование =&lt;br /&gt;
&lt;br /&gt;
=== Микросервисы робота и их нагрузка ===&lt;br /&gt;
Робот функционирует на базе 4 микросервисов, каждый из которых может быть вынесен на отдельный сервер, или исполняться на общем сервере. &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Микросервисы робота&lt;br /&gt;
!Название&lt;br /&gt;
!Назначение&lt;br /&gt;
!Ключевые ресурсы&lt;br /&gt;
!Минимальное потребление VRAM&lt;br /&gt;
!Дополнительное потребление VRAM из расчета на 1 сессию&lt;br /&gt;
!Условное потребление Compute на 1 сессию&lt;br /&gt;
|-&lt;br /&gt;
|secondchain&lt;br /&gt;
|Инференс модели VAD (CPU), логика робота, голосовой pipeline, работа с сессиями, SIP-клиент&lt;br /&gt;
|CPU, RAM&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
|vLLM (qwen3.5-35b-a3b-INT4)&lt;br /&gt;
Данные указаны с окном контекста 8192 токена.&lt;br /&gt;
|Инференс больших языковых моделей (LLM)&lt;br /&gt;
|VRAM, Compute&lt;br /&gt;
|22gb&lt;br /&gt;
|0.3gb&lt;br /&gt;
|~3 GFLOP/токен&lt;br /&gt;
|-&lt;br /&gt;
|T-one (Triton Inference Server)&lt;br /&gt;
|Инференс T-One speech-to-text&lt;br /&gt;
|Compute&lt;br /&gt;
|600mb&lt;br /&gt;
|10mb&lt;br /&gt;
|~1-3 GFLOP/секунда речи&lt;br /&gt;
|-&lt;br /&gt;
|LightTTS&lt;br /&gt;
|Инференс CosyVoice3 TTS&lt;br /&gt;
|Compute, VRAM&lt;br /&gt;
|8gb&lt;br /&gt;
|0.3gb&lt;br /&gt;
|~120GFLOP/секунда генерируемоей речи&lt;br /&gt;
|}&lt;br /&gt;
При высокой конкуренции за Compute, увеличиваются задержки на каждом из этапов инференса. Самым чувствительным компонентом, при этом, является LightTTS - из-за архитектурных особенностей. TTS требует много вычислительных ресурсов, и большое количество параллельных генераций могут значительно увеличивать задержку. В случае использования нескольких серверов рекомендуется первично выносить на отдельный сервер либо LightTTS, либо vLLM (для высвобождения Compute).&lt;br /&gt;
&lt;br /&gt;
Архитектурно при этом, робот устроен таким образом, чтобы минимизировать инференс LightTTS при возможности (агрессивное кеширование результатов TTS). &lt;br /&gt;
&lt;br /&gt;
=== Нюансы подбора GPU ===&lt;br /&gt;
При подборе GPU под данный стек объём VRAM не является определяющим критерием. Веса любой из трёх моделей помещаются в память практически любой современной карты (уровня 5090 или выше), тогда как реальными ограничивающими факторами выступают пропускная способность памяти на этапе декодирования LLM и вычислительная нагрузка DiT-декодера в TTS. Соответственно, при выборе оборудования следует ориентироваться в первую очередь на memory bandwidth и на аппаратную поддержку современных типов данных, а не на номинальный объём видеопамяти.&lt;br /&gt;
&lt;br /&gt;
Отдельного внимания заслуживает интерфейс межкарточного взаимодействия. Потребительские карты рассчитаны преимущественно на одиночную эксплуатацию: в актуальных линейках Blackwell и Ada поддержка NVLink отсутствует, и обмен между несколькими GPU на одном сервере осуществляется исключительно через PCIe (Gen4/Gen5). При использовании tensor parallelism это создаёт заметные накладные расходы на межкарточную коммуникацию, что становится ощутимым при высокой конкурентной нагрузке. Дата-центровые решения (H100, H200, а также RTX PRO 6000 в соответствующем сегменте) либо предоставляют NVLink с пропускной способностью в сотни ГБ/с, либо обладают достаточным объёмом памяти для размещения моделей на одной карте, что позволяет полностью исключить tensor parallelism и связанные с ним издержки.&lt;br /&gt;
&lt;br /&gt;
Следует также учитывать высокие темпы развития архитектур GPU. Производительная карта шестилетней давности может уступать современному решению среднего уровня как по вычислительной мощности, так и — что существенно в данном случае — по набору поддерживаемых типов данных. Например, NVIDIA V100 (Volta, 2017), несмотря на наличие NVLink и памяти HBM, не поддерживает аппаратное ускорение FP8 и Int4 на тензорных ядрах. Между тем рассматриваемый стек существенно опирается на эти форматы: Qwen в квантизации GPTQ-Int4 с fp8 KV-cache, T-one в TensorRT, TTS с int8-квантизацией. На оборудовании предыдущих поколений соответствующие операции либо неработоспособны в требуемых форматах, либо выполняются с существенным замедлением за счёт программной эмуляции.&lt;br /&gt;
&lt;br /&gt;
С практической точки зрения приоритеты при выборе оборудования под данный пайплайн выстраиваются следующим образом: в первую очередь — поколение архитектуры (Ada, Ampere, Hopper, Blackwell — ввиду поддержки FP8 и Int4 на тензорных ядрах), далее — пропускная способность памяти, и лишь затем — объём VRAM, поскольку последний в рамках данной задачи практически всегда достаточен.&lt;br /&gt;
&lt;br /&gt;
Робот тестировался преимущественно на картах поколения Blackwell:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;RTX5090&#039;&#039;&#039; (использовалась другая LLM меньшего размера)&lt;br /&gt;
* &#039;&#039;&#039;RTX PRO 5000&#039;&#039;&#039; 48gb&lt;br /&gt;
* &#039;&#039;&#039;RTX PRO 6000&#039;&#039;&#039; 96gb&lt;br /&gt;
&lt;br /&gt;
Однако проводились также тесты на картах архитектуры &#039;&#039;&#039;Ampere&#039;&#039;&#039;. Результат можно считать удовлетворительным, особенно для организации тестовых и демо-сред без постоянной большой нагрузки.&lt;br /&gt;
&lt;br /&gt;
Отдельно хочется сказать про ускорители других производителей (AMD, Intel):&lt;br /&gt;
&lt;br /&gt;
К большому сожалению, большая часть инфраструктурного софта оптимизируется в первую очередь под ускорители NVIDIA. В связи с этим даже более производительные карты AMD &amp;quot;на бумаге&amp;quot;, по факту показывают значительно меньшие скорости при реальных задачах. Некоторые же библиотеки и компоненты (TensorRT, Triton Inference Server и т.д.) вообще являются проприетарными разработками NVIDIA и не поддерживают работу с ускорителями других производителей.&lt;br /&gt;
&lt;br /&gt;
=== Анизотропность нагрузки ===&lt;br /&gt;
Из-за логики работы голосового робота, нагрузка на его компоненты в рамках одной сессии достаточно неравномерна. Большинство моделей включаются последовательно после завершения инференса модели на предыдущем шаге:&lt;br /&gt;
&lt;br /&gt;
* VAD (детектирование голосовой активности) - работает всегда (но не вносит существенной нагрузки)&lt;br /&gt;
* ASR (распознавание речи) - запускается при срабатывании триггера VAD (окончание реплики)&lt;br /&gt;
* LLM - запускается после завершения работы ASR&lt;br /&gt;
* TTS - запускается во время / после завершения работы ASR (LLM возвращает текст в потоковом режиме. Текст разбивается на предложения и передается TTS в реальном времени)&lt;br /&gt;
&lt;br /&gt;
Кроме того, архитектурные особенности робота позволяют избегать шага вызова TTS для всех реплик, которые уже были сгенерированы ранее и помещены в кеш. Получается, что если инструкция робота задана таким образом, чтобы его реплики были &amp;quot;статичны&amp;quot; от сессии к сессии, получается экономить значительное количество ресурсов, переиспользуя уже существующие генерации.&lt;br /&gt;
&lt;br /&gt;
Свои оптимизации есть и на стороне инференса LLM:&lt;br /&gt;
&lt;br /&gt;
В команду запуска vLLM по-умолчанию включен режим prefix caching. Данный механизм позволяет кешировать системный промпт и переиспользовать ранее произведенные вычисления для новых запросов. Включение prefix caching позволяет экономить compute для однотипных запросов, а также уменьшить скорость отклика.&lt;br /&gt;
&lt;br /&gt;
Поскольку в рамках голосового робота все запросы (к конкретной конфигурации) используют один системный промпт, это позволяет серьезно экономить.&lt;br /&gt;
&lt;br /&gt;
Данный механизм теряет свою эффективность, к одной LLM будет обращаться большое число роботов с существенно отличающимися системными промптами (50+, точное количество зависит от доступного объема VRAM и настроек vLLM). Также механизм будет мешать, если LLM используется для каких-либо других задач, кроме работы голосового робота.&lt;br /&gt;
&lt;br /&gt;
=== Приблизительный расчет требуемых мощностей ===&lt;br /&gt;
Рекомендуемой конфигурацией является следующая:&lt;br /&gt;
&lt;br /&gt;
CPU 8x&lt;br /&gt;
&lt;br /&gt;
RAM 64gb DDR5&lt;br /&gt;
&lt;br /&gt;
300gb SSD &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Сравнение ускорителей&lt;br /&gt;
!Ускоритель&lt;br /&gt;
!Архитектура&lt;br /&gt;
!VRAM&lt;br /&gt;
!Bandwith&lt;br /&gt;
!Compute (INT8)&lt;br /&gt;
!Приблизительное количество параллельных сессий&lt;br /&gt;
|-&lt;br /&gt;
|RTX PRO 5000&lt;br /&gt;
|Blackwell&lt;br /&gt;
|48gb&lt;br /&gt;
|1.34TB/s&lt;br /&gt;
|516 TOPS&lt;br /&gt;
|30-40&lt;br /&gt;
|-&lt;br /&gt;
|RTX PRO 6000&lt;br /&gt;
|Blackwell&lt;br /&gt;
|96gb&lt;br /&gt;
|1.79TB/s&lt;br /&gt;
|1000 TOPS&lt;br /&gt;
|50-70&lt;br /&gt;
|-&lt;br /&gt;
|RTX 4090/48&lt;br /&gt;
|Ada&lt;br /&gt;
|48gb&lt;br /&gt;
|1TB/s&lt;br /&gt;
|660 TOPS&lt;br /&gt;
|25-30&lt;br /&gt;
|-&lt;br /&gt;
|2x RTX 5090&lt;br /&gt;
|Blackwell&lt;br /&gt;
|2x32gb&lt;br /&gt;
|1.79TB/s&lt;br /&gt;
|828 TOPS&lt;br /&gt;
|30-40&lt;br /&gt;
|-&lt;br /&gt;
|2x RTX 4090/24&lt;br /&gt;
|Ada&lt;br /&gt;
|2x24gb&lt;br /&gt;
|1TB/s&lt;br /&gt;
|660 TOPS&lt;br /&gt;
|10-20&lt;br /&gt;
|-&lt;br /&gt;
|A100/40&lt;br /&gt;
|Ampere&lt;br /&gt;
|40gb&lt;br /&gt;
|1.56TB/s&lt;br /&gt;
|624 TOPS&lt;br /&gt;
|18-23&lt;br /&gt;
|-&lt;br /&gt;
|A100/80&lt;br /&gt;
|Ampere&lt;br /&gt;
|80gb&lt;br /&gt;
|2TB/s&lt;br /&gt;
|624 TOPS&lt;br /&gt;
|55-75&lt;br /&gt;
|-&lt;br /&gt;
|H100&lt;br /&gt;
|Hopper&lt;br /&gt;
|80gb&lt;br /&gt;
|3.35TB/s&lt;br /&gt;
|990 TOPS&lt;br /&gt;
|70-100&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
При использовании конфигураций из двух карт с небольшим объемом VRAM (24, 32gb) будет происходить проблема дисбаланса:&lt;br /&gt;
&lt;br /&gt;
Одну из карт будет полностью занимать LLM (22gb базовых весов), а другую карту будут занимать другие модели. При этом в случае 2x24gb VRAM, для LLM будет оставаться крайне мало памяти на активные сессии, что будет являться главным ограничителем. Использовать память или compute соседней карты невозможно без NVLINK, а в потребительских картах он отсутствует.&lt;br /&gt;
&lt;br /&gt;
Таким образом вариант 2x4090/24 может использовать только для ненагруженных систем - демо стендов или сред разработки. Для такой конфигурации возможно заменить вторую карту на более простую, например 4080, так как TTS + ASR не реализуют 24gb vram.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем оперативной памяти не может быть меньше, чем 32gb, так как в процессе запуска веса моделей помещаются сначала в оперативную память, и только затем в VRAM.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Масштабирование сервиса ===&lt;br /&gt;
При масштабировании голосового робота существует три подхода:&lt;br /&gt;
&lt;br /&gt;
* Использование дополнительных GPU, либо переход на сервер с более производительным GPU&lt;br /&gt;
* Использование нескольких серверов с GPU для балансировки нагрузки&lt;br /&gt;
* Использование нескольких экземпляров робота (движков)&lt;br /&gt;
&lt;br /&gt;
На текущий момент наиболее удобным вариантом масштабирования является второй. Наиболее нагруженные сервисы vLLM и LightTTS можно выносить на отдельные сервера. При этом, например, для LightTTS не требуется большой объем VRAM, и он может качественно работать на сравнительно недорогих потребительских ускорителях (4090, 5080). &lt;br /&gt;
&lt;br /&gt;
Отдельно стоит упомянуть вынесение на отдельный сервер ASR. Данный компонент работает в потоковом режиме по протоколу gRPC, и не рекомендуется вынесение его на другие площадки с высокой задержкой. Остальные компоненты (за исключением VAD, который работает на CPU в составе главного сервиса secondchain), не чувствительны к дополнительным задержкам (в рамках разумного, до 50-70мс).&lt;br /&gt;
&lt;br /&gt;
=== Запуск робота с использованием облачных сервисов инференса ===&lt;br /&gt;
В случае, когда проектные требования позволяют использовать облачную инфраструктуру, нет необходимости полного разворота всех сервисов локально. Можно использовать ресурсы облачных провайдеров и ресурсы, предоставляемые командой платформы.&lt;br /&gt;
&lt;br /&gt;
Сервис поддерживает наиболее популярные API для работы с облачными моделями:&lt;br /&gt;
&lt;br /&gt;
* OpenAI-like формат для LLM. Позволяет подключать к роботу любые из современных передовых языковых моделей.&lt;br /&gt;
* OpenAI-like transcription формат для распознавания речи.&lt;br /&gt;
* LightTTS API формат для генерации речи&lt;br /&gt;
&lt;br /&gt;
Часто, экономически эффективным может быть использование только облачной LLM, так как она требует большого объема VRAM и дорогих ускорителей. При этом остальные модели запускаются локально, на более простой карте.&lt;br /&gt;
&lt;br /&gt;
При выборе облачной LLM критичными показателями являются следующие:&lt;br /&gt;
&lt;br /&gt;
* Метрика TTFT (Time To First Token). Время отклика модели до пересылки первых токенов ответа. Должна быть &amp;lt;=300мс, включая сетевые задержки;&lt;br /&gt;
* Поддержка streaming (SSE/chunked) ответов;&lt;br /&gt;
* Возможность отключения режима thinking/reasoning; &lt;br /&gt;
* Скорость генерации ответа &amp;gt;30 токенов/сек.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Популярные подписки на современные модели по типу &amp;quot;Token Plan&amp;quot;, которые предлагают использование с ограничением на количество запросов, а не тарификацию по токенам, зачастую непригодны для использования с роботом. Данные подписки используются в агентских системах, где время отклика не является целевой метрикой, а запросы инференса с таких подписок, как правило обрабатываются облачными сервисами с меньшим приоритетом.&amp;lt;/blockquote&amp;gt;При использовании всех облачных сервисов инференса, локально разворачивается только главный контейнер - secondchain. Рекомендуемые требования к серверу для такой среды:&lt;br /&gt;
&lt;br /&gt;
4x CPU&lt;br /&gt;
&lt;br /&gt;
8gb RAM&lt;br /&gt;
&lt;br /&gt;
80gb SSD&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
Установка самого Docker:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установка Nvidia Container Toolkit (только для серверов с GPU):&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# репозиторий&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \&lt;br /&gt;
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \&lt;br /&gt;
  sed &#039;s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g&#039; | \&lt;br /&gt;
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-container-toolkit&lt;br /&gt;
sudo nvidia-ctk runtime configure --runtime=docker&lt;br /&gt;
sudo systemctl restart docker&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (только для серверов с GPU) =&lt;br /&gt;
&lt;br /&gt;
Инструкция написана для Unbuntu 24.04.&lt;br /&gt;
&lt;br /&gt;
При написании данной инструкции использовался сервер с RTX PRO 5000 48gb.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Компиляция моделей может занимать больше VRAM, чем запущенный сервис, поэтому в случае дефицита видеопамяти, рекомендуется временно отключать свеже созданные контейнеры, собирать их по одному, после чего запускать по очереди уже в собранном виде.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton Inference Server) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
I0706 22:41:02.484518 1 grpc_server.cc:2562] &amp;quot;Started GRPCInferenceService at 0.0.0.0:8001&amp;quot;&lt;br /&gt;
I0706 22:41:02.484664 1 http_server.cc:4832] &amp;quot;Started HTTPService at 0.0.0.0:8000&amp;quot;&lt;br /&gt;
I0706 22:41:02.525792 1 http_server.cc:358] &amp;quot;Started Metrics Service at 0.0.0.0:8002&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
Установка выполняется из Docker Hub, следующей командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
* &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; — директория хост-машины, где будет храниться кеш весов модели (24gb)&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
После запуска vllm скачает веса модели для запуска (24gb). После завершения запуска и загрузки весов в логах можно наблюдать следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
(APIServer pid=1) INFO:     Started server process [1]&lt;br /&gt;
(APIServer pid=1) INFO:     Waiting for application startup.&lt;br /&gt;
(APIServer pid=1) INFO:     Application startup complete.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Как только они появятся, можно переходить к следующему шагу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080.&#039;&#039;&#039; Первый запрос к модели будет занимать достаточно много времени:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}],&lt;br /&gt;
    &amp;quot;chat_template_kwargs&amp;quot;: {&amp;quot;enable_thinking&amp;quot;: false}&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load -i lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights \&lt;br /&gt;
  python -m light_tts.server.api_server \&lt;br /&gt;
    --model_dir /opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
    --data_type float16 \&lt;br /&gt;
    --load_trt True \&lt;br /&gt;
    --host 0.0.0.0&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;После запуска сервис скомпилирует веса, по аналогии с T-One. После завершения подготовки в логах будут следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:391] ✅ Startup health check passed!&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:395] ✅ Application ready! Server is now accepting requests&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:396] 🌐 Listening at: http://localhost:8080&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — 10 &#039;&#039;&#039;GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 17000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 17001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Контейнеры сервисов инференса голосового робота.png|центр|безрамки|1067x1067пкс]]&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
&lt;br /&gt;
Необходимо переименовать файл example.env в .env и изменить в нём следующие параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&lt;br /&gt;
POSTGRES_HOST=[хост postgresql]&lt;br /&gt;
POSTGRES_PORT=5432&lt;br /&gt;
POSTGRES_USER=[логин postgresql]&lt;br /&gt;
POSTGRES_PASSWORD=[пароль postgresql]&lt;br /&gt;
POSTGRES_DB=[имя БД, если укзаанная БД отсутствует - она будет автоматически создана]&lt;br /&gt;
&lt;br /&gt;
CONCURRENT_SESSIONS=[Жесткое ограничение количества одновременных сессий]&lt;br /&gt;
&lt;br /&gt;
SIP_SERVER=[адрес Эры]&lt;br /&gt;
SIP_PORT=[порт SIP]&lt;br /&gt;
SIP_USERNAME=[Имя учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_PASSWORD=[Пароль учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_DOMAIN=[Полное имя домена, например robot.era-platform.ru]&lt;br /&gt;
#Детальные настройки SIP-клиента. В случае необходимости обхода NAT&lt;br /&gt;
SIP_TRANSPORT=udp&lt;br /&gt;
# NAT Traversal&lt;br /&gt;
SIP_STUN_SERVER=stun.l.google.com:19302&lt;br /&gt;
SIP_USE_ICE=false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
LLM_MODE=openai_api&lt;br /&gt;
#В случае использования сервиса инфереса vLLM на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LLM_OPENAI_API_BASE=http://localhost:16080/v1 &lt;br /&gt;
LLM_OPENAI_MODEL=qwen35-35b-a3b&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ASR_MODE=triton&lt;br /&gt;
#В случае использования сервиса инфереса tone-triton на другом хосте, необходимо изменить адреса/порты&lt;br /&gt;
ASR_TRITON_URL=http://localhost:17000&lt;br /&gt;
ASR_TRITON_GRPC=localhost:17001&lt;br /&gt;
ASR_TRITON_MODEL=streaming_acoustic&lt;br /&gt;
ASR_TRITON_TIMEOUT=10&lt;br /&gt;
ASR_DECODER_TYPE=beam_search&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
TTS_PROVIDER=lighttts&lt;br /&gt;
#В случае использования сервиса инфереса LightTTS на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LIGHTTTS_URL=http://localhost:8080/&lt;br /&gt;
LIGHTTTS_SAMPLE_RATE=24000&lt;br /&gt;
LIGHTTTS_STREAMING=false&lt;br /&gt;
LIGHTTTS_CONCURRENCY=4&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Плейсхолдер под подробное описание .env --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Запуск контейнера и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
docker load -i secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
[[Файл:Голос робота в приложении ИИ.png|мини]]&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
[[Файл:Инструменты робота.png|мини]]&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
[[Файл:Пример робота в приложении ИИ.png|мини]]&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
[[Файл:Статус робота.png|мини]]&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
[[Файл:Робот в очереди.png|мини]]&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%A0%D0%BE%D0%B1%D0%BE%D1%82_%D0%B2_%D0%BE%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D0%B8.png&amp;diff=2451</id>
		<title>Файл:Робот в очереди.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%A0%D0%BE%D0%B1%D0%BE%D1%82_%D0%B2_%D0%BE%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D0%B8.png&amp;diff=2451"/>
		<updated>2026-07-07T12:02:51Z</updated>

		<summary type="html">&lt;p&gt;AZykov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Робот в очереди&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%A1%D1%82%D0%B0%D1%82%D1%83%D1%81_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0.png&amp;diff=2450</id>
		<title>Файл:Статус робота.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%A1%D1%82%D0%B0%D1%82%D1%83%D1%81_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0.png&amp;diff=2450"/>
		<updated>2026-07-07T12:02:04Z</updated>

		<summary type="html">&lt;p&gt;AZykov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Статус робота&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%9F%D1%80%D0%B8%D0%BC%D0%B5%D1%80_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0_%D0%B2_%D0%BF%D1%80%D0%B8%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B8_%D0%98%D0%98.png&amp;diff=2449</id>
		<title>Файл:Пример робота в приложении ИИ.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%9F%D1%80%D0%B8%D0%BC%D0%B5%D1%80_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0_%D0%B2_%D0%BF%D1%80%D0%B8%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B8_%D0%98%D0%98.png&amp;diff=2449"/>
		<updated>2026-07-07T12:00:25Z</updated>

		<summary type="html">&lt;p&gt;AZykov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Пример робота в приложении ИИ&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%98%D0%BD%D1%81%D1%82%D1%80%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D1%8B_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0.png&amp;diff=2448</id>
		<title>Файл:Инструменты робота.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%98%D0%BD%D1%81%D1%82%D1%80%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D1%8B_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0.png&amp;diff=2448"/>
		<updated>2026-07-07T11:59:27Z</updated>

		<summary type="html">&lt;p&gt;AZykov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Инструменты робота&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%93%D0%BE%D0%BB%D0%BE%D1%81_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0_%D0%B2_%D0%BF%D1%80%D0%B8%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B8_%D0%98%D0%98.png&amp;diff=2447</id>
		<title>Файл:Голос робота в приложении ИИ.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%93%D0%BE%D0%BB%D0%BE%D1%81_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0_%D0%B2_%D0%BF%D1%80%D0%B8%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B8_%D0%98%D0%98.png&amp;diff=2447"/>
		<updated>2026-07-07T11:58:52Z</updated>

		<summary type="html">&lt;p&gt;AZykov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Голос робота в приложении ИИ&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2446</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2446"/>
		<updated>2026-07-07T11:54:17Z</updated>

		<summary type="html">&lt;p&gt;AZykov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Общая информация =&lt;br /&gt;
[[Файл:Архитектура голосового робота.png|центр|безрамки|763x763пкс]]&lt;br /&gt;
Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 1. Подготовка|Подготовка]]&#039;&#039;&#039; — Docker, PostgreSQL, настройки в системе телефонии.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 2. Установка сервисов инференса (опционально)|Установка сервисов инференса]]&#039;&#039;&#039; — ASR, LLM, TTS. &#039;&#039;Опционально, только для развёртывания на собственном сервере с GPU.&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 3. Настройка .env|Настройка .env]]&#039;&#039;&#039; — параметры подключения.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 4. Запуск контейнера и создание робота|Запуск контейнера и создание робота]]&#039;&#039;&#039; — старт сервиса и конфигурация робота.&lt;br /&gt;
&lt;br /&gt;
= Глоссарий =&lt;br /&gt;
&#039;&#039;&#039;Модель&#039;&#039;&#039; — обученная нейросеть, задающая соответствие между входом и выходом (текст -&amp;gt; текст, звук -&amp;gt; текст и т.д.). Модель определяется архитектурой и набором весов, полученных при обучении. В стеке робота их четыре:VAD (детекция голосовой активности), ASR (распознавание речи), LLM (генерация ответа), TTS (синтез речи).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Веса&#039;&#039;&#039; — числовые параметры модели, полученные при обучении. Именно они хранятся в файлах модели и загружаются в VRAM при старте. «Загрузка весов» в логах vLLM — это чтение этих файлов с диска в память GPU.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Инференс&#039;&#039;&#039; — использование готовой модели для получения ответа на новый вход («прогон» данных через веса). В отличие от обучения, веса не меняются. Сервисы инференса в статье — Triton, vLLM, LightTTS.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;LLM&#039;&#039;&#039; — Большая языковая модель. Класс моделей text-to-text, обученных на больших объемах мультиязычных и мультидоменных данных.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Triton&#039;&#039;&#039; (NVIDIA Triton Inference Server) — сервер инференса от NVIDIA, обслуживающий модели по gRPC и HTTP. В стеке на нём крутится ASR-модель T-one.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TensorRT&#039;&#039;&#039; — библиотека NVIDIA для оптимизации моделей под конкретный GPU: она компилирует модель в специализированный «движок» ради ускорения инференса. Сборка такого движка — разовая операция под железо, поэтому в LightTTS и T-One Triton она выполняется на первой фазе и коммитится в образ.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;vLLM&#039;&#039;&#039; — движок инференса для больших языковых моделей (LLM), оптимизированный на пропускную способность и эффективную работу с памятью. Предоставляет OpenAI-совместимый API.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;nvidia-smi&#039;&#039;&#039; (NVIDIA System Management Interface) — консольная утилита для просмотра состояния GPU: модель карты, версия драйвера, загрузка, потребление VRAM, запущенные процессы. Используется для проверки, что драйвер установлен и GPU виден (в т.ч. изнутри контейнера).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;KV-Cache&#039;&#039;&#039; (кэш ключей и значений) — память, где LLM хранит промежуточные представления уже обработанных токенов, чтобы не пересчитывать их при генерации каждого нового токена. Ускоряет генерацию ценой VRAM. В конфиге ограничен параметром &amp;lt;code&amp;gt;--kv-cache-memory&amp;lt;/code&amp;gt; (3 GiB). Растёт с числом сессий и длиной контекста — поэтому его размер критичен на картах с малым запасом VRAM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;LightTTS&#039;&#039;&#039; — движок инференса для TTS-моделей (синтеза речи). В стеке запускает модель CosyVoice3, слушает порт 8080.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Промпт&#039;&#039;&#039; — Инструкция, которой следует большая языковая модель.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Токен&#039;&#039;&#039; —В &#039;&#039;контексте LLM&#039;&#039; — единица текста, которой оперирует модель (примерно часть слова / слово / знак). Именно в токенах измеряются окно контекста и объём генерации.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Окно контекста&#039;&#039;&#039; — максимальное количество токенов, которое LLM может учитывать за один запрос (вход + генерируемый ответ вместе). Чем больше окно, тем больше VRAM уходит под KV-Cache, поэтому на картах с ограниченным объёмом его сокращают.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Compute&#039;&#039;&#039; — Вычислительные ресурсы GPU. Абстрактный ресурс видеоускорителя, аналог CPU Time при обычных расчетах. Измеряется в GFLOP/TFLOP (операциях в секунду)&lt;br /&gt;
&lt;br /&gt;
= Требования к оборудованию, нагрузка и мастштабирование =&lt;br /&gt;
&lt;br /&gt;
=== Микросервисы робота и их нагрузка ===&lt;br /&gt;
Робот функционирует на базе 4 микросервисов, каждый из которых может быть вынесен на отдельный сервер, или исполняться на общем сервере. &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Микросервисы робота&lt;br /&gt;
!Название&lt;br /&gt;
!Назначение&lt;br /&gt;
!Ключевые ресурсы&lt;br /&gt;
!Минимальное потребление VRAM&lt;br /&gt;
!Дополнительное потребление VRAM из расчета на 1 сессию&lt;br /&gt;
!Условное потребление Compute на 1 сессию&lt;br /&gt;
|-&lt;br /&gt;
|secondchain&lt;br /&gt;
|Инференс модели VAD (CPU), логика робота, голосовой pipeline, работа с сессиями, SIP-клиент&lt;br /&gt;
|CPU, RAM&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
|vLLM (qwen3.5-35b-a3b-INT4)&lt;br /&gt;
Данные указаны с окном контекста 8192 токена.&lt;br /&gt;
|Инференс больших языковых моделей (LLM)&lt;br /&gt;
|VRAM, Compute&lt;br /&gt;
|22gb&lt;br /&gt;
|0.3gb&lt;br /&gt;
|~3 GFLOP/токен&lt;br /&gt;
|-&lt;br /&gt;
|T-one (Triton Inference Server)&lt;br /&gt;
|Инференс T-One speech-to-text&lt;br /&gt;
|Compute&lt;br /&gt;
|600mb&lt;br /&gt;
|10mb&lt;br /&gt;
|~1-3 GFLOP/секунда речи&lt;br /&gt;
|-&lt;br /&gt;
|LightTTS&lt;br /&gt;
|Инференс CosyVoice3 TTS&lt;br /&gt;
|Compute, VRAM&lt;br /&gt;
|8gb&lt;br /&gt;
|0.3gb&lt;br /&gt;
|~120GFLOP/секунда генерируемоей речи&lt;br /&gt;
|}&lt;br /&gt;
При высокой конкуренции за Compute, увеличиваются задержки на каждом из этапов инференса. Самым чувствительным компонентом, при этом, является LightTTS - из-за архитектурных особенностей. TTS требует много вычислительных ресурсов, и большое количество параллельных генераций могут значительно увеличивать задержку. В случае использования нескольких серверов рекомендуется первично выносить на отдельный сервер либо LightTTS, либо vLLM (для высвобождения Compute).&lt;br /&gt;
&lt;br /&gt;
Архитектурно при этом, робот устроен таким образом, чтобы минимизировать инференс LightTTS при возможности (агрессивное кеширование результатов TTS). &lt;br /&gt;
&lt;br /&gt;
=== Нюансы подбора GPU ===&lt;br /&gt;
При подборе GPU под данный стек объём VRAM не является определяющим критерием. Веса любой из трёх моделей помещаются в память практически любой современной карты (уровня 5090 или выше), тогда как реальными ограничивающими факторами выступают пропускная способность памяти на этапе декодирования LLM и вычислительная нагрузка DiT-декодера в TTS. Соответственно, при выборе оборудования следует ориентироваться в первую очередь на memory bandwidth и на аппаратную поддержку современных типов данных, а не на номинальный объём видеопамяти.&lt;br /&gt;
&lt;br /&gt;
Отдельного внимания заслуживает интерфейс межкарточного взаимодействия. Потребительские карты рассчитаны преимущественно на одиночную эксплуатацию: в актуальных линейках Blackwell и Ada поддержка NVLink отсутствует, и обмен между несколькими GPU на одном сервере осуществляется исключительно через PCIe (Gen4/Gen5). При использовании tensor parallelism это создаёт заметные накладные расходы на межкарточную коммуникацию, что становится ощутимым при высокой конкурентной нагрузке. Дата-центровые решения (H100, H200, а также RTX PRO 6000 в соответствующем сегменте) либо предоставляют NVLink с пропускной способностью в сотни ГБ/с, либо обладают достаточным объёмом памяти для размещения моделей на одной карте, что позволяет полностью исключить tensor parallelism и связанные с ним издержки.&lt;br /&gt;
&lt;br /&gt;
Следует также учитывать высокие темпы развития архитектур GPU. Производительная карта шестилетней давности может уступать современному решению среднего уровня как по вычислительной мощности, так и — что существенно в данном случае — по набору поддерживаемых типов данных. Например, NVIDIA V100 (Volta, 2017), несмотря на наличие NVLink и памяти HBM, не поддерживает аппаратное ускорение FP8 и Int4 на тензорных ядрах. Между тем рассматриваемый стек существенно опирается на эти форматы: Qwen в квантизации GPTQ-Int4 с fp8 KV-cache, T-one в TensorRT, TTS с int8-квантизацией. На оборудовании предыдущих поколений соответствующие операции либо неработоспособны в требуемых форматах, либо выполняются с существенным замедлением за счёт программной эмуляции.&lt;br /&gt;
&lt;br /&gt;
С практической точки зрения приоритеты при выборе оборудования под данный пайплайн выстраиваются следующим образом: в первую очередь — поколение архитектуры (Ada, Ampere, Hopper, Blackwell — ввиду поддержки FP8 и Int4 на тензорных ядрах), далее — пропускная способность памяти, и лишь затем — объём VRAM, поскольку последний в рамках данной задачи практически всегда достаточен.&lt;br /&gt;
&lt;br /&gt;
Робот тестировался преимущественно на картах поколения Blackwell:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;RTX5090&#039;&#039;&#039; (использовалась другая LLM меньшего размера)&lt;br /&gt;
* &#039;&#039;&#039;RTX PRO 5000&#039;&#039;&#039; 48gb&lt;br /&gt;
* &#039;&#039;&#039;RTX PRO 6000&#039;&#039;&#039; 96gb&lt;br /&gt;
&lt;br /&gt;
Однако проводились также тесты на картах архитектуры &#039;&#039;&#039;Ampere&#039;&#039;&#039;. Результат можно считать удовлетворительным, особенно для организации тестовых и демо-сред без постоянной большой нагрузки.&lt;br /&gt;
&lt;br /&gt;
Отдельно хочется сказать про ускорители других производителей (AMD, Intel):&lt;br /&gt;
&lt;br /&gt;
К большому сожалению, большая часть инфраструктурного софта оптимизируется в первую очередь под ускорители NVIDIA. В связи с этим даже более производительные карты AMD &amp;quot;на бумаге&amp;quot;, по факту показывают значительно меньшие скорости при реальных задачах. Некоторые же библиотеки и компоненты (TensorRT, Triton Inference Server и т.д.) вообще являются проприетарными разработками NVIDIA и не поддерживают работу с ускорителями других производителей.&lt;br /&gt;
&lt;br /&gt;
=== Анизотропность нагрузки ===&lt;br /&gt;
Из-за логики работы голосового робота, нагрузка на его компоненты в рамках одной сессии достаточно неравномерна. Большинство моделей включаются последовательно после завершения инференса модели на предыдущем шаге:&lt;br /&gt;
&lt;br /&gt;
* VAD (детектирование голосовой активности) - работает всегда (но не вносит существенной нагрузки)&lt;br /&gt;
* ASR (распознавание речи) - запускается при срабатывании триггера VAD (окончание реплики)&lt;br /&gt;
* LLM - запускается после завершения работы ASR&lt;br /&gt;
* TTS - запускается во время / после завершения работы ASR (LLM возвращает текст в потоковом режиме. Текст разбивается на предложения и передается TTS в реальном времени)&lt;br /&gt;
&lt;br /&gt;
Кроме того, архитектурные особенности робота позволяют избегать шага вызова TTS для всех реплик, которые уже были сгенерированы ранее и помещены в кеш. Получается, что если инструкция робота задана таким образом, чтобы его реплики были &amp;quot;статичны&amp;quot; от сессии к сессии, получается экономить значительное количество ресурсов, переиспользуя уже существующие генерации.&lt;br /&gt;
&lt;br /&gt;
Свои оптимизации есть и на стороне инференса LLM:&lt;br /&gt;
&lt;br /&gt;
В команду запуска vLLM по-умолчанию включен режим prefix caching. Данный механизм позволяет кешировать системный промпт и переиспользовать ранее произведенные вычисления для новых запросов. Включение prefix caching позволяет экономить compute для однотипных запросов, а также уменьшить скорость отклика.&lt;br /&gt;
&lt;br /&gt;
Поскольку в рамках голосового робота все запросы (к конкретной конфигурации) используют один системный промпт, это позволяет серьезно экономить.&lt;br /&gt;
&lt;br /&gt;
Данный механизм теряет свою эффективность, к одной LLM будет обращаться большое число роботов с существенно отличающимися системными промптами (50+, точное количество зависит от доступного объема VRAM и настроек vLLM). Также механизм будет мешать, если LLM используется для каких-либо других задач, кроме работы голосового робота.&lt;br /&gt;
&lt;br /&gt;
=== Приблизительный расчет требуемых мощностей ===&lt;br /&gt;
Рекомендуемой конфигурацией является следующая:&lt;br /&gt;
&lt;br /&gt;
CPU 8x&lt;br /&gt;
&lt;br /&gt;
RAM 64gb DDR5&lt;br /&gt;
&lt;br /&gt;
300gb SSD &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Сравнение ускорителей&lt;br /&gt;
!Ускоритель&lt;br /&gt;
!Архитектура&lt;br /&gt;
!VRAM&lt;br /&gt;
!Bandwith&lt;br /&gt;
!Compute (INT8)&lt;br /&gt;
!Приблизительное количество параллельных сессий&lt;br /&gt;
|-&lt;br /&gt;
|RTX PRO 5000&lt;br /&gt;
|Blackwell&lt;br /&gt;
|48gb&lt;br /&gt;
|1.34TB/s&lt;br /&gt;
|516 TOPS&lt;br /&gt;
|30-40&lt;br /&gt;
|-&lt;br /&gt;
|RTX PRO 6000&lt;br /&gt;
|Blackwell&lt;br /&gt;
|96gb&lt;br /&gt;
|1.79TB/s&lt;br /&gt;
|1000 TOPS&lt;br /&gt;
|50-70&lt;br /&gt;
|-&lt;br /&gt;
|RTX 4090/48&lt;br /&gt;
|Ada&lt;br /&gt;
|48gb&lt;br /&gt;
|1TB/s&lt;br /&gt;
|660 TOPS&lt;br /&gt;
|25-30&lt;br /&gt;
|-&lt;br /&gt;
|2x RTX 5090&lt;br /&gt;
|Blackwell&lt;br /&gt;
|2x32gb&lt;br /&gt;
|1.79TB/s&lt;br /&gt;
|828 TOPS&lt;br /&gt;
|30-40&lt;br /&gt;
|-&lt;br /&gt;
|2x RTX 4090/24&lt;br /&gt;
|Ada&lt;br /&gt;
|2x24gb&lt;br /&gt;
|1TB/s&lt;br /&gt;
|660 TOPS&lt;br /&gt;
|10-20&lt;br /&gt;
|-&lt;br /&gt;
|A100/40&lt;br /&gt;
|Ampere&lt;br /&gt;
|40gb&lt;br /&gt;
|1.56TB/s&lt;br /&gt;
|624 TOPS&lt;br /&gt;
|18-23&lt;br /&gt;
|-&lt;br /&gt;
|A100/80&lt;br /&gt;
|Ampere&lt;br /&gt;
|80gb&lt;br /&gt;
|2TB/s&lt;br /&gt;
|624 TOPS&lt;br /&gt;
|55-75&lt;br /&gt;
|-&lt;br /&gt;
|H100&lt;br /&gt;
|Hopper&lt;br /&gt;
|80gb&lt;br /&gt;
|3.35TB/s&lt;br /&gt;
|990 TOPS&lt;br /&gt;
|70-100&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
При использовании конфигураций из двух карт с небольшим объемом VRAM (24, 32gb) будет происходить проблема дисбаланса:&lt;br /&gt;
&lt;br /&gt;
Одну из карт будет полностью занимать LLM (22gb базовых весов), а другую карту будут занимать другие модели. При этом в случае 2x24gb VRAM, для LLM будет оставаться крайне мало памяти на активные сессии, что будет являться главным ограничителем. Использовать память или compute соседней карты невозможно без NVLINK, а в потребительских картах он отсутствует.&lt;br /&gt;
&lt;br /&gt;
Таким образом вариант 2x4090/24 может использовать только для ненагруженных систем - демо стендов или сред разработки. Для такой конфигурации возможно заменить вторую карту на более простую, например 4080, так как TTS + ASR не реализуют 24gb vram.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем оперативной памяти не может быть меньше, чем 32gb, так как в процессе запуска веса моделей помещаются сначала в оперативную память, и только затем в VRAM.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Масштабирование сервиса ===&lt;br /&gt;
При масштабировании голосового робота существует три подхода:&lt;br /&gt;
&lt;br /&gt;
* Использование дополнительных GPU, либо переход на сервер с более производительным GPU&lt;br /&gt;
* Использование нескольких серверов с GPU для балансировки нагрузки&lt;br /&gt;
* Использование нескольких экземпляров робота (движков)&lt;br /&gt;
&lt;br /&gt;
На текущий момент наиболее удобным вариантом масштабирования является второй. Наиболее нагруженные сервисы vLLM и LightTTS можно выносить на отдельные сервера. При этом, например, для LightTTS не требуется большой объем VRAM, и он может качественно работать на сравнительно недорогих потребительских ускорителях (4090, 5080). &lt;br /&gt;
&lt;br /&gt;
Отдельно стоит упомянуть вынесение на отдельный сервер ASR. Данный компонент работает в потоковом режиме по протоколу gRPC, и не рекомендуется вынесение его на другие площадки с высокой задержкой. Остальные компоненты (за исключением VAD, который работает на CPU в составе главного сервиса secondchain), не чувствительны к дополнительным задержкам (в рамках разумного, до 50-70мс).&lt;br /&gt;
&lt;br /&gt;
=== Запуск робота с использованием облачных сервисов инференса ===&lt;br /&gt;
В случае, когда проектные требования позволяют использовать облачную инфраструктуру, нет необходимости полного разворота всех сервисов локально. Можно использовать ресурсы облачных провайдеров и ресурсы, предоставляемые командой платформы.&lt;br /&gt;
&lt;br /&gt;
Сервис поддерживает наиболее популярные API для работы с облачными моделями:&lt;br /&gt;
&lt;br /&gt;
* OpenAI-like формат для LLM. Позволяет подключать к роботу любые из современных передовых языковых моделей.&lt;br /&gt;
* OpenAI-like transcription формат для распознавания речи.&lt;br /&gt;
* LightTTS API формат для генерации речи&lt;br /&gt;
&lt;br /&gt;
Часто, экономически эффективным может быть использование только облачной LLM, так как она требует большого объема VRAM и дорогих ускорителей. При этом остальные модели запускаются локально, на более простой карте.&lt;br /&gt;
&lt;br /&gt;
При выборе облачной LLM критичными показателями являются следующие:&lt;br /&gt;
&lt;br /&gt;
* Метрика TTFT (Time To First Token). Время отклика модели до пересылки первых токенов ответа. Должна быть &amp;lt;=300мс, включая сетевые задержки;&lt;br /&gt;
* Поддержка streaming (SSE/chunked) ответов;&lt;br /&gt;
* Возможность отключения режима thinking/reasoning; &lt;br /&gt;
* Скорость генерации ответа &amp;gt;30 токенов/сек.&lt;br /&gt;
&lt;br /&gt;
При использовании всех облачных сервисов инференса, локально разворачивается только главный контейнер - secondchain. Рекомендуемые требования к серверу для такой среды:&lt;br /&gt;
&lt;br /&gt;
4x CPU&lt;br /&gt;
&lt;br /&gt;
8gb RAM&lt;br /&gt;
&lt;br /&gt;
80gb SSD&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
Установка самого Docker:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установка Nvidia Container Toolkit (только для серверов с GPU):&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# репозиторий&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \&lt;br /&gt;
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \&lt;br /&gt;
  sed &#039;s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g&#039; | \&lt;br /&gt;
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-container-toolkit&lt;br /&gt;
sudo nvidia-ctk runtime configure --runtime=docker&lt;br /&gt;
sudo systemctl restart docker&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (опционально) =&lt;br /&gt;
&lt;br /&gt;
Инструкция написана для Unbuntu 24.04.&lt;br /&gt;
&lt;br /&gt;
При написании данной инструкции использовался сервер с RTX PRO 5000 48gb.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Компиляция моделей может занимать больше VRAM, чем запущенный сервис, поэтому в случае дефицита видеопамяти, рекомендуется временно отключать свеже созданные контейнеры, собирать их по одному, после чего запускать по очереди уже в собранном виде.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton Inference Server) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
I0706 22:41:02.484518 1 grpc_server.cc:2562] &amp;quot;Started GRPCInferenceService at 0.0.0.0:8001&amp;quot;&lt;br /&gt;
I0706 22:41:02.484664 1 http_server.cc:4832] &amp;quot;Started HTTPService at 0.0.0.0:8000&amp;quot;&lt;br /&gt;
I0706 22:41:02.525792 1 http_server.cc:358] &amp;quot;Started Metrics Service at 0.0.0.0:8002&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
Установка выполняется из Docker Hub, следующей командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
* &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; — директория хост-машины, где будет храниться кеш весов модели (24gb)&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
После запуска vllm скачает веса модели для запуска (24gb). После завершения запуска и загрузки весов в логах можно наблюдать следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
(APIServer pid=1) INFO:     Started server process [1]&lt;br /&gt;
(APIServer pid=1) INFO:     Waiting for application startup.&lt;br /&gt;
(APIServer pid=1) INFO:     Application startup complete.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Как только они появятся, можно переходить к следующему шагу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080.&#039;&#039;&#039; Первый запрос к модели будет занимать достаточно много времени:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}],&lt;br /&gt;
    &amp;quot;chat_template_kwargs&amp;quot;: {&amp;quot;enable_thinking&amp;quot;: false}&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load -i lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights \&lt;br /&gt;
  python -m light_tts.server.api_server \&lt;br /&gt;
    --model_dir /opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
    --data_type float16 \&lt;br /&gt;
    --load_trt True \&lt;br /&gt;
    --host 0.0.0.0&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;После запуска сервис скомпилирует веса, по аналогии с T-One. После завершения подготовки в логах будут следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:391] ✅ Startup health check passed!&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:395] ✅ Application ready! Server is now accepting requests&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:396] 🌐 Listening at: http://localhost:8080&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — 10 &#039;&#039;&#039;GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 17000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 17001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Контейнеры сервисов инференса голосового робота.png|центр|безрамки|1067x1067пкс]]&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
&lt;br /&gt;
Необходимо переименовать файл example.env в .env и изменить в нём следующие параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&lt;br /&gt;
POSTGRES_HOST=[хост postgresql]&lt;br /&gt;
POSTGRES_PORT=5432&lt;br /&gt;
POSTGRES_USER=[логин postgresql]&lt;br /&gt;
POSTGRES_PASSWORD=[пароль postgresql]&lt;br /&gt;
POSTGRES_DB=[имя БД, если укзаанная БД отсутствует - она будет автоматически создана]&lt;br /&gt;
&lt;br /&gt;
CONCURRENT_SESSIONS=[Жесткое ограничение количества одновременных сессий]&lt;br /&gt;
&lt;br /&gt;
SIP_SERVER=[адрес Эры]&lt;br /&gt;
SIP_PORT=[порт SIP]&lt;br /&gt;
SIP_USERNAME=[Имя учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_PASSWORD=[Пароль учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_DOMAIN=[Полное имя домена, например robot.era-platform.ru]&lt;br /&gt;
#Детальные настройки SIP-клиента. В случае необходимости обхода NAT&lt;br /&gt;
SIP_TRANSPORT=udp&lt;br /&gt;
# NAT Traversal&lt;br /&gt;
SIP_STUN_SERVER=stun.l.google.com:19302&lt;br /&gt;
SIP_USE_ICE=false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
LLM_MODE=openai_api&lt;br /&gt;
#В случае использования сервиса инфереса vLLM на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LLM_OPENAI_API_BASE=http://localhost:16080/v1 &lt;br /&gt;
LLM_OPENAI_MODEL=qwen35-35b-a3b&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ASR_MODE=triton&lt;br /&gt;
#В случае использования сервиса инфереса tone-triton на другом хосте, необходимо изменить адреса/порты&lt;br /&gt;
ASR_TRITON_URL=http://localhost:17000&lt;br /&gt;
ASR_TRITON_GRPC=localhost:17001&lt;br /&gt;
ASR_TRITON_MODEL=streaming_acoustic&lt;br /&gt;
ASR_TRITON_TIMEOUT=10&lt;br /&gt;
ASR_DECODER_TYPE=beam_search&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
TTS_PROVIDER=lighttts&lt;br /&gt;
#В случае использования сервиса инфереса LightTTS на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LIGHTTTS_URL=http://localhost:8080/&lt;br /&gt;
LIGHTTTS_SAMPLE_RATE=24000&lt;br /&gt;
LIGHTTTS_STREAMING=false&lt;br /&gt;
LIGHTTTS_CONCURRENCY=4&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Плейсхолдер под подробное описание .env --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Запуск контейнера и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
docker load -i secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2445</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2445"/>
		<updated>2026-07-07T11:53:32Z</updated>

		<summary type="html">&lt;p&gt;AZykov: /* Запуск сервиса робота с использованием облачных сервисов инференса */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Общая информация =&lt;br /&gt;
[[Файл:Архитектура голосового робота.png|центр|безрамки|763x763пкс]]&lt;br /&gt;
Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 1. Подготовка|Подготовка]]&#039;&#039;&#039; — Docker, PostgreSQL, настройки в системе телефонии.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 2. Установка сервисов инференса (опционально)|Установка сервисов инференса]]&#039;&#039;&#039; — ASR, LLM, TTS. &#039;&#039;Опционально, только для развёртывания на собственном сервере с GPU.&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 3. Настройка .env|Настройка .env]]&#039;&#039;&#039; — параметры подключения.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 4. Запуск контейнера и создание робота|Запуск контейнера и создание робота]]&#039;&#039;&#039; — старт сервиса и конфигурация робота.&lt;br /&gt;
&lt;br /&gt;
= Глоссарий =&lt;br /&gt;
&#039;&#039;&#039;Модель&#039;&#039;&#039; — обученная нейросеть, задающая соответствие между входом и выходом (текст -&amp;gt; текст, звук -&amp;gt; текст и т.д.). Модель определяется архитектурой и набором весов, полученных при обучении. В стеке робота их четыре:VAD (детекция голосовой активности), ASR (распознавание речи), LLM (генерация ответа), TTS (синтез речи).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Веса&#039;&#039;&#039; — числовые параметры модели, полученные при обучении. Именно они хранятся в файлах модели и загружаются в VRAM при старте. «Загрузка весов» в логах vLLM — это чтение этих файлов с диска в память GPU.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Инференс&#039;&#039;&#039; — использование готовой модели для получения ответа на новый вход («прогон» данных через веса). В отличие от обучения, веса не меняются. Сервисы инференса в статье — Triton, vLLM, LightTTS.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;LLM&#039;&#039;&#039; — Большая языковая модель. Класс моделей text-to-text, обученных на больших объемах мультиязычных и мультидоменных данных.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Triton&#039;&#039;&#039; (NVIDIA Triton Inference Server) — сервер инференса от NVIDIA, обслуживающий модели по gRPC и HTTP. В стеке на нём крутится ASR-модель T-one.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TensorRT&#039;&#039;&#039; — библиотека NVIDIA для оптимизации моделей под конкретный GPU: она компилирует модель в специализированный «движок» ради ускорения инференса. Сборка такого движка — разовая операция под железо, поэтому в LightTTS и T-One Triton она выполняется на первой фазе и коммитится в образ.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;vLLM&#039;&#039;&#039; — движок инференса для больших языковых моделей (LLM), оптимизированный на пропускную способность и эффективную работу с памятью. Предоставляет OpenAI-совместимый API.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;nvidia-smi&#039;&#039;&#039; (NVIDIA System Management Interface) — консольная утилита для просмотра состояния GPU: модель карты, версия драйвера, загрузка, потребление VRAM, запущенные процессы. Используется для проверки, что драйвер установлен и GPU виден (в т.ч. изнутри контейнера).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;KV-Cache&#039;&#039;&#039; (кэш ключей и значений) — память, где LLM хранит промежуточные представления уже обработанных токенов, чтобы не пересчитывать их при генерации каждого нового токена. Ускоряет генерацию ценой VRAM. В конфиге ограничен параметром &amp;lt;code&amp;gt;--kv-cache-memory&amp;lt;/code&amp;gt; (3 GiB). Растёт с числом сессий и длиной контекста — поэтому его размер критичен на картах с малым запасом VRAM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;LightTTS&#039;&#039;&#039; — движок инференса для TTS-моделей (синтеза речи). В стеке запускает модель CosyVoice3, слушает порт 8080.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Промпт&#039;&#039;&#039; — Инструкция, которой следует большая языковая модель.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Токен&#039;&#039;&#039; —В &#039;&#039;контексте LLM&#039;&#039; — единица текста, которой оперирует модель (примерно часть слова / слово / знак). Именно в токенах измеряются окно контекста и объём генерации.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Окно контекста&#039;&#039;&#039; — максимальное количество токенов, которое LLM может учитывать за один запрос (вход + генерируемый ответ вместе). Чем больше окно, тем больше VRAM уходит под KV-Cache, поэтому на картах с ограниченным объёмом его сокращают.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Compute&#039;&#039;&#039; — Вычислительные ресурсы GPU. Абстрактный ресурс видеоускорителя, аналог CPU Time при обычных расчетах. Измеряется в GFLOP/TFLOP (операциях в секунду)&lt;br /&gt;
&lt;br /&gt;
= Требования к оборудованию, нагрузка и мастштабирование =&lt;br /&gt;
&lt;br /&gt;
=== Микросервисы робота и их нагрузка ===&lt;br /&gt;
Робот функционирует на базе 4 микросервисов, каждый из которых может быть вынесен на отдельный сервер, или исполняться на общем сервере. &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Микросервисы робота&lt;br /&gt;
!Название&lt;br /&gt;
!Назначение&lt;br /&gt;
!Ключевые ресурсы&lt;br /&gt;
!Минимальное потребление VRAM&lt;br /&gt;
!Дополнительное потребление VRAM из расчета на 1 сессию&lt;br /&gt;
!Условное потребление Compute на 1 сессию&lt;br /&gt;
|-&lt;br /&gt;
|secondchain&lt;br /&gt;
|Инференс модели VAD (CPU), логика робота, голосовой pipeline, работа с сессиями, SIP-клиент&lt;br /&gt;
|CPU, RAM&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
|vLLM (qwen3.5-35b-a3b-INT4)&lt;br /&gt;
Данные указаны с окном контекста 8192 токена.&lt;br /&gt;
|Инференс больших языковых моделей (LLM)&lt;br /&gt;
|VRAM, Compute&lt;br /&gt;
|22gb&lt;br /&gt;
|0.3gb&lt;br /&gt;
|~3 GFLOP/токен&lt;br /&gt;
|-&lt;br /&gt;
|T-one (Triton Inference Server)&lt;br /&gt;
|Инференс T-One speech-to-text&lt;br /&gt;
|Compute&lt;br /&gt;
|600mb&lt;br /&gt;
|10mb&lt;br /&gt;
|~1-3 GFLOP/секунда речи&lt;br /&gt;
|-&lt;br /&gt;
|LightTTS&lt;br /&gt;
|Инференс CosyVoice3 TTS&lt;br /&gt;
|Compute, VRAM&lt;br /&gt;
|8gb&lt;br /&gt;
|0.3gb&lt;br /&gt;
|~120GFLOP/секунда генерируемоей речи&lt;br /&gt;
|}&lt;br /&gt;
При высокой конкуренции за Compute, увеличиваются задержки на каждом из этапов инференса. Самым чувствительным компонентом, при этом, является LightTTS - из-за архитектурных особенностей. TTS требует много вычислительных ресурсов, и большое количество параллельных генераций могут значительно увеличивать задержку. В случае использования нескольких серверов рекомендуется первично выносить на отдельный сервер либо LightTTS, либо vLLM (для высвобождения Compute).&lt;br /&gt;
&lt;br /&gt;
Архитектурно при этом, робот устроен таким образом, чтобы минимизировать инференс LightTTS при возможности (агрессивное кеширование результатов TTS). &lt;br /&gt;
&lt;br /&gt;
=== Нюансы подбора GPU ===&lt;br /&gt;
При подборе GPU под данный стек объём VRAM не является определяющим критерием. Веса любой из трёх моделей помещаются в память практически любой современной карты (уровня 5090 или выше), тогда как реальными ограничивающими факторами выступают пропускная способность памяти на этапе декодирования LLM и вычислительная нагрузка DiT-декодера в TTS. Соответственно, при выборе оборудования следует ориентироваться в первую очередь на memory bandwidth и на аппаратную поддержку современных типов данных, а не на номинальный объём видеопамяти.&lt;br /&gt;
&lt;br /&gt;
Отдельного внимания заслуживает интерфейс межкарточного взаимодействия. Потребительские карты рассчитаны преимущественно на одиночную эксплуатацию: в актуальных линейках Blackwell и Ada поддержка NVLink отсутствует, и обмен между несколькими GPU на одном сервере осуществляется исключительно через PCIe (Gen4/Gen5). При использовании tensor parallelism это создаёт заметные накладные расходы на межкарточную коммуникацию, что становится ощутимым при высокой конкурентной нагрузке. Дата-центровые решения (H100, H200, а также RTX PRO 6000 в соответствующем сегменте) либо предоставляют NVLink с пропускной способностью в сотни ГБ/с, либо обладают достаточным объёмом памяти для размещения моделей на одной карте, что позволяет полностью исключить tensor parallelism и связанные с ним издержки.&lt;br /&gt;
&lt;br /&gt;
Следует также учитывать высокие темпы развития архитектур GPU. Производительная карта шестилетней давности может уступать современному решению среднего уровня как по вычислительной мощности, так и — что существенно в данном случае — по набору поддерживаемых типов данных. Например, NVIDIA V100 (Volta, 2017), несмотря на наличие NVLink и памяти HBM, не поддерживает аппаратное ускорение FP8 и Int4 на тензорных ядрах. Между тем рассматриваемый стек существенно опирается на эти форматы: Qwen в квантизации GPTQ-Int4 с fp8 KV-cache, T-one в TensorRT, TTS с int8-квантизацией. На оборудовании предыдущих поколений соответствующие операции либо неработоспособны в требуемых форматах, либо выполняются с существенным замедлением за счёт программной эмуляции.&lt;br /&gt;
&lt;br /&gt;
С практической точки зрения приоритеты при выборе оборудования под данный пайплайн выстраиваются следующим образом: в первую очередь — поколение архитектуры (Ada, Ampere, Hopper, Blackwell — ввиду поддержки FP8 и Int4 на тензорных ядрах), далее — пропускная способность памяти, и лишь затем — объём VRAM, поскольку последний в рамках данной задачи практически всегда достаточен.&lt;br /&gt;
&lt;br /&gt;
Робот тестировался преимущественно на картах поколения Blackwell:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;RTX5090&#039;&#039;&#039; (использовалась другая LLM меньшего размера)&lt;br /&gt;
* &#039;&#039;&#039;RTX PRO 5000&#039;&#039;&#039; 48gb&lt;br /&gt;
* &#039;&#039;&#039;RTX PRO 6000&#039;&#039;&#039; 96gb&lt;br /&gt;
&lt;br /&gt;
Однако проводились также тесты на картах архитектуры &#039;&#039;&#039;Ampere&#039;&#039;&#039;. Результат можно считать удовлетворительным, особенно для организации тестовых и демо-сред без постоянной большой нагрузки.&lt;br /&gt;
&lt;br /&gt;
Отдельно хочется сказать про ускорители других производителей (AMD, Intel):&lt;br /&gt;
&lt;br /&gt;
К большому сожалению, большая часть инфраструктурного софта оптимизируется в первую очередь под ускорители NVIDIA. В связи с этим даже более производительные карты AMD &amp;quot;на бумаге&amp;quot;, по факту показывают значительно меньшие скорости при реальных задачах. Некоторые же библиотеки и компоненты (TensorRT, Triton Inference Server и т.д.) вообще являются проприетарными разработками NVIDIA и не поддерживают работу с ускорителями других производителей.&lt;br /&gt;
&lt;br /&gt;
=== Анизотропность нагрузки ===&lt;br /&gt;
Из-за логики работы голосового робота, нагрузка на его компоненты в рамках одной сессии достаточно неравномерна. Большинство моделей включаются последовательно после завершения инференса модели на предыдущем шаге:&lt;br /&gt;
&lt;br /&gt;
* VAD (детектирование голосовой активности) - работает всегда (но не вносит существенной нагрузки)&lt;br /&gt;
* ASR (распознавание речи) - запускается при срабатывании триггера VAD (окончание реплики)&lt;br /&gt;
* LLM - запускается после завершения работы ASR&lt;br /&gt;
* TTS - запускается во время / после завершения работы ASR (LLM возвращает текст в потоковом режиме. Текст разбивается на предложения и передается TTS в реальном времени)&lt;br /&gt;
&lt;br /&gt;
Кроме того, архитектурные особенности робота позволяют избегать шага вызова TTS для всех реплик, которые уже были сгенерированы ранее и помещены в кеш. Получается, что если инструкция робота задана таким образом, чтобы его реплики были &amp;quot;статичны&amp;quot; от сессии к сессии, получается экономить значительное количество ресурсов, переиспользуя уже существующие генерации.&lt;br /&gt;
&lt;br /&gt;
Свои оптимизации есть и на стороне инференса LLM:&lt;br /&gt;
&lt;br /&gt;
В команду запуска vLLM по-умолчанию включен режим prefix caching. Данный механизм позволяет кешировать системный промпт и переиспользовать ранее произведенные вычисления для новых запросов. Включение prefix caching позволяет экономить compute для однотипных запросов, а также уменьшить скорость отклика.&lt;br /&gt;
&lt;br /&gt;
Поскольку в рамках голосового робота все запросы (к конкретной конфигурации) используют один системный промпт, это позволяет серьезно экономить.&lt;br /&gt;
&lt;br /&gt;
Данный механизм теряет свою эффективность, к одной LLM будет обращаться большое число роботов с существенно отличающимися системными промптами (50+, точное количество зависит от доступного объема VRAM и настроек vLLM). Также механизм будет мешать, если LLM используется для каких-либо других задач, кроме работы голосового робота.&lt;br /&gt;
&lt;br /&gt;
=== Приблизительный расчет требуемых мощностей ===&lt;br /&gt;
Рекомендуемой конфигурацией является следующая:&lt;br /&gt;
&lt;br /&gt;
CPU 8x&lt;br /&gt;
&lt;br /&gt;
RAM 64gb DDR5&lt;br /&gt;
&lt;br /&gt;
300gb SSD &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Сравнение ускорителей&lt;br /&gt;
!Ускоритель&lt;br /&gt;
!Архитектура&lt;br /&gt;
!VRAM&lt;br /&gt;
!Bandwith&lt;br /&gt;
!Compute (INT8)&lt;br /&gt;
!Приблизительное количество параллельных сессий&lt;br /&gt;
|-&lt;br /&gt;
|RTX PRO 5000&lt;br /&gt;
|Blackwell&lt;br /&gt;
|48gb&lt;br /&gt;
|1.34TB/s&lt;br /&gt;
|516 TOPS&lt;br /&gt;
|30-40&lt;br /&gt;
|-&lt;br /&gt;
|RTX PRO 6000&lt;br /&gt;
|Blackwell&lt;br /&gt;
|96gb&lt;br /&gt;
|1.79TB/s&lt;br /&gt;
|1000 TOPS&lt;br /&gt;
|50-70&lt;br /&gt;
|-&lt;br /&gt;
|RTX 4090/48&lt;br /&gt;
|Ada&lt;br /&gt;
|48gb&lt;br /&gt;
|1TB/s&lt;br /&gt;
|660 TOPS&lt;br /&gt;
|25-30&lt;br /&gt;
|-&lt;br /&gt;
|2x RTX 5090&lt;br /&gt;
|Blackwell&lt;br /&gt;
|2x32gb&lt;br /&gt;
|1.79TB/s&lt;br /&gt;
|828 TOPS&lt;br /&gt;
|30-40&lt;br /&gt;
|-&lt;br /&gt;
|2x RTX 4090/24&lt;br /&gt;
|Ada&lt;br /&gt;
|2x24gb&lt;br /&gt;
|1TB/s&lt;br /&gt;
|660 TOPS&lt;br /&gt;
|10-20&lt;br /&gt;
|-&lt;br /&gt;
|A100/40&lt;br /&gt;
|Ampere&lt;br /&gt;
|40gb&lt;br /&gt;
|1.56TB/s&lt;br /&gt;
|624 TOPS&lt;br /&gt;
|18-23&lt;br /&gt;
|-&lt;br /&gt;
|A100/80&lt;br /&gt;
|Ampere&lt;br /&gt;
|80gb&lt;br /&gt;
|2TB/s&lt;br /&gt;
|624 TOPS&lt;br /&gt;
|55-75&lt;br /&gt;
|-&lt;br /&gt;
|H100&lt;br /&gt;
|Hopper&lt;br /&gt;
|80gb&lt;br /&gt;
|3.35TB/s&lt;br /&gt;
|990 TOPS&lt;br /&gt;
|70-100&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
При использовании конфигураций из двух карт с небольшим объемом VRAM (24, 32gb) будет происходить проблема дисбаланса:&lt;br /&gt;
&lt;br /&gt;
Одну из карт будет полностью занимать LLM (22gb базовых весов), а другую карту будут занимать другие модели. При этом в случае 2x24gb VRAM, для LLM будет оставаться крайне мало памяти на активные сессии, что будет являться главным ограничителем. Использовать память или compute соседней карты невозможно без NVLINK, а в потребительских картах он отсутствует.&lt;br /&gt;
&lt;br /&gt;
Таким образом вариант 2x4090/24 может использовать только для ненагруженных систем - демо стендов или сред разработки. Для такой конфигурации возможно заменить вторую карту на более простую, например 4080, так как TTS + ASR не реализуют 24gb vram.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем оперативной памяти не может быть меньше, чем 32gb, так как в процессе запуска веса моделей помещаются сначала в оперативную память, и только затем в VRAM.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Масштабирование сервиса ===&lt;br /&gt;
При масштабировании голосового робота существует три подхода:&lt;br /&gt;
&lt;br /&gt;
* Использование дополнительных GPU, либо переход на сервер с более производительным GPU&lt;br /&gt;
* Использование нескольких серверов с GPU для балансировки нагрузки&lt;br /&gt;
* Использование нескольких экземпляров робота (движков)&lt;br /&gt;
&lt;br /&gt;
На текущий момент наиболее удобным вариантом масштабирования является второй. Наиболее нагруженные сервисы vLLM и LightTTS можно выносить на отдельные сервера. При этом, например, для LightTTS не требуется большой объем VRAM, и он может качественно работать на сравнительно недорогих потребительских ускорителях (4090, 5080). &lt;br /&gt;
&lt;br /&gt;
Отдельно стоит упомянуть вынесение на отдельный сервер ASR. Данный компонент работает в потоковом режиме по протоколу gRPC, и не рекомендуется вынесение его на другие площадки с высокой задержкой. Остальные компоненты (за исключением VAD, который работает на CPU в составе главного сервиса secondchain), не чувствительны к дополнительным задержкам (в рамках разумного, до 50-70мс).&lt;br /&gt;
&lt;br /&gt;
=== Запуск робота с использованием облачных сервисов инференса ===&lt;br /&gt;
В случае, когда проектные требования позволяют использовать облачную инфраструктуру, нет необходимости полного разворота всех сервисов локально. Можно использовать ресурсы облачных провайдеров и ресурсы, предоставляемые командой платформы.&lt;br /&gt;
&lt;br /&gt;
Сервис поддерживает наиболее популярные API для работы с облачными моделями:&lt;br /&gt;
&lt;br /&gt;
* OpenAI-like формат для LLM. Позволяет подключать к роботу любые из современных передовых языковых моделей.&lt;br /&gt;
* OpenAI-like transcription формат для распознавания речи.&lt;br /&gt;
* LightTTS API формат для генерации речи&lt;br /&gt;
&lt;br /&gt;
Часто, экономически эффективным может быть использование только облачной LLM, так как она требует большого объема VRAM и дорогих ускорителей.&lt;br /&gt;
&lt;br /&gt;
При выборе облачной LLM критичными показателями являются следующие:&lt;br /&gt;
&lt;br /&gt;
* Метрика TTFT (Time To First Token). Время отклика модели до пересылки первых токенов ответа. Должна быть &amp;lt;=300мс, включая сетевые задержки;&lt;br /&gt;
* Поддержка streaming (SSE/chunked) ответов;&lt;br /&gt;
* Возможность отключения режима thinking/reasoning; &lt;br /&gt;
* Скорость генерации ответа &amp;gt;30 токенов/сек.&lt;br /&gt;
&lt;br /&gt;
При использовании всех облачных сервисов инференса, локально разворачивается только главный контейнер - secondchain. Рекомендуемые требования к серверу для такой среды:&lt;br /&gt;
&lt;br /&gt;
4x CPU&lt;br /&gt;
&lt;br /&gt;
8gb RAM&lt;br /&gt;
&lt;br /&gt;
80gb SSD&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
Установка самого Docker:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установка Nvidia Container Toolkit (только для серверов с GPU):&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# репозиторий&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \&lt;br /&gt;
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \&lt;br /&gt;
  sed &#039;s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g&#039; | \&lt;br /&gt;
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-container-toolkit&lt;br /&gt;
sudo nvidia-ctk runtime configure --runtime=docker&lt;br /&gt;
sudo systemctl restart docker&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (опционально) =&lt;br /&gt;
&lt;br /&gt;
Инструкция написана для Unbuntu 24.04.&lt;br /&gt;
&lt;br /&gt;
При написании данной инструкции использовался сервер с RTX PRO 5000 48gb.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Компиляция моделей может занимать больше VRAM, чем запущенный сервис, поэтому в случае дефицита видеопамяти, рекомендуется временно отключать свеже созданные контейнеры, собирать их по одному, после чего запускать по очереди уже в собранном виде.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton Inference Server) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
I0706 22:41:02.484518 1 grpc_server.cc:2562] &amp;quot;Started GRPCInferenceService at 0.0.0.0:8001&amp;quot;&lt;br /&gt;
I0706 22:41:02.484664 1 http_server.cc:4832] &amp;quot;Started HTTPService at 0.0.0.0:8000&amp;quot;&lt;br /&gt;
I0706 22:41:02.525792 1 http_server.cc:358] &amp;quot;Started Metrics Service at 0.0.0.0:8002&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
Установка выполняется из Docker Hub, следующей командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
* &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; — директория хост-машины, где будет храниться кеш весов модели (24gb)&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
После запуска vllm скачает веса модели для запуска (24gb). После завершения запуска и загрузки весов в логах можно наблюдать следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
(APIServer pid=1) INFO:     Started server process [1]&lt;br /&gt;
(APIServer pid=1) INFO:     Waiting for application startup.&lt;br /&gt;
(APIServer pid=1) INFO:     Application startup complete.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Как только они появятся, можно переходить к следующему шагу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080.&#039;&#039;&#039; Первый запрос к модели будет занимать достаточно много времени:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}],&lt;br /&gt;
    &amp;quot;chat_template_kwargs&amp;quot;: {&amp;quot;enable_thinking&amp;quot;: false}&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load -i lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights \&lt;br /&gt;
  python -m light_tts.server.api_server \&lt;br /&gt;
    --model_dir /opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
    --data_type float16 \&lt;br /&gt;
    --load_trt True \&lt;br /&gt;
    --host 0.0.0.0&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;После запуска сервис скомпилирует веса, по аналогии с T-One. После завершения подготовки в логах будут следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:391] ✅ Startup health check passed!&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:395] ✅ Application ready! Server is now accepting requests&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:396] 🌐 Listening at: http://localhost:8080&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — 10 &#039;&#039;&#039;GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 17000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 17001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Контейнеры сервисов инференса голосового робота.png|центр|безрамки|1067x1067пкс]]&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
&lt;br /&gt;
Необходимо переименовать файл example.env в .env и изменить в нём следующие параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&lt;br /&gt;
POSTGRES_HOST=[хост postgresql]&lt;br /&gt;
POSTGRES_PORT=5432&lt;br /&gt;
POSTGRES_USER=[логин postgresql]&lt;br /&gt;
POSTGRES_PASSWORD=[пароль postgresql]&lt;br /&gt;
POSTGRES_DB=[имя БД, если укзаанная БД отсутствует - она будет автоматически создана]&lt;br /&gt;
&lt;br /&gt;
CONCURRENT_SESSIONS=[Жесткое ограничение количества одновременных сессий]&lt;br /&gt;
&lt;br /&gt;
SIP_SERVER=[адрес Эры]&lt;br /&gt;
SIP_PORT=[порт SIP]&lt;br /&gt;
SIP_USERNAME=[Имя учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_PASSWORD=[Пароль учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_DOMAIN=[Полное имя домена, например robot.era-platform.ru]&lt;br /&gt;
#Детальные настройки SIP-клиента. В случае необходимости обхода NAT&lt;br /&gt;
SIP_TRANSPORT=udp&lt;br /&gt;
# NAT Traversal&lt;br /&gt;
SIP_STUN_SERVER=stun.l.google.com:19302&lt;br /&gt;
SIP_USE_ICE=false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
LLM_MODE=openai_api&lt;br /&gt;
#В случае использования сервиса инфереса vLLM на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LLM_OPENAI_API_BASE=http://localhost:16080/v1 &lt;br /&gt;
LLM_OPENAI_MODEL=qwen35-35b-a3b&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ASR_MODE=triton&lt;br /&gt;
#В случае использования сервиса инфереса tone-triton на другом хосте, необходимо изменить адреса/порты&lt;br /&gt;
ASR_TRITON_URL=http://localhost:17000&lt;br /&gt;
ASR_TRITON_GRPC=localhost:17001&lt;br /&gt;
ASR_TRITON_MODEL=streaming_acoustic&lt;br /&gt;
ASR_TRITON_TIMEOUT=10&lt;br /&gt;
ASR_DECODER_TYPE=beam_search&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
TTS_PROVIDER=lighttts&lt;br /&gt;
#В случае использования сервиса инфереса LightTTS на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LIGHTTTS_URL=http://localhost:8080/&lt;br /&gt;
LIGHTTTS_SAMPLE_RATE=24000&lt;br /&gt;
LIGHTTTS_STREAMING=false&lt;br /&gt;
LIGHTTTS_CONCURRENCY=4&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Плейсхолдер под подробное описание .env --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Запуск контейнера и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
docker load -i secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2444</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2444"/>
		<updated>2026-07-07T11:53:18Z</updated>

		<summary type="html">&lt;p&gt;AZykov: /* Масштабирование сервиса */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Общая информация =&lt;br /&gt;
[[Файл:Архитектура голосового робота.png|центр|безрамки|763x763пкс]]&lt;br /&gt;
Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 1. Подготовка|Подготовка]]&#039;&#039;&#039; — Docker, PostgreSQL, настройки в системе телефонии.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 2. Установка сервисов инференса (опционально)|Установка сервисов инференса]]&#039;&#039;&#039; — ASR, LLM, TTS. &#039;&#039;Опционально, только для развёртывания на собственном сервере с GPU.&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 3. Настройка .env|Настройка .env]]&#039;&#039;&#039; — параметры подключения.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 4. Запуск контейнера и создание робота|Запуск контейнера и создание робота]]&#039;&#039;&#039; — старт сервиса и конфигурация робота.&lt;br /&gt;
&lt;br /&gt;
= Глоссарий =&lt;br /&gt;
&#039;&#039;&#039;Модель&#039;&#039;&#039; — обученная нейросеть, задающая соответствие между входом и выходом (текст -&amp;gt; текст, звук -&amp;gt; текст и т.д.). Модель определяется архитектурой и набором весов, полученных при обучении. В стеке робота их четыре:VAD (детекция голосовой активности), ASR (распознавание речи), LLM (генерация ответа), TTS (синтез речи).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Веса&#039;&#039;&#039; — числовые параметры модели, полученные при обучении. Именно они хранятся в файлах модели и загружаются в VRAM при старте. «Загрузка весов» в логах vLLM — это чтение этих файлов с диска в память GPU.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Инференс&#039;&#039;&#039; — использование готовой модели для получения ответа на новый вход («прогон» данных через веса). В отличие от обучения, веса не меняются. Сервисы инференса в статье — Triton, vLLM, LightTTS.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;LLM&#039;&#039;&#039; — Большая языковая модель. Класс моделей text-to-text, обученных на больших объемах мультиязычных и мультидоменных данных.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Triton&#039;&#039;&#039; (NVIDIA Triton Inference Server) — сервер инференса от NVIDIA, обслуживающий модели по gRPC и HTTP. В стеке на нём крутится ASR-модель T-one.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TensorRT&#039;&#039;&#039; — библиотека NVIDIA для оптимизации моделей под конкретный GPU: она компилирует модель в специализированный «движок» ради ускорения инференса. Сборка такого движка — разовая операция под железо, поэтому в LightTTS и T-One Triton она выполняется на первой фазе и коммитится в образ.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;vLLM&#039;&#039;&#039; — движок инференса для больших языковых моделей (LLM), оптимизированный на пропускную способность и эффективную работу с памятью. Предоставляет OpenAI-совместимый API.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;nvidia-smi&#039;&#039;&#039; (NVIDIA System Management Interface) — консольная утилита для просмотра состояния GPU: модель карты, версия драйвера, загрузка, потребление VRAM, запущенные процессы. Используется для проверки, что драйвер установлен и GPU виден (в т.ч. изнутри контейнера).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;KV-Cache&#039;&#039;&#039; (кэш ключей и значений) — память, где LLM хранит промежуточные представления уже обработанных токенов, чтобы не пересчитывать их при генерации каждого нового токена. Ускоряет генерацию ценой VRAM. В конфиге ограничен параметром &amp;lt;code&amp;gt;--kv-cache-memory&amp;lt;/code&amp;gt; (3 GiB). Растёт с числом сессий и длиной контекста — поэтому его размер критичен на картах с малым запасом VRAM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;LightTTS&#039;&#039;&#039; — движок инференса для TTS-моделей (синтеза речи). В стеке запускает модель CosyVoice3, слушает порт 8080.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Промпт&#039;&#039;&#039; — Инструкция, которой следует большая языковая модель.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Токен&#039;&#039;&#039; —В &#039;&#039;контексте LLM&#039;&#039; — единица текста, которой оперирует модель (примерно часть слова / слово / знак). Именно в токенах измеряются окно контекста и объём генерации.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Окно контекста&#039;&#039;&#039; — максимальное количество токенов, которое LLM может учитывать за один запрос (вход + генерируемый ответ вместе). Чем больше окно, тем больше VRAM уходит под KV-Cache, поэтому на картах с ограниченным объёмом его сокращают.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Compute&#039;&#039;&#039; — Вычислительные ресурсы GPU. Абстрактный ресурс видеоускорителя, аналог CPU Time при обычных расчетах. Измеряется в GFLOP/TFLOP (операциях в секунду)&lt;br /&gt;
&lt;br /&gt;
= Требования к оборудованию, нагрузка и мастштабирование =&lt;br /&gt;
&lt;br /&gt;
=== Микросервисы робота и их нагрузка ===&lt;br /&gt;
Робот функционирует на базе 4 микросервисов, каждый из которых может быть вынесен на отдельный сервер, или исполняться на общем сервере. &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Микросервисы робота&lt;br /&gt;
!Название&lt;br /&gt;
!Назначение&lt;br /&gt;
!Ключевые ресурсы&lt;br /&gt;
!Минимальное потребление VRAM&lt;br /&gt;
!Дополнительное потребление VRAM из расчета на 1 сессию&lt;br /&gt;
!Условное потребление Compute на 1 сессию&lt;br /&gt;
|-&lt;br /&gt;
|secondchain&lt;br /&gt;
|Инференс модели VAD (CPU), логика робота, голосовой pipeline, работа с сессиями, SIP-клиент&lt;br /&gt;
|CPU, RAM&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
|vLLM (qwen3.5-35b-a3b-INT4)&lt;br /&gt;
Данные указаны с окном контекста 8192 токена.&lt;br /&gt;
|Инференс больших языковых моделей (LLM)&lt;br /&gt;
|VRAM, Compute&lt;br /&gt;
|22gb&lt;br /&gt;
|0.3gb&lt;br /&gt;
|~3 GFLOP/токен&lt;br /&gt;
|-&lt;br /&gt;
|T-one (Triton Inference Server)&lt;br /&gt;
|Инференс T-One speech-to-text&lt;br /&gt;
|Compute&lt;br /&gt;
|600mb&lt;br /&gt;
|10mb&lt;br /&gt;
|~1-3 GFLOP/секунда речи&lt;br /&gt;
|-&lt;br /&gt;
|LightTTS&lt;br /&gt;
|Инференс CosyVoice3 TTS&lt;br /&gt;
|Compute, VRAM&lt;br /&gt;
|8gb&lt;br /&gt;
|0.3gb&lt;br /&gt;
|~120GFLOP/секунда генерируемоей речи&lt;br /&gt;
|}&lt;br /&gt;
При высокой конкуренции за Compute, увеличиваются задержки на каждом из этапов инференса. Самым чувствительным компонентом, при этом, является LightTTS - из-за архитектурных особенностей. TTS требует много вычислительных ресурсов, и большое количество параллельных генераций могут значительно увеличивать задержку. В случае использования нескольких серверов рекомендуется первично выносить на отдельный сервер либо LightTTS, либо vLLM (для высвобождения Compute).&lt;br /&gt;
&lt;br /&gt;
Архитектурно при этом, робот устроен таким образом, чтобы минимизировать инференс LightTTS при возможности (агрессивное кеширование результатов TTS). &lt;br /&gt;
&lt;br /&gt;
=== Нюансы подбора GPU ===&lt;br /&gt;
При подборе GPU под данный стек объём VRAM не является определяющим критерием. Веса любой из трёх моделей помещаются в память практически любой современной карты (уровня 5090 или выше), тогда как реальными ограничивающими факторами выступают пропускная способность памяти на этапе декодирования LLM и вычислительная нагрузка DiT-декодера в TTS. Соответственно, при выборе оборудования следует ориентироваться в первую очередь на memory bandwidth и на аппаратную поддержку современных типов данных, а не на номинальный объём видеопамяти.&lt;br /&gt;
&lt;br /&gt;
Отдельного внимания заслуживает интерфейс межкарточного взаимодействия. Потребительские карты рассчитаны преимущественно на одиночную эксплуатацию: в актуальных линейках Blackwell и Ada поддержка NVLink отсутствует, и обмен между несколькими GPU на одном сервере осуществляется исключительно через PCIe (Gen4/Gen5). При использовании tensor parallelism это создаёт заметные накладные расходы на межкарточную коммуникацию, что становится ощутимым при высокой конкурентной нагрузке. Дата-центровые решения (H100, H200, а также RTX PRO 6000 в соответствующем сегменте) либо предоставляют NVLink с пропускной способностью в сотни ГБ/с, либо обладают достаточным объёмом памяти для размещения моделей на одной карте, что позволяет полностью исключить tensor parallelism и связанные с ним издержки.&lt;br /&gt;
&lt;br /&gt;
Следует также учитывать высокие темпы развития архитектур GPU. Производительная карта шестилетней давности может уступать современному решению среднего уровня как по вычислительной мощности, так и — что существенно в данном случае — по набору поддерживаемых типов данных. Например, NVIDIA V100 (Volta, 2017), несмотря на наличие NVLink и памяти HBM, не поддерживает аппаратное ускорение FP8 и Int4 на тензорных ядрах. Между тем рассматриваемый стек существенно опирается на эти форматы: Qwen в квантизации GPTQ-Int4 с fp8 KV-cache, T-one в TensorRT, TTS с int8-квантизацией. На оборудовании предыдущих поколений соответствующие операции либо неработоспособны в требуемых форматах, либо выполняются с существенным замедлением за счёт программной эмуляции.&lt;br /&gt;
&lt;br /&gt;
С практической точки зрения приоритеты при выборе оборудования под данный пайплайн выстраиваются следующим образом: в первую очередь — поколение архитектуры (Ada, Ampere, Hopper, Blackwell — ввиду поддержки FP8 и Int4 на тензорных ядрах), далее — пропускная способность памяти, и лишь затем — объём VRAM, поскольку последний в рамках данной задачи практически всегда достаточен.&lt;br /&gt;
&lt;br /&gt;
Робот тестировался преимущественно на картах поколения Blackwell:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;RTX5090&#039;&#039;&#039; (использовалась другая LLM меньшего размера)&lt;br /&gt;
* &#039;&#039;&#039;RTX PRO 5000&#039;&#039;&#039; 48gb&lt;br /&gt;
* &#039;&#039;&#039;RTX PRO 6000&#039;&#039;&#039; 96gb&lt;br /&gt;
&lt;br /&gt;
Однако проводились также тесты на картах архитектуры &#039;&#039;&#039;Ampere&#039;&#039;&#039;. Результат можно считать удовлетворительным, особенно для организации тестовых и демо-сред без постоянной большой нагрузки.&lt;br /&gt;
&lt;br /&gt;
Отдельно хочется сказать про ускорители других производителей (AMD, Intel):&lt;br /&gt;
&lt;br /&gt;
К большому сожалению, большая часть инфраструктурного софта оптимизируется в первую очередь под ускорители NVIDIA. В связи с этим даже более производительные карты AMD &amp;quot;на бумаге&amp;quot;, по факту показывают значительно меньшие скорости при реальных задачах. Некоторые же библиотеки и компоненты (TensorRT, Triton Inference Server и т.д.) вообще являются проприетарными разработками NVIDIA и не поддерживают работу с ускорителями других производителей.&lt;br /&gt;
&lt;br /&gt;
=== Анизотропность нагрузки ===&lt;br /&gt;
Из-за логики работы голосового робота, нагрузка на его компоненты в рамках одной сессии достаточно неравномерна. Большинство моделей включаются последовательно после завершения инференса модели на предыдущем шаге:&lt;br /&gt;
&lt;br /&gt;
* VAD (детектирование голосовой активности) - работает всегда (но не вносит существенной нагрузки)&lt;br /&gt;
* ASR (распознавание речи) - запускается при срабатывании триггера VAD (окончание реплики)&lt;br /&gt;
* LLM - запускается после завершения работы ASR&lt;br /&gt;
* TTS - запускается во время / после завершения работы ASR (LLM возвращает текст в потоковом режиме. Текст разбивается на предложения и передается TTS в реальном времени)&lt;br /&gt;
&lt;br /&gt;
Кроме того, архитектурные особенности робота позволяют избегать шага вызова TTS для всех реплик, которые уже были сгенерированы ранее и помещены в кеш. Получается, что если инструкция робота задана таким образом, чтобы его реплики были &amp;quot;статичны&amp;quot; от сессии к сессии, получается экономить значительное количество ресурсов, переиспользуя уже существующие генерации.&lt;br /&gt;
&lt;br /&gt;
Свои оптимизации есть и на стороне инференса LLM:&lt;br /&gt;
&lt;br /&gt;
В команду запуска vLLM по-умолчанию включен режим prefix caching. Данный механизм позволяет кешировать системный промпт и переиспользовать ранее произведенные вычисления для новых запросов. Включение prefix caching позволяет экономить compute для однотипных запросов, а также уменьшить скорость отклика.&lt;br /&gt;
&lt;br /&gt;
Поскольку в рамках голосового робота все запросы (к конкретной конфигурации) используют один системный промпт, это позволяет серьезно экономить.&lt;br /&gt;
&lt;br /&gt;
Данный механизм теряет свою эффективность, к одной LLM будет обращаться большое число роботов с существенно отличающимися системными промптами (50+, точное количество зависит от доступного объема VRAM и настроек vLLM). Также механизм будет мешать, если LLM используется для каких-либо других задач, кроме работы голосового робота.&lt;br /&gt;
&lt;br /&gt;
=== Приблизительный расчет требуемых мощностей ===&lt;br /&gt;
Рекомендуемой конфигурацией является следующая:&lt;br /&gt;
&lt;br /&gt;
CPU 8x&lt;br /&gt;
&lt;br /&gt;
RAM 64gb DDR5&lt;br /&gt;
&lt;br /&gt;
300gb SSD &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Сравнение ускорителей&lt;br /&gt;
!Ускоритель&lt;br /&gt;
!Архитектура&lt;br /&gt;
!VRAM&lt;br /&gt;
!Bandwith&lt;br /&gt;
!Compute (INT8)&lt;br /&gt;
!Приблизительное количество параллельных сессий&lt;br /&gt;
|-&lt;br /&gt;
|RTX PRO 5000&lt;br /&gt;
|Blackwell&lt;br /&gt;
|48gb&lt;br /&gt;
|1.34TB/s&lt;br /&gt;
|516 TOPS&lt;br /&gt;
|30-40&lt;br /&gt;
|-&lt;br /&gt;
|RTX PRO 6000&lt;br /&gt;
|Blackwell&lt;br /&gt;
|96gb&lt;br /&gt;
|1.79TB/s&lt;br /&gt;
|1000 TOPS&lt;br /&gt;
|50-70&lt;br /&gt;
|-&lt;br /&gt;
|RTX 4090/48&lt;br /&gt;
|Ada&lt;br /&gt;
|48gb&lt;br /&gt;
|1TB/s&lt;br /&gt;
|660 TOPS&lt;br /&gt;
|25-30&lt;br /&gt;
|-&lt;br /&gt;
|2x RTX 5090&lt;br /&gt;
|Blackwell&lt;br /&gt;
|2x32gb&lt;br /&gt;
|1.79TB/s&lt;br /&gt;
|828 TOPS&lt;br /&gt;
|30-40&lt;br /&gt;
|-&lt;br /&gt;
|2x RTX 4090/24&lt;br /&gt;
|Ada&lt;br /&gt;
|2x24gb&lt;br /&gt;
|1TB/s&lt;br /&gt;
|660 TOPS&lt;br /&gt;
|10-20&lt;br /&gt;
|-&lt;br /&gt;
|A100/40&lt;br /&gt;
|Ampere&lt;br /&gt;
|40gb&lt;br /&gt;
|1.56TB/s&lt;br /&gt;
|624 TOPS&lt;br /&gt;
|18-23&lt;br /&gt;
|-&lt;br /&gt;
|A100/80&lt;br /&gt;
|Ampere&lt;br /&gt;
|80gb&lt;br /&gt;
|2TB/s&lt;br /&gt;
|624 TOPS&lt;br /&gt;
|55-75&lt;br /&gt;
|-&lt;br /&gt;
|H100&lt;br /&gt;
|Hopper&lt;br /&gt;
|80gb&lt;br /&gt;
|3.35TB/s&lt;br /&gt;
|990 TOPS&lt;br /&gt;
|70-100&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
При использовании конфигураций из двух карт с небольшим объемом VRAM (24, 32gb) будет происходить проблема дисбаланса:&lt;br /&gt;
&lt;br /&gt;
Одну из карт будет полностью занимать LLM (22gb базовых весов), а другую карту будут занимать другие модели. При этом в случае 2x24gb VRAM, для LLM будет оставаться крайне мало памяти на активные сессии, что будет являться главным ограничителем. Использовать память или compute соседней карты невозможно без NVLINK, а в потребительских картах он отсутствует.&lt;br /&gt;
&lt;br /&gt;
Таким образом вариант 2x4090/24 может использовать только для ненагруженных систем - демо стендов или сред разработки. Для такой конфигурации возможно заменить вторую карту на более простую, например 4080, так как TTS + ASR не реализуют 24gb vram.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем оперативной памяти не может быть меньше, чем 32gb, так как в процессе запуска веса моделей помещаются сначала в оперативную память, и только затем в VRAM.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Масштабирование сервиса ===&lt;br /&gt;
При масштабировании голосового робота существует три подхода:&lt;br /&gt;
&lt;br /&gt;
* Использование дополнительных GPU, либо переход на сервер с более производительным GPU&lt;br /&gt;
* Использование нескольких серверов с GPU для балансировки нагрузки&lt;br /&gt;
* Использование нескольких экземпляров робота (движков)&lt;br /&gt;
&lt;br /&gt;
На текущий момент наиболее удобным вариантом масштабирования является второй. Наиболее нагруженные сервисы vLLM и LightTTS можно выносить на отдельные сервера. При этом, например, для LightTTS не требуется большой объем VRAM, и он может качественно работать на сравнительно недорогих потребительских ускорителях (4090, 5080). &lt;br /&gt;
&lt;br /&gt;
Отдельно стоит упомянуть вынесение на отдельный сервер ASR. Данный компонент работает в потоковом режиме по протоколу gRPC, и не рекомендуется вынесение его на другие площадки с высокой задержкой. Остальные компоненты (за исключением VAD, который работает на CPU в составе главного сервиса secondchain), не чувствительны к дополнительным задержкам (в рамках разумного, до 50-70мс).&lt;br /&gt;
&lt;br /&gt;
=== Запуск сервиса робота с использованием облачных сервисов инференса ===&lt;br /&gt;
В случае, когда проектные требования позволяют использовать облачную инфраструктуру, нет необходимости полного разворота всех сервисов локально. Можно использовать ресурсы облачных провайдеров и ресурсы, предоставляемые командой платформы.&lt;br /&gt;
&lt;br /&gt;
Сервис поддерживает наиболее популярные API для работы с облачными моделями:&lt;br /&gt;
&lt;br /&gt;
* OpenAI-like формат для LLM. Позволяет подключать к роботу любые из современных передовых языковых моделей.&lt;br /&gt;
* OpenAI-like transcription формат для распознавания речи.&lt;br /&gt;
* LightTTS API формат для генерации речи&lt;br /&gt;
&lt;br /&gt;
Часто, экономически эффективным может быть использование только облачной LLM, так как она требует большого объема VRAM и дорогих ускорителей.&lt;br /&gt;
&lt;br /&gt;
При выборе облачной LLM критичными показателями являются следующие:&lt;br /&gt;
&lt;br /&gt;
* Метрика TTFT (Time To First Token). Время отклика модели до пересылки первых токенов ответа. Должна быть &amp;lt;=300мс, включая сетевые задержки;&lt;br /&gt;
* Поддержка streaming (SSE/chunked) ответов;&lt;br /&gt;
* Возможность отключения режима thinking/reasoning; &lt;br /&gt;
* Скорость генерации ответа &amp;gt;30 токенов/сек.&lt;br /&gt;
&lt;br /&gt;
При использовании всех облачных сервисов инференса, локально разворачивается только главный контейнер - secondchain. Рекомендуемые требования к серверу для такой среды:&lt;br /&gt;
&lt;br /&gt;
4x CPU&lt;br /&gt;
&lt;br /&gt;
8gb RAM&lt;br /&gt;
&lt;br /&gt;
80gb SSD&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
Установка самого Docker:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установка Nvidia Container Toolkit (только для серверов с GPU):&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# репозиторий&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \&lt;br /&gt;
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \&lt;br /&gt;
  sed &#039;s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g&#039; | \&lt;br /&gt;
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-container-toolkit&lt;br /&gt;
sudo nvidia-ctk runtime configure --runtime=docker&lt;br /&gt;
sudo systemctl restart docker&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (опционально) =&lt;br /&gt;
&lt;br /&gt;
Инструкция написана для Unbuntu 24.04.&lt;br /&gt;
&lt;br /&gt;
При написании данной инструкции использовался сервер с RTX PRO 5000 48gb.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Компиляция моделей может занимать больше VRAM, чем запущенный сервис, поэтому в случае дефицита видеопамяти, рекомендуется временно отключать свеже созданные контейнеры, собирать их по одному, после чего запускать по очереди уже в собранном виде.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton Inference Server) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
I0706 22:41:02.484518 1 grpc_server.cc:2562] &amp;quot;Started GRPCInferenceService at 0.0.0.0:8001&amp;quot;&lt;br /&gt;
I0706 22:41:02.484664 1 http_server.cc:4832] &amp;quot;Started HTTPService at 0.0.0.0:8000&amp;quot;&lt;br /&gt;
I0706 22:41:02.525792 1 http_server.cc:358] &amp;quot;Started Metrics Service at 0.0.0.0:8002&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
Установка выполняется из Docker Hub, следующей командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
* &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; — директория хост-машины, где будет храниться кеш весов модели (24gb)&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
После запуска vllm скачает веса модели для запуска (24gb). После завершения запуска и загрузки весов в логах можно наблюдать следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
(APIServer pid=1) INFO:     Started server process [1]&lt;br /&gt;
(APIServer pid=1) INFO:     Waiting for application startup.&lt;br /&gt;
(APIServer pid=1) INFO:     Application startup complete.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Как только они появятся, можно переходить к следующему шагу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080.&#039;&#039;&#039; Первый запрос к модели будет занимать достаточно много времени:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}],&lt;br /&gt;
    &amp;quot;chat_template_kwargs&amp;quot;: {&amp;quot;enable_thinking&amp;quot;: false}&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load -i lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights \&lt;br /&gt;
  python -m light_tts.server.api_server \&lt;br /&gt;
    --model_dir /opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
    --data_type float16 \&lt;br /&gt;
    --load_trt True \&lt;br /&gt;
    --host 0.0.0.0&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;После запуска сервис скомпилирует веса, по аналогии с T-One. После завершения подготовки в логах будут следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:391] ✅ Startup health check passed!&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:395] ✅ Application ready! Server is now accepting requests&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:396] 🌐 Listening at: http://localhost:8080&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — 10 &#039;&#039;&#039;GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 17000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 17001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Контейнеры сервисов инференса голосового робота.png|центр|безрамки|1067x1067пкс]]&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
&lt;br /&gt;
Необходимо переименовать файл example.env в .env и изменить в нём следующие параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&lt;br /&gt;
POSTGRES_HOST=[хост postgresql]&lt;br /&gt;
POSTGRES_PORT=5432&lt;br /&gt;
POSTGRES_USER=[логин postgresql]&lt;br /&gt;
POSTGRES_PASSWORD=[пароль postgresql]&lt;br /&gt;
POSTGRES_DB=[имя БД, если укзаанная БД отсутствует - она будет автоматически создана]&lt;br /&gt;
&lt;br /&gt;
CONCURRENT_SESSIONS=[Жесткое ограничение количества одновременных сессий]&lt;br /&gt;
&lt;br /&gt;
SIP_SERVER=[адрес Эры]&lt;br /&gt;
SIP_PORT=[порт SIP]&lt;br /&gt;
SIP_USERNAME=[Имя учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_PASSWORD=[Пароль учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_DOMAIN=[Полное имя домена, например robot.era-platform.ru]&lt;br /&gt;
#Детальные настройки SIP-клиента. В случае необходимости обхода NAT&lt;br /&gt;
SIP_TRANSPORT=udp&lt;br /&gt;
# NAT Traversal&lt;br /&gt;
SIP_STUN_SERVER=stun.l.google.com:19302&lt;br /&gt;
SIP_USE_ICE=false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
LLM_MODE=openai_api&lt;br /&gt;
#В случае использования сервиса инфереса vLLM на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LLM_OPENAI_API_BASE=http://localhost:16080/v1 &lt;br /&gt;
LLM_OPENAI_MODEL=qwen35-35b-a3b&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ASR_MODE=triton&lt;br /&gt;
#В случае использования сервиса инфереса tone-triton на другом хосте, необходимо изменить адреса/порты&lt;br /&gt;
ASR_TRITON_URL=http://localhost:17000&lt;br /&gt;
ASR_TRITON_GRPC=localhost:17001&lt;br /&gt;
ASR_TRITON_MODEL=streaming_acoustic&lt;br /&gt;
ASR_TRITON_TIMEOUT=10&lt;br /&gt;
ASR_DECODER_TYPE=beam_search&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
TTS_PROVIDER=lighttts&lt;br /&gt;
#В случае использования сервиса инфереса LightTTS на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LIGHTTTS_URL=http://localhost:8080/&lt;br /&gt;
LIGHTTTS_SAMPLE_RATE=24000&lt;br /&gt;
LIGHTTTS_STREAMING=false&lt;br /&gt;
LIGHTTTS_CONCURRENCY=4&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Плейсхолдер под подробное описание .env --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Запуск контейнера и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
docker load -i secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2443</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2443"/>
		<updated>2026-07-07T11:39:18Z</updated>

		<summary type="html">&lt;p&gt;AZykov: /* Приблизительный расчет требуемых мощностей */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Общая информация =&lt;br /&gt;
[[Файл:Архитектура голосового робота.png|центр|безрамки|763x763пкс]]&lt;br /&gt;
Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 1. Подготовка|Подготовка]]&#039;&#039;&#039; — Docker, PostgreSQL, настройки в системе телефонии.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 2. Установка сервисов инференса (опционально)|Установка сервисов инференса]]&#039;&#039;&#039; — ASR, LLM, TTS. &#039;&#039;Опционально, только для развёртывания на собственном сервере с GPU.&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 3. Настройка .env|Настройка .env]]&#039;&#039;&#039; — параметры подключения.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 4. Запуск контейнера и создание робота|Запуск контейнера и создание робота]]&#039;&#039;&#039; — старт сервиса и конфигурация робота.&lt;br /&gt;
&lt;br /&gt;
= Глоссарий =&lt;br /&gt;
&#039;&#039;&#039;Модель&#039;&#039;&#039; — обученная нейросеть, задающая соответствие между входом и выходом (текст -&amp;gt; текст, звук -&amp;gt; текст и т.д.). Модель определяется архитектурой и набором весов, полученных при обучении. В стеке робота их четыре:VAD (детекция голосовой активности), ASR (распознавание речи), LLM (генерация ответа), TTS (синтез речи).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Веса&#039;&#039;&#039; — числовые параметры модели, полученные при обучении. Именно они хранятся в файлах модели и загружаются в VRAM при старте. «Загрузка весов» в логах vLLM — это чтение этих файлов с диска в память GPU.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Инференс&#039;&#039;&#039; — использование готовой модели для получения ответа на новый вход («прогон» данных через веса). В отличие от обучения, веса не меняются. Сервисы инференса в статье — Triton, vLLM, LightTTS.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;LLM&#039;&#039;&#039; — Большая языковая модель. Класс моделей text-to-text, обученных на больших объемах мультиязычных и мультидоменных данных.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Triton&#039;&#039;&#039; (NVIDIA Triton Inference Server) — сервер инференса от NVIDIA, обслуживающий модели по gRPC и HTTP. В стеке на нём крутится ASR-модель T-one.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TensorRT&#039;&#039;&#039; — библиотека NVIDIA для оптимизации моделей под конкретный GPU: она компилирует модель в специализированный «движок» ради ускорения инференса. Сборка такого движка — разовая операция под железо, поэтому в LightTTS и T-One Triton она выполняется на первой фазе и коммитится в образ.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;vLLM&#039;&#039;&#039; — движок инференса для больших языковых моделей (LLM), оптимизированный на пропускную способность и эффективную работу с памятью. Предоставляет OpenAI-совместимый API.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;nvidia-smi&#039;&#039;&#039; (NVIDIA System Management Interface) — консольная утилита для просмотра состояния GPU: модель карты, версия драйвера, загрузка, потребление VRAM, запущенные процессы. Используется для проверки, что драйвер установлен и GPU виден (в т.ч. изнутри контейнера).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;KV-Cache&#039;&#039;&#039; (кэш ключей и значений) — память, где LLM хранит промежуточные представления уже обработанных токенов, чтобы не пересчитывать их при генерации каждого нового токена. Ускоряет генерацию ценой VRAM. В конфиге ограничен параметром &amp;lt;code&amp;gt;--kv-cache-memory&amp;lt;/code&amp;gt; (3 GiB). Растёт с числом сессий и длиной контекста — поэтому его размер критичен на картах с малым запасом VRAM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;LightTTS&#039;&#039;&#039; — движок инференса для TTS-моделей (синтеза речи). В стеке запускает модель CosyVoice3, слушает порт 8080.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Промпт&#039;&#039;&#039; — Инструкция, которой следует большая языковая модель.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Токен&#039;&#039;&#039; —В &#039;&#039;контексте LLM&#039;&#039; — единица текста, которой оперирует модель (примерно часть слова / слово / знак). Именно в токенах измеряются окно контекста и объём генерации.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Окно контекста&#039;&#039;&#039; — максимальное количество токенов, которое LLM может учитывать за один запрос (вход + генерируемый ответ вместе). Чем больше окно, тем больше VRAM уходит под KV-Cache, поэтому на картах с ограниченным объёмом его сокращают.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Compute&#039;&#039;&#039; — Вычислительные ресурсы GPU. Абстрактный ресурс видеоускорителя, аналог CPU Time при обычных расчетах. Измеряется в GFLOP/TFLOP (операциях в секунду)&lt;br /&gt;
&lt;br /&gt;
= Требования к оборудованию, нагрузка и мастштабирование =&lt;br /&gt;
&lt;br /&gt;
=== Микросервисы робота и их нагрузка ===&lt;br /&gt;
Робот функционирует на базе 4 микросервисов, каждый из которых может быть вынесен на отдельный сервер, или исполняться на общем сервере. &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Микросервисы робота&lt;br /&gt;
!Название&lt;br /&gt;
!Назначение&lt;br /&gt;
!Ключевые ресурсы&lt;br /&gt;
!Минимальное потребление VRAM&lt;br /&gt;
!Дополнительное потребление VRAM из расчета на 1 сессию&lt;br /&gt;
!Условное потребление Compute на 1 сессию&lt;br /&gt;
|-&lt;br /&gt;
|secondchain&lt;br /&gt;
|Инференс модели VAD (CPU), логика робота, голосовой pipeline, работа с сессиями, SIP-клиент&lt;br /&gt;
|CPU, RAM&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
|vLLM (qwen3.5-35b-a3b-INT4)&lt;br /&gt;
Данные указаны с окном контекста 8192 токена.&lt;br /&gt;
|Инференс больших языковых моделей (LLM)&lt;br /&gt;
|VRAM, Compute&lt;br /&gt;
|22gb&lt;br /&gt;
|0.3gb&lt;br /&gt;
|~3 GFLOP/токен&lt;br /&gt;
|-&lt;br /&gt;
|T-one (Triton Inference Server)&lt;br /&gt;
|Инференс T-One speech-to-text&lt;br /&gt;
|Compute&lt;br /&gt;
|600mb&lt;br /&gt;
|10mb&lt;br /&gt;
|~1-3 GFLOP/секунда речи&lt;br /&gt;
|-&lt;br /&gt;
|LightTTS&lt;br /&gt;
|Инференс CosyVoice3 TTS&lt;br /&gt;
|Compute, VRAM&lt;br /&gt;
|8gb&lt;br /&gt;
|0.3gb&lt;br /&gt;
|~120GFLOP/секунда генерируемоей речи&lt;br /&gt;
|}&lt;br /&gt;
При высокой конкуренции за Compute, увеличиваются задержки на каждом из этапов инференса. Самым чувствительным компонентом, при этом, является LightTTS - из-за архитектурных особенностей. TTS требует много вычислительных ресурсов, и большое количество параллельных генераций могут значительно увеличивать задержку. В случае использования нескольких серверов рекомендуется первично выносить на отдельный сервер либо LightTTS, либо vLLM (для высвобождения Compute).&lt;br /&gt;
&lt;br /&gt;
Архитектурно при этом, робот устроен таким образом, чтобы минимизировать инференс LightTTS при возможности (агрессивное кеширование результатов TTS). &lt;br /&gt;
&lt;br /&gt;
=== Нюансы подбора GPU ===&lt;br /&gt;
При подборе GPU под данный стек объём VRAM не является определяющим критерием. Веса любой из трёх моделей помещаются в память практически любой современной карты (уровня 5090 или выше), тогда как реальными ограничивающими факторами выступают пропускная способность памяти на этапе декодирования LLM и вычислительная нагрузка DiT-декодера в TTS. Соответственно, при выборе оборудования следует ориентироваться в первую очередь на memory bandwidth и на аппаратную поддержку современных типов данных, а не на номинальный объём видеопамяти.&lt;br /&gt;
&lt;br /&gt;
Отдельного внимания заслуживает интерфейс межкарточного взаимодействия. Потребительские карты рассчитаны преимущественно на одиночную эксплуатацию: в актуальных линейках Blackwell и Ada поддержка NVLink отсутствует, и обмен между несколькими GPU на одном сервере осуществляется исключительно через PCIe (Gen4/Gen5). При использовании tensor parallelism это создаёт заметные накладные расходы на межкарточную коммуникацию, что становится ощутимым при высокой конкурентной нагрузке. Дата-центровые решения (H100, H200, а также RTX PRO 6000 в соответствующем сегменте) либо предоставляют NVLink с пропускной способностью в сотни ГБ/с, либо обладают достаточным объёмом памяти для размещения моделей на одной карте, что позволяет полностью исключить tensor parallelism и связанные с ним издержки.&lt;br /&gt;
&lt;br /&gt;
Следует также учитывать высокие темпы развития архитектур GPU. Производительная карта шестилетней давности может уступать современному решению среднего уровня как по вычислительной мощности, так и — что существенно в данном случае — по набору поддерживаемых типов данных. Например, NVIDIA V100 (Volta, 2017), несмотря на наличие NVLink и памяти HBM, не поддерживает аппаратное ускорение FP8 и Int4 на тензорных ядрах. Между тем рассматриваемый стек существенно опирается на эти форматы: Qwen в квантизации GPTQ-Int4 с fp8 KV-cache, T-one в TensorRT, TTS с int8-квантизацией. На оборудовании предыдущих поколений соответствующие операции либо неработоспособны в требуемых форматах, либо выполняются с существенным замедлением за счёт программной эмуляции.&lt;br /&gt;
&lt;br /&gt;
С практической точки зрения приоритеты при выборе оборудования под данный пайплайн выстраиваются следующим образом: в первую очередь — поколение архитектуры (Ada, Ampere, Hopper, Blackwell — ввиду поддержки FP8 и Int4 на тензорных ядрах), далее — пропускная способность памяти, и лишь затем — объём VRAM, поскольку последний в рамках данной задачи практически всегда достаточен.&lt;br /&gt;
&lt;br /&gt;
Робот тестировался преимущественно на картах поколения Blackwell:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;RTX5090&#039;&#039;&#039; (использовалась другая LLM меньшего размера)&lt;br /&gt;
* &#039;&#039;&#039;RTX PRO 5000&#039;&#039;&#039; 48gb&lt;br /&gt;
* &#039;&#039;&#039;RTX PRO 6000&#039;&#039;&#039; 96gb&lt;br /&gt;
&lt;br /&gt;
Однако проводились также тесты на картах архитектуры &#039;&#039;&#039;Ampere&#039;&#039;&#039;. Результат можно считать удовлетворительным, особенно для организации тестовых и демо-сред без постоянной большой нагрузки.&lt;br /&gt;
&lt;br /&gt;
Отдельно хочется сказать про ускорители других производителей (AMD, Intel):&lt;br /&gt;
&lt;br /&gt;
К большому сожалению, большая часть инфраструктурного софта оптимизируется в первую очередь под ускорители NVIDIA. В связи с этим даже более производительные карты AMD &amp;quot;на бумаге&amp;quot;, по факту показывают значительно меньшие скорости при реальных задачах. Некоторые же библиотеки и компоненты (TensorRT, Triton Inference Server и т.д.) вообще являются проприетарными разработками NVIDIA и не поддерживают работу с ускорителями других производителей.&lt;br /&gt;
&lt;br /&gt;
=== Анизотропность нагрузки ===&lt;br /&gt;
Из-за логики работы голосового робота, нагрузка на его компоненты в рамках одной сессии достаточно неравномерна. Большинство моделей включаются последовательно после завершения инференса модели на предыдущем шаге:&lt;br /&gt;
&lt;br /&gt;
* VAD (детектирование голосовой активности) - работает всегда (но не вносит существенной нагрузки)&lt;br /&gt;
* ASR (распознавание речи) - запускается при срабатывании триггера VAD (окончание реплики)&lt;br /&gt;
* LLM - запускается после завершения работы ASR&lt;br /&gt;
* TTS - запускается во время / после завершения работы ASR (LLM возвращает текст в потоковом режиме. Текст разбивается на предложения и передается TTS в реальном времени)&lt;br /&gt;
&lt;br /&gt;
Кроме того, архитектурные особенности робота позволяют избегать шага вызова TTS для всех реплик, которые уже были сгенерированы ранее и помещены в кеш. Получается, что если инструкция робота задана таким образом, чтобы его реплики были &amp;quot;статичны&amp;quot; от сессии к сессии, получается экономить значительное количество ресурсов, переиспользуя уже существующие генерации.&lt;br /&gt;
&lt;br /&gt;
Свои оптимизации есть и на стороне инференса LLM:&lt;br /&gt;
&lt;br /&gt;
В команду запуска vLLM по-умолчанию включен режим prefix caching. Данный механизм позволяет кешировать системный промпт и переиспользовать ранее произведенные вычисления для новых запросов. Включение prefix caching позволяет экономить compute для однотипных запросов, а также уменьшить скорость отклика.&lt;br /&gt;
&lt;br /&gt;
Поскольку в рамках голосового робота все запросы (к конкретной конфигурации) используют один системный промпт, это позволяет серьезно экономить.&lt;br /&gt;
&lt;br /&gt;
Данный механизм теряет свою эффективность, к одной LLM будет обращаться большое число роботов с существенно отличающимися системными промптами (50+, точное количество зависит от доступного объема VRAM и настроек vLLM). Также механизм будет мешать, если LLM используется для каких-либо других задач, кроме работы голосового робота.&lt;br /&gt;
&lt;br /&gt;
=== Приблизительный расчет требуемых мощностей ===&lt;br /&gt;
Минимальной конфигурацией является следующая:&lt;br /&gt;
&lt;br /&gt;
CPU 8x&lt;br /&gt;
&lt;br /&gt;
RAM 64gb DDR5&lt;br /&gt;
&lt;br /&gt;
300gb SSD &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Сравнение ускорителей&lt;br /&gt;
!Ускоритель&lt;br /&gt;
!Архитектура&lt;br /&gt;
!VRAM&lt;br /&gt;
!Bandwith&lt;br /&gt;
!Compute (INT8)&lt;br /&gt;
!Приблизительное количество параллельных сессий&lt;br /&gt;
|-&lt;br /&gt;
|RTX PRO 5000&lt;br /&gt;
|Blackwell&lt;br /&gt;
|48gb&lt;br /&gt;
|1.34TB/s&lt;br /&gt;
|516 TOPS&lt;br /&gt;
|30-40&lt;br /&gt;
|-&lt;br /&gt;
|RTX PRO 6000&lt;br /&gt;
|Blackwell&lt;br /&gt;
|96gb&lt;br /&gt;
|1.79TB/s&lt;br /&gt;
|1000 TOPS&lt;br /&gt;
|50-70&lt;br /&gt;
|-&lt;br /&gt;
|RTX 4090/48&lt;br /&gt;
|Ada&lt;br /&gt;
|48gb&lt;br /&gt;
|1TB/s&lt;br /&gt;
|660 TOPS&lt;br /&gt;
|25-30&lt;br /&gt;
|-&lt;br /&gt;
|2x RTX 5090&lt;br /&gt;
|Blackwell&lt;br /&gt;
|2x32gb&lt;br /&gt;
|1.79TB/s&lt;br /&gt;
|828 TOPS&lt;br /&gt;
|30-40&lt;br /&gt;
|-&lt;br /&gt;
|2x RTX 4090/24&lt;br /&gt;
|Ada&lt;br /&gt;
|2x24gb&lt;br /&gt;
|1TB/s&lt;br /&gt;
|660 TOPS&lt;br /&gt;
|10-20&lt;br /&gt;
|-&lt;br /&gt;
|A100/40&lt;br /&gt;
|Ampere&lt;br /&gt;
|40gb&lt;br /&gt;
|1.56TB/s&lt;br /&gt;
|624 TOPS&lt;br /&gt;
|18-23&lt;br /&gt;
|-&lt;br /&gt;
|A100/80&lt;br /&gt;
|Ampere&lt;br /&gt;
|80gb&lt;br /&gt;
|2TB/s&lt;br /&gt;
|624 TOPS&lt;br /&gt;
|55-75&lt;br /&gt;
|-&lt;br /&gt;
|H100&lt;br /&gt;
|Hopper&lt;br /&gt;
|80gb&lt;br /&gt;
|3.35TB/s&lt;br /&gt;
|990 TOPS&lt;br /&gt;
|70-100&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
При использовании конфигураций из двух карт с небольшим объемом VRAM (24, 32gb) будет происходить проблема дисбаланса:&lt;br /&gt;
&lt;br /&gt;
Одну из карт будет полностью занимать LLM (22gb базовых весов), а другую карту будут занимать другие модели. При этом в случае 2x24gb VRAM, для LLM будет оставаться крайне мало памяти на активные сессии, что будет являться главным ограничителем. Использовать память или compute соседней карты невозможно без NVLINK, а в потребительских картах он отсутствует.&lt;br /&gt;
&lt;br /&gt;
Таким образом вариант 2x4090/24 может использовать только для ненагруженных систем - демо стендов или сред разработки. Для такой конфигурации возможно заменить вторую карту на более простую, например 4080, так как TTS + ASR не реализуют 24gb vram.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем оперативной памяти не может быть меньше, чем VRAM, так как в процессе запуска веса моделей помещаются сначала в оперативную память, и только затем в VRAM.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Масштабирование сервиса ===&lt;br /&gt;
При масштабировании голосового робота существует три подхода:&lt;br /&gt;
&lt;br /&gt;
* Использование дополнительных GPU, либо переход на сервер с более производительным GPU&lt;br /&gt;
* Использование нескольких серверов с GPU для балансировки нагрузки&lt;br /&gt;
* Использование нескольких экземпляров робота (движков)&lt;br /&gt;
&lt;br /&gt;
На текущий момент наиболее удобным вариантом масштабирования является второй. Наиболее нагруженные сервисы vLLM и LightTTS можно выносить на отдельные сервера. При этом, например, для LightTTS не требуется большой объем VRAM, и он может качественно работать на сравнительно недорогих потребительских ускорителях (4090, 5080). &lt;br /&gt;
&lt;br /&gt;
Отдельно стоит упомянуть вынесение на отдельный сервер ASR. Данный компонент работает в потоковом режиме по протоколу gRPC, и не рекомендуется вынесение его на другие площадки с высокой задержкой. Остальные компоненты (за исключением VAD, который работает на CPU в составе главного сервиса secondchain), не чувствительны к дополнительным задержкам (в рамках разумного, до 50-70мс).&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
Установка самого Docker:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установка Nvidia Container Toolkit (только для серверов с GPU):&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# репозиторий&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \&lt;br /&gt;
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \&lt;br /&gt;
  sed &#039;s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g&#039; | \&lt;br /&gt;
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-container-toolkit&lt;br /&gt;
sudo nvidia-ctk runtime configure --runtime=docker&lt;br /&gt;
sudo systemctl restart docker&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (опционально) =&lt;br /&gt;
&lt;br /&gt;
Инструкция написана для Unbuntu 24.04.&lt;br /&gt;
&lt;br /&gt;
При написании данной инструкции использовался сервер с RTX PRO 5000 48gb.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Компиляция моделей может занимать больше VRAM, чем запущенный сервис, поэтому в случае дефицита видеопамяти, рекомендуется временно отключать свеже созданные контейнеры, собирать их по одному, после чего запускать по очереди уже в собранном виде.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton Inference Server) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
I0706 22:41:02.484518 1 grpc_server.cc:2562] &amp;quot;Started GRPCInferenceService at 0.0.0.0:8001&amp;quot;&lt;br /&gt;
I0706 22:41:02.484664 1 http_server.cc:4832] &amp;quot;Started HTTPService at 0.0.0.0:8000&amp;quot;&lt;br /&gt;
I0706 22:41:02.525792 1 http_server.cc:358] &amp;quot;Started Metrics Service at 0.0.0.0:8002&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
Установка выполняется из Docker Hub, следующей командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
* &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; — директория хост-машины, где будет храниться кеш весов модели (24gb)&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
После запуска vllm скачает веса модели для запуска (24gb). После завершения запуска и загрузки весов в логах можно наблюдать следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
(APIServer pid=1) INFO:     Started server process [1]&lt;br /&gt;
(APIServer pid=1) INFO:     Waiting for application startup.&lt;br /&gt;
(APIServer pid=1) INFO:     Application startup complete.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Как только они появятся, можно переходить к следующему шагу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080.&#039;&#039;&#039; Первый запрос к модели будет занимать достаточно много времени:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}],&lt;br /&gt;
    &amp;quot;chat_template_kwargs&amp;quot;: {&amp;quot;enable_thinking&amp;quot;: false}&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load -i lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights \&lt;br /&gt;
  python -m light_tts.server.api_server \&lt;br /&gt;
    --model_dir /opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
    --data_type float16 \&lt;br /&gt;
    --load_trt True \&lt;br /&gt;
    --host 0.0.0.0&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;После запуска сервис скомпилирует веса, по аналогии с T-One. После завершения подготовки в логах будут следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:391] ✅ Startup health check passed!&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:395] ✅ Application ready! Server is now accepting requests&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:396] 🌐 Listening at: http://localhost:8080&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — 10 &#039;&#039;&#039;GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 17000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 17001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Контейнеры сервисов инференса голосового робота.png|центр|безрамки|1067x1067пкс]]&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
&lt;br /&gt;
Необходимо переименовать файл example.env в .env и изменить в нём следующие параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&lt;br /&gt;
POSTGRES_HOST=[хост postgresql]&lt;br /&gt;
POSTGRES_PORT=5432&lt;br /&gt;
POSTGRES_USER=[логин postgresql]&lt;br /&gt;
POSTGRES_PASSWORD=[пароль postgresql]&lt;br /&gt;
POSTGRES_DB=[имя БД, если укзаанная БД отсутствует - она будет автоматически создана]&lt;br /&gt;
&lt;br /&gt;
CONCURRENT_SESSIONS=[Жесткое ограничение количества одновременных сессий]&lt;br /&gt;
&lt;br /&gt;
SIP_SERVER=[адрес Эры]&lt;br /&gt;
SIP_PORT=[порт SIP]&lt;br /&gt;
SIP_USERNAME=[Имя учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_PASSWORD=[Пароль учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_DOMAIN=[Полное имя домена, например robot.era-platform.ru]&lt;br /&gt;
#Детальные настройки SIP-клиента. В случае необходимости обхода NAT&lt;br /&gt;
SIP_TRANSPORT=udp&lt;br /&gt;
# NAT Traversal&lt;br /&gt;
SIP_STUN_SERVER=stun.l.google.com:19302&lt;br /&gt;
SIP_USE_ICE=false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
LLM_MODE=openai_api&lt;br /&gt;
#В случае использования сервиса инфереса vLLM на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LLM_OPENAI_API_BASE=http://localhost:16080/v1 &lt;br /&gt;
LLM_OPENAI_MODEL=qwen35-35b-a3b&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ASR_MODE=triton&lt;br /&gt;
#В случае использования сервиса инфереса tone-triton на другом хосте, необходимо изменить адреса/порты&lt;br /&gt;
ASR_TRITON_URL=http://localhost:17000&lt;br /&gt;
ASR_TRITON_GRPC=localhost:17001&lt;br /&gt;
ASR_TRITON_MODEL=streaming_acoustic&lt;br /&gt;
ASR_TRITON_TIMEOUT=10&lt;br /&gt;
ASR_DECODER_TYPE=beam_search&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
TTS_PROVIDER=lighttts&lt;br /&gt;
#В случае использования сервиса инфереса LightTTS на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LIGHTTTS_URL=http://localhost:8080/&lt;br /&gt;
LIGHTTTS_SAMPLE_RATE=24000&lt;br /&gt;
LIGHTTTS_STREAMING=false&lt;br /&gt;
LIGHTTTS_CONCURRENCY=4&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Плейсхолдер под подробное описание .env --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Запуск контейнера и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
docker load -i secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2442</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2442"/>
		<updated>2026-07-07T11:31:42Z</updated>

		<summary type="html">&lt;p&gt;AZykov: /* Приблизительный расчет требуемых мощностей */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Общая информация =&lt;br /&gt;
[[Файл:Архитектура голосового робота.png|центр|безрамки|763x763пкс]]&lt;br /&gt;
Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 1. Подготовка|Подготовка]]&#039;&#039;&#039; — Docker, PostgreSQL, настройки в системе телефонии.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 2. Установка сервисов инференса (опционально)|Установка сервисов инференса]]&#039;&#039;&#039; — ASR, LLM, TTS. &#039;&#039;Опционально, только для развёртывания на собственном сервере с GPU.&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 3. Настройка .env|Настройка .env]]&#039;&#039;&#039; — параметры подключения.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 4. Запуск контейнера и создание робота|Запуск контейнера и создание робота]]&#039;&#039;&#039; — старт сервиса и конфигурация робота.&lt;br /&gt;
&lt;br /&gt;
= Глоссарий =&lt;br /&gt;
&#039;&#039;&#039;Модель&#039;&#039;&#039; — обученная нейросеть, задающая соответствие между входом и выходом (текст -&amp;gt; текст, звук -&amp;gt; текст и т.д.). Модель определяется архитектурой и набором весов, полученных при обучении. В стеке робота их четыре:VAD (детекция голосовой активности), ASR (распознавание речи), LLM (генерация ответа), TTS (синтез речи).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Веса&#039;&#039;&#039; — числовые параметры модели, полученные при обучении. Именно они хранятся в файлах модели и загружаются в VRAM при старте. «Загрузка весов» в логах vLLM — это чтение этих файлов с диска в память GPU.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Инференс&#039;&#039;&#039; — использование готовой модели для получения ответа на новый вход («прогон» данных через веса). В отличие от обучения, веса не меняются. Сервисы инференса в статье — Triton, vLLM, LightTTS.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;LLM&#039;&#039;&#039; — Большая языковая модель. Класс моделей text-to-text, обученных на больших объемах мультиязычных и мультидоменных данных.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Triton&#039;&#039;&#039; (NVIDIA Triton Inference Server) — сервер инференса от NVIDIA, обслуживающий модели по gRPC и HTTP. В стеке на нём крутится ASR-модель T-one.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TensorRT&#039;&#039;&#039; — библиотека NVIDIA для оптимизации моделей под конкретный GPU: она компилирует модель в специализированный «движок» ради ускорения инференса. Сборка такого движка — разовая операция под железо, поэтому в LightTTS и T-One Triton она выполняется на первой фазе и коммитится в образ.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;vLLM&#039;&#039;&#039; — движок инференса для больших языковых моделей (LLM), оптимизированный на пропускную способность и эффективную работу с памятью. Предоставляет OpenAI-совместимый API.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;nvidia-smi&#039;&#039;&#039; (NVIDIA System Management Interface) — консольная утилита для просмотра состояния GPU: модель карты, версия драйвера, загрузка, потребление VRAM, запущенные процессы. Используется для проверки, что драйвер установлен и GPU виден (в т.ч. изнутри контейнера).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;KV-Cache&#039;&#039;&#039; (кэш ключей и значений) — память, где LLM хранит промежуточные представления уже обработанных токенов, чтобы не пересчитывать их при генерации каждого нового токена. Ускоряет генерацию ценой VRAM. В конфиге ограничен параметром &amp;lt;code&amp;gt;--kv-cache-memory&amp;lt;/code&amp;gt; (3 GiB). Растёт с числом сессий и длиной контекста — поэтому его размер критичен на картах с малым запасом VRAM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;LightTTS&#039;&#039;&#039; — движок инференса для TTS-моделей (синтеза речи). В стеке запускает модель CosyVoice3, слушает порт 8080.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Промпт&#039;&#039;&#039; — Инструкция, которой следует большая языковая модель.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Токен&#039;&#039;&#039; —В &#039;&#039;контексте LLM&#039;&#039; — единица текста, которой оперирует модель (примерно часть слова / слово / знак). Именно в токенах измеряются окно контекста и объём генерации.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Окно контекста&#039;&#039;&#039; — максимальное количество токенов, которое LLM может учитывать за один запрос (вход + генерируемый ответ вместе). Чем больше окно, тем больше VRAM уходит под KV-Cache, поэтому на картах с ограниченным объёмом его сокращают.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Compute&#039;&#039;&#039; — Вычислительные ресурсы GPU. Абстрактный ресурс видеоускорителя, аналог CPU Time при обычных расчетах. Измеряется в GFLOP/TFLOP (операциях в секунду)&lt;br /&gt;
&lt;br /&gt;
= Требования к оборудованию, нагрузка и мастштабирование =&lt;br /&gt;
&lt;br /&gt;
=== Микросервисы робота и их нагрузка ===&lt;br /&gt;
Робот функционирует на базе 4 микросервисов, каждый из которых может быть вынесен на отдельный сервер, или исполняться на общем сервере. &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Микросервисы робота&lt;br /&gt;
!Название&lt;br /&gt;
!Назначение&lt;br /&gt;
!Ключевые ресурсы&lt;br /&gt;
!Минимальное потребление VRAM&lt;br /&gt;
!Дополнительное потребление VRAM из расчета на 1 сессию&lt;br /&gt;
!Условное потребление Compute на 1 сессию&lt;br /&gt;
|-&lt;br /&gt;
|secondchain&lt;br /&gt;
|Инференс модели VAD (CPU), логика робота, голосовой pipeline, работа с сессиями, SIP-клиент&lt;br /&gt;
|CPU, RAM&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
|vLLM (qwen3.5-35b-a3b-INT4)&lt;br /&gt;
Данные указаны с окном контекста 8192 токена.&lt;br /&gt;
|Инференс больших языковых моделей (LLM)&lt;br /&gt;
|VRAM, Compute&lt;br /&gt;
|22gb&lt;br /&gt;
|0.3gb&lt;br /&gt;
|~3 GFLOP/токен&lt;br /&gt;
|-&lt;br /&gt;
|T-one (Triton Inference Server)&lt;br /&gt;
|Инференс T-One speech-to-text&lt;br /&gt;
|Compute&lt;br /&gt;
|600mb&lt;br /&gt;
|10mb&lt;br /&gt;
|~1-3 GFLOP/секунда речи&lt;br /&gt;
|-&lt;br /&gt;
|LightTTS&lt;br /&gt;
|Инференс CosyVoice3 TTS&lt;br /&gt;
|Compute, VRAM&lt;br /&gt;
|8gb&lt;br /&gt;
|0.3gb&lt;br /&gt;
|~120GFLOP/секунда генерируемоей речи&lt;br /&gt;
|}&lt;br /&gt;
При высокой конкуренции за Compute, увеличиваются задержки на каждом из этапов инференса. Самым чувствительным компонентом, при этом, является LightTTS - из-за архитектурных особенностей. TTS требует много вычислительных ресурсов, и большое количество параллельных генераций могут значительно увеличивать задержку. В случае использования нескольких серверов рекомендуется первично выносить на отдельный сервер либо LightTTS, либо vLLM (для высвобождения Compute).&lt;br /&gt;
&lt;br /&gt;
Архитектурно при этом, робот устроен таким образом, чтобы минимизировать инференс LightTTS при возможности (агрессивное кеширование результатов TTS). &lt;br /&gt;
&lt;br /&gt;
=== Нюансы подбора GPU ===&lt;br /&gt;
При подборе GPU под данный стек объём VRAM не является определяющим критерием. Веса любой из трёх моделей помещаются в память практически любой современной карты (уровня 5090 или выше), тогда как реальными ограничивающими факторами выступают пропускная способность памяти на этапе декодирования LLM и вычислительная нагрузка DiT-декодера в TTS. Соответственно, при выборе оборудования следует ориентироваться в первую очередь на memory bandwidth и на аппаратную поддержку современных типов данных, а не на номинальный объём видеопамяти.&lt;br /&gt;
&lt;br /&gt;
Отдельного внимания заслуживает интерфейс межкарточного взаимодействия. Потребительские карты рассчитаны преимущественно на одиночную эксплуатацию: в актуальных линейках Blackwell и Ada поддержка NVLink отсутствует, и обмен между несколькими GPU на одном сервере осуществляется исключительно через PCIe (Gen4/Gen5). При использовании tensor parallelism это создаёт заметные накладные расходы на межкарточную коммуникацию, что становится ощутимым при высокой конкурентной нагрузке. Дата-центровые решения (H100, H200, а также RTX PRO 6000 в соответствующем сегменте) либо предоставляют NVLink с пропускной способностью в сотни ГБ/с, либо обладают достаточным объёмом памяти для размещения моделей на одной карте, что позволяет полностью исключить tensor parallelism и связанные с ним издержки.&lt;br /&gt;
&lt;br /&gt;
Следует также учитывать высокие темпы развития архитектур GPU. Производительная карта шестилетней давности может уступать современному решению среднего уровня как по вычислительной мощности, так и — что существенно в данном случае — по набору поддерживаемых типов данных. Например, NVIDIA V100 (Volta, 2017), несмотря на наличие NVLink и памяти HBM, не поддерживает аппаратное ускорение FP8 и Int4 на тензорных ядрах. Между тем рассматриваемый стек существенно опирается на эти форматы: Qwen в квантизации GPTQ-Int4 с fp8 KV-cache, T-one в TensorRT, TTS с int8-квантизацией. На оборудовании предыдущих поколений соответствующие операции либо неработоспособны в требуемых форматах, либо выполняются с существенным замедлением за счёт программной эмуляции.&lt;br /&gt;
&lt;br /&gt;
С практической точки зрения приоритеты при выборе оборудования под данный пайплайн выстраиваются следующим образом: в первую очередь — поколение архитектуры (Ada, Ampere, Hopper, Blackwell — ввиду поддержки FP8 и Int4 на тензорных ядрах), далее — пропускная способность памяти, и лишь затем — объём VRAM, поскольку последний в рамках данной задачи практически всегда достаточен.&lt;br /&gt;
&lt;br /&gt;
Робот тестировался преимущественно на картах поколения Blackwell:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;RTX5090&#039;&#039;&#039; (использовалась другая LLM меньшего размера)&lt;br /&gt;
* &#039;&#039;&#039;RTX PRO 5000&#039;&#039;&#039; 48gb&lt;br /&gt;
* &#039;&#039;&#039;RTX PRO 6000&#039;&#039;&#039; 96gb&lt;br /&gt;
&lt;br /&gt;
Однако проводились также тесты на картах архитектуры &#039;&#039;&#039;Ampere&#039;&#039;&#039;. Результат можно считать удовлетворительным, особенно для организации тестовых и демо-сред без постоянной большой нагрузки.&lt;br /&gt;
&lt;br /&gt;
Отдельно хочется сказать про ускорители других производителей (AMD, Intel):&lt;br /&gt;
&lt;br /&gt;
К большому сожалению, большая часть инфраструктурного софта оптимизируется в первую очередь под ускорители NVIDIA. В связи с этим даже более производительные карты AMD &amp;quot;на бумаге&amp;quot;, по факту показывают значительно меньшие скорости при реальных задачах. Некоторые же библиотеки и компоненты (TensorRT, Triton Inference Server и т.д.) вообще являются проприетарными разработками NVIDIA и не поддерживают работу с ускорителями других производителей.&lt;br /&gt;
&lt;br /&gt;
=== Анизотропность нагрузки ===&lt;br /&gt;
Из-за логики работы голосового робота, нагрузка на его компоненты в рамках одной сессии достаточно неравномерна. Большинство моделей включаются последовательно после завершения инференса модели на предыдущем шаге:&lt;br /&gt;
&lt;br /&gt;
* VAD (детектирование голосовой активности) - работает всегда (но не вносит существенной нагрузки)&lt;br /&gt;
* ASR (распознавание речи) - запускается при срабатывании триггера VAD (окончание реплики)&lt;br /&gt;
* LLM - запускается после завершения работы ASR&lt;br /&gt;
* TTS - запускается во время / после завершения работы ASR (LLM возвращает текст в потоковом режиме. Текст разбивается на предложения и передается TTS в реальном времени)&lt;br /&gt;
&lt;br /&gt;
Кроме того, архитектурные особенности робота позволяют избегать шага вызова TTS для всех реплик, которые уже были сгенерированы ранее и помещены в кеш. Получается, что если инструкция робота задана таким образом, чтобы его реплики были &amp;quot;статичны&amp;quot; от сессии к сессии, получается экономить значительное количество ресурсов, переиспользуя уже существующие генерации.&lt;br /&gt;
&lt;br /&gt;
Свои оптимизации есть и на стороне инференса LLM:&lt;br /&gt;
&lt;br /&gt;
В команду запуска vLLM по-умолчанию включен режим prefix caching. Данный механизм позволяет кешировать системный промпт и переиспользовать ранее произведенные вычисления для новых запросов. Включение prefix caching позволяет экономить compute для однотипных запросов, а также уменьшить скорость отклика.&lt;br /&gt;
&lt;br /&gt;
Поскольку в рамках голосового робота все запросы (к конкретной конфигурации) используют один системный промпт, это позволяет серьезно экономить.&lt;br /&gt;
&lt;br /&gt;
Данный механизм теряет свою эффективность, к одной LLM будет обращаться большое число роботов с существенно отличающимися системными промптами (50+, точное количество зависит от доступного объема VRAM и настроек vLLM). Также механизм будет мешать, если LLM используется для каких-либо других задач, кроме работы голосового робота.&lt;br /&gt;
&lt;br /&gt;
=== Приблизительный расчет требуемых мощностей ===&lt;br /&gt;
Минимальной конфигурацией является следующая:&lt;br /&gt;
&lt;br /&gt;
CPU 8x&lt;br /&gt;
&lt;br /&gt;
RAM 64gb DDR5&lt;br /&gt;
&lt;br /&gt;
300gb SSD &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Сравнение ускорителей&lt;br /&gt;
!Ускоритель&lt;br /&gt;
!Архитектура&lt;br /&gt;
!VRAM&lt;br /&gt;
!Bandwith&lt;br /&gt;
!Compute (INT8)&lt;br /&gt;
!Приблизительное количество параллельных сессий&lt;br /&gt;
|-&lt;br /&gt;
|RTX PRO 5000&lt;br /&gt;
|Blackwell&lt;br /&gt;
|48gb&lt;br /&gt;
|1.34TB/s&lt;br /&gt;
|516 TOPS&lt;br /&gt;
|40-50&lt;br /&gt;
|-&lt;br /&gt;
|RTX PRO 6000&lt;br /&gt;
|Blackwell&lt;br /&gt;
|96gb&lt;br /&gt;
|1.79TB/s&lt;br /&gt;
|1000 TOPS&lt;br /&gt;
|50-70&lt;br /&gt;
|-&lt;br /&gt;
|RTX 4090/48&lt;br /&gt;
|Ada&lt;br /&gt;
|48gb&lt;br /&gt;
|1TB/s&lt;br /&gt;
|660 TOPS&lt;br /&gt;
|25-30&lt;br /&gt;
|-&lt;br /&gt;
|2x RTX 5090&lt;br /&gt;
|Blackwell&lt;br /&gt;
|2x32gb&lt;br /&gt;
|1.79TB/s&lt;br /&gt;
|828 TOPS&lt;br /&gt;
|30-40&lt;br /&gt;
|-&lt;br /&gt;
|2x RTX 4090/24&lt;br /&gt;
|Ada&lt;br /&gt;
|2x24gb&lt;br /&gt;
|1TB/s&lt;br /&gt;
|660 TOPS&lt;br /&gt;
|10-20&lt;br /&gt;
|-&lt;br /&gt;
|A100/40&lt;br /&gt;
|Ampere&lt;br /&gt;
|40gb&lt;br /&gt;
|1.56TB/s&lt;br /&gt;
|624 TOPS&lt;br /&gt;
|18-23&lt;br /&gt;
|-&lt;br /&gt;
|A100/80&lt;br /&gt;
|Ampere&lt;br /&gt;
|80gb&lt;br /&gt;
|2TB/s&lt;br /&gt;
|624 TOPS&lt;br /&gt;
|55-75&lt;br /&gt;
|-&lt;br /&gt;
|H100&lt;br /&gt;
|Hopper&lt;br /&gt;
|80gb&lt;br /&gt;
|3.35TB/s&lt;br /&gt;
|990 TOPS&lt;br /&gt;
|70-100&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабирование сервиса ===&lt;br /&gt;
При масштабировании голосового робота существует три подхода:&lt;br /&gt;
&lt;br /&gt;
* Использование дополнительных GPU, либо переход на сервер с более производительным GPU&lt;br /&gt;
* Использование нескольких серверов с GPU для балансировки нагрузки&lt;br /&gt;
* Использование нескольких экземпляров робота (движков)&lt;br /&gt;
&lt;br /&gt;
На текущий момент наиболее удобным вариантом масштабирования является второй. Наиболее нагруженные сервисы vLLM и LightTTS можно выносить на отдельные сервера. При этом, например, для LightTTS не требуется большой объем VRAM, и он может качественно работать на сравнительно недорогих потребительских ускорителях (4090, 5080). &lt;br /&gt;
&lt;br /&gt;
Отдельно стоит упомянуть вынесение на отдельный сервер ASR. Данный компонент работает в потоковом режиме по протоколу gRPC, и не рекомендуется вынесение его на другие площадки с высокой задержкой. Остальные компоненты (за исключением VAD, который работает на CPU в составе главного сервиса secondchain), не чувствительны к дополнительным задержкам (в рамках разумного, до 50-70мс).&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
Установка самого Docker:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установка Nvidia Container Toolkit (только для серверов с GPU):&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# репозиторий&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \&lt;br /&gt;
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \&lt;br /&gt;
  sed &#039;s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g&#039; | \&lt;br /&gt;
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-container-toolkit&lt;br /&gt;
sudo nvidia-ctk runtime configure --runtime=docker&lt;br /&gt;
sudo systemctl restart docker&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (опционально) =&lt;br /&gt;
&lt;br /&gt;
Инструкция для &#039;&#039;&#039;Ubuntu Server 24.04&#039;&#039;&#039;. Стек: ASR (T-one/Triton) → LLM (Qwen3.5-35B-A3B на vLLM) → TTS (LightTTS + CosyVoice3).&lt;br /&gt;
&lt;br /&gt;
Целевая машина — сервер с GPU: &#039;&#039;&#039;RTX PRO 5000 (48GB)&#039;&#039;&#039; или &#039;&#039;&#039;RTX PRO 6000 Blackwell (96GB)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
=== Бюджет VRAM ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Компонент !! VRAM&lt;br /&gt;
|-&lt;br /&gt;
| ASR (T-one/Triton) || 600–800 MB&lt;br /&gt;
|-&lt;br /&gt;
| LLM (Qwen3.5-35B-A3B) || 24–48 GB (зависит от числа сессий и длины контекста)&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS/CosyVoice3) || 10 GB&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Суммарное потребление в пике — ~36–60 GB.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 6000 (96GB):&#039;&#039;&#039; объёма достаточно с большим запасом. Допустимо использование максимального числа сессий и длинного контекста.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 5000 (48GB):&#039;&#039;&#039; запас минимальный. Фиксированная сумма ASR (~0.8 GB) и TTS (11 GB) составляет ~12 GB, на LLM остаётся ~36 GB. Это покрывает только нижнюю границу диапазона LLM (24 GB). Требуется ограничение параметров &amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt; во избежание ошибки OOM. Значение &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; (~24 GB на карте 48GB) для данного сценария допустимо при условии, что ASR и TTS инициализированы до старта LLM.&lt;br /&gt;
&lt;br /&gt;
Объем оперативной памяти не может быть меньше, чем VRAM, так как в процессе запуска веса моделей помещаются сначала в оперативную память, и только затем в VRAM.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Компиляция моделей может занимать больше VRAM, чем запущенный сервис, поэтому в случае дефицита видеопамяти, рекомендуется временно отключать свеже созданные контейнеры, собирать их по одному, после чего запускать по очереди уже в собранном виде.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton Inference Server) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
I0706 22:41:02.484518 1 grpc_server.cc:2562] &amp;quot;Started GRPCInferenceService at 0.0.0.0:8001&amp;quot;&lt;br /&gt;
I0706 22:41:02.484664 1 http_server.cc:4832] &amp;quot;Started HTTPService at 0.0.0.0:8000&amp;quot;&lt;br /&gt;
I0706 22:41:02.525792 1 http_server.cc:358] &amp;quot;Started Metrics Service at 0.0.0.0:8002&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
Установка выполняется из Docker Hub, следующей командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
* &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; — директория хост-машины, где будет храниться кеш весов модели (24gb)&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
После запуска vllm скачает веса модели для запуска (24gb). После завершения запуска и загрузки весов в логах можно наблюдать следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
(APIServer pid=1) INFO:     Started server process [1]&lt;br /&gt;
(APIServer pid=1) INFO:     Waiting for application startup.&lt;br /&gt;
(APIServer pid=1) INFO:     Application startup complete.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Как только они появятся, можно переходить к следующему шагу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080.&#039;&#039;&#039; Первый запрос к модели будет занимать достаточно много времени:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}],&lt;br /&gt;
    &amp;quot;chat_template_kwargs&amp;quot;: {&amp;quot;enable_thinking&amp;quot;: false}&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load -i lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights \&lt;br /&gt;
  python -m light_tts.server.api_server \&lt;br /&gt;
    --model_dir /opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
    --data_type float16 \&lt;br /&gt;
    --load_trt True \&lt;br /&gt;
    --host 0.0.0.0&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;После запуска сервис скомпилирует веса, по аналогии с T-One. После завершения подготовки в логах будут следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:391] ✅ Startup health check passed!&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:395] ✅ Application ready! Server is now accepting requests&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:396] 🌐 Listening at: http://localhost:8080&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — 10 &#039;&#039;&#039;GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 17000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 17001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Контейнеры сервисов инференса голосового робота.png|центр|безрамки|1067x1067пкс]]&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
&lt;br /&gt;
Необходимо переименовать файл example.env в .env и изменить в нём следующие параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&lt;br /&gt;
POSTGRES_HOST=[хост postgresql]&lt;br /&gt;
POSTGRES_PORT=5432&lt;br /&gt;
POSTGRES_USER=[логин postgresql]&lt;br /&gt;
POSTGRES_PASSWORD=[пароль postgresql]&lt;br /&gt;
POSTGRES_DB=[имя БД, если укзаанная БД отсутствует - она будет автоматически создана]&lt;br /&gt;
&lt;br /&gt;
CONCURRENT_SESSIONS=[Жесткое ограничение количества одновременных сессий]&lt;br /&gt;
&lt;br /&gt;
SIP_SERVER=[адрес Эры]&lt;br /&gt;
SIP_PORT=[порт SIP]&lt;br /&gt;
SIP_USERNAME=[Имя учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_PASSWORD=[Пароль учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_DOMAIN=[Полное имя домена, например robot.era-platform.ru]&lt;br /&gt;
#Детальные настройки SIP-клиента. В случае необходимости обхода NAT&lt;br /&gt;
SIP_TRANSPORT=udp&lt;br /&gt;
# NAT Traversal&lt;br /&gt;
SIP_STUN_SERVER=stun.l.google.com:19302&lt;br /&gt;
SIP_USE_ICE=false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
LLM_MODE=openai_api&lt;br /&gt;
#В случае использования сервиса инфереса vLLM на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LLM_OPENAI_API_BASE=http://localhost:16080/v1 &lt;br /&gt;
LLM_OPENAI_MODEL=qwen35-35b-a3b&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ASR_MODE=triton&lt;br /&gt;
#В случае использования сервиса инфереса tone-triton на другом хосте, необходимо изменить адреса/порты&lt;br /&gt;
ASR_TRITON_URL=http://localhost:17000&lt;br /&gt;
ASR_TRITON_GRPC=localhost:17001&lt;br /&gt;
ASR_TRITON_MODEL=streaming_acoustic&lt;br /&gt;
ASR_TRITON_TIMEOUT=10&lt;br /&gt;
ASR_DECODER_TYPE=beam_search&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
TTS_PROVIDER=lighttts&lt;br /&gt;
#В случае использования сервиса инфереса LightTTS на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LIGHTTTS_URL=http://localhost:8080/&lt;br /&gt;
LIGHTTTS_SAMPLE_RATE=24000&lt;br /&gt;
LIGHTTTS_STREAMING=false&lt;br /&gt;
LIGHTTTS_CONCURRENCY=4&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Плейсхолдер под подробное описание .env --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Запуск контейнера и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
docker load -i secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2441</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2441"/>
		<updated>2026-07-07T11:10:40Z</updated>

		<summary type="html">&lt;p&gt;AZykov: /* Масштабирование сервиса */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Общая информация =&lt;br /&gt;
[[Файл:Архитектура голосового робота.png|центр|безрамки|763x763пкс]]&lt;br /&gt;
Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 1. Подготовка|Подготовка]]&#039;&#039;&#039; — Docker, PostgreSQL, настройки в системе телефонии.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 2. Установка сервисов инференса (опционально)|Установка сервисов инференса]]&#039;&#039;&#039; — ASR, LLM, TTS. &#039;&#039;Опционально, только для развёртывания на собственном сервере с GPU.&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 3. Настройка .env|Настройка .env]]&#039;&#039;&#039; — параметры подключения.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 4. Запуск контейнера и создание робота|Запуск контейнера и создание робота]]&#039;&#039;&#039; — старт сервиса и конфигурация робота.&lt;br /&gt;
&lt;br /&gt;
= Глоссарий =&lt;br /&gt;
&#039;&#039;&#039;Модель&#039;&#039;&#039; — обученная нейросеть, задающая соответствие между входом и выходом (текст -&amp;gt; текст, звук -&amp;gt; текст и т.д.). Модель определяется архитектурой и набором весов, полученных при обучении. В стеке робота их четыре:VAD (детекция голосовой активности), ASR (распознавание речи), LLM (генерация ответа), TTS (синтез речи).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Веса&#039;&#039;&#039; — числовые параметры модели, полученные при обучении. Именно они хранятся в файлах модели и загружаются в VRAM при старте. «Загрузка весов» в логах vLLM — это чтение этих файлов с диска в память GPU.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Инференс&#039;&#039;&#039; — использование готовой модели для получения ответа на новый вход («прогон» данных через веса). В отличие от обучения, веса не меняются. Сервисы инференса в статье — Triton, vLLM, LightTTS.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;LLM&#039;&#039;&#039; — Большая языковая модель. Класс моделей text-to-text, обученных на больших объемах мультиязычных и мультидоменных данных.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Triton&#039;&#039;&#039; (NVIDIA Triton Inference Server) — сервер инференса от NVIDIA, обслуживающий модели по gRPC и HTTP. В стеке на нём крутится ASR-модель T-one.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TensorRT&#039;&#039;&#039; — библиотека NVIDIA для оптимизации моделей под конкретный GPU: она компилирует модель в специализированный «движок» ради ускорения инференса. Сборка такого движка — разовая операция под железо, поэтому в LightTTS и T-One Triton она выполняется на первой фазе и коммитится в образ.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;vLLM&#039;&#039;&#039; — движок инференса для больших языковых моделей (LLM), оптимизированный на пропускную способность и эффективную работу с памятью. Предоставляет OpenAI-совместимый API.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;nvidia-smi&#039;&#039;&#039; (NVIDIA System Management Interface) — консольная утилита для просмотра состояния GPU: модель карты, версия драйвера, загрузка, потребление VRAM, запущенные процессы. Используется для проверки, что драйвер установлен и GPU виден (в т.ч. изнутри контейнера).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;KV-Cache&#039;&#039;&#039; (кэш ключей и значений) — память, где LLM хранит промежуточные представления уже обработанных токенов, чтобы не пересчитывать их при генерации каждого нового токена. Ускоряет генерацию ценой VRAM. В конфиге ограничен параметром &amp;lt;code&amp;gt;--kv-cache-memory&amp;lt;/code&amp;gt; (3 GiB). Растёт с числом сессий и длиной контекста — поэтому его размер критичен на картах с малым запасом VRAM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;LightTTS&#039;&#039;&#039; — движок инференса для TTS-моделей (синтеза речи). В стеке запускает модель CosyVoice3, слушает порт 8080.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Промпт&#039;&#039;&#039; — Инструкция, которой следует большая языковая модель.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Токен&#039;&#039;&#039; —В &#039;&#039;контексте LLM&#039;&#039; — единица текста, которой оперирует модель (примерно часть слова / слово / знак). Именно в токенах измеряются окно контекста и объём генерации.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Окно контекста&#039;&#039;&#039; — максимальное количество токенов, которое LLM может учитывать за один запрос (вход + генерируемый ответ вместе). Чем больше окно, тем больше VRAM уходит под KV-Cache, поэтому на картах с ограниченным объёмом его сокращают.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Compute&#039;&#039;&#039; — Вычислительные ресурсы GPU. Абстрактный ресурс видеоускорителя, аналог CPU Time при обычных расчетах. Измеряется в GFLOP/TFLOP (операциях в секунду)&lt;br /&gt;
&lt;br /&gt;
= Требования к оборудованию, нагрузка и мастштабирование =&lt;br /&gt;
&lt;br /&gt;
=== Микросервисы робота и их нагрузка ===&lt;br /&gt;
Робот функционирует на базе 4 микросервисов, каждый из которых может быть вынесен на отдельный сервер, или исполняться на общем сервере. &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Микросервисы робота&lt;br /&gt;
!Название&lt;br /&gt;
!Назначение&lt;br /&gt;
!Ключевые ресурсы&lt;br /&gt;
!Минимальное потребление VRAM&lt;br /&gt;
!Дополнительное потребление VRAM из расчета на 1 сессию&lt;br /&gt;
!Условное потребление Compute на 1 сессию&lt;br /&gt;
|-&lt;br /&gt;
|secondchain&lt;br /&gt;
|Инференс модели VAD (CPU), логика робота, голосовой pipeline, работа с сессиями, SIP-клиент&lt;br /&gt;
|CPU, RAM&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
|vLLM (qwen3.5-35b-a3b-INT4)&lt;br /&gt;
Данные указаны с окном контекста 8192 токена.&lt;br /&gt;
|Инференс больших языковых моделей (LLM)&lt;br /&gt;
|VRAM, Compute&lt;br /&gt;
|22gb&lt;br /&gt;
|0.3gb&lt;br /&gt;
|~3 GFLOP/токен&lt;br /&gt;
|-&lt;br /&gt;
|T-one (Triton Inference Server)&lt;br /&gt;
|Инференс T-One speech-to-text&lt;br /&gt;
|Compute&lt;br /&gt;
|600mb&lt;br /&gt;
|10mb&lt;br /&gt;
|~1-3 GFLOP/секунда речи&lt;br /&gt;
|-&lt;br /&gt;
|LightTTS&lt;br /&gt;
|Инференс CosyVoice3 TTS&lt;br /&gt;
|Compute, VRAM&lt;br /&gt;
|8gb&lt;br /&gt;
|0.3gb&lt;br /&gt;
|~120GFLOP/секунда генерируемоей речи&lt;br /&gt;
|}&lt;br /&gt;
При высокой конкуренции за Compute, увеличиваются задержки на каждом из этапов инференса. Самым чувствительным компонентом, при этом, является LightTTS - из-за архитектурных особенностей. TTS требует много вычислительных ресурсов, и большое количество параллельных генераций могут значительно увеличивать задержку. В случае использования нескольких серверов рекомендуется первично выносить на отдельный сервер либо LightTTS, либо vLLM (для высвобождения Compute).&lt;br /&gt;
&lt;br /&gt;
Архитектурно при этом, робот устроен таким образом, чтобы минимизировать инференс LightTTS при возможности (агрессивное кеширование результатов TTS). &lt;br /&gt;
&lt;br /&gt;
=== Нюансы подбора GPU ===&lt;br /&gt;
При подборе GPU под данный стек объём VRAM не является определяющим критерием. Веса любой из трёх моделей помещаются в память практически любой современной карты (уровня 5090 или выше), тогда как реальными ограничивающими факторами выступают пропускная способность памяти на этапе декодирования LLM и вычислительная нагрузка DiT-декодера в TTS. Соответственно, при выборе оборудования следует ориентироваться в первую очередь на memory bandwidth и на аппаратную поддержку современных типов данных, а не на номинальный объём видеопамяти.&lt;br /&gt;
&lt;br /&gt;
Отдельного внимания заслуживает интерфейс межкарточного взаимодействия. Потребительские карты рассчитаны преимущественно на одиночную эксплуатацию: в актуальных линейках Blackwell и Ada поддержка NVLink отсутствует, и обмен между несколькими GPU на одном сервере осуществляется исключительно через PCIe (Gen4/Gen5). При использовании tensor parallelism это создаёт заметные накладные расходы на межкарточную коммуникацию, что становится ощутимым при высокой конкурентной нагрузке. Дата-центровые решения (H100, H200, а также RTX PRO 6000 в соответствующем сегменте) либо предоставляют NVLink с пропускной способностью в сотни ГБ/с, либо обладают достаточным объёмом памяти для размещения моделей на одной карте, что позволяет полностью исключить tensor parallelism и связанные с ним издержки.&lt;br /&gt;
&lt;br /&gt;
Следует также учитывать высокие темпы развития архитектур GPU. Производительная карта шестилетней давности может уступать современному решению среднего уровня как по вычислительной мощности, так и — что существенно в данном случае — по набору поддерживаемых типов данных. Например, NVIDIA V100 (Volta, 2017), несмотря на наличие NVLink и памяти HBM, не поддерживает аппаратное ускорение FP8 и Int4 на тензорных ядрах. Между тем рассматриваемый стек существенно опирается на эти форматы: Qwen в квантизации GPTQ-Int4 с fp8 KV-cache, T-one в TensorRT, TTS с int8-квантизацией. На оборудовании предыдущих поколений соответствующие операции либо неработоспособны в требуемых форматах, либо выполняются с существенным замедлением за счёт программной эмуляции.&lt;br /&gt;
&lt;br /&gt;
С практической точки зрения приоритеты при выборе оборудования под данный пайплайн выстраиваются следующим образом: в первую очередь — поколение архитектуры (Ada, Ampere, Hopper, Blackwell — ввиду поддержки FP8 и Int4 на тензорных ядрах), далее — пропускная способность памяти, и лишь затем — объём VRAM, поскольку последний в рамках данной задачи практически всегда достаточен.&lt;br /&gt;
&lt;br /&gt;
Робот тестировался преимущественно на картах поколения Blackwell:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;RTX5090&#039;&#039;&#039; (использовалась другая LLM меньшего размера)&lt;br /&gt;
* &#039;&#039;&#039;RTX PRO 5000&#039;&#039;&#039; 48gb&lt;br /&gt;
* &#039;&#039;&#039;RTX PRO 6000&#039;&#039;&#039; 96gb&lt;br /&gt;
&lt;br /&gt;
Однако проводились также тесты на картах архитектуры &#039;&#039;&#039;Ampere&#039;&#039;&#039;. Результат можно считать удовлетворительным, особенно для организации тестовых и демо-сред без постоянной большой нагрузки.&lt;br /&gt;
&lt;br /&gt;
Отдельно хочется сказать про ускорители других производителей (AMD, Intel):&lt;br /&gt;
&lt;br /&gt;
К большому сожалению, большая часть инфраструктурного софта оптимизируется в первую очередь под ускорители NVIDIA. В связи с этим даже более производительные карты AMD &amp;quot;на бумаге&amp;quot;, по факту показывают значительно меньшие скорости при реальных задачах. Некоторые же библиотеки и компоненты (TensorRT, Triton Inference Server и т.д.) вообще являются проприетарными разработками NVIDIA и не поддерживают работу с ускорителями других производителей.&lt;br /&gt;
&lt;br /&gt;
=== Анизотропность нагрузки ===&lt;br /&gt;
Из-за логики работы голосового робота, нагрузка на его компоненты в рамках одной сессии достаточно неравномерна. Большинство моделей включаются последовательно после завершения инференса модели на предыдущем шаге:&lt;br /&gt;
&lt;br /&gt;
* VAD (детектирование голосовой активности) - работает всегда (но не вносит существенной нагрузки)&lt;br /&gt;
* ASR (распознавание речи) - запускается при срабатывании триггера VAD (окончание реплики)&lt;br /&gt;
* LLM - запускается после завершения работы ASR&lt;br /&gt;
* TTS - запускается во время / после завершения работы ASR (LLM возвращает текст в потоковом режиме. Текст разбивается на предложения и передается TTS в реальном времени)&lt;br /&gt;
&lt;br /&gt;
Кроме того, архитектурные особенности робота позволяют избегать шага вызова TTS для всех реплик, которые уже были сгенерированы ранее и помещены в кеш. Получается, что если инструкция робота задана таким образом, чтобы его реплики были &amp;quot;статичны&amp;quot; от сессии к сессии, получается экономить значительное количество ресурсов, переиспользуя уже существующие генерации.&lt;br /&gt;
&lt;br /&gt;
Свои оптимизации есть и на стороне инференса LLM:&lt;br /&gt;
&lt;br /&gt;
В команду запуска vLLM по-умолчанию включен режим prefix caching. Данный механизм позволяет кешировать системный промпт и переиспользовать ранее произведенные вычисления для новых запросов. Включение prefix caching позволяет экономить compute для однотипных запросов, а также уменьшить скорость отклика.&lt;br /&gt;
&lt;br /&gt;
Поскольку в рамках голосового робота все запросы (к конкретной конфигурации) используют один системный промпт, это позволяет серьезно экономить.&lt;br /&gt;
&lt;br /&gt;
Данный механизм теряет свою эффективность, к одной LLM будет обращаться большое число роботов с существенно отличающимися системными промптами (50+, точное количество зависит от доступного объема VRAM и настроек vLLM). Также механизм будет мешать, если LLM используется для каких-либо других задач, кроме работы голосового робота.&lt;br /&gt;
&lt;br /&gt;
=== Приблизительный расчет требуемых мощностей ===&lt;br /&gt;
паывпывапыв&lt;br /&gt;
&lt;br /&gt;
=== Масштабирование сервиса ===&lt;br /&gt;
При масштабировании голосового робота существует три подхода:&lt;br /&gt;
&lt;br /&gt;
* Использование дополнительных GPU, либо переход на сервер с более производительным GPU&lt;br /&gt;
* Использование нескольких серверов с GPU для балансировки нагрузки&lt;br /&gt;
* Использование нескольких экземпляров робота (движков)&lt;br /&gt;
&lt;br /&gt;
На текущий момент наиболее удобным вариантом масштабирования является второй. Наиболее нагруженные сервисы vLLM и LightTTS можно выносить на отдельные сервера. При этом, например, для LightTTS не требуется большой объем VRAM, и он может качественно работать на сравнительно недорогих потребительских ускорителях (4090, 5080). &lt;br /&gt;
&lt;br /&gt;
Отдельно стоит упомянуть вынесение на отдельный сервер ASR. Данный компонент работает в потоковом режиме по протоколу gRPC, и не рекомендуется вынесение его на другие площадки с высокой задержкой. Остальные компоненты (за исключением VAD, который работает на CPU в составе главного сервиса secondchain), не чувствительны к дополнительным задержкам (в рамках разумного, до 50-70мс).&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
Установка самого Docker:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установка Nvidia Container Toolkit (только для серверов с GPU):&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# репозиторий&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \&lt;br /&gt;
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \&lt;br /&gt;
  sed &#039;s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g&#039; | \&lt;br /&gt;
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-container-toolkit&lt;br /&gt;
sudo nvidia-ctk runtime configure --runtime=docker&lt;br /&gt;
sudo systemctl restart docker&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (опционально) =&lt;br /&gt;
&lt;br /&gt;
Инструкция для &#039;&#039;&#039;Ubuntu Server 24.04&#039;&#039;&#039;. Стек: ASR (T-one/Triton) → LLM (Qwen3.5-35B-A3B на vLLM) → TTS (LightTTS + CosyVoice3).&lt;br /&gt;
&lt;br /&gt;
Целевая машина — сервер с GPU: &#039;&#039;&#039;RTX PRO 5000 (48GB)&#039;&#039;&#039; или &#039;&#039;&#039;RTX PRO 6000 Blackwell (96GB)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
=== Бюджет VRAM ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Компонент !! VRAM&lt;br /&gt;
|-&lt;br /&gt;
| ASR (T-one/Triton) || 600–800 MB&lt;br /&gt;
|-&lt;br /&gt;
| LLM (Qwen3.5-35B-A3B) || 24–48 GB (зависит от числа сессий и длины контекста)&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS/CosyVoice3) || 10 GB&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Суммарное потребление в пике — ~36–60 GB.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 6000 (96GB):&#039;&#039;&#039; объёма достаточно с большим запасом. Допустимо использование максимального числа сессий и длинного контекста.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 5000 (48GB):&#039;&#039;&#039; запас минимальный. Фиксированная сумма ASR (~0.8 GB) и TTS (11 GB) составляет ~12 GB, на LLM остаётся ~36 GB. Это покрывает только нижнюю границу диапазона LLM (24 GB). Требуется ограничение параметров &amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt; во избежание ошибки OOM. Значение &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; (~24 GB на карте 48GB) для данного сценария допустимо при условии, что ASR и TTS инициализированы до старта LLM.&lt;br /&gt;
&lt;br /&gt;
Объем оперативной памяти не может быть меньше, чем VRAM, так как в процессе запуска веса моделей помещаются сначала в оперативную память, и только затем в VRAM.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Компиляция моделей может занимать больше VRAM, чем запущенный сервис, поэтому в случае дефицита видеопамяти, рекомендуется временно отключать свеже созданные контейнеры, собирать их по одному, после чего запускать по очереди уже в собранном виде.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton Inference Server) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
I0706 22:41:02.484518 1 grpc_server.cc:2562] &amp;quot;Started GRPCInferenceService at 0.0.0.0:8001&amp;quot;&lt;br /&gt;
I0706 22:41:02.484664 1 http_server.cc:4832] &amp;quot;Started HTTPService at 0.0.0.0:8000&amp;quot;&lt;br /&gt;
I0706 22:41:02.525792 1 http_server.cc:358] &amp;quot;Started Metrics Service at 0.0.0.0:8002&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
Установка выполняется из Docker Hub, следующей командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
* &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; — директория хост-машины, где будет храниться кеш весов модели (24gb)&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
После запуска vllm скачает веса модели для запуска (24gb). После завершения запуска и загрузки весов в логах можно наблюдать следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
(APIServer pid=1) INFO:     Started server process [1]&lt;br /&gt;
(APIServer pid=1) INFO:     Waiting for application startup.&lt;br /&gt;
(APIServer pid=1) INFO:     Application startup complete.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Как только они появятся, можно переходить к следующему шагу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080.&#039;&#039;&#039; Первый запрос к модели будет занимать достаточно много времени:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}],&lt;br /&gt;
    &amp;quot;chat_template_kwargs&amp;quot;: {&amp;quot;enable_thinking&amp;quot;: false}&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load -i lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights \&lt;br /&gt;
  python -m light_tts.server.api_server \&lt;br /&gt;
    --model_dir /opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
    --data_type float16 \&lt;br /&gt;
    --load_trt True \&lt;br /&gt;
    --host 0.0.0.0&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;После запуска сервис скомпилирует веса, по аналогии с T-One. После завершения подготовки в логах будут следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:391] ✅ Startup health check passed!&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:395] ✅ Application ready! Server is now accepting requests&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:396] 🌐 Listening at: http://localhost:8080&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — 10 &#039;&#039;&#039;GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 17000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 17001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Контейнеры сервисов инференса голосового робота.png|центр|безрамки|1067x1067пкс]]&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
&lt;br /&gt;
Необходимо переименовать файл example.env в .env и изменить в нём следующие параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&lt;br /&gt;
POSTGRES_HOST=[хост postgresql]&lt;br /&gt;
POSTGRES_PORT=5432&lt;br /&gt;
POSTGRES_USER=[логин postgresql]&lt;br /&gt;
POSTGRES_PASSWORD=[пароль postgresql]&lt;br /&gt;
POSTGRES_DB=[имя БД, если укзаанная БД отсутствует - она будет автоматически создана]&lt;br /&gt;
&lt;br /&gt;
CONCURRENT_SESSIONS=[Жесткое ограничение количества одновременных сессий]&lt;br /&gt;
&lt;br /&gt;
SIP_SERVER=[адрес Эры]&lt;br /&gt;
SIP_PORT=[порт SIP]&lt;br /&gt;
SIP_USERNAME=[Имя учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_PASSWORD=[Пароль учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_DOMAIN=[Полное имя домена, например robot.era-platform.ru]&lt;br /&gt;
#Детальные настройки SIP-клиента. В случае необходимости обхода NAT&lt;br /&gt;
SIP_TRANSPORT=udp&lt;br /&gt;
# NAT Traversal&lt;br /&gt;
SIP_STUN_SERVER=stun.l.google.com:19302&lt;br /&gt;
SIP_USE_ICE=false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
LLM_MODE=openai_api&lt;br /&gt;
#В случае использования сервиса инфереса vLLM на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LLM_OPENAI_API_BASE=http://localhost:16080/v1 &lt;br /&gt;
LLM_OPENAI_MODEL=qwen35-35b-a3b&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ASR_MODE=triton&lt;br /&gt;
#В случае использования сервиса инфереса tone-triton на другом хосте, необходимо изменить адреса/порты&lt;br /&gt;
ASR_TRITON_URL=http://localhost:17000&lt;br /&gt;
ASR_TRITON_GRPC=localhost:17001&lt;br /&gt;
ASR_TRITON_MODEL=streaming_acoustic&lt;br /&gt;
ASR_TRITON_TIMEOUT=10&lt;br /&gt;
ASR_DECODER_TYPE=beam_search&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
TTS_PROVIDER=lighttts&lt;br /&gt;
#В случае использования сервиса инфереса LightTTS на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LIGHTTTS_URL=http://localhost:8080/&lt;br /&gt;
LIGHTTTS_SAMPLE_RATE=24000&lt;br /&gt;
LIGHTTTS_STREAMING=false&lt;br /&gt;
LIGHTTTS_CONCURRENCY=4&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Плейсхолдер под подробное описание .env --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Запуск контейнера и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
docker load -i secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2440</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2440"/>
		<updated>2026-07-07T10:51:58Z</updated>

		<summary type="html">&lt;p&gt;AZykov: /* Нюансы подбора GPU */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Общая информация =&lt;br /&gt;
[[Файл:Архитектура голосового робота.png|центр|безрамки|763x763пкс]]&lt;br /&gt;
Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 1. Подготовка|Подготовка]]&#039;&#039;&#039; — Docker, PostgreSQL, настройки в системе телефонии.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 2. Установка сервисов инференса (опционально)|Установка сервисов инференса]]&#039;&#039;&#039; — ASR, LLM, TTS. &#039;&#039;Опционально, только для развёртывания на собственном сервере с GPU.&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 3. Настройка .env|Настройка .env]]&#039;&#039;&#039; — параметры подключения.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 4. Запуск контейнера и создание робота|Запуск контейнера и создание робота]]&#039;&#039;&#039; — старт сервиса и конфигурация робота.&lt;br /&gt;
&lt;br /&gt;
= Глоссарий =&lt;br /&gt;
&#039;&#039;&#039;Модель&#039;&#039;&#039; — обученная нейросеть, задающая соответствие между входом и выходом (текст -&amp;gt; текст, звук -&amp;gt; текст и т.д.). Модель определяется архитектурой и набором весов, полученных при обучении. В стеке робота их четыре:VAD (детекция голосовой активности), ASR (распознавание речи), LLM (генерация ответа), TTS (синтез речи).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Веса&#039;&#039;&#039; — числовые параметры модели, полученные при обучении. Именно они хранятся в файлах модели и загружаются в VRAM при старте. «Загрузка весов» в логах vLLM — это чтение этих файлов с диска в память GPU.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Инференс&#039;&#039;&#039; — использование готовой модели для получения ответа на новый вход («прогон» данных через веса). В отличие от обучения, веса не меняются. Сервисы инференса в статье — Triton, vLLM, LightTTS.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;LLM&#039;&#039;&#039; — Большая языковая модель. Класс моделей text-to-text, обученных на больших объемах мультиязычных и мультидоменных данных.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Triton&#039;&#039;&#039; (NVIDIA Triton Inference Server) — сервер инференса от NVIDIA, обслуживающий модели по gRPC и HTTP. В стеке на нём крутится ASR-модель T-one.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TensorRT&#039;&#039;&#039; — библиотека NVIDIA для оптимизации моделей под конкретный GPU: она компилирует модель в специализированный «движок» ради ускорения инференса. Сборка такого движка — разовая операция под железо, поэтому в LightTTS и T-One Triton она выполняется на первой фазе и коммитится в образ.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;vLLM&#039;&#039;&#039; — движок инференса для больших языковых моделей (LLM), оптимизированный на пропускную способность и эффективную работу с памятью. Предоставляет OpenAI-совместимый API.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;nvidia-smi&#039;&#039;&#039; (NVIDIA System Management Interface) — консольная утилита для просмотра состояния GPU: модель карты, версия драйвера, загрузка, потребление VRAM, запущенные процессы. Используется для проверки, что драйвер установлен и GPU виден (в т.ч. изнутри контейнера).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;KV-Cache&#039;&#039;&#039; (кэш ключей и значений) — память, где LLM хранит промежуточные представления уже обработанных токенов, чтобы не пересчитывать их при генерации каждого нового токена. Ускоряет генерацию ценой VRAM. В конфиге ограничен параметром &amp;lt;code&amp;gt;--kv-cache-memory&amp;lt;/code&amp;gt; (3 GiB). Растёт с числом сессий и длиной контекста — поэтому его размер критичен на картах с малым запасом VRAM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;LightTTS&#039;&#039;&#039; — движок инференса для TTS-моделей (синтеза речи). В стеке запускает модель CosyVoice3, слушает порт 8080.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Промпт&#039;&#039;&#039; — Инструкция, которой следует большая языковая модель.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Токен&#039;&#039;&#039; —В &#039;&#039;контексте LLM&#039;&#039; — единица текста, которой оперирует модель (примерно часть слова / слово / знак). Именно в токенах измеряются окно контекста и объём генерации.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Окно контекста&#039;&#039;&#039; — максимальное количество токенов, которое LLM может учитывать за один запрос (вход + генерируемый ответ вместе). Чем больше окно, тем больше VRAM уходит под KV-Cache, поэтому на картах с ограниченным объёмом его сокращают.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Compute&#039;&#039;&#039; — Вычислительные ресурсы GPU. Абстрактный ресурс видеоускорителя, аналог CPU Time при обычных расчетах. Измеряется в GFLOP/TFLOP (операциях в секунду)&lt;br /&gt;
&lt;br /&gt;
= Требования к оборудованию, нагрузка и мастштабирование =&lt;br /&gt;
&lt;br /&gt;
=== Микросервисы робота и их нагрузка ===&lt;br /&gt;
Робот функционирует на базе 4 микросервисов, каждый из которых может быть вынесен на отдельный сервер, или исполняться на общем сервере. &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Микросервисы робота&lt;br /&gt;
!Название&lt;br /&gt;
!Назначение&lt;br /&gt;
!Ключевые ресурсы&lt;br /&gt;
!Минимальное потребление VRAM&lt;br /&gt;
!Дополнительное потребление VRAM из расчета на 1 сессию&lt;br /&gt;
!Условное потребление Compute на 1 сессию&lt;br /&gt;
|-&lt;br /&gt;
|secondchain&lt;br /&gt;
|Инференс модели VAD (CPU), логика робота, голосовой pipeline, работа с сессиями, SIP-клиент&lt;br /&gt;
|CPU, RAM&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
|vLLM (qwen3.5-35b-a3b-INT4)&lt;br /&gt;
Данные указаны с окном контекста 8192 токена.&lt;br /&gt;
|Инференс больших языковых моделей (LLM)&lt;br /&gt;
|VRAM, Compute&lt;br /&gt;
|22gb&lt;br /&gt;
|0.3gb&lt;br /&gt;
|~3 GFLOP/токен&lt;br /&gt;
|-&lt;br /&gt;
|T-one (Triton Inference Server)&lt;br /&gt;
|Инференс T-One speech-to-text&lt;br /&gt;
|Compute&lt;br /&gt;
|600mb&lt;br /&gt;
|10mb&lt;br /&gt;
|~1-3 GFLOP/секунда речи&lt;br /&gt;
|-&lt;br /&gt;
|LightTTS&lt;br /&gt;
|Инференс CosyVoice3 TTS&lt;br /&gt;
|Compute, VRAM&lt;br /&gt;
|8gb&lt;br /&gt;
|0.3gb&lt;br /&gt;
|~120GFLOP/секунда генерируемоей речи&lt;br /&gt;
|}&lt;br /&gt;
При высокой конкуренции за Compute, увеличиваются задержки на каждом из этапов инференса. Самым чувствительным компонентом, при этом, является LightTTS - из-за архитектурных особенностей. TTS требует много вычислительных ресурсов, и большое количество параллельных генераций могут значительно увеличивать задержку. В случае использования нескольких серверов рекомендуется первично выносить на отдельный сервер либо LightTTS, либо vLLM (для высвобождения Compute).&lt;br /&gt;
&lt;br /&gt;
Архитектурно при этом, робот устроен таким образом, чтобы минимизировать инференс LightTTS при возможности (агрессивное кеширование результатов TTS). &lt;br /&gt;
&lt;br /&gt;
=== Нюансы подбора GPU ===&lt;br /&gt;
При подборе GPU под данный стек объём VRAM не является определяющим критерием. Веса любой из трёх моделей помещаются в память практически любой современной карты (уровня 5090 или выше), тогда как реальными ограничивающими факторами выступают пропускная способность памяти на этапе декодирования LLM и вычислительная нагрузка DiT-декодера в TTS. Соответственно, при выборе оборудования следует ориентироваться в первую очередь на memory bandwidth и на аппаратную поддержку современных типов данных, а не на номинальный объём видеопамяти.&lt;br /&gt;
&lt;br /&gt;
Отдельного внимания заслуживает интерфейс межкарточного взаимодействия. Потребительские карты рассчитаны преимущественно на одиночную эксплуатацию: в актуальных линейках Blackwell и Ada поддержка NVLink отсутствует, и обмен между несколькими GPU на одном сервере осуществляется исключительно через PCIe (Gen4/Gen5). При использовании tensor parallelism это создаёт заметные накладные расходы на межкарточную коммуникацию, что становится ощутимым при высокой конкурентной нагрузке. Дата-центровые решения (H100, H200, а также RTX PRO 6000 в соответствующем сегменте) либо предоставляют NVLink с пропускной способностью в сотни ГБ/с, либо обладают достаточным объёмом памяти для размещения моделей на одной карте, что позволяет полностью исключить tensor parallelism и связанные с ним издержки.&lt;br /&gt;
&lt;br /&gt;
Следует также учитывать высокие темпы развития архитектур GPU. Производительная карта шестилетней давности может уступать современному решению среднего уровня как по вычислительной мощности, так и — что существенно в данном случае — по набору поддерживаемых типов данных. Например, NVIDIA V100 (Volta, 2017), несмотря на наличие NVLink и памяти HBM, не поддерживает аппаратное ускорение FP8 и Int4 на тензорных ядрах. Между тем рассматриваемый стек существенно опирается на эти форматы: Qwen в квантизации GPTQ-Int4 с fp8 KV-cache, T-one в TensorRT, TTS с int8-квантизацией. На оборудовании предыдущих поколений соответствующие операции либо неработоспособны в требуемых форматах, либо выполняются с существенным замедлением за счёт программной эмуляции.&lt;br /&gt;
&lt;br /&gt;
С практической точки зрения приоритеты при выборе оборудования под данный пайплайн выстраиваются следующим образом: в первую очередь — поколение архитектуры (Ada, Ampere, Hopper, Blackwell — ввиду поддержки FP8 и Int4 на тензорных ядрах), далее — пропускная способность памяти, и лишь затем — объём VRAM, поскольку последний в рамках данной задачи практически всегда достаточен.&lt;br /&gt;
&lt;br /&gt;
Робот тестировался преимущественно на картах поколения Blackwell:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;RTX5090&#039;&#039;&#039; (использовалась другая LLM меньшего размера)&lt;br /&gt;
* &#039;&#039;&#039;RTX PRO 5000&#039;&#039;&#039; 48gb&lt;br /&gt;
* &#039;&#039;&#039;RTX PRO 6000&#039;&#039;&#039; 96gb&lt;br /&gt;
&lt;br /&gt;
Однако проводились также тесты на картах архитектуры &#039;&#039;&#039;Ampere&#039;&#039;&#039;. Результат можно считать удовлетворительным, особенно для организации тестовых и демо-сред без постоянной большой нагрузки.&lt;br /&gt;
&lt;br /&gt;
Отдельно хочется сказать про ускорители других производителей (AMD, Intel):&lt;br /&gt;
&lt;br /&gt;
К большому сожалению, большая часть инфраструктурного софта оптимизируется в первую очередь под ускорители NVIDIA. В связи с этим даже более производительные карты AMD &amp;quot;на бумаге&amp;quot;, по факту показывают значительно меньшие скорости при реальных задачах. Некоторые же библиотеки и компоненты (TensorRT, Triton Inference Server и т.д.) вообще являются проприетарными разработками NVIDIA и не поддерживают работу с ускорителями других производителей.&lt;br /&gt;
&lt;br /&gt;
=== Анизотропность нагрузки ===&lt;br /&gt;
Из-за логики работы голосового робота, нагрузка на его компоненты в рамках одной сессии достаточно неравномерна. Большинство моделей включаются последовательно после завершения инференса модели на предыдущем шаге:&lt;br /&gt;
&lt;br /&gt;
* VAD (детектирование голосовой активности) - работает всегда (но не вносит существенной нагрузки)&lt;br /&gt;
* ASR (распознавание речи) - запускается при срабатывании триггера VAD (окончание реплики)&lt;br /&gt;
* LLM - запускается после завершения работы ASR&lt;br /&gt;
* TTS - запускается во время / после завершения работы ASR (LLM возвращает текст в потоковом режиме. Текст разбивается на предложения и передается TTS в реальном времени)&lt;br /&gt;
&lt;br /&gt;
Кроме того, архитектурные особенности робота позволяют избегать шага вызова TTS для всех реплик, которые уже были сгенерированы ранее и помещены в кеш. Получается, что если инструкция робота задана таким образом, чтобы его реплики были &amp;quot;статичны&amp;quot; от сессии к сессии, получается экономить значительное количество ресурсов, переиспользуя уже существующие генерации.&lt;br /&gt;
&lt;br /&gt;
Свои оптимизации есть и на стороне инференса LLM:&lt;br /&gt;
&lt;br /&gt;
В команду запуска vLLM по-умолчанию включен режим prefix caching. Данный механизм позволяет кешировать системный промпт и переиспользовать ранее произведенные вычисления для новых запросов. Включение prefix caching позволяет экономить compute для однотипных запросов, а также уменьшить скорость отклика.&lt;br /&gt;
&lt;br /&gt;
Поскольку в рамках голосового робота все запросы (к конкретной конфигурации) используют один системный промпт, это позволяет серьезно экономить.&lt;br /&gt;
&lt;br /&gt;
Данный механизм теряет свою эффективность, к одной LLM будет обращаться большое число роботов с существенно отличающимися системными промптами (50+, точное количество зависит от доступного объема VRAM и настроек vLLM). Также механизм будет мешать, если LLM используется для каких-либо других задач, кроме работы голосового робота.&lt;br /&gt;
&lt;br /&gt;
=== Приблизительный расчет требуемых мощностей ===&lt;br /&gt;
паывпывапыв&lt;br /&gt;
&lt;br /&gt;
=== Масштабирование сервиса ===&lt;br /&gt;
При масштабировании голосового робота существует три подхода:&lt;br /&gt;
&lt;br /&gt;
* Использование дополнительных GPU, либо переход на сервер с более производительным GPU&lt;br /&gt;
* Использование нескольких серверов с GPU для балансировки нагрузки&lt;br /&gt;
* Использование нескольких экземпляров робота (движков)&lt;br /&gt;
&lt;br /&gt;
На текущий момент наиболее удобным вариантом масштабирования является второй. Наиболее нагруженные сервисы&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
Установка самого Docker:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установка Nvidia Container Toolkit (только для серверов с GPU):&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# репозиторий&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \&lt;br /&gt;
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \&lt;br /&gt;
  sed &#039;s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g&#039; | \&lt;br /&gt;
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-container-toolkit&lt;br /&gt;
sudo nvidia-ctk runtime configure --runtime=docker&lt;br /&gt;
sudo systemctl restart docker&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (опционально) =&lt;br /&gt;
&lt;br /&gt;
Инструкция для &#039;&#039;&#039;Ubuntu Server 24.04&#039;&#039;&#039;. Стек: ASR (T-one/Triton) → LLM (Qwen3.5-35B-A3B на vLLM) → TTS (LightTTS + CosyVoice3).&lt;br /&gt;
&lt;br /&gt;
Целевая машина — сервер с GPU: &#039;&#039;&#039;RTX PRO 5000 (48GB)&#039;&#039;&#039; или &#039;&#039;&#039;RTX PRO 6000 Blackwell (96GB)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
=== Бюджет VRAM ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Компонент !! VRAM&lt;br /&gt;
|-&lt;br /&gt;
| ASR (T-one/Triton) || 600–800 MB&lt;br /&gt;
|-&lt;br /&gt;
| LLM (Qwen3.5-35B-A3B) || 24–48 GB (зависит от числа сессий и длины контекста)&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS/CosyVoice3) || 10 GB&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Суммарное потребление в пике — ~36–60 GB.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 6000 (96GB):&#039;&#039;&#039; объёма достаточно с большим запасом. Допустимо использование максимального числа сессий и длинного контекста.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 5000 (48GB):&#039;&#039;&#039; запас минимальный. Фиксированная сумма ASR (~0.8 GB) и TTS (11 GB) составляет ~12 GB, на LLM остаётся ~36 GB. Это покрывает только нижнюю границу диапазона LLM (24 GB). Требуется ограничение параметров &amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt; во избежание ошибки OOM. Значение &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; (~24 GB на карте 48GB) для данного сценария допустимо при условии, что ASR и TTS инициализированы до старта LLM.&lt;br /&gt;
&lt;br /&gt;
Объем оперативной памяти не может быть меньше, чем VRAM, так как в процессе запуска веса моделей помещаются сначала в оперативную память, и только затем в VRAM.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Компиляция моделей может занимать больше VRAM, чем запущенный сервис, поэтому в случае дефицита видеопамяти, рекомендуется временно отключать свеже созданные контейнеры, собирать их по одному, после чего запускать по очереди уже в собранном виде.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton Inference Server) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
I0706 22:41:02.484518 1 grpc_server.cc:2562] &amp;quot;Started GRPCInferenceService at 0.0.0.0:8001&amp;quot;&lt;br /&gt;
I0706 22:41:02.484664 1 http_server.cc:4832] &amp;quot;Started HTTPService at 0.0.0.0:8000&amp;quot;&lt;br /&gt;
I0706 22:41:02.525792 1 http_server.cc:358] &amp;quot;Started Metrics Service at 0.0.0.0:8002&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
Установка выполняется из Docker Hub, следующей командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
* &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; — директория хост-машины, где будет храниться кеш весов модели (24gb)&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
После запуска vllm скачает веса модели для запуска (24gb). После завершения запуска и загрузки весов в логах можно наблюдать следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
(APIServer pid=1) INFO:     Started server process [1]&lt;br /&gt;
(APIServer pid=1) INFO:     Waiting for application startup.&lt;br /&gt;
(APIServer pid=1) INFO:     Application startup complete.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Как только они появятся, можно переходить к следующему шагу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080.&#039;&#039;&#039; Первый запрос к модели будет занимать достаточно много времени:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}],&lt;br /&gt;
    &amp;quot;chat_template_kwargs&amp;quot;: {&amp;quot;enable_thinking&amp;quot;: false}&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load -i lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights \&lt;br /&gt;
  python -m light_tts.server.api_server \&lt;br /&gt;
    --model_dir /opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
    --data_type float16 \&lt;br /&gt;
    --load_trt True \&lt;br /&gt;
    --host 0.0.0.0&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;После запуска сервис скомпилирует веса, по аналогии с T-One. После завершения подготовки в логах будут следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:391] ✅ Startup health check passed!&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:395] ✅ Application ready! Server is now accepting requests&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:396] 🌐 Listening at: http://localhost:8080&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — 10 &#039;&#039;&#039;GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 17000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 17001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Контейнеры сервисов инференса голосового робота.png|центр|безрамки|1067x1067пкс]]&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
&lt;br /&gt;
Необходимо переименовать файл example.env в .env и изменить в нём следующие параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&lt;br /&gt;
POSTGRES_HOST=[хост postgresql]&lt;br /&gt;
POSTGRES_PORT=5432&lt;br /&gt;
POSTGRES_USER=[логин postgresql]&lt;br /&gt;
POSTGRES_PASSWORD=[пароль postgresql]&lt;br /&gt;
POSTGRES_DB=[имя БД, если укзаанная БД отсутствует - она будет автоматически создана]&lt;br /&gt;
&lt;br /&gt;
CONCURRENT_SESSIONS=[Жесткое ограничение количества одновременных сессий]&lt;br /&gt;
&lt;br /&gt;
SIP_SERVER=[адрес Эры]&lt;br /&gt;
SIP_PORT=[порт SIP]&lt;br /&gt;
SIP_USERNAME=[Имя учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_PASSWORD=[Пароль учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_DOMAIN=[Полное имя домена, например robot.era-platform.ru]&lt;br /&gt;
#Детальные настройки SIP-клиента. В случае необходимости обхода NAT&lt;br /&gt;
SIP_TRANSPORT=udp&lt;br /&gt;
# NAT Traversal&lt;br /&gt;
SIP_STUN_SERVER=stun.l.google.com:19302&lt;br /&gt;
SIP_USE_ICE=false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
LLM_MODE=openai_api&lt;br /&gt;
#В случае использования сервиса инфереса vLLM на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LLM_OPENAI_API_BASE=http://localhost:16080/v1 &lt;br /&gt;
LLM_OPENAI_MODEL=qwen35-35b-a3b&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ASR_MODE=triton&lt;br /&gt;
#В случае использования сервиса инфереса tone-triton на другом хосте, необходимо изменить адреса/порты&lt;br /&gt;
ASR_TRITON_URL=http://localhost:17000&lt;br /&gt;
ASR_TRITON_GRPC=localhost:17001&lt;br /&gt;
ASR_TRITON_MODEL=streaming_acoustic&lt;br /&gt;
ASR_TRITON_TIMEOUT=10&lt;br /&gt;
ASR_DECODER_TYPE=beam_search&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
TTS_PROVIDER=lighttts&lt;br /&gt;
#В случае использования сервиса инфереса LightTTS на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LIGHTTTS_URL=http://localhost:8080/&lt;br /&gt;
LIGHTTTS_SAMPLE_RATE=24000&lt;br /&gt;
LIGHTTTS_STREAMING=false&lt;br /&gt;
LIGHTTTS_CONCURRENCY=4&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Плейсхолдер под подробное описание .env --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Запуск контейнера и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
docker load -i secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2439</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2439"/>
		<updated>2026-07-07T10:32:56Z</updated>

		<summary type="html">&lt;p&gt;AZykov: /* Нюансы подбора GPU */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Общая информация =&lt;br /&gt;
[[Файл:Архитектура голосового робота.png|центр|безрамки|763x763пкс]]&lt;br /&gt;
Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 1. Подготовка|Подготовка]]&#039;&#039;&#039; — Docker, PostgreSQL, настройки в системе телефонии.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 2. Установка сервисов инференса (опционально)|Установка сервисов инференса]]&#039;&#039;&#039; — ASR, LLM, TTS. &#039;&#039;Опционально, только для развёртывания на собственном сервере с GPU.&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 3. Настройка .env|Настройка .env]]&#039;&#039;&#039; — параметры подключения.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 4. Запуск контейнера и создание робота|Запуск контейнера и создание робота]]&#039;&#039;&#039; — старт сервиса и конфигурация робота.&lt;br /&gt;
&lt;br /&gt;
= Глоссарий =&lt;br /&gt;
&#039;&#039;&#039;Модель&#039;&#039;&#039; — обученная нейросеть, задающая соответствие между входом и выходом (текст -&amp;gt; текст, звук -&amp;gt; текст и т.д.). Модель определяется архитектурой и набором весов, полученных при обучении. В стеке робота их четыре:VAD (детекция голосовой активности), ASR (распознавание речи), LLM (генерация ответа), TTS (синтез речи).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Веса&#039;&#039;&#039; — числовые параметры модели, полученные при обучении. Именно они хранятся в файлах модели и загружаются в VRAM при старте. «Загрузка весов» в логах vLLM — это чтение этих файлов с диска в память GPU.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Инференс&#039;&#039;&#039; — использование готовой модели для получения ответа на новый вход («прогон» данных через веса). В отличие от обучения, веса не меняются. Сервисы инференса в статье — Triton, vLLM, LightTTS.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Triton&#039;&#039;&#039; (NVIDIA Triton Inference Server) — сервер инференса от NVIDIA, обслуживающий модели по gRPC и HTTP. В стеке на нём крутится ASR-модель T-one.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TensorRT&#039;&#039;&#039; — библиотека NVIDIA для оптимизации моделей под конкретный GPU: она компилирует модель в специализированный «движок» ради ускорения инференса. Сборка такого движка — разовая операция под железо, поэтому в LightTTS и T-One Triton она выполняется на первой фазе и коммитится в образ.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;vLLM&#039;&#039;&#039; — движок инференса для больших языковых моделей (LLM), оптимизированный на пропускную способность и эффективную работу с памятью. Предоставляет OpenAI-совместимый API.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;nvidia-smi&#039;&#039;&#039; (NVIDIA System Management Interface) — консольная утилита для просмотра состояния GPU: модель карты, версия драйвера, загрузка, потребление VRAM, запущенные процессы. Используется для проверки, что драйвер установлен и GPU виден (в т.ч. изнутри контейнера).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;KV-Cache&#039;&#039;&#039; (кэш ключей и значений) — память, где LLM хранит промежуточные представления уже обработанных токенов, чтобы не пересчитывать их при генерации каждого нового токена. Ускоряет генерацию ценой VRAM. В конфиге ограничен параметром &amp;lt;code&amp;gt;--kv-cache-memory&amp;lt;/code&amp;gt; (3 GiB). Растёт с числом сессий и длиной контекста — поэтому его размер критичен на картах с малым запасом VRAM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;LightTTS&#039;&#039;&#039; — движок инференса для TTS-моделей (синтеза речи). В стеке запускает модель CosyVoice3, слушает порт 8080.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Токен&#039;&#039;&#039; —В &#039;&#039;контексте LLM&#039;&#039; — единица текста, которой оперирует модель (примерно часть слова / слово / знак). Именно в токенах измеряются окно контекста и объём генерации.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Окно контекста&#039;&#039;&#039; — максимальное количество токенов, которое LLM может учитывать за один запрос (вход + генерируемый ответ вместе). Чем больше окно, тем больше VRAM уходит под KV-Cache, поэтому на картах с ограниченным объёмом его сокращают.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Compute&#039;&#039;&#039; — Вычислительные ресурсы GPU. Абстрактный ресурс видеоускорителя, аналог CPU Time при обычных расчетах. Измеряется в GFLOP/TFLOP (операциях в секунду)&lt;br /&gt;
&lt;br /&gt;
= Требования к оборудованию, нагрузка и мастштабирование =&lt;br /&gt;
&lt;br /&gt;
=== Микросервисы робота и их нагрузка ===&lt;br /&gt;
Робот функционирует на базе 4 микросервисов, каждый из которых может быть вынесен на отдельный сервер, или исполняться на общем сервере. &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Микросервисы робота&lt;br /&gt;
!Название&lt;br /&gt;
!Назначение&lt;br /&gt;
!Ключевые ресурсы&lt;br /&gt;
!Минимальное потребление VRAM&lt;br /&gt;
!Дополнительное потребление VRAM из расчета на 1 сессию&lt;br /&gt;
!Условное потребление Compute на 1 сессию&lt;br /&gt;
|-&lt;br /&gt;
|secondchain&lt;br /&gt;
|Инференс модели VAD (CPU), логика робота, голосовой pipeline, работа с сессиями, SIP-клиент&lt;br /&gt;
|CPU, RAM&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
|vLLM (qwen3.5-35b-a3b-INT4)&lt;br /&gt;
Данные указаны с окном контекста 8192 токена.&lt;br /&gt;
|Инференс больших языковых моделей (LLM)&lt;br /&gt;
|VRAM, Compute&lt;br /&gt;
|22gb&lt;br /&gt;
|0.3gb&lt;br /&gt;
|~3 GFLOP/токен&lt;br /&gt;
|-&lt;br /&gt;
|T-one (Triton Inference Server)&lt;br /&gt;
|Инференс T-One speech-to-text&lt;br /&gt;
|Compute&lt;br /&gt;
|600mb&lt;br /&gt;
|10mb&lt;br /&gt;
|~1-3 GFLOP/секунда речи&lt;br /&gt;
|-&lt;br /&gt;
|LightTTS&lt;br /&gt;
|Инференс CosyVoice3 TTS&lt;br /&gt;
|Compute, VRAM&lt;br /&gt;
|8gb&lt;br /&gt;
|0.3gb&lt;br /&gt;
|~120GFLOP/секунда генерируемоей речи&lt;br /&gt;
|}&lt;br /&gt;
При высокой конкуренции за Compute, увеличиваются задержки на каждом из этапов инференса. Самым чувствительным компонентом, при этом, является LightTTS - из-за архитектурных особенностей. TTS требует много вычислительных ресурсов, и большое количество параллельных генераций могут значительно увеличивать задержку. В случае использования нескольких серверов рекомендуется первично выносить на отдельный сервер либо LightTTS, либо vLLM (для высвобождения Compute).&lt;br /&gt;
&lt;br /&gt;
Архитектурно при этом, робот устроен таким образом, чтобы минимизировать инференс LightTTS при возможности (агрессивное кеширование результатов TTS). &lt;br /&gt;
&lt;br /&gt;
=== Нюансы подбора GPU ===&lt;br /&gt;
При подборе GPU под данный стек объём VRAM не является определяющим критерием. Веса любой из трёх моделей помещаются в память практически любой современной карты (уровня 5090 или выше), тогда как реальными ограничивающими факторами выступают пропускная способность памяти на этапе декодирования LLM и вычислительная нагрузка DiT-декодера в TTS. Соответственно, при выборе оборудования следует ориентироваться в первую очередь на memory bandwidth и на аппаратную поддержку современных типов данных, а не на номинальный объём видеопамяти.&lt;br /&gt;
&lt;br /&gt;
Отдельного внимания заслуживает интерфейс межкарточного взаимодействия. Потребительские карты рассчитаны преимущественно на одиночную эксплуатацию: в актуальных линейках Blackwell и Ada поддержка NVLink отсутствует, и обмен между несколькими GPU на одном сервере осуществляется исключительно через PCIe (Gen4/Gen5). При использовании tensor parallelism это создаёт заметные накладные расходы на межкарточную коммуникацию, что становится ощутимым при высокой конкурентной нагрузке. Дата-центровые решения (H100, H200, а также RTX PRO 6000 в соответствующем сегменте) либо предоставляют NVLink с пропускной способностью в сотни ГБ/с, либо обладают достаточным объёмом памяти для размещения моделей на одной карте, что позволяет полностью исключить tensor parallelism и связанные с ним издержки.&lt;br /&gt;
&lt;br /&gt;
Следует также учитывать высокие темпы развития архитектур GPU. Производительная карта шестилетней давности может уступать современному решению среднего уровня как по вычислительной мощности, так и — что существенно в данном случае — по набору поддерживаемых типов данных. Например, NVIDIA V100 (Volta, 2017), несмотря на наличие NVLink и памяти HBM, не поддерживает аппаратное ускорение FP8 и Int4 на тензорных ядрах. Между тем рассматриваемый стек существенно опирается на эти форматы: Qwen в квантизации GPTQ-Int4 с fp8 KV-cache, T-one в TensorRT, TTS с int8-квантизацией. На оборудовании предыдущих поколений соответствующие операции либо неработоспособны в требуемых форматах, либо выполняются с существенным замедлением за счёт программной эмуляции.&lt;br /&gt;
&lt;br /&gt;
С практической точки зрения приоритеты при выборе оборудования под данный пайплайн выстраиваются следующим образом: в первую очередь — поколение архитектуры (Ada, Hopper, Blackwell — ввиду поддержки FP8 и Int4 на тензорных ядрах), далее — пропускная способность памяти, и лишь затем — объём VRAM, поскольку последний в рамках данной задачи практически всегда достаточен.&lt;br /&gt;
&lt;br /&gt;
Робот тестировался преимущественно на картах поколения Blackwell:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;RTX5090&#039;&#039;&#039; (использовалась другая LLM меньшего размера)&lt;br /&gt;
* &#039;&#039;&#039;RTX PRO 5000&#039;&#039;&#039; 48gb&lt;br /&gt;
* &#039;&#039;&#039;RTX PRO 6000&#039;&#039;&#039; 96gb&lt;br /&gt;
&lt;br /&gt;
Однако проводились также тесты на картах архитектуры Ampere. Результат можно считать удовлетворительным, особенно для организации тестовых и демо-сред без постоянной большой нагрузки.&lt;br /&gt;
&lt;br /&gt;
Отдельно хочется сказать про ускорители других производителей (AMD, Intel):&lt;br /&gt;
&lt;br /&gt;
К большому сожалению, большая часть инфраструктурного софта оптимизируется в первую очередь под ускорители NVIDIA. В связи с этим даже более производительные карты AMD &amp;quot;на бумаге&amp;quot;, по факту показывают значительно меньшие скорости при реальных задачах. Некоторые же библиотеки и компоненты (TensorRT, Triton Inference Server и т.д.) вообще являются проприетарными разработками NVIDIA и не поддерживают работу с ускорителями других производителей.&lt;br /&gt;
&lt;br /&gt;
=== Анизотропность нагрузки ===&lt;br /&gt;
пывпаывпыва&lt;br /&gt;
&lt;br /&gt;
=== Приблизительный расчет требуемых мощностей ===&lt;br /&gt;
паывпывапыв&lt;br /&gt;
&lt;br /&gt;
=== Масштабирование сервиса ===&lt;br /&gt;
авыфаывафыв&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
Установка самого Docker:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установка Nvidia Container Toolkit (только для серверов с GPU):&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# репозиторий&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \&lt;br /&gt;
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \&lt;br /&gt;
  sed &#039;s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g&#039; | \&lt;br /&gt;
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-container-toolkit&lt;br /&gt;
sudo nvidia-ctk runtime configure --runtime=docker&lt;br /&gt;
sudo systemctl restart docker&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (опционально) =&lt;br /&gt;
&lt;br /&gt;
Инструкция для &#039;&#039;&#039;Ubuntu Server 24.04&#039;&#039;&#039;. Стек: ASR (T-one/Triton) → LLM (Qwen3.5-35B-A3B на vLLM) → TTS (LightTTS + CosyVoice3).&lt;br /&gt;
&lt;br /&gt;
Целевая машина — сервер с GPU: &#039;&#039;&#039;RTX PRO 5000 (48GB)&#039;&#039;&#039; или &#039;&#039;&#039;RTX PRO 6000 Blackwell (96GB)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
=== Бюджет VRAM ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Компонент !! VRAM&lt;br /&gt;
|-&lt;br /&gt;
| ASR (T-one/Triton) || 600–800 MB&lt;br /&gt;
|-&lt;br /&gt;
| LLM (Qwen3.5-35B-A3B) || 24–48 GB (зависит от числа сессий и длины контекста)&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS/CosyVoice3) || 10 GB&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Суммарное потребление в пике — ~36–60 GB.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 6000 (96GB):&#039;&#039;&#039; объёма достаточно с большим запасом. Допустимо использование максимального числа сессий и длинного контекста.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 5000 (48GB):&#039;&#039;&#039; запас минимальный. Фиксированная сумма ASR (~0.8 GB) и TTS (11 GB) составляет ~12 GB, на LLM остаётся ~36 GB. Это покрывает только нижнюю границу диапазона LLM (24 GB). Требуется ограничение параметров &amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt; во избежание ошибки OOM. Значение &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; (~24 GB на карте 48GB) для данного сценария допустимо при условии, что ASR и TTS инициализированы до старта LLM.&lt;br /&gt;
&lt;br /&gt;
Объем оперативной памяти не может быть меньше, чем VRAM, так как в процессе запуска веса моделей помещаются сначала в оперативную память, и только затем в VRAM.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Компиляция моделей может занимать больше VRAM, чем запущенный сервис, поэтому в случае дефицита видеопамяти, рекомендуется временно отключать свеже созданные контейнеры, собирать их по одному, после чего запускать по очереди уже в собранном виде.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton Inference Server) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
I0706 22:41:02.484518 1 grpc_server.cc:2562] &amp;quot;Started GRPCInferenceService at 0.0.0.0:8001&amp;quot;&lt;br /&gt;
I0706 22:41:02.484664 1 http_server.cc:4832] &amp;quot;Started HTTPService at 0.0.0.0:8000&amp;quot;&lt;br /&gt;
I0706 22:41:02.525792 1 http_server.cc:358] &amp;quot;Started Metrics Service at 0.0.0.0:8002&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
Установка выполняется из Docker Hub, следующей командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
* &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; — директория хост-машины, где будет храниться кеш весов модели (24gb)&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
После запуска vllm скачает веса модели для запуска (24gb). После завершения запуска и загрузки весов в логах можно наблюдать следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
(APIServer pid=1) INFO:     Started server process [1]&lt;br /&gt;
(APIServer pid=1) INFO:     Waiting for application startup.&lt;br /&gt;
(APIServer pid=1) INFO:     Application startup complete.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Как только они появятся, можно переходить к следующему шагу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080.&#039;&#039;&#039; Первый запрос к модели будет занимать достаточно много времени:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}],&lt;br /&gt;
    &amp;quot;chat_template_kwargs&amp;quot;: {&amp;quot;enable_thinking&amp;quot;: false}&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load -i lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights \&lt;br /&gt;
  python -m light_tts.server.api_server \&lt;br /&gt;
    --model_dir /opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
    --data_type float16 \&lt;br /&gt;
    --load_trt True \&lt;br /&gt;
    --host 0.0.0.0&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;После запуска сервис скомпилирует веса, по аналогии с T-One. После завершения подготовки в логах будут следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:391] ✅ Startup health check passed!&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:395] ✅ Application ready! Server is now accepting requests&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:396] 🌐 Listening at: http://localhost:8080&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — 10 &#039;&#039;&#039;GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 17000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 17001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Контейнеры сервисов инференса голосового робота.png|центр|безрамки|1067x1067пкс]]&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
&lt;br /&gt;
Необходимо переименовать файл example.env в .env и изменить в нём следующие параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&lt;br /&gt;
POSTGRES_HOST=[хост postgresql]&lt;br /&gt;
POSTGRES_PORT=5432&lt;br /&gt;
POSTGRES_USER=[логин postgresql]&lt;br /&gt;
POSTGRES_PASSWORD=[пароль postgresql]&lt;br /&gt;
POSTGRES_DB=[имя БД, если укзаанная БД отсутствует - она будет автоматически создана]&lt;br /&gt;
&lt;br /&gt;
CONCURRENT_SESSIONS=[Жесткое ограничение количества одновременных сессий]&lt;br /&gt;
&lt;br /&gt;
SIP_SERVER=[адрес Эры]&lt;br /&gt;
SIP_PORT=[порт SIP]&lt;br /&gt;
SIP_USERNAME=[Имя учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_PASSWORD=[Пароль учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_DOMAIN=[Полное имя домена, например robot.era-platform.ru]&lt;br /&gt;
#Детальные настройки SIP-клиента. В случае необходимости обхода NAT&lt;br /&gt;
SIP_TRANSPORT=udp&lt;br /&gt;
# NAT Traversal&lt;br /&gt;
SIP_STUN_SERVER=stun.l.google.com:19302&lt;br /&gt;
SIP_USE_ICE=false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
LLM_MODE=openai_api&lt;br /&gt;
#В случае использования сервиса инфереса vLLM на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LLM_OPENAI_API_BASE=http://localhost:16080/v1 &lt;br /&gt;
LLM_OPENAI_MODEL=qwen35-35b-a3b&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ASR_MODE=triton&lt;br /&gt;
#В случае использования сервиса инфереса tone-triton на другом хосте, необходимо изменить адреса/порты&lt;br /&gt;
ASR_TRITON_URL=http://localhost:17000&lt;br /&gt;
ASR_TRITON_GRPC=localhost:17001&lt;br /&gt;
ASR_TRITON_MODEL=streaming_acoustic&lt;br /&gt;
ASR_TRITON_TIMEOUT=10&lt;br /&gt;
ASR_DECODER_TYPE=beam_search&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
TTS_PROVIDER=lighttts&lt;br /&gt;
#В случае использования сервиса инфереса LightTTS на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LIGHTTTS_URL=http://localhost:8080/&lt;br /&gt;
LIGHTTTS_SAMPLE_RATE=24000&lt;br /&gt;
LIGHTTTS_STREAMING=false&lt;br /&gt;
LIGHTTTS_CONCURRENCY=4&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Плейсхолдер под подробное описание .env --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Запуск контейнера и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
docker load -i secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2438</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2438"/>
		<updated>2026-07-07T10:22:15Z</updated>

		<summary type="html">&lt;p&gt;AZykov: /* Микросервисы робота и их нагрузка */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Общая информация =&lt;br /&gt;
[[Файл:Архитектура голосового робота.png|центр|безрамки|763x763пкс]]&lt;br /&gt;
Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 1. Подготовка|Подготовка]]&#039;&#039;&#039; — Docker, PostgreSQL, настройки в системе телефонии.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 2. Установка сервисов инференса (опционально)|Установка сервисов инференса]]&#039;&#039;&#039; — ASR, LLM, TTS. &#039;&#039;Опционально, только для развёртывания на собственном сервере с GPU.&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 3. Настройка .env|Настройка .env]]&#039;&#039;&#039; — параметры подключения.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 4. Запуск контейнера и создание робота|Запуск контейнера и создание робота]]&#039;&#039;&#039; — старт сервиса и конфигурация робота.&lt;br /&gt;
&lt;br /&gt;
= Глоссарий =&lt;br /&gt;
&#039;&#039;&#039;Модель&#039;&#039;&#039; — обученная нейросеть, задающая соответствие между входом и выходом (текст -&amp;gt; текст, звук -&amp;gt; текст и т.д.). Модель определяется архитектурой и набором весов, полученных при обучении. В стеке робота их четыре:VAD (детекция голосовой активности), ASR (распознавание речи), LLM (генерация ответа), TTS (синтез речи).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Веса&#039;&#039;&#039; — числовые параметры модели, полученные при обучении. Именно они хранятся в файлах модели и загружаются в VRAM при старте. «Загрузка весов» в логах vLLM — это чтение этих файлов с диска в память GPU.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Инференс&#039;&#039;&#039; — использование готовой модели для получения ответа на новый вход («прогон» данных через веса). В отличие от обучения, веса не меняются. Сервисы инференса в статье — Triton, vLLM, LightTTS.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Triton&#039;&#039;&#039; (NVIDIA Triton Inference Server) — сервер инференса от NVIDIA, обслуживающий модели по gRPC и HTTP. В стеке на нём крутится ASR-модель T-one.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TensorRT&#039;&#039;&#039; — библиотека NVIDIA для оптимизации моделей под конкретный GPU: она компилирует модель в специализированный «движок» ради ускорения инференса. Сборка такого движка — разовая операция под железо, поэтому в LightTTS и T-One Triton она выполняется на первой фазе и коммитится в образ.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;vLLM&#039;&#039;&#039; — движок инференса для больших языковых моделей (LLM), оптимизированный на пропускную способность и эффективную работу с памятью. Предоставляет OpenAI-совместимый API.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;nvidia-smi&#039;&#039;&#039; (NVIDIA System Management Interface) — консольная утилита для просмотра состояния GPU: модель карты, версия драйвера, загрузка, потребление VRAM, запущенные процессы. Используется для проверки, что драйвер установлен и GPU виден (в т.ч. изнутри контейнера).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;KV-Cache&#039;&#039;&#039; (кэш ключей и значений) — память, где LLM хранит промежуточные представления уже обработанных токенов, чтобы не пересчитывать их при генерации каждого нового токена. Ускоряет генерацию ценой VRAM. В конфиге ограничен параметром &amp;lt;code&amp;gt;--kv-cache-memory&amp;lt;/code&amp;gt; (3 GiB). Растёт с числом сессий и длиной контекста — поэтому его размер критичен на картах с малым запасом VRAM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;LightTTS&#039;&#039;&#039; — движок инференса для TTS-моделей (синтеза речи). В стеке запускает модель CosyVoice3, слушает порт 8080.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Токен&#039;&#039;&#039; —В &#039;&#039;контексте LLM&#039;&#039; — единица текста, которой оперирует модель (примерно часть слова / слово / знак). Именно в токенах измеряются окно контекста и объём генерации.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Окно контекста&#039;&#039;&#039; — максимальное количество токенов, которое LLM может учитывать за один запрос (вход + генерируемый ответ вместе). Чем больше окно, тем больше VRAM уходит под KV-Cache, поэтому на картах с ограниченным объёмом его сокращают.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Compute&#039;&#039;&#039; — Вычислительные ресурсы GPU. Абстрактный ресурс видеоускорителя, аналог CPU Time при обычных расчетах. Измеряется в GFLOP/TFLOP (операциях в секунду)&lt;br /&gt;
&lt;br /&gt;
= Требования к оборудованию, нагрузка и мастштабирование =&lt;br /&gt;
&lt;br /&gt;
=== Микросервисы робота и их нагрузка ===&lt;br /&gt;
Робот функционирует на базе 4 микросервисов, каждый из которых может быть вынесен на отдельный сервер, или исполняться на общем сервере. &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Микросервисы робота&lt;br /&gt;
!Название&lt;br /&gt;
!Назначение&lt;br /&gt;
!Ключевые ресурсы&lt;br /&gt;
!Минимальное потребление VRAM&lt;br /&gt;
!Дополнительное потребление VRAM из расчета на 1 сессию&lt;br /&gt;
!Условное потребление Compute на 1 сессию&lt;br /&gt;
|-&lt;br /&gt;
|secondchain&lt;br /&gt;
|Инференс модели VAD (CPU), логика робота, голосовой pipeline, работа с сессиями, SIP-клиент&lt;br /&gt;
|CPU, RAM&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
|vLLM (qwen3.5-35b-a3b-INT4)&lt;br /&gt;
Данные указаны с окном контекста 8192 токена.&lt;br /&gt;
|Инференс больших языковых моделей (LLM)&lt;br /&gt;
|VRAM, Compute&lt;br /&gt;
|22gb&lt;br /&gt;
|0.3gb&lt;br /&gt;
|~3 GFLOP/токен&lt;br /&gt;
|-&lt;br /&gt;
|T-one (Triton Inference Server)&lt;br /&gt;
|Инференс T-One speech-to-text&lt;br /&gt;
|Compute&lt;br /&gt;
|600mb&lt;br /&gt;
|10mb&lt;br /&gt;
|~1-3 GFLOP/секунда речи&lt;br /&gt;
|-&lt;br /&gt;
|LightTTS&lt;br /&gt;
|Инференс CosyVoice3 TTS&lt;br /&gt;
|Compute, VRAM&lt;br /&gt;
|8gb&lt;br /&gt;
|0.3gb&lt;br /&gt;
|~120GFLOP/секунда генерируемоей речи&lt;br /&gt;
|}&lt;br /&gt;
При высокой конкуренции за Compute, увеличиваются задержки на каждом из этапов инференса. Самым чувствительным компонентом, при этом, является LightTTS - из-за архитектурных особенностей. TTS требует много вычислительных ресурсов, и большое количество параллельных генераций могут значительно увеличивать задержку. В случае использования нескольких серверов рекомендуется первично выносить на отдельный сервер либо LightTTS, либо vLLM (для высвобождения Compute).&lt;br /&gt;
&lt;br /&gt;
Архитектурно при этом, робот устроен таким образом, чтобы минимизировать инференс LightTTS при возможности (агрессивное кеширование результатов TTS). &lt;br /&gt;
&lt;br /&gt;
=== Нюансы подбора GPU ===&lt;br /&gt;
паывпывапва&lt;br /&gt;
&lt;br /&gt;
=== Анизотропность нагрузки ===&lt;br /&gt;
пывпаывпыва&lt;br /&gt;
&lt;br /&gt;
=== Приблизительный расчет требуемых мощностей ===&lt;br /&gt;
паывпывапыв&lt;br /&gt;
&lt;br /&gt;
=== Масштабирование сервиса ===&lt;br /&gt;
авыфаывафыв&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
Установка самого Docker:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установка Nvidia Container Toolkit (только для серверов с GPU):&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# репозиторий&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \&lt;br /&gt;
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \&lt;br /&gt;
  sed &#039;s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g&#039; | \&lt;br /&gt;
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-container-toolkit&lt;br /&gt;
sudo nvidia-ctk runtime configure --runtime=docker&lt;br /&gt;
sudo systemctl restart docker&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (опционально) =&lt;br /&gt;
&lt;br /&gt;
Инструкция для &#039;&#039;&#039;Ubuntu Server 24.04&#039;&#039;&#039;. Стек: ASR (T-one/Triton) → LLM (Qwen3.5-35B-A3B на vLLM) → TTS (LightTTS + CosyVoice3).&lt;br /&gt;
&lt;br /&gt;
Целевая машина — сервер с GPU: &#039;&#039;&#039;RTX PRO 5000 (48GB)&#039;&#039;&#039; или &#039;&#039;&#039;RTX PRO 6000 Blackwell (96GB)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
=== Бюджет VRAM ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Компонент !! VRAM&lt;br /&gt;
|-&lt;br /&gt;
| ASR (T-one/Triton) || 600–800 MB&lt;br /&gt;
|-&lt;br /&gt;
| LLM (Qwen3.5-35B-A3B) || 24–48 GB (зависит от числа сессий и длины контекста)&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS/CosyVoice3) || 10 GB&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Суммарное потребление в пике — ~36–60 GB.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 6000 (96GB):&#039;&#039;&#039; объёма достаточно с большим запасом. Допустимо использование максимального числа сессий и длинного контекста.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 5000 (48GB):&#039;&#039;&#039; запас минимальный. Фиксированная сумма ASR (~0.8 GB) и TTS (11 GB) составляет ~12 GB, на LLM остаётся ~36 GB. Это покрывает только нижнюю границу диапазона LLM (24 GB). Требуется ограничение параметров &amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt; во избежание ошибки OOM. Значение &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; (~24 GB на карте 48GB) для данного сценария допустимо при условии, что ASR и TTS инициализированы до старта LLM.&lt;br /&gt;
&lt;br /&gt;
Объем оперативной памяти не может быть меньше, чем VRAM, так как в процессе запуска веса моделей помещаются сначала в оперативную память, и только затем в VRAM.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Компиляция моделей может занимать больше VRAM, чем запущенный сервис, поэтому в случае дефицита видеопамяти, рекомендуется временно отключать свеже созданные контейнеры, собирать их по одному, после чего запускать по очереди уже в собранном виде.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton Inference Server) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
I0706 22:41:02.484518 1 grpc_server.cc:2562] &amp;quot;Started GRPCInferenceService at 0.0.0.0:8001&amp;quot;&lt;br /&gt;
I0706 22:41:02.484664 1 http_server.cc:4832] &amp;quot;Started HTTPService at 0.0.0.0:8000&amp;quot;&lt;br /&gt;
I0706 22:41:02.525792 1 http_server.cc:358] &amp;quot;Started Metrics Service at 0.0.0.0:8002&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
Установка выполняется из Docker Hub, следующей командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
* &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; — директория хост-машины, где будет храниться кеш весов модели (24gb)&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
После запуска vllm скачает веса модели для запуска (24gb). После завершения запуска и загрузки весов в логах можно наблюдать следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
(APIServer pid=1) INFO:     Started server process [1]&lt;br /&gt;
(APIServer pid=1) INFO:     Waiting for application startup.&lt;br /&gt;
(APIServer pid=1) INFO:     Application startup complete.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Как только они появятся, можно переходить к следующему шагу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080.&#039;&#039;&#039; Первый запрос к модели будет занимать достаточно много времени:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}],&lt;br /&gt;
    &amp;quot;chat_template_kwargs&amp;quot;: {&amp;quot;enable_thinking&amp;quot;: false}&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load -i lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights \&lt;br /&gt;
  python -m light_tts.server.api_server \&lt;br /&gt;
    --model_dir /opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
    --data_type float16 \&lt;br /&gt;
    --load_trt True \&lt;br /&gt;
    --host 0.0.0.0&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;После запуска сервис скомпилирует веса, по аналогии с T-One. После завершения подготовки в логах будут следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:391] ✅ Startup health check passed!&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:395] ✅ Application ready! Server is now accepting requests&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:396] 🌐 Listening at: http://localhost:8080&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — 10 &#039;&#039;&#039;GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 17000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 17001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Контейнеры сервисов инференса голосового робота.png|центр|безрамки|1067x1067пкс]]&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
&lt;br /&gt;
Необходимо переименовать файл example.env в .env и изменить в нём следующие параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&lt;br /&gt;
POSTGRES_HOST=[хост postgresql]&lt;br /&gt;
POSTGRES_PORT=5432&lt;br /&gt;
POSTGRES_USER=[логин postgresql]&lt;br /&gt;
POSTGRES_PASSWORD=[пароль postgresql]&lt;br /&gt;
POSTGRES_DB=[имя БД, если укзаанная БД отсутствует - она будет автоматически создана]&lt;br /&gt;
&lt;br /&gt;
CONCURRENT_SESSIONS=[Жесткое ограничение количества одновременных сессий]&lt;br /&gt;
&lt;br /&gt;
SIP_SERVER=[адрес Эры]&lt;br /&gt;
SIP_PORT=[порт SIP]&lt;br /&gt;
SIP_USERNAME=[Имя учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_PASSWORD=[Пароль учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_DOMAIN=[Полное имя домена, например robot.era-platform.ru]&lt;br /&gt;
#Детальные настройки SIP-клиента. В случае необходимости обхода NAT&lt;br /&gt;
SIP_TRANSPORT=udp&lt;br /&gt;
# NAT Traversal&lt;br /&gt;
SIP_STUN_SERVER=stun.l.google.com:19302&lt;br /&gt;
SIP_USE_ICE=false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
LLM_MODE=openai_api&lt;br /&gt;
#В случае использования сервиса инфереса vLLM на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LLM_OPENAI_API_BASE=http://localhost:16080/v1 &lt;br /&gt;
LLM_OPENAI_MODEL=qwen35-35b-a3b&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ASR_MODE=triton&lt;br /&gt;
#В случае использования сервиса инфереса tone-triton на другом хосте, необходимо изменить адреса/порты&lt;br /&gt;
ASR_TRITON_URL=http://localhost:17000&lt;br /&gt;
ASR_TRITON_GRPC=localhost:17001&lt;br /&gt;
ASR_TRITON_MODEL=streaming_acoustic&lt;br /&gt;
ASR_TRITON_TIMEOUT=10&lt;br /&gt;
ASR_DECODER_TYPE=beam_search&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
TTS_PROVIDER=lighttts&lt;br /&gt;
#В случае использования сервиса инфереса LightTTS на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LIGHTTTS_URL=http://localhost:8080/&lt;br /&gt;
LIGHTTTS_SAMPLE_RATE=24000&lt;br /&gt;
LIGHTTTS_STREAMING=false&lt;br /&gt;
LIGHTTTS_CONCURRENCY=4&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Плейсхолдер под подробное описание .env --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Запуск контейнера и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
docker load -i secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2437</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2437"/>
		<updated>2026-07-07T10:21:19Z</updated>

		<summary type="html">&lt;p&gt;AZykov: /* Глоссарий */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Общая информация =&lt;br /&gt;
[[Файл:Архитектура голосового робота.png|центр|безрамки|763x763пкс]]&lt;br /&gt;
Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 1. Подготовка|Подготовка]]&#039;&#039;&#039; — Docker, PostgreSQL, настройки в системе телефонии.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 2. Установка сервисов инференса (опционально)|Установка сервисов инференса]]&#039;&#039;&#039; — ASR, LLM, TTS. &#039;&#039;Опционально, только для развёртывания на собственном сервере с GPU.&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 3. Настройка .env|Настройка .env]]&#039;&#039;&#039; — параметры подключения.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 4. Запуск контейнера и создание робота|Запуск контейнера и создание робота]]&#039;&#039;&#039; — старт сервиса и конфигурация робота.&lt;br /&gt;
&lt;br /&gt;
= Глоссарий =&lt;br /&gt;
&#039;&#039;&#039;Модель&#039;&#039;&#039; — обученная нейросеть, задающая соответствие между входом и выходом (текст -&amp;gt; текст, звук -&amp;gt; текст и т.д.). Модель определяется архитектурой и набором весов, полученных при обучении. В стеке робота их четыре:VAD (детекция голосовой активности), ASR (распознавание речи), LLM (генерация ответа), TTS (синтез речи).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Веса&#039;&#039;&#039; — числовые параметры модели, полученные при обучении. Именно они хранятся в файлах модели и загружаются в VRAM при старте. «Загрузка весов» в логах vLLM — это чтение этих файлов с диска в память GPU.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Инференс&#039;&#039;&#039; — использование готовой модели для получения ответа на новый вход («прогон» данных через веса). В отличие от обучения, веса не меняются. Сервисы инференса в статье — Triton, vLLM, LightTTS.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Triton&#039;&#039;&#039; (NVIDIA Triton Inference Server) — сервер инференса от NVIDIA, обслуживающий модели по gRPC и HTTP. В стеке на нём крутится ASR-модель T-one.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TensorRT&#039;&#039;&#039; — библиотека NVIDIA для оптимизации моделей под конкретный GPU: она компилирует модель в специализированный «движок» ради ускорения инференса. Сборка такого движка — разовая операция под железо, поэтому в LightTTS и T-One Triton она выполняется на первой фазе и коммитится в образ.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;vLLM&#039;&#039;&#039; — движок инференса для больших языковых моделей (LLM), оптимизированный на пропускную способность и эффективную работу с памятью. Предоставляет OpenAI-совместимый API.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;nvidia-smi&#039;&#039;&#039; (NVIDIA System Management Interface) — консольная утилита для просмотра состояния GPU: модель карты, версия драйвера, загрузка, потребление VRAM, запущенные процессы. Используется для проверки, что драйвер установлен и GPU виден (в т.ч. изнутри контейнера).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;KV-Cache&#039;&#039;&#039; (кэш ключей и значений) — память, где LLM хранит промежуточные представления уже обработанных токенов, чтобы не пересчитывать их при генерации каждого нового токена. Ускоряет генерацию ценой VRAM. В конфиге ограничен параметром &amp;lt;code&amp;gt;--kv-cache-memory&amp;lt;/code&amp;gt; (3 GiB). Растёт с числом сессий и длиной контекста — поэтому его размер критичен на картах с малым запасом VRAM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;LightTTS&#039;&#039;&#039; — движок инференса для TTS-моделей (синтеза речи). В стеке запускает модель CosyVoice3, слушает порт 8080.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Токен&#039;&#039;&#039; —В &#039;&#039;контексте LLM&#039;&#039; — единица текста, которой оперирует модель (примерно часть слова / слово / знак). Именно в токенах измеряются окно контекста и объём генерации.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Окно контекста&#039;&#039;&#039; — максимальное количество токенов, которое LLM может учитывать за один запрос (вход + генерируемый ответ вместе). Чем больше окно, тем больше VRAM уходит под KV-Cache, поэтому на картах с ограниченным объёмом его сокращают.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Compute&#039;&#039;&#039; — Вычислительные ресурсы GPU. Абстрактный ресурс видеоускорителя, аналог CPU Time при обычных расчетах. Измеряется в GFLOP/TFLOP (операциях в секунду)&lt;br /&gt;
&lt;br /&gt;
= Требования к оборудованию, нагрузка и мастштабирование =&lt;br /&gt;
&lt;br /&gt;
=== Микросервисы робота и их нагрузка ===&lt;br /&gt;
Робот функционирует на базе 4 микросервисов, каждый из которых может быть вынесен на отдельный сервер, или исполняться на общем сервере. &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Микросервисы робота&lt;br /&gt;
!Название&lt;br /&gt;
!Назначение&lt;br /&gt;
!Ключевые ресурсы&lt;br /&gt;
!Минимальное потребление VRAM&lt;br /&gt;
!Дополнительное потребление VRAM из расчета на 1 сессию&lt;br /&gt;
!Условное потребление Compute на 1 сессию&lt;br /&gt;
|-&lt;br /&gt;
|secondchain&lt;br /&gt;
|Инференс модели VAD (CPU), логика робота, голосовой pipeline, работа с сессиями, SIP-клиент&lt;br /&gt;
|CPU, RAM&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
|vLLM (qwen3.5-35b-a3b-INT4)&lt;br /&gt;
Данные указаны с окном контекста 8192 токена.&lt;br /&gt;
|Инференс больших языковых моделей (LLM)&lt;br /&gt;
|VRAM, Compute&lt;br /&gt;
|22gb&lt;br /&gt;
|0.25gb&lt;br /&gt;
|~3 GFLOP/токен&lt;br /&gt;
|-&lt;br /&gt;
|T-one (Triton Inference Server)&lt;br /&gt;
|Инференс T-One speech-to-text&lt;br /&gt;
|Compute&lt;br /&gt;
|600mb&lt;br /&gt;
|10mb&lt;br /&gt;
|~1-3 GFLOP/секунда речи&lt;br /&gt;
|-&lt;br /&gt;
|LightTTS&lt;br /&gt;
|Инференс CosyVoice3 TTS&lt;br /&gt;
|Compute, VRAM&lt;br /&gt;
|8gb&lt;br /&gt;
|0.3gb&lt;br /&gt;
|~120GFLOP/секунда генерируемоей речи&lt;br /&gt;
|}&lt;br /&gt;
При высокой конкуренции за Compute, увеличиваются задержки на каждом из этапов инференса. Самым чувствительным компонентом, при этом, является LightTTS - из-за архитектурных особенностей. TTS требует много вычислительных ресурсов, и большое количество параллельных генераций могут значительно увеличивать задержку. В случае использования нескольких серверов рекомендуется первично выносить на отдельный сервер либо LightTTS, либо vLLM (для высвобождения Compute).&lt;br /&gt;
&lt;br /&gt;
Архитектурно при этом, робот устроен таким образом, чтобы минимизировать инференс LightTTS при возможности (агрессивное кеширование результатов TTS). &lt;br /&gt;
&lt;br /&gt;
=== Нюансы подбора GPU ===&lt;br /&gt;
паывпывапва&lt;br /&gt;
&lt;br /&gt;
=== Анизотропность нагрузки ===&lt;br /&gt;
пывпаывпыва&lt;br /&gt;
&lt;br /&gt;
=== Приблизительный расчет требуемых мощностей ===&lt;br /&gt;
паывпывапыв&lt;br /&gt;
&lt;br /&gt;
=== Масштабирование сервиса ===&lt;br /&gt;
авыфаывафыв&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
Установка самого Docker:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установка Nvidia Container Toolkit (только для серверов с GPU):&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# репозиторий&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \&lt;br /&gt;
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \&lt;br /&gt;
  sed &#039;s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g&#039; | \&lt;br /&gt;
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-container-toolkit&lt;br /&gt;
sudo nvidia-ctk runtime configure --runtime=docker&lt;br /&gt;
sudo systemctl restart docker&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (опционально) =&lt;br /&gt;
&lt;br /&gt;
Инструкция для &#039;&#039;&#039;Ubuntu Server 24.04&#039;&#039;&#039;. Стек: ASR (T-one/Triton) → LLM (Qwen3.5-35B-A3B на vLLM) → TTS (LightTTS + CosyVoice3).&lt;br /&gt;
&lt;br /&gt;
Целевая машина — сервер с GPU: &#039;&#039;&#039;RTX PRO 5000 (48GB)&#039;&#039;&#039; или &#039;&#039;&#039;RTX PRO 6000 Blackwell (96GB)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
=== Бюджет VRAM ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Компонент !! VRAM&lt;br /&gt;
|-&lt;br /&gt;
| ASR (T-one/Triton) || 600–800 MB&lt;br /&gt;
|-&lt;br /&gt;
| LLM (Qwen3.5-35B-A3B) || 24–48 GB (зависит от числа сессий и длины контекста)&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS/CosyVoice3) || 10 GB&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Суммарное потребление в пике — ~36–60 GB.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 6000 (96GB):&#039;&#039;&#039; объёма достаточно с большим запасом. Допустимо использование максимального числа сессий и длинного контекста.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 5000 (48GB):&#039;&#039;&#039; запас минимальный. Фиксированная сумма ASR (~0.8 GB) и TTS (11 GB) составляет ~12 GB, на LLM остаётся ~36 GB. Это покрывает только нижнюю границу диапазона LLM (24 GB). Требуется ограничение параметров &amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt; во избежание ошибки OOM. Значение &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; (~24 GB на карте 48GB) для данного сценария допустимо при условии, что ASR и TTS инициализированы до старта LLM.&lt;br /&gt;
&lt;br /&gt;
Объем оперативной памяти не может быть меньше, чем VRAM, так как в процессе запуска веса моделей помещаются сначала в оперативную память, и только затем в VRAM.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Компиляция моделей может занимать больше VRAM, чем запущенный сервис, поэтому в случае дефицита видеопамяти, рекомендуется временно отключать свеже созданные контейнеры, собирать их по одному, после чего запускать по очереди уже в собранном виде.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton Inference Server) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
I0706 22:41:02.484518 1 grpc_server.cc:2562] &amp;quot;Started GRPCInferenceService at 0.0.0.0:8001&amp;quot;&lt;br /&gt;
I0706 22:41:02.484664 1 http_server.cc:4832] &amp;quot;Started HTTPService at 0.0.0.0:8000&amp;quot;&lt;br /&gt;
I0706 22:41:02.525792 1 http_server.cc:358] &amp;quot;Started Metrics Service at 0.0.0.0:8002&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
Установка выполняется из Docker Hub, следующей командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
* &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; — директория хост-машины, где будет храниться кеш весов модели (24gb)&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
После запуска vllm скачает веса модели для запуска (24gb). После завершения запуска и загрузки весов в логах можно наблюдать следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
(APIServer pid=1) INFO:     Started server process [1]&lt;br /&gt;
(APIServer pid=1) INFO:     Waiting for application startup.&lt;br /&gt;
(APIServer pid=1) INFO:     Application startup complete.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Как только они появятся, можно переходить к следующему шагу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080.&#039;&#039;&#039; Первый запрос к модели будет занимать достаточно много времени:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}],&lt;br /&gt;
    &amp;quot;chat_template_kwargs&amp;quot;: {&amp;quot;enable_thinking&amp;quot;: false}&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load -i lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights \&lt;br /&gt;
  python -m light_tts.server.api_server \&lt;br /&gt;
    --model_dir /opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
    --data_type float16 \&lt;br /&gt;
    --load_trt True \&lt;br /&gt;
    --host 0.0.0.0&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;После запуска сервис скомпилирует веса, по аналогии с T-One. После завершения подготовки в логах будут следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:391] ✅ Startup health check passed!&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:395] ✅ Application ready! Server is now accepting requests&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:396] 🌐 Listening at: http://localhost:8080&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — 10 &#039;&#039;&#039;GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 17000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 17001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Контейнеры сервисов инференса голосового робота.png|центр|безрамки|1067x1067пкс]]&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
&lt;br /&gt;
Необходимо переименовать файл example.env в .env и изменить в нём следующие параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&lt;br /&gt;
POSTGRES_HOST=[хост postgresql]&lt;br /&gt;
POSTGRES_PORT=5432&lt;br /&gt;
POSTGRES_USER=[логин postgresql]&lt;br /&gt;
POSTGRES_PASSWORD=[пароль postgresql]&lt;br /&gt;
POSTGRES_DB=[имя БД, если укзаанная БД отсутствует - она будет автоматически создана]&lt;br /&gt;
&lt;br /&gt;
CONCURRENT_SESSIONS=[Жесткое ограничение количества одновременных сессий]&lt;br /&gt;
&lt;br /&gt;
SIP_SERVER=[адрес Эры]&lt;br /&gt;
SIP_PORT=[порт SIP]&lt;br /&gt;
SIP_USERNAME=[Имя учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_PASSWORD=[Пароль учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_DOMAIN=[Полное имя домена, например robot.era-platform.ru]&lt;br /&gt;
#Детальные настройки SIP-клиента. В случае необходимости обхода NAT&lt;br /&gt;
SIP_TRANSPORT=udp&lt;br /&gt;
# NAT Traversal&lt;br /&gt;
SIP_STUN_SERVER=stun.l.google.com:19302&lt;br /&gt;
SIP_USE_ICE=false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
LLM_MODE=openai_api&lt;br /&gt;
#В случае использования сервиса инфереса vLLM на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LLM_OPENAI_API_BASE=http://localhost:16080/v1 &lt;br /&gt;
LLM_OPENAI_MODEL=qwen35-35b-a3b&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ASR_MODE=triton&lt;br /&gt;
#В случае использования сервиса инфереса tone-triton на другом хосте, необходимо изменить адреса/порты&lt;br /&gt;
ASR_TRITON_URL=http://localhost:17000&lt;br /&gt;
ASR_TRITON_GRPC=localhost:17001&lt;br /&gt;
ASR_TRITON_MODEL=streaming_acoustic&lt;br /&gt;
ASR_TRITON_TIMEOUT=10&lt;br /&gt;
ASR_DECODER_TYPE=beam_search&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
TTS_PROVIDER=lighttts&lt;br /&gt;
#В случае использования сервиса инфереса LightTTS на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LIGHTTTS_URL=http://localhost:8080/&lt;br /&gt;
LIGHTTTS_SAMPLE_RATE=24000&lt;br /&gt;
LIGHTTTS_STREAMING=false&lt;br /&gt;
LIGHTTTS_CONCURRENCY=4&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Плейсхолдер под подробное описание .env --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Запуск контейнера и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
docker load -i secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2436</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2436"/>
		<updated>2026-07-07T09:59:31Z</updated>

		<summary type="html">&lt;p&gt;AZykov: /* Микросервисы робота и их нагрузка */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Общая информация =&lt;br /&gt;
[[Файл:Архитектура голосового робота.png|центр|безрамки|763x763пкс]]&lt;br /&gt;
Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 1. Подготовка|Подготовка]]&#039;&#039;&#039; — Docker, PostgreSQL, настройки в системе телефонии.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 2. Установка сервисов инференса (опционально)|Установка сервисов инференса]]&#039;&#039;&#039; — ASR, LLM, TTS. &#039;&#039;Опционально, только для развёртывания на собственном сервере с GPU.&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 3. Настройка .env|Настройка .env]]&#039;&#039;&#039; — параметры подключения.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 4. Запуск контейнера и создание робота|Запуск контейнера и создание робота]]&#039;&#039;&#039; — старт сервиса и конфигурация робота.&lt;br /&gt;
&lt;br /&gt;
= Глоссарий =&lt;br /&gt;
&#039;&#039;&#039;Модель&#039;&#039;&#039; — обученная нейросеть, задающая соответствие между входом и выходом (текст -&amp;gt; текст, звук -&amp;gt; текст и т.д.). Модель определяется архитектурой и набором весов, полученных при обучении. В стеке робота их четыре:VAD (детекция голосовой активности), ASR (распознавание речи), LLM (генерация ответа), TTS (синтез речи).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Веса&#039;&#039;&#039; — числовые параметры модели, полученные при обучении. Именно они хранятся в файлах модели и загружаются в VRAM при старте. «Загрузка весов» в логах vLLM — это чтение этих файлов с диска в память GPU.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Инференс&#039;&#039;&#039; — использование готовой модели для получения ответа на новый вход («прогон» данных через веса). В отличие от обучения, веса не меняются. Сервисы инференса в статье — Triton, vLLM, LightTTS.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Triton&#039;&#039;&#039; (NVIDIA Triton Inference Server) — сервер инференса от NVIDIA, обслуживающий модели по gRPC и HTTP. В стеке на нём крутится ASR-модель T-one.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TensorRT&#039;&#039;&#039; — библиотека NVIDIA для оптимизации моделей под конкретный GPU: она компилирует модель в специализированный «движок» ради ускорения инференса. Сборка такого движка — разовая операция под железо, поэтому в LightTTS и T-One Triton она выполняется на первой фазе и коммитится в образ.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;vLLM&#039;&#039;&#039; — движок инференса для больших языковых моделей (LLM), оптимизированный на пропускную способность и эффективную работу с памятью. Предоставляет OpenAI-совместимый API.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;nvidia-smi&#039;&#039;&#039; (NVIDIA System Management Interface) — консольная утилита для просмотра состояния GPU: модель карты, версия драйвера, загрузка, потребление VRAM, запущенные процессы. Используется для проверки, что драйвер установлен и GPU виден (в т.ч. изнутри контейнера).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;KV-Cache&#039;&#039;&#039; (кэш ключей и значений) — память, где LLM хранит промежуточные представления уже обработанных токенов, чтобы не пересчитывать их при генерации каждого нового токена. Ускоряет генерацию ценой VRAM. В конфиге ограничен параметром &amp;lt;code&amp;gt;--kv-cache-memory&amp;lt;/code&amp;gt; (3 GiB). Растёт с числом сессий и длиной контекста — поэтому его размер критичен на картах с малым запасом VRAM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;LightTTS&#039;&#039;&#039; — движок инференса для TTS-моделей (синтеза речи). В стеке запускает модель CosyVoice3, слушает порт 8080.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Токен&#039;&#039;&#039; —В &#039;&#039;контексте LLM&#039;&#039; — единица текста, которой оперирует модель (примерно часть слова / слово / знак). Именно в токенах измеряются окно контекста и объём генерации.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Окно контекста&#039;&#039;&#039; — максимальное количество токенов, которое LLM может учитывать за один запрос (вход + генерируемый ответ вместе). Чем больше окно, тем больше VRAM уходит под KV-Cache, поэтому на картах с ограниченным объёмом его сокращают.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Compute&#039;&#039;&#039; — Вычислительные ресурсы GPU. Абстрактный ресурс видеоускорителя, аналог CPU Time при обычных расчетах.&lt;br /&gt;
&lt;br /&gt;
= Требования к оборудованию, нагрузка и мастштабирование =&lt;br /&gt;
&lt;br /&gt;
=== Микросервисы робота и их нагрузка ===&lt;br /&gt;
Робот функционирует на базе 4 микросервисов, каждый из которых может быть вынесен на отдельный сервер, или исполняться на общем сервере. &lt;br /&gt;
&lt;br /&gt;
=== Нюансы подбора GPU ===&lt;br /&gt;
паывпывапва&lt;br /&gt;
&lt;br /&gt;
=== Анизотропность нагрузки ===&lt;br /&gt;
пывпаывпыва&lt;br /&gt;
&lt;br /&gt;
=== Приблизительный расчет требуемых мощностей ===&lt;br /&gt;
паывпывапыв&lt;br /&gt;
&lt;br /&gt;
=== Масштабирование сервиса ===&lt;br /&gt;
авыфаывафыв&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
Установка самого Docker:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установка Nvidia Container Toolkit (только для серверов с GPU):&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# репозиторий&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \&lt;br /&gt;
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \&lt;br /&gt;
  sed &#039;s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g&#039; | \&lt;br /&gt;
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-container-toolkit&lt;br /&gt;
sudo nvidia-ctk runtime configure --runtime=docker&lt;br /&gt;
sudo systemctl restart docker&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (опционально) =&lt;br /&gt;
&lt;br /&gt;
Инструкция для &#039;&#039;&#039;Ubuntu Server 24.04&#039;&#039;&#039;. Стек: ASR (T-one/Triton) → LLM (Qwen3.5-35B-A3B на vLLM) → TTS (LightTTS + CosyVoice3).&lt;br /&gt;
&lt;br /&gt;
Целевая машина — сервер с GPU: &#039;&#039;&#039;RTX PRO 5000 (48GB)&#039;&#039;&#039; или &#039;&#039;&#039;RTX PRO 6000 Blackwell (96GB)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
=== Бюджет VRAM ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Компонент !! VRAM&lt;br /&gt;
|-&lt;br /&gt;
| ASR (T-one/Triton) || 600–800 MB&lt;br /&gt;
|-&lt;br /&gt;
| LLM (Qwen3.5-35B-A3B) || 24–48 GB (зависит от числа сессий и длины контекста)&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS/CosyVoice3) || 10 GB&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Суммарное потребление в пике — ~36–60 GB.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 6000 (96GB):&#039;&#039;&#039; объёма достаточно с большим запасом. Допустимо использование максимального числа сессий и длинного контекста.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 5000 (48GB):&#039;&#039;&#039; запас минимальный. Фиксированная сумма ASR (~0.8 GB) и TTS (11 GB) составляет ~12 GB, на LLM остаётся ~36 GB. Это покрывает только нижнюю границу диапазона LLM (24 GB). Требуется ограничение параметров &amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt; во избежание ошибки OOM. Значение &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; (~24 GB на карте 48GB) для данного сценария допустимо при условии, что ASR и TTS инициализированы до старта LLM.&lt;br /&gt;
&lt;br /&gt;
Объем оперативной памяти не может быть меньше, чем VRAM, так как в процессе запуска веса моделей помещаются сначала в оперативную память, и только затем в VRAM.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Компиляция моделей может занимать больше VRAM, чем запущенный сервис, поэтому в случае дефицита видеопамяти, рекомендуется временно отключать свеже созданные контейнеры, собирать их по одному, после чего запускать по очереди уже в собранном виде.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton Inference Server) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
I0706 22:41:02.484518 1 grpc_server.cc:2562] &amp;quot;Started GRPCInferenceService at 0.0.0.0:8001&amp;quot;&lt;br /&gt;
I0706 22:41:02.484664 1 http_server.cc:4832] &amp;quot;Started HTTPService at 0.0.0.0:8000&amp;quot;&lt;br /&gt;
I0706 22:41:02.525792 1 http_server.cc:358] &amp;quot;Started Metrics Service at 0.0.0.0:8002&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
Установка выполняется из Docker Hub, следующей командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
* &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; — директория хост-машины, где будет храниться кеш весов модели (24gb)&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
После запуска vllm скачает веса модели для запуска (24gb). После завершения запуска и загрузки весов в логах можно наблюдать следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
(APIServer pid=1) INFO:     Started server process [1]&lt;br /&gt;
(APIServer pid=1) INFO:     Waiting for application startup.&lt;br /&gt;
(APIServer pid=1) INFO:     Application startup complete.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Как только они появятся, можно переходить к следующему шагу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080.&#039;&#039;&#039; Первый запрос к модели будет занимать достаточно много времени:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}],&lt;br /&gt;
    &amp;quot;chat_template_kwargs&amp;quot;: {&amp;quot;enable_thinking&amp;quot;: false}&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load -i lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights \&lt;br /&gt;
  python -m light_tts.server.api_server \&lt;br /&gt;
    --model_dir /opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
    --data_type float16 \&lt;br /&gt;
    --load_trt True \&lt;br /&gt;
    --host 0.0.0.0&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;После запуска сервис скомпилирует веса, по аналогии с T-One. После завершения подготовки в логах будут следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:391] ✅ Startup health check passed!&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:395] ✅ Application ready! Server is now accepting requests&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:396] 🌐 Listening at: http://localhost:8080&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — 10 &#039;&#039;&#039;GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 17000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 17001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Контейнеры сервисов инференса голосового робота.png|центр|безрамки|1067x1067пкс]]&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
&lt;br /&gt;
Необходимо переименовать файл example.env в .env и изменить в нём следующие параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&lt;br /&gt;
POSTGRES_HOST=[хост postgresql]&lt;br /&gt;
POSTGRES_PORT=5432&lt;br /&gt;
POSTGRES_USER=[логин postgresql]&lt;br /&gt;
POSTGRES_PASSWORD=[пароль postgresql]&lt;br /&gt;
POSTGRES_DB=[имя БД, если укзаанная БД отсутствует - она будет автоматически создана]&lt;br /&gt;
&lt;br /&gt;
CONCURRENT_SESSIONS=[Жесткое ограничение количества одновременных сессий]&lt;br /&gt;
&lt;br /&gt;
SIP_SERVER=[адрес Эры]&lt;br /&gt;
SIP_PORT=[порт SIP]&lt;br /&gt;
SIP_USERNAME=[Имя учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_PASSWORD=[Пароль учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_DOMAIN=[Полное имя домена, например robot.era-platform.ru]&lt;br /&gt;
#Детальные настройки SIP-клиента. В случае необходимости обхода NAT&lt;br /&gt;
SIP_TRANSPORT=udp&lt;br /&gt;
# NAT Traversal&lt;br /&gt;
SIP_STUN_SERVER=stun.l.google.com:19302&lt;br /&gt;
SIP_USE_ICE=false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
LLM_MODE=openai_api&lt;br /&gt;
#В случае использования сервиса инфереса vLLM на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LLM_OPENAI_API_BASE=http://localhost:16080/v1 &lt;br /&gt;
LLM_OPENAI_MODEL=qwen35-35b-a3b&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ASR_MODE=triton&lt;br /&gt;
#В случае использования сервиса инфереса tone-triton на другом хосте, необходимо изменить адреса/порты&lt;br /&gt;
ASR_TRITON_URL=http://localhost:17000&lt;br /&gt;
ASR_TRITON_GRPC=localhost:17001&lt;br /&gt;
ASR_TRITON_MODEL=streaming_acoustic&lt;br /&gt;
ASR_TRITON_TIMEOUT=10&lt;br /&gt;
ASR_DECODER_TYPE=beam_search&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
TTS_PROVIDER=lighttts&lt;br /&gt;
#В случае использования сервиса инфереса LightTTS на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LIGHTTTS_URL=http://localhost:8080/&lt;br /&gt;
LIGHTTTS_SAMPLE_RATE=24000&lt;br /&gt;
LIGHTTTS_STREAMING=false&lt;br /&gt;
LIGHTTTS_CONCURRENCY=4&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Плейсхолдер под подробное описание .env --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Запуск контейнера и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
docker load -i secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2435</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2435"/>
		<updated>2026-07-07T09:56:12Z</updated>

		<summary type="html">&lt;p&gt;AZykov: /* Общая информация */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Общая информация =&lt;br /&gt;
[[Файл:Архитектура голосового робота.png|центр|безрамки|763x763пкс]]&lt;br /&gt;
Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 1. Подготовка|Подготовка]]&#039;&#039;&#039; — Docker, PostgreSQL, настройки в системе телефонии.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 2. Установка сервисов инференса (опционально)|Установка сервисов инференса]]&#039;&#039;&#039; — ASR, LLM, TTS. &#039;&#039;Опционально, только для развёртывания на собственном сервере с GPU.&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 3. Настройка .env|Настройка .env]]&#039;&#039;&#039; — параметры подключения.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 4. Запуск контейнера и создание робота|Запуск контейнера и создание робота]]&#039;&#039;&#039; — старт сервиса и конфигурация робота.&lt;br /&gt;
&lt;br /&gt;
= Глоссарий =&lt;br /&gt;
&#039;&#039;&#039;Модель&#039;&#039;&#039; — обученная нейросеть, задающая соответствие между входом и выходом (текст -&amp;gt; текст, звук -&amp;gt; текст и т.д.). Модель определяется архитектурой и набором весов, полученных при обучении. В стеке робота их четыре:VAD (детекция голосовой активности), ASR (распознавание речи), LLM (генерация ответа), TTS (синтез речи).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Веса&#039;&#039;&#039; — числовые параметры модели, полученные при обучении. Именно они хранятся в файлах модели и загружаются в VRAM при старте. «Загрузка весов» в логах vLLM — это чтение этих файлов с диска в память GPU.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Инференс&#039;&#039;&#039; — использование готовой модели для получения ответа на новый вход («прогон» данных через веса). В отличие от обучения, веса не меняются. Сервисы инференса в статье — Triton, vLLM, LightTTS.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Triton&#039;&#039;&#039; (NVIDIA Triton Inference Server) — сервер инференса от NVIDIA, обслуживающий модели по gRPC и HTTP. В стеке на нём крутится ASR-модель T-one.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TensorRT&#039;&#039;&#039; — библиотека NVIDIA для оптимизации моделей под конкретный GPU: она компилирует модель в специализированный «движок» ради ускорения инференса. Сборка такого движка — разовая операция под железо, поэтому в LightTTS и T-One Triton она выполняется на первой фазе и коммитится в образ.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;vLLM&#039;&#039;&#039; — движок инференса для больших языковых моделей (LLM), оптимизированный на пропускную способность и эффективную работу с памятью. Предоставляет OpenAI-совместимый API.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;nvidia-smi&#039;&#039;&#039; (NVIDIA System Management Interface) — консольная утилита для просмотра состояния GPU: модель карты, версия драйвера, загрузка, потребление VRAM, запущенные процессы. Используется для проверки, что драйвер установлен и GPU виден (в т.ч. изнутри контейнера).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;KV-Cache&#039;&#039;&#039; (кэш ключей и значений) — память, где LLM хранит промежуточные представления уже обработанных токенов, чтобы не пересчитывать их при генерации каждого нового токена. Ускоряет генерацию ценой VRAM. В конфиге ограничен параметром &amp;lt;code&amp;gt;--kv-cache-memory&amp;lt;/code&amp;gt; (3 GiB). Растёт с числом сессий и длиной контекста — поэтому его размер критичен на картах с малым запасом VRAM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;LightTTS&#039;&#039;&#039; — движок инференса для TTS-моделей (синтеза речи). В стеке запускает модель CosyVoice3, слушает порт 8080.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Токен&#039;&#039;&#039; —В &#039;&#039;контексте LLM&#039;&#039; — единица текста, которой оперирует модель (примерно часть слова / слово / знак). Именно в токенах измеряются окно контекста и объём генерации.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Окно контекста&#039;&#039;&#039; — максимальное количество токенов, которое LLM может учитывать за один запрос (вход + генерируемый ответ вместе). Чем больше окно, тем больше VRAM уходит под KV-Cache, поэтому на картах с ограниченным объёмом его сокращают.&lt;br /&gt;
&lt;br /&gt;
= Требования к оборудованию, нагрузка и мастштабирование =&lt;br /&gt;
&lt;br /&gt;
=== Микросервисы робота и их нагрузка ===&lt;br /&gt;
правпыва&lt;br /&gt;
&lt;br /&gt;
=== Нюансы подбора GPU ===&lt;br /&gt;
паывпывапва&lt;br /&gt;
&lt;br /&gt;
=== Анизотропность нагрузки ===&lt;br /&gt;
пывпаывпыва&lt;br /&gt;
&lt;br /&gt;
=== Приблизительный расчет требуемых мощностей ===&lt;br /&gt;
паывпывапыв&lt;br /&gt;
&lt;br /&gt;
=== Масштабирование сервиса ===&lt;br /&gt;
авыфаывафыв&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
Установка самого Docker:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установка Nvidia Container Toolkit (только для серверов с GPU):&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# репозиторий&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \&lt;br /&gt;
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \&lt;br /&gt;
  sed &#039;s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g&#039; | \&lt;br /&gt;
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-container-toolkit&lt;br /&gt;
sudo nvidia-ctk runtime configure --runtime=docker&lt;br /&gt;
sudo systemctl restart docker&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (опционально) =&lt;br /&gt;
&lt;br /&gt;
Инструкция для &#039;&#039;&#039;Ubuntu Server 24.04&#039;&#039;&#039;. Стек: ASR (T-one/Triton) → LLM (Qwen3.5-35B-A3B на vLLM) → TTS (LightTTS + CosyVoice3).&lt;br /&gt;
&lt;br /&gt;
Целевая машина — сервер с GPU: &#039;&#039;&#039;RTX PRO 5000 (48GB)&#039;&#039;&#039; или &#039;&#039;&#039;RTX PRO 6000 Blackwell (96GB)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
=== Бюджет VRAM ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Компонент !! VRAM&lt;br /&gt;
|-&lt;br /&gt;
| ASR (T-one/Triton) || 600–800 MB&lt;br /&gt;
|-&lt;br /&gt;
| LLM (Qwen3.5-35B-A3B) || 24–48 GB (зависит от числа сессий и длины контекста)&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS/CosyVoice3) || 10 GB&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Суммарное потребление в пике — ~36–60 GB.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 6000 (96GB):&#039;&#039;&#039; объёма достаточно с большим запасом. Допустимо использование максимального числа сессий и длинного контекста.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 5000 (48GB):&#039;&#039;&#039; запас минимальный. Фиксированная сумма ASR (~0.8 GB) и TTS (11 GB) составляет ~12 GB, на LLM остаётся ~36 GB. Это покрывает только нижнюю границу диапазона LLM (24 GB). Требуется ограничение параметров &amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt; во избежание ошибки OOM. Значение &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; (~24 GB на карте 48GB) для данного сценария допустимо при условии, что ASR и TTS инициализированы до старта LLM.&lt;br /&gt;
&lt;br /&gt;
Объем оперативной памяти не может быть меньше, чем VRAM, так как в процессе запуска веса моделей помещаются сначала в оперативную память, и только затем в VRAM.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Компиляция моделей может занимать больше VRAM, чем запущенный сервис, поэтому в случае дефицита видеопамяти, рекомендуется временно отключать свеже созданные контейнеры, собирать их по одному, после чего запускать по очереди уже в собранном виде.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton Inference Server) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
I0706 22:41:02.484518 1 grpc_server.cc:2562] &amp;quot;Started GRPCInferenceService at 0.0.0.0:8001&amp;quot;&lt;br /&gt;
I0706 22:41:02.484664 1 http_server.cc:4832] &amp;quot;Started HTTPService at 0.0.0.0:8000&amp;quot;&lt;br /&gt;
I0706 22:41:02.525792 1 http_server.cc:358] &amp;quot;Started Metrics Service at 0.0.0.0:8002&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
Установка выполняется из Docker Hub, следующей командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
* &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; — директория хост-машины, где будет храниться кеш весов модели (24gb)&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
После запуска vllm скачает веса модели для запуска (24gb). После завершения запуска и загрузки весов в логах можно наблюдать следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
(APIServer pid=1) INFO:     Started server process [1]&lt;br /&gt;
(APIServer pid=1) INFO:     Waiting for application startup.&lt;br /&gt;
(APIServer pid=1) INFO:     Application startup complete.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Как только они появятся, можно переходить к следующему шагу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080.&#039;&#039;&#039; Первый запрос к модели будет занимать достаточно много времени:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}],&lt;br /&gt;
    &amp;quot;chat_template_kwargs&amp;quot;: {&amp;quot;enable_thinking&amp;quot;: false}&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load -i lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights \&lt;br /&gt;
  python -m light_tts.server.api_server \&lt;br /&gt;
    --model_dir /opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
    --data_type float16 \&lt;br /&gt;
    --load_trt True \&lt;br /&gt;
    --host 0.0.0.0&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;После запуска сервис скомпилирует веса, по аналогии с T-One. После завершения подготовки в логах будут следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:391] ✅ Startup health check passed!&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:395] ✅ Application ready! Server is now accepting requests&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:396] 🌐 Listening at: http://localhost:8080&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — 10 &#039;&#039;&#039;GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 17000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 17001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Контейнеры сервисов инференса голосового робота.png|центр|безрамки|1067x1067пкс]]&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
&lt;br /&gt;
Необходимо переименовать файл example.env в .env и изменить в нём следующие параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&lt;br /&gt;
POSTGRES_HOST=[хост postgresql]&lt;br /&gt;
POSTGRES_PORT=5432&lt;br /&gt;
POSTGRES_USER=[логин postgresql]&lt;br /&gt;
POSTGRES_PASSWORD=[пароль postgresql]&lt;br /&gt;
POSTGRES_DB=[имя БД, если укзаанная БД отсутствует - она будет автоматически создана]&lt;br /&gt;
&lt;br /&gt;
CONCURRENT_SESSIONS=[Жесткое ограничение количества одновременных сессий]&lt;br /&gt;
&lt;br /&gt;
SIP_SERVER=[адрес Эры]&lt;br /&gt;
SIP_PORT=[порт SIP]&lt;br /&gt;
SIP_USERNAME=[Имя учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_PASSWORD=[Пароль учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_DOMAIN=[Полное имя домена, например robot.era-platform.ru]&lt;br /&gt;
#Детальные настройки SIP-клиента. В случае необходимости обхода NAT&lt;br /&gt;
SIP_TRANSPORT=udp&lt;br /&gt;
# NAT Traversal&lt;br /&gt;
SIP_STUN_SERVER=stun.l.google.com:19302&lt;br /&gt;
SIP_USE_ICE=false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
LLM_MODE=openai_api&lt;br /&gt;
#В случае использования сервиса инфереса vLLM на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LLM_OPENAI_API_BASE=http://localhost:16080/v1 &lt;br /&gt;
LLM_OPENAI_MODEL=qwen35-35b-a3b&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ASR_MODE=triton&lt;br /&gt;
#В случае использования сервиса инфереса tone-triton на другом хосте, необходимо изменить адреса/порты&lt;br /&gt;
ASR_TRITON_URL=http://localhost:17000&lt;br /&gt;
ASR_TRITON_GRPC=localhost:17001&lt;br /&gt;
ASR_TRITON_MODEL=streaming_acoustic&lt;br /&gt;
ASR_TRITON_TIMEOUT=10&lt;br /&gt;
ASR_DECODER_TYPE=beam_search&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
TTS_PROVIDER=lighttts&lt;br /&gt;
#В случае использования сервиса инфереса LightTTS на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LIGHTTTS_URL=http://localhost:8080/&lt;br /&gt;
LIGHTTTS_SAMPLE_RATE=24000&lt;br /&gt;
LIGHTTTS_STREAMING=false&lt;br /&gt;
LIGHTTTS_CONCURRENCY=4&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Плейсхолдер под подробное описание .env --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Запуск контейнера и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
docker load -i secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2434</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2434"/>
		<updated>2026-07-06T23:53:51Z</updated>

		<summary type="html">&lt;p&gt;AZykov: /* Установка и настройка голосового робота Эра */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Общая информация =&lt;br /&gt;
[[Файл:Архитектура голосового робота.png|центр|безрамки|763x763пкс]]&lt;br /&gt;
Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 1. Подготовка|Подготовка]]&#039;&#039;&#039; — Docker, PostgreSQL, настройки в системе телефонии.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 2. Установка сервисов инференса (опционально)|Установка сервисов инференса]]&#039;&#039;&#039; — ASR, LLM, TTS. &#039;&#039;Опционально, только для развёртывания на собственном сервере с GPU.&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 3. Настройка .env|Настройка .env]]&#039;&#039;&#039; — параметры подключения.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 4. Запуск контейнера и создание робота|Запуск контейнера и создание робота]]&#039;&#039;&#039; — старт сервиса и конфигурация робота.&lt;br /&gt;
&lt;br /&gt;
= Глоссарий =&lt;br /&gt;
&#039;&#039;&#039;Модель&#039;&#039;&#039; — обученная нейросеть, задающая соответствие между входом и выходом (текст -&amp;gt; текст, звук -&amp;gt; текст и т.д.). Модель определяется архитектурой и набором весов, полученных при обучении. В стеке робота их четыре:VAD (детекция голосовой активности), ASR (распознавание речи), LLM (генерация ответа), TTS (синтез речи).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Веса&#039;&#039;&#039; — числовые параметры модели, полученные при обучении. Именно они хранятся в файлах модели и загружаются в VRAM при старте. «Загрузка весов» в логах vLLM — это чтение этих файлов с диска в память GPU.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Инференс&#039;&#039;&#039; — использование готовой модели для получения ответа на новый вход («прогон» данных через веса). В отличие от обучения, веса не меняются. Сервисы инференса в статье — Triton, vLLM, LightTTS.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Triton&#039;&#039;&#039; (NVIDIA Triton Inference Server) — сервер инференса от NVIDIA, обслуживающий модели по gRPC и HTTP. В стеке на нём крутится ASR-модель T-one.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TensorRT&#039;&#039;&#039; — библиотека NVIDIA для оптимизации моделей под конкретный GPU: она компилирует модель в специализированный «движок» ради ускорения инференса. Сборка такого движка — разовая операция под железо, поэтому в LightTTS и T-One Triton она выполняется на первой фазе и коммитится в образ.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;vLLM&#039;&#039;&#039; — движок инференса для больших языковых моделей (LLM), оптимизированный на пропускную способность и эффективную работу с памятью. Предоставляет OpenAI-совместимый API.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;nvidia-smi&#039;&#039;&#039; (NVIDIA System Management Interface) — консольная утилита для просмотра состояния GPU: модель карты, версия драйвера, загрузка, потребление VRAM, запущенные процессы. Используется для проверки, что драйвер установлен и GPU виден (в т.ч. изнутри контейнера).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;KV-Cache&#039;&#039;&#039; (кэш ключей и значений) — память, где LLM хранит промежуточные представления уже обработанных токенов, чтобы не пересчитывать их при генерации каждого нового токена. Ускоряет генерацию ценой VRAM. В конфиге ограничен параметром &amp;lt;code&amp;gt;--kv-cache-memory&amp;lt;/code&amp;gt; (3 GiB). Растёт с числом сессий и длиной контекста — поэтому его размер критичен на картах с малым запасом VRAM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;LightTTS&#039;&#039;&#039; — движок инференса для TTS-моделей (синтеза речи). В стеке запускает модель CosyVoice3, слушает порт 8080.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Токен&#039;&#039;&#039; —В &#039;&#039;контексте LLM&#039;&#039; — единица текста, которой оперирует модель (примерно часть слова / слово / знак). Именно в токенах измеряются окно контекста и объём генерации.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Окно контекста&#039;&#039;&#039; — максимальное количество токенов, которое LLM может учитывать за один запрос (вход + генерируемый ответ вместе). Чем больше окно, тем больше VRAM уходит под KV-Cache, поэтому на картах с ограниченным объёмом его сокращают.&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
Установка самого Docker:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установка Nvidia Container Toolkit (только для серверов с GPU):&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# репозиторий&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \&lt;br /&gt;
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \&lt;br /&gt;
  sed &#039;s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g&#039; | \&lt;br /&gt;
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-container-toolkit&lt;br /&gt;
sudo nvidia-ctk runtime configure --runtime=docker&lt;br /&gt;
sudo systemctl restart docker&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (опционально) =&lt;br /&gt;
&lt;br /&gt;
Инструкция для &#039;&#039;&#039;Ubuntu Server 24.04&#039;&#039;&#039;. Стек: ASR (T-one/Triton) → LLM (Qwen3.5-35B-A3B на vLLM) → TTS (LightTTS + CosyVoice3).&lt;br /&gt;
&lt;br /&gt;
Целевая машина — сервер с GPU: &#039;&#039;&#039;RTX PRO 5000 (48GB)&#039;&#039;&#039; или &#039;&#039;&#039;RTX PRO 6000 Blackwell (96GB)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
=== Бюджет VRAM ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Компонент !! VRAM&lt;br /&gt;
|-&lt;br /&gt;
| ASR (T-one/Triton) || 600–800 MB&lt;br /&gt;
|-&lt;br /&gt;
| LLM (Qwen3.5-35B-A3B) || 24–48 GB (зависит от числа сессий и длины контекста)&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS/CosyVoice3) || 10 GB&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Суммарное потребление в пике — ~36–60 GB.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 6000 (96GB):&#039;&#039;&#039; объёма достаточно с большим запасом. Допустимо использование максимального числа сессий и длинного контекста.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 5000 (48GB):&#039;&#039;&#039; запас минимальный. Фиксированная сумма ASR (~0.8 GB) и TTS (11 GB) составляет ~12 GB, на LLM остаётся ~36 GB. Это покрывает только нижнюю границу диапазона LLM (24 GB). Требуется ограничение параметров &amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt; во избежание ошибки OOM. Значение &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; (~24 GB на карте 48GB) для данного сценария допустимо при условии, что ASR и TTS инициализированы до старта LLM.&lt;br /&gt;
&lt;br /&gt;
Объем оперативной памяти не может быть меньше, чем VRAM, так как в процессе запуска веса моделей помещаются сначала в оперативную память, и только затем в VRAM.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Компиляция моделей может занимать больше VRAM, чем запущенный сервис, поэтому в случае дефицита видеопамяти, рекомендуется временно отключать свеже созданные контейнеры, собирать их по одному, после чего запускать по очереди уже в собранном виде.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton Inference Server) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
I0706 22:41:02.484518 1 grpc_server.cc:2562] &amp;quot;Started GRPCInferenceService at 0.0.0.0:8001&amp;quot;&lt;br /&gt;
I0706 22:41:02.484664 1 http_server.cc:4832] &amp;quot;Started HTTPService at 0.0.0.0:8000&amp;quot;&lt;br /&gt;
I0706 22:41:02.525792 1 http_server.cc:358] &amp;quot;Started Metrics Service at 0.0.0.0:8002&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
Установка выполняется из Docker Hub, следующей командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
* &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; — директория хост-машины, где будет храниться кеш весов модели (24gb)&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
После запуска vllm скачает веса модели для запуска (24gb). После завершения запуска и загрузки весов в логах можно наблюдать следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
(APIServer pid=1) INFO:     Started server process [1]&lt;br /&gt;
(APIServer pid=1) INFO:     Waiting for application startup.&lt;br /&gt;
(APIServer pid=1) INFO:     Application startup complete.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Как только они появятся, можно переходить к следующему шагу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080.&#039;&#039;&#039; Первый запрос к модели будет занимать достаточно много времени:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}],&lt;br /&gt;
    &amp;quot;chat_template_kwargs&amp;quot;: {&amp;quot;enable_thinking&amp;quot;: false}&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load -i lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights \&lt;br /&gt;
  python -m light_tts.server.api_server \&lt;br /&gt;
    --model_dir /opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
    --data_type float16 \&lt;br /&gt;
    --load_trt True \&lt;br /&gt;
    --host 0.0.0.0&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;После запуска сервис скомпилирует веса, по аналогии с T-One. После завершения подготовки в логах будут следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:391] ✅ Startup health check passed!&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:395] ✅ Application ready! Server is now accepting requests&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:396] 🌐 Listening at: http://localhost:8080&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — 10 &#039;&#039;&#039;GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 17000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 17001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Контейнеры сервисов инференса голосового робота.png|центр|безрамки|1067x1067пкс]]&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
&lt;br /&gt;
Необходимо переименовать файл example.env в .env и изменить в нём следующие параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&lt;br /&gt;
POSTGRES_HOST=[хост postgresql]&lt;br /&gt;
POSTGRES_PORT=5432&lt;br /&gt;
POSTGRES_USER=[логин postgresql]&lt;br /&gt;
POSTGRES_PASSWORD=[пароль postgresql]&lt;br /&gt;
POSTGRES_DB=[имя БД, если укзаанная БД отсутствует - она будет автоматически создана]&lt;br /&gt;
&lt;br /&gt;
CONCURRENT_SESSIONS=[Жесткое ограничение количества одновременных сессий]&lt;br /&gt;
&lt;br /&gt;
SIP_SERVER=[адрес Эры]&lt;br /&gt;
SIP_PORT=[порт SIP]&lt;br /&gt;
SIP_USERNAME=[Имя учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_PASSWORD=[Пароль учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_DOMAIN=[Полное имя домена, например robot.era-platform.ru]&lt;br /&gt;
#Детальные настройки SIP-клиента. В случае необходимости обхода NAT&lt;br /&gt;
SIP_TRANSPORT=udp&lt;br /&gt;
# NAT Traversal&lt;br /&gt;
SIP_STUN_SERVER=stun.l.google.com:19302&lt;br /&gt;
SIP_USE_ICE=false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
LLM_MODE=openai_api&lt;br /&gt;
#В случае использования сервиса инфереса vLLM на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LLM_OPENAI_API_BASE=http://localhost:16080/v1 &lt;br /&gt;
LLM_OPENAI_MODEL=qwen35-35b-a3b&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ASR_MODE=triton&lt;br /&gt;
#В случае использования сервиса инфереса tone-triton на другом хосте, необходимо изменить адреса/порты&lt;br /&gt;
ASR_TRITON_URL=http://localhost:17000&lt;br /&gt;
ASR_TRITON_GRPC=localhost:17001&lt;br /&gt;
ASR_TRITON_MODEL=streaming_acoustic&lt;br /&gt;
ASR_TRITON_TIMEOUT=10&lt;br /&gt;
ASR_DECODER_TYPE=beam_search&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
TTS_PROVIDER=lighttts&lt;br /&gt;
#В случае использования сервиса инфереса LightTTS на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LIGHTTTS_URL=http://localhost:8080/&lt;br /&gt;
LIGHTTTS_SAMPLE_RATE=24000&lt;br /&gt;
LIGHTTTS_STREAMING=false&lt;br /&gt;
LIGHTTTS_CONCURRENCY=4&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Плейсхолдер под подробное описание .env --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Запуск контейнера и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
docker load -i secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2433</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2433"/>
		<updated>2026-07-06T23:52:22Z</updated>

		<summary type="html">&lt;p&gt;AZykov: /* 2.6. Итоговая карта портов */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Установка и настройка голосового робота Эра =&lt;br /&gt;
[[Файл:Архитектура голосового робота.png|центр|безрамки|763x763пкс]]&lt;br /&gt;
Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 1. Подготовка|Подготовка]]&#039;&#039;&#039; — Docker, PostgreSQL, настройки в системе телефонии.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 2. Установка сервисов инференса (опционально)|Установка сервисов инференса]]&#039;&#039;&#039; — ASR, LLM, TTS. &#039;&#039;Опционально, только для развёртывания на собственном сервере с GPU.&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 3. Настройка .env|Настройка .env]]&#039;&#039;&#039; — параметры подключения.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 4. Запуск контейнера и создание робота|Запуск контейнера и создание робота]]&#039;&#039;&#039; — старт сервиса и конфигурация робота.&lt;br /&gt;
&lt;br /&gt;
= Глоссарий =&lt;br /&gt;
&#039;&#039;&#039;Модель&#039;&#039;&#039; — обученная нейросеть, задающая соответствие между входом и выходом (текст -&amp;gt; текст, звук -&amp;gt; текст и т.д.). Модель определяется архитектурой и набором весов, полученных при обучении. В стеке робота их четыре:VAD (детекция голосовой активности), ASR (распознавание речи), LLM (генерация ответа), TTS (синтез речи).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Веса&#039;&#039;&#039; — числовые параметры модели, полученные при обучении. Именно они хранятся в файлах модели и загружаются в VRAM при старте. «Загрузка весов» в логах vLLM — это чтение этих файлов с диска в память GPU.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Инференс&#039;&#039;&#039; — использование готовой модели для получения ответа на новый вход («прогон» данных через веса). В отличие от обучения, веса не меняются. Сервисы инференса в статье — Triton, vLLM, LightTTS.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Triton&#039;&#039;&#039; (NVIDIA Triton Inference Server) — сервер инференса от NVIDIA, обслуживающий модели по gRPC и HTTP. В стеке на нём крутится ASR-модель T-one.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TensorRT&#039;&#039;&#039; — библиотека NVIDIA для оптимизации моделей под конкретный GPU: она компилирует модель в специализированный «движок» ради ускорения инференса. Сборка такого движка — разовая операция под железо, поэтому в LightTTS и T-One Triton она выполняется на первой фазе и коммитится в образ.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;vLLM&#039;&#039;&#039; — движок инференса для больших языковых моделей (LLM), оптимизированный на пропускную способность и эффективную работу с памятью. Предоставляет OpenAI-совместимый API.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;nvidia-smi&#039;&#039;&#039; (NVIDIA System Management Interface) — консольная утилита для просмотра состояния GPU: модель карты, версия драйвера, загрузка, потребление VRAM, запущенные процессы. Используется для проверки, что драйвер установлен и GPU виден (в т.ч. изнутри контейнера).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;KV-Cache&#039;&#039;&#039; (кэш ключей и значений) — память, где LLM хранит промежуточные представления уже обработанных токенов, чтобы не пересчитывать их при генерации каждого нового токена. Ускоряет генерацию ценой VRAM. В конфиге ограничен параметром &amp;lt;code&amp;gt;--kv-cache-memory&amp;lt;/code&amp;gt; (3 GiB). Растёт с числом сессий и длиной контекста — поэтому его размер критичен на картах с малым запасом VRAM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;LightTTS&#039;&#039;&#039; — движок инференса для TTS-моделей (синтеза речи). В стеке запускает модель CosyVoice3, слушает порт 8080.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Токен&#039;&#039;&#039; —В &#039;&#039;контексте LLM&#039;&#039; — единица текста, которой оперирует модель (примерно часть слова / слово / знак). Именно в токенах измеряются окно контекста и объём генерации.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Окно контекста&#039;&#039;&#039; — максимальное количество токенов, которое LLM может учитывать за один запрос (вход + генерируемый ответ вместе). Чем больше окно, тем больше VRAM уходит под KV-Cache, поэтому на картах с ограниченным объёмом его сокращают.&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
Установка самого Docker:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установка Nvidia Container Toolkit (только для серверов с GPU):&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# репозиторий&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \&lt;br /&gt;
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \&lt;br /&gt;
  sed &#039;s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g&#039; | \&lt;br /&gt;
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-container-toolkit&lt;br /&gt;
sudo nvidia-ctk runtime configure --runtime=docker&lt;br /&gt;
sudo systemctl restart docker&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (опционально) =&lt;br /&gt;
&lt;br /&gt;
Инструкция для &#039;&#039;&#039;Ubuntu Server 24.04&#039;&#039;&#039;. Стек: ASR (T-one/Triton) → LLM (Qwen3.5-35B-A3B на vLLM) → TTS (LightTTS + CosyVoice3).&lt;br /&gt;
&lt;br /&gt;
Целевая машина — сервер с GPU: &#039;&#039;&#039;RTX PRO 5000 (48GB)&#039;&#039;&#039; или &#039;&#039;&#039;RTX PRO 6000 Blackwell (96GB)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
=== Бюджет VRAM ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Компонент !! VRAM&lt;br /&gt;
|-&lt;br /&gt;
| ASR (T-one/Triton) || 600–800 MB&lt;br /&gt;
|-&lt;br /&gt;
| LLM (Qwen3.5-35B-A3B) || 24–48 GB (зависит от числа сессий и длины контекста)&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS/CosyVoice3) || 10 GB&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Суммарное потребление в пике — ~36–60 GB.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 6000 (96GB):&#039;&#039;&#039; объёма достаточно с большим запасом. Допустимо использование максимального числа сессий и длинного контекста.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 5000 (48GB):&#039;&#039;&#039; запас минимальный. Фиксированная сумма ASR (~0.8 GB) и TTS (11 GB) составляет ~12 GB, на LLM остаётся ~36 GB. Это покрывает только нижнюю границу диапазона LLM (24 GB). Требуется ограничение параметров &amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt; во избежание ошибки OOM. Значение &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; (~24 GB на карте 48GB) для данного сценария допустимо при условии, что ASR и TTS инициализированы до старта LLM.&lt;br /&gt;
&lt;br /&gt;
Объем оперативной памяти не может быть меньше, чем VRAM, так как в процессе запуска веса моделей помещаются сначала в оперативную память, и только затем в VRAM.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Компиляция моделей может занимать больше VRAM, чем запущенный сервис, поэтому в случае дефицита видеопамяти, рекомендуется временно отключать свеже созданные контейнеры, собирать их по одному, после чего запускать по очереди уже в собранном виде.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton Inference Server) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
I0706 22:41:02.484518 1 grpc_server.cc:2562] &amp;quot;Started GRPCInferenceService at 0.0.0.0:8001&amp;quot;&lt;br /&gt;
I0706 22:41:02.484664 1 http_server.cc:4832] &amp;quot;Started HTTPService at 0.0.0.0:8000&amp;quot;&lt;br /&gt;
I0706 22:41:02.525792 1 http_server.cc:358] &amp;quot;Started Metrics Service at 0.0.0.0:8002&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
Установка выполняется из Docker Hub, следующей командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
* &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; — директория хост-машины, где будет храниться кеш весов модели (24gb)&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
После запуска vllm скачает веса модели для запуска (24gb). После завершения запуска и загрузки весов в логах можно наблюдать следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
(APIServer pid=1) INFO:     Started server process [1]&lt;br /&gt;
(APIServer pid=1) INFO:     Waiting for application startup.&lt;br /&gt;
(APIServer pid=1) INFO:     Application startup complete.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Как только они появятся, можно переходить к следующему шагу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080.&#039;&#039;&#039; Первый запрос к модели будет занимать достаточно много времени:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}],&lt;br /&gt;
    &amp;quot;chat_template_kwargs&amp;quot;: {&amp;quot;enable_thinking&amp;quot;: false}&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load -i lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights \&lt;br /&gt;
  python -m light_tts.server.api_server \&lt;br /&gt;
    --model_dir /opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
    --data_type float16 \&lt;br /&gt;
    --load_trt True \&lt;br /&gt;
    --host 0.0.0.0&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;После запуска сервис скомпилирует веса, по аналогии с T-One. После завершения подготовки в логах будут следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:391] ✅ Startup health check passed!&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:395] ✅ Application ready! Server is now accepting requests&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:396] 🌐 Listening at: http://localhost:8080&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — 10 &#039;&#039;&#039;GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 17000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 17001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Контейнеры сервисов инференса голосового робота.png|центр|безрамки|1067x1067пкс]]&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
&lt;br /&gt;
Необходимо переименовать файл example.env в .env и изменить в нём следующие параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&lt;br /&gt;
POSTGRES_HOST=[хост postgresql]&lt;br /&gt;
POSTGRES_PORT=5432&lt;br /&gt;
POSTGRES_USER=[логин postgresql]&lt;br /&gt;
POSTGRES_PASSWORD=[пароль postgresql]&lt;br /&gt;
POSTGRES_DB=[имя БД, если укзаанная БД отсутствует - она будет автоматически создана]&lt;br /&gt;
&lt;br /&gt;
CONCURRENT_SESSIONS=[Жесткое ограничение количества одновременных сессий]&lt;br /&gt;
&lt;br /&gt;
SIP_SERVER=[адрес Эры]&lt;br /&gt;
SIP_PORT=[порт SIP]&lt;br /&gt;
SIP_USERNAME=[Имя учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_PASSWORD=[Пароль учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_DOMAIN=[Полное имя домена, например robot.era-platform.ru]&lt;br /&gt;
#Детальные настройки SIP-клиента. В случае необходимости обхода NAT&lt;br /&gt;
SIP_TRANSPORT=udp&lt;br /&gt;
# NAT Traversal&lt;br /&gt;
SIP_STUN_SERVER=stun.l.google.com:19302&lt;br /&gt;
SIP_USE_ICE=false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
LLM_MODE=openai_api&lt;br /&gt;
#В случае использования сервиса инфереса vLLM на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LLM_OPENAI_API_BASE=http://localhost:16080/v1 &lt;br /&gt;
LLM_OPENAI_MODEL=qwen35-35b-a3b&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ASR_MODE=triton&lt;br /&gt;
#В случае использования сервиса инфереса tone-triton на другом хосте, необходимо изменить адреса/порты&lt;br /&gt;
ASR_TRITON_URL=http://localhost:17000&lt;br /&gt;
ASR_TRITON_GRPC=localhost:17001&lt;br /&gt;
ASR_TRITON_MODEL=streaming_acoustic&lt;br /&gt;
ASR_TRITON_TIMEOUT=10&lt;br /&gt;
ASR_DECODER_TYPE=beam_search&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
TTS_PROVIDER=lighttts&lt;br /&gt;
#В случае использования сервиса инфереса LightTTS на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LIGHTTTS_URL=http://localhost:8080/&lt;br /&gt;
LIGHTTTS_SAMPLE_RATE=24000&lt;br /&gt;
LIGHTTTS_STREAMING=false&lt;br /&gt;
LIGHTTTS_CONCURRENCY=4&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Плейсхолдер под подробное описание .env --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Запуск контейнера и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
docker load -i secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2432</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2432"/>
		<updated>2026-07-06T23:51:08Z</updated>

		<summary type="html">&lt;p&gt;AZykov: /* Установка и настройка голосового робота Эра (SecondChain) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Установка и настройка голосового робота Эра =&lt;br /&gt;
[[Файл:Архитектура голосового робота.png|центр|безрамки|763x763пкс]]&lt;br /&gt;
Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 1. Подготовка|Подготовка]]&#039;&#039;&#039; — Docker, PostgreSQL, настройки в системе телефонии.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 2. Установка сервисов инференса (опционально)|Установка сервисов инференса]]&#039;&#039;&#039; — ASR, LLM, TTS. &#039;&#039;Опционально, только для развёртывания на собственном сервере с GPU.&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 3. Настройка .env|Настройка .env]]&#039;&#039;&#039; — параметры подключения.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 4. Запуск контейнера и создание робота|Запуск контейнера и создание робота]]&#039;&#039;&#039; — старт сервиса и конфигурация робота.&lt;br /&gt;
&lt;br /&gt;
= Глоссарий =&lt;br /&gt;
&#039;&#039;&#039;Модель&#039;&#039;&#039; — обученная нейросеть, задающая соответствие между входом и выходом (текст -&amp;gt; текст, звук -&amp;gt; текст и т.д.). Модель определяется архитектурой и набором весов, полученных при обучении. В стеке робота их четыре:VAD (детекция голосовой активности), ASR (распознавание речи), LLM (генерация ответа), TTS (синтез речи).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Веса&#039;&#039;&#039; — числовые параметры модели, полученные при обучении. Именно они хранятся в файлах модели и загружаются в VRAM при старте. «Загрузка весов» в логах vLLM — это чтение этих файлов с диска в память GPU.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Инференс&#039;&#039;&#039; — использование готовой модели для получения ответа на новый вход («прогон» данных через веса). В отличие от обучения, веса не меняются. Сервисы инференса в статье — Triton, vLLM, LightTTS.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Triton&#039;&#039;&#039; (NVIDIA Triton Inference Server) — сервер инференса от NVIDIA, обслуживающий модели по gRPC и HTTP. В стеке на нём крутится ASR-модель T-one.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TensorRT&#039;&#039;&#039; — библиотека NVIDIA для оптимизации моделей под конкретный GPU: она компилирует модель в специализированный «движок» ради ускорения инференса. Сборка такого движка — разовая операция под железо, поэтому в LightTTS и T-One Triton она выполняется на первой фазе и коммитится в образ.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;vLLM&#039;&#039;&#039; — движок инференса для больших языковых моделей (LLM), оптимизированный на пропускную способность и эффективную работу с памятью. Предоставляет OpenAI-совместимый API.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;nvidia-smi&#039;&#039;&#039; (NVIDIA System Management Interface) — консольная утилита для просмотра состояния GPU: модель карты, версия драйвера, загрузка, потребление VRAM, запущенные процессы. Используется для проверки, что драйвер установлен и GPU виден (в т.ч. изнутри контейнера).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;KV-Cache&#039;&#039;&#039; (кэш ключей и значений) — память, где LLM хранит промежуточные представления уже обработанных токенов, чтобы не пересчитывать их при генерации каждого нового токена. Ускоряет генерацию ценой VRAM. В конфиге ограничен параметром &amp;lt;code&amp;gt;--kv-cache-memory&amp;lt;/code&amp;gt; (3 GiB). Растёт с числом сессий и длиной контекста — поэтому его размер критичен на картах с малым запасом VRAM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;LightTTS&#039;&#039;&#039; — движок инференса для TTS-моделей (синтеза речи). В стеке запускает модель CosyVoice3, слушает порт 8080.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Токен&#039;&#039;&#039; —В &#039;&#039;контексте LLM&#039;&#039; — единица текста, которой оперирует модель (примерно часть слова / слово / знак). Именно в токенах измеряются окно контекста и объём генерации.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Окно контекста&#039;&#039;&#039; — максимальное количество токенов, которое LLM может учитывать за один запрос (вход + генерируемый ответ вместе). Чем больше окно, тем больше VRAM уходит под KV-Cache, поэтому на картах с ограниченным объёмом его сокращают.&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
Установка самого Docker:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установка Nvidia Container Toolkit (только для серверов с GPU):&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# репозиторий&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \&lt;br /&gt;
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \&lt;br /&gt;
  sed &#039;s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g&#039; | \&lt;br /&gt;
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-container-toolkit&lt;br /&gt;
sudo nvidia-ctk runtime configure --runtime=docker&lt;br /&gt;
sudo systemctl restart docker&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (опционально) =&lt;br /&gt;
&lt;br /&gt;
Инструкция для &#039;&#039;&#039;Ubuntu Server 24.04&#039;&#039;&#039;. Стек: ASR (T-one/Triton) → LLM (Qwen3.5-35B-A3B на vLLM) → TTS (LightTTS + CosyVoice3).&lt;br /&gt;
&lt;br /&gt;
Целевая машина — сервер с GPU: &#039;&#039;&#039;RTX PRO 5000 (48GB)&#039;&#039;&#039; или &#039;&#039;&#039;RTX PRO 6000 Blackwell (96GB)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
=== Бюджет VRAM ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Компонент !! VRAM&lt;br /&gt;
|-&lt;br /&gt;
| ASR (T-one/Triton) || 600–800 MB&lt;br /&gt;
|-&lt;br /&gt;
| LLM (Qwen3.5-35B-A3B) || 24–48 GB (зависит от числа сессий и длины контекста)&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS/CosyVoice3) || 10 GB&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Суммарное потребление в пике — ~36–60 GB.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 6000 (96GB):&#039;&#039;&#039; объёма достаточно с большим запасом. Допустимо использование максимального числа сессий и длинного контекста.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 5000 (48GB):&#039;&#039;&#039; запас минимальный. Фиксированная сумма ASR (~0.8 GB) и TTS (11 GB) составляет ~12 GB, на LLM остаётся ~36 GB. Это покрывает только нижнюю границу диапазона LLM (24 GB). Требуется ограничение параметров &amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt; во избежание ошибки OOM. Значение &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; (~24 GB на карте 48GB) для данного сценария допустимо при условии, что ASR и TTS инициализированы до старта LLM.&lt;br /&gt;
&lt;br /&gt;
Объем оперативной памяти не может быть меньше, чем VRAM, так как в процессе запуска веса моделей помещаются сначала в оперативную память, и только затем в VRAM.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Компиляция моделей может занимать больше VRAM, чем запущенный сервис, поэтому в случае дефицита видеопамяти, рекомендуется временно отключать свеже созданные контейнеры, собирать их по одному, после чего запускать по очереди уже в собранном виде.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton Inference Server) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
I0706 22:41:02.484518 1 grpc_server.cc:2562] &amp;quot;Started GRPCInferenceService at 0.0.0.0:8001&amp;quot;&lt;br /&gt;
I0706 22:41:02.484664 1 http_server.cc:4832] &amp;quot;Started HTTPService at 0.0.0.0:8000&amp;quot;&lt;br /&gt;
I0706 22:41:02.525792 1 http_server.cc:358] &amp;quot;Started Metrics Service at 0.0.0.0:8002&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
Установка выполняется из Docker Hub, следующей командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
* &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; — директория хост-машины, где будет храниться кеш весов модели (24gb)&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
После запуска vllm скачает веса модели для запуска (24gb). После завершения запуска и загрузки весов в логах можно наблюдать следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
(APIServer pid=1) INFO:     Started server process [1]&lt;br /&gt;
(APIServer pid=1) INFO:     Waiting for application startup.&lt;br /&gt;
(APIServer pid=1) INFO:     Application startup complete.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Как только они появятся, можно переходить к следующему шагу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080.&#039;&#039;&#039; Первый запрос к модели будет занимать достаточно много времени:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}],&lt;br /&gt;
    &amp;quot;chat_template_kwargs&amp;quot;: {&amp;quot;enable_thinking&amp;quot;: false}&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load -i lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights \&lt;br /&gt;
  python -m light_tts.server.api_server \&lt;br /&gt;
    --model_dir /opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
    --data_type float16 \&lt;br /&gt;
    --load_trt True \&lt;br /&gt;
    --host 0.0.0.0&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;После запуска сервис скомпилирует веса, по аналогии с T-One. После завершения подготовки в логах будут следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:391] ✅ Startup health check passed!&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:395] ✅ Application ready! Server is now accepting requests&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:396] 🌐 Listening at: http://localhost:8080&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — 10 &#039;&#039;&#039;GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 8000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 8001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Контейнеры сервисов инференса голосового робота.png|центр|безрамки|1067x1067пкс]]&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
&lt;br /&gt;
Необходимо переименовать файл example.env в .env и изменить в нём следующие параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&lt;br /&gt;
POSTGRES_HOST=[хост postgresql]&lt;br /&gt;
POSTGRES_PORT=5432&lt;br /&gt;
POSTGRES_USER=[логин postgresql]&lt;br /&gt;
POSTGRES_PASSWORD=[пароль postgresql]&lt;br /&gt;
POSTGRES_DB=[имя БД, если укзаанная БД отсутствует - она будет автоматически создана]&lt;br /&gt;
&lt;br /&gt;
CONCURRENT_SESSIONS=[Жесткое ограничение количества одновременных сессий]&lt;br /&gt;
&lt;br /&gt;
SIP_SERVER=[адрес Эры]&lt;br /&gt;
SIP_PORT=[порт SIP]&lt;br /&gt;
SIP_USERNAME=[Имя учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_PASSWORD=[Пароль учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_DOMAIN=[Полное имя домена, например robot.era-platform.ru]&lt;br /&gt;
#Детальные настройки SIP-клиента. В случае необходимости обхода NAT&lt;br /&gt;
SIP_TRANSPORT=udp&lt;br /&gt;
# NAT Traversal&lt;br /&gt;
SIP_STUN_SERVER=stun.l.google.com:19302&lt;br /&gt;
SIP_USE_ICE=false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
LLM_MODE=openai_api&lt;br /&gt;
#В случае использования сервиса инфереса vLLM на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LLM_OPENAI_API_BASE=http://localhost:16080/v1 &lt;br /&gt;
LLM_OPENAI_MODEL=qwen35-35b-a3b&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ASR_MODE=triton&lt;br /&gt;
#В случае использования сервиса инфереса tone-triton на другом хосте, необходимо изменить адреса/порты&lt;br /&gt;
ASR_TRITON_URL=http://localhost:17000&lt;br /&gt;
ASR_TRITON_GRPC=localhost:17001&lt;br /&gt;
ASR_TRITON_MODEL=streaming_acoustic&lt;br /&gt;
ASR_TRITON_TIMEOUT=10&lt;br /&gt;
ASR_DECODER_TYPE=beam_search&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
TTS_PROVIDER=lighttts&lt;br /&gt;
#В случае использования сервиса инфереса LightTTS на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LIGHTTTS_URL=http://localhost:8080/&lt;br /&gt;
LIGHTTTS_SAMPLE_RATE=24000&lt;br /&gt;
LIGHTTTS_STREAMING=false&lt;br /&gt;
LIGHTTTS_CONCURRENCY=4&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Плейсхолдер под подробное описание .env --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Запуск контейнера и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
docker load -i secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2431</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2431"/>
		<updated>2026-07-06T23:50:53Z</updated>

		<summary type="html">&lt;p&gt;AZykov: /* Установка и настройка голосового робота Эра (SecondChain) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Установка и настройка голосового робота Эра (SecondChain) =&lt;br /&gt;
[[Файл:Архитектура голосового робота.png|центр|безрамки|763x763пкс]]&lt;br /&gt;
Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 1. Подготовка|Подготовка]]&#039;&#039;&#039; — Docker, PostgreSQL, настройки в системе телефонии.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 2. Установка сервисов инференса (опционально)|Установка сервисов инференса]]&#039;&#039;&#039; — ASR, LLM, TTS. &#039;&#039;Опционально, только для развёртывания на собственном сервере с GPU.&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 3. Настройка .env|Настройка .env]]&#039;&#039;&#039; — параметры подключения.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 4. Запуск контейнера и создание робота|Запуск контейнера и создание робота]]&#039;&#039;&#039; — старт сервиса и конфигурация робота.&lt;br /&gt;
&lt;br /&gt;
= Глоссарий =&lt;br /&gt;
&#039;&#039;&#039;Модель&#039;&#039;&#039; — обученная нейросеть, задающая соответствие между входом и выходом (текст -&amp;gt; текст, звук -&amp;gt; текст и т.д.). Модель определяется архитектурой и набором весов, полученных при обучении. В стеке робота их четыре:VAD (детекция голосовой активности), ASR (распознавание речи), LLM (генерация ответа), TTS (синтез речи).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Веса&#039;&#039;&#039; — числовые параметры модели, полученные при обучении. Именно они хранятся в файлах модели и загружаются в VRAM при старте. «Загрузка весов» в логах vLLM — это чтение этих файлов с диска в память GPU.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Инференс&#039;&#039;&#039; — использование готовой модели для получения ответа на новый вход («прогон» данных через веса). В отличие от обучения, веса не меняются. Сервисы инференса в статье — Triton, vLLM, LightTTS.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Triton&#039;&#039;&#039; (NVIDIA Triton Inference Server) — сервер инференса от NVIDIA, обслуживающий модели по gRPC и HTTP. В стеке на нём крутится ASR-модель T-one.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TensorRT&#039;&#039;&#039; — библиотека NVIDIA для оптимизации моделей под конкретный GPU: она компилирует модель в специализированный «движок» ради ускорения инференса. Сборка такого движка — разовая операция под железо, поэтому в LightTTS и T-One Triton она выполняется на первой фазе и коммитится в образ.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;vLLM&#039;&#039;&#039; — движок инференса для больших языковых моделей (LLM), оптимизированный на пропускную способность и эффективную работу с памятью. Предоставляет OpenAI-совместимый API.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;nvidia-smi&#039;&#039;&#039; (NVIDIA System Management Interface) — консольная утилита для просмотра состояния GPU: модель карты, версия драйвера, загрузка, потребление VRAM, запущенные процессы. Используется для проверки, что драйвер установлен и GPU виден (в т.ч. изнутри контейнера).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;KV-Cache&#039;&#039;&#039; (кэш ключей и значений) — память, где LLM хранит промежуточные представления уже обработанных токенов, чтобы не пересчитывать их при генерации каждого нового токена. Ускоряет генерацию ценой VRAM. В конфиге ограничен параметром &amp;lt;code&amp;gt;--kv-cache-memory&amp;lt;/code&amp;gt; (3 GiB). Растёт с числом сессий и длиной контекста — поэтому его размер критичен на картах с малым запасом VRAM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;LightTTS&#039;&#039;&#039; — движок инференса для TTS-моделей (синтеза речи). В стеке запускает модель CosyVoice3, слушает порт 8080.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Токен&#039;&#039;&#039; —В &#039;&#039;контексте LLM&#039;&#039; — единица текста, которой оперирует модель (примерно часть слова / слово / знак). Именно в токенах измеряются окно контекста и объём генерации.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Окно контекста&#039;&#039;&#039; — максимальное количество токенов, которое LLM может учитывать за один запрос (вход + генерируемый ответ вместе). Чем больше окно, тем больше VRAM уходит под KV-Cache, поэтому на картах с ограниченным объёмом его сокращают.&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
Установка самого Docker:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установка Nvidia Container Toolkit (только для серверов с GPU):&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# репозиторий&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \&lt;br /&gt;
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \&lt;br /&gt;
  sed &#039;s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g&#039; | \&lt;br /&gt;
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-container-toolkit&lt;br /&gt;
sudo nvidia-ctk runtime configure --runtime=docker&lt;br /&gt;
sudo systemctl restart docker&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (опционально) =&lt;br /&gt;
&lt;br /&gt;
Инструкция для &#039;&#039;&#039;Ubuntu Server 24.04&#039;&#039;&#039;. Стек: ASR (T-one/Triton) → LLM (Qwen3.5-35B-A3B на vLLM) → TTS (LightTTS + CosyVoice3).&lt;br /&gt;
&lt;br /&gt;
Целевая машина — сервер с GPU: &#039;&#039;&#039;RTX PRO 5000 (48GB)&#039;&#039;&#039; или &#039;&#039;&#039;RTX PRO 6000 Blackwell (96GB)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
=== Бюджет VRAM ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Компонент !! VRAM&lt;br /&gt;
|-&lt;br /&gt;
| ASR (T-one/Triton) || 600–800 MB&lt;br /&gt;
|-&lt;br /&gt;
| LLM (Qwen3.5-35B-A3B) || 24–48 GB (зависит от числа сессий и длины контекста)&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS/CosyVoice3) || 10 GB&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Суммарное потребление в пике — ~36–60 GB.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 6000 (96GB):&#039;&#039;&#039; объёма достаточно с большим запасом. Допустимо использование максимального числа сессий и длинного контекста.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 5000 (48GB):&#039;&#039;&#039; запас минимальный. Фиксированная сумма ASR (~0.8 GB) и TTS (11 GB) составляет ~12 GB, на LLM остаётся ~36 GB. Это покрывает только нижнюю границу диапазона LLM (24 GB). Требуется ограничение параметров &amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt; во избежание ошибки OOM. Значение &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; (~24 GB на карте 48GB) для данного сценария допустимо при условии, что ASR и TTS инициализированы до старта LLM.&lt;br /&gt;
&lt;br /&gt;
Объем оперативной памяти не может быть меньше, чем VRAM, так как в процессе запуска веса моделей помещаются сначала в оперативную память, и только затем в VRAM.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Компиляция моделей может занимать больше VRAM, чем запущенный сервис, поэтому в случае дефицита видеопамяти, рекомендуется временно отключать свеже созданные контейнеры, собирать их по одному, после чего запускать по очереди уже в собранном виде.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton Inference Server) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
I0706 22:41:02.484518 1 grpc_server.cc:2562] &amp;quot;Started GRPCInferenceService at 0.0.0.0:8001&amp;quot;&lt;br /&gt;
I0706 22:41:02.484664 1 http_server.cc:4832] &amp;quot;Started HTTPService at 0.0.0.0:8000&amp;quot;&lt;br /&gt;
I0706 22:41:02.525792 1 http_server.cc:358] &amp;quot;Started Metrics Service at 0.0.0.0:8002&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
Установка выполняется из Docker Hub, следующей командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
* &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; — директория хост-машины, где будет храниться кеш весов модели (24gb)&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
После запуска vllm скачает веса модели для запуска (24gb). После завершения запуска и загрузки весов в логах можно наблюдать следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
(APIServer pid=1) INFO:     Started server process [1]&lt;br /&gt;
(APIServer pid=1) INFO:     Waiting for application startup.&lt;br /&gt;
(APIServer pid=1) INFO:     Application startup complete.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Как только они появятся, можно переходить к следующему шагу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080.&#039;&#039;&#039; Первый запрос к модели будет занимать достаточно много времени:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}],&lt;br /&gt;
    &amp;quot;chat_template_kwargs&amp;quot;: {&amp;quot;enable_thinking&amp;quot;: false}&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load -i lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights \&lt;br /&gt;
  python -m light_tts.server.api_server \&lt;br /&gt;
    --model_dir /opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
    --data_type float16 \&lt;br /&gt;
    --load_trt True \&lt;br /&gt;
    --host 0.0.0.0&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;После запуска сервис скомпилирует веса, по аналогии с T-One. После завершения подготовки в логах будут следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:391] ✅ Startup health check passed!&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:395] ✅ Application ready! Server is now accepting requests&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:396] 🌐 Listening at: http://localhost:8080&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — 10 &#039;&#039;&#039;GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 8000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 8001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Контейнеры сервисов инференса голосового робота.png|центр|безрамки|1067x1067пкс]]&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
&lt;br /&gt;
Необходимо переименовать файл example.env в .env и изменить в нём следующие параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&lt;br /&gt;
POSTGRES_HOST=[хост postgresql]&lt;br /&gt;
POSTGRES_PORT=5432&lt;br /&gt;
POSTGRES_USER=[логин postgresql]&lt;br /&gt;
POSTGRES_PASSWORD=[пароль postgresql]&lt;br /&gt;
POSTGRES_DB=[имя БД, если укзаанная БД отсутствует - она будет автоматически создана]&lt;br /&gt;
&lt;br /&gt;
CONCURRENT_SESSIONS=[Жесткое ограничение количества одновременных сессий]&lt;br /&gt;
&lt;br /&gt;
SIP_SERVER=[адрес Эры]&lt;br /&gt;
SIP_PORT=[порт SIP]&lt;br /&gt;
SIP_USERNAME=[Имя учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_PASSWORD=[Пароль учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_DOMAIN=[Полное имя домена, например robot.era-platform.ru]&lt;br /&gt;
#Детальные настройки SIP-клиента. В случае необходимости обхода NAT&lt;br /&gt;
SIP_TRANSPORT=udp&lt;br /&gt;
# NAT Traversal&lt;br /&gt;
SIP_STUN_SERVER=stun.l.google.com:19302&lt;br /&gt;
SIP_USE_ICE=false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
LLM_MODE=openai_api&lt;br /&gt;
#В случае использования сервиса инфереса vLLM на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LLM_OPENAI_API_BASE=http://localhost:16080/v1 &lt;br /&gt;
LLM_OPENAI_MODEL=qwen35-35b-a3b&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ASR_MODE=triton&lt;br /&gt;
#В случае использования сервиса инфереса tone-triton на другом хосте, необходимо изменить адреса/порты&lt;br /&gt;
ASR_TRITON_URL=http://localhost:17000&lt;br /&gt;
ASR_TRITON_GRPC=localhost:17001&lt;br /&gt;
ASR_TRITON_MODEL=streaming_acoustic&lt;br /&gt;
ASR_TRITON_TIMEOUT=10&lt;br /&gt;
ASR_DECODER_TYPE=beam_search&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
TTS_PROVIDER=lighttts&lt;br /&gt;
#В случае использования сервиса инфереса LightTTS на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LIGHTTTS_URL=http://localhost:8080/&lt;br /&gt;
LIGHTTTS_SAMPLE_RATE=24000&lt;br /&gt;
LIGHTTTS_STREAMING=false&lt;br /&gt;
LIGHTTTS_CONCURRENCY=4&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Плейсхолдер под подробное описание .env --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Запуск контейнера и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
docker load -i secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%90%D1%80%D1%85%D0%B8%D1%82%D0%B5%D0%BA%D1%82%D1%83%D1%80%D0%B0_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0.png&amp;diff=2430</id>
		<title>Файл:Архитектура голосового робота.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%90%D1%80%D1%85%D0%B8%D1%82%D0%B5%D0%BA%D1%82%D1%83%D1%80%D0%B0_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0.png&amp;diff=2430"/>
		<updated>2026-07-06T23:50:34Z</updated>

		<summary type="html">&lt;p&gt;AZykov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Архитектура голосового робота&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2429</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2429"/>
		<updated>2026-07-06T23:41:08Z</updated>

		<summary type="html">&lt;p&gt;AZykov: /* 2.5. TTS (LightTTS + CosyVoice3) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Установка и настройка голосового робота Эра (SecondChain) =&lt;br /&gt;
&lt;br /&gt;
Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 1. Подготовка|Подготовка]]&#039;&#039;&#039; — Docker, PostgreSQL, настройки в системе телефонии.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 2. Установка сервисов инференса (опционально)|Установка сервисов инференса]]&#039;&#039;&#039; — ASR, LLM, TTS. &#039;&#039;Опционально, только для развёртывания на собственном сервере с GPU.&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 3. Настройка .env|Настройка .env]]&#039;&#039;&#039; — параметры подключения.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 4. Запуск контейнера и создание робота|Запуск контейнера и создание робота]]&#039;&#039;&#039; — старт сервиса и конфигурация робота.&lt;br /&gt;
&lt;br /&gt;
= Глоссарий =&lt;br /&gt;
&#039;&#039;&#039;Модель&#039;&#039;&#039; — обученная нейросеть, задающая соответствие между входом и выходом (текст -&amp;gt; текст, звук -&amp;gt; текст и т.д.). Модель определяется архитектурой и набором весов, полученных при обучении. В стеке робота их четыре:VAD (детекция голосовой активности), ASR (распознавание речи), LLM (генерация ответа), TTS (синтез речи).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Веса&#039;&#039;&#039; — числовые параметры модели, полученные при обучении. Именно они хранятся в файлах модели и загружаются в VRAM при старте. «Загрузка весов» в логах vLLM — это чтение этих файлов с диска в память GPU.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Инференс&#039;&#039;&#039; — использование готовой модели для получения ответа на новый вход («прогон» данных через веса). В отличие от обучения, веса не меняются. Сервисы инференса в статье — Triton, vLLM, LightTTS.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Triton&#039;&#039;&#039; (NVIDIA Triton Inference Server) — сервер инференса от NVIDIA, обслуживающий модели по gRPC и HTTP. В стеке на нём крутится ASR-модель T-one.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TensorRT&#039;&#039;&#039; — библиотека NVIDIA для оптимизации моделей под конкретный GPU: она компилирует модель в специализированный «движок» ради ускорения инференса. Сборка такого движка — разовая операция под железо, поэтому в LightTTS и T-One Triton она выполняется на первой фазе и коммитится в образ.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;vLLM&#039;&#039;&#039; — движок инференса для больших языковых моделей (LLM), оптимизированный на пропускную способность и эффективную работу с памятью. Предоставляет OpenAI-совместимый API.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;nvidia-smi&#039;&#039;&#039; (NVIDIA System Management Interface) — консольная утилита для просмотра состояния GPU: модель карты, версия драйвера, загрузка, потребление VRAM, запущенные процессы. Используется для проверки, что драйвер установлен и GPU виден (в т.ч. изнутри контейнера).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;KV-Cache&#039;&#039;&#039; (кэш ключей и значений) — память, где LLM хранит промежуточные представления уже обработанных токенов, чтобы не пересчитывать их при генерации каждого нового токена. Ускоряет генерацию ценой VRAM. В конфиге ограничен параметром &amp;lt;code&amp;gt;--kv-cache-memory&amp;lt;/code&amp;gt; (3 GiB). Растёт с числом сессий и длиной контекста — поэтому его размер критичен на картах с малым запасом VRAM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;LightTTS&#039;&#039;&#039; — движок инференса для TTS-моделей (синтеза речи). В стеке запускает модель CosyVoice3, слушает порт 8080.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Токен&#039;&#039;&#039; —В &#039;&#039;контексте LLM&#039;&#039; — единица текста, которой оперирует модель (примерно часть слова / слово / знак). Именно в токенах измеряются окно контекста и объём генерации.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Окно контекста&#039;&#039;&#039; — максимальное количество токенов, которое LLM может учитывать за один запрос (вход + генерируемый ответ вместе). Чем больше окно, тем больше VRAM уходит под KV-Cache, поэтому на картах с ограниченным объёмом его сокращают.&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
Установка самого Docker:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установка Nvidia Container Toolkit (только для серверов с GPU):&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# репозиторий&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \&lt;br /&gt;
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \&lt;br /&gt;
  sed &#039;s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g&#039; | \&lt;br /&gt;
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-container-toolkit&lt;br /&gt;
sudo nvidia-ctk runtime configure --runtime=docker&lt;br /&gt;
sudo systemctl restart docker&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (опционально) =&lt;br /&gt;
&lt;br /&gt;
Инструкция для &#039;&#039;&#039;Ubuntu Server 24.04&#039;&#039;&#039;. Стек: ASR (T-one/Triton) → LLM (Qwen3.5-35B-A3B на vLLM) → TTS (LightTTS + CosyVoice3).&lt;br /&gt;
&lt;br /&gt;
Целевая машина — сервер с GPU: &#039;&#039;&#039;RTX PRO 5000 (48GB)&#039;&#039;&#039; или &#039;&#039;&#039;RTX PRO 6000 Blackwell (96GB)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
=== Бюджет VRAM ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Компонент !! VRAM&lt;br /&gt;
|-&lt;br /&gt;
| ASR (T-one/Triton) || 600–800 MB&lt;br /&gt;
|-&lt;br /&gt;
| LLM (Qwen3.5-35B-A3B) || 24–48 GB (зависит от числа сессий и длины контекста)&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS/CosyVoice3) || 10 GB&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Суммарное потребление в пике — ~36–60 GB.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 6000 (96GB):&#039;&#039;&#039; объёма достаточно с большим запасом. Допустимо использование максимального числа сессий и длинного контекста.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 5000 (48GB):&#039;&#039;&#039; запас минимальный. Фиксированная сумма ASR (~0.8 GB) и TTS (11 GB) составляет ~12 GB, на LLM остаётся ~36 GB. Это покрывает только нижнюю границу диапазона LLM (24 GB). Требуется ограничение параметров &amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt; во избежание ошибки OOM. Значение &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; (~24 GB на карте 48GB) для данного сценария допустимо при условии, что ASR и TTS инициализированы до старта LLM.&lt;br /&gt;
&lt;br /&gt;
Объем оперативной памяти не может быть меньше, чем VRAM, так как в процессе запуска веса моделей помещаются сначала в оперативную память, и только затем в VRAM.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Компиляция моделей может занимать больше VRAM, чем запущенный сервис, поэтому в случае дефицита видеопамяти, рекомендуется временно отключать свеже созданные контейнеры, собирать их по одному, после чего запускать по очереди уже в собранном виде.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton Inference Server) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
I0706 22:41:02.484518 1 grpc_server.cc:2562] &amp;quot;Started GRPCInferenceService at 0.0.0.0:8001&amp;quot;&lt;br /&gt;
I0706 22:41:02.484664 1 http_server.cc:4832] &amp;quot;Started HTTPService at 0.0.0.0:8000&amp;quot;&lt;br /&gt;
I0706 22:41:02.525792 1 http_server.cc:358] &amp;quot;Started Metrics Service at 0.0.0.0:8002&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
Установка выполняется из Docker Hub, следующей командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
* &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; — директория хост-машины, где будет храниться кеш весов модели (24gb)&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
После запуска vllm скачает веса модели для запуска (24gb). После завершения запуска и загрузки весов в логах можно наблюдать следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
(APIServer pid=1) INFO:     Started server process [1]&lt;br /&gt;
(APIServer pid=1) INFO:     Waiting for application startup.&lt;br /&gt;
(APIServer pid=1) INFO:     Application startup complete.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Как только они появятся, можно переходить к следующему шагу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080.&#039;&#039;&#039; Первый запрос к модели будет занимать достаточно много времени:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}],&lt;br /&gt;
    &amp;quot;chat_template_kwargs&amp;quot;: {&amp;quot;enable_thinking&amp;quot;: false}&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load -i lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights \&lt;br /&gt;
  python -m light_tts.server.api_server \&lt;br /&gt;
    --model_dir /opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
    --data_type float16 \&lt;br /&gt;
    --load_trt True \&lt;br /&gt;
    --host 0.0.0.0&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;После запуска сервис скомпилирует веса, по аналогии с T-One. После завершения подготовки в логах будут следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:391] ✅ Startup health check passed!&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:395] ✅ Application ready! Server is now accepting requests&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:396] 🌐 Listening at: http://localhost:8080&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — 10 &#039;&#039;&#039;GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 8000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 8001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Контейнеры сервисов инференса голосового робота.png|центр|безрамки|1067x1067пкс]]&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
&lt;br /&gt;
Необходимо переименовать файл example.env в .env и изменить в нём следующие параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&lt;br /&gt;
POSTGRES_HOST=[хост postgresql]&lt;br /&gt;
POSTGRES_PORT=5432&lt;br /&gt;
POSTGRES_USER=[логин postgresql]&lt;br /&gt;
POSTGRES_PASSWORD=[пароль postgresql]&lt;br /&gt;
POSTGRES_DB=[имя БД, если укзаанная БД отсутствует - она будет автоматически создана]&lt;br /&gt;
&lt;br /&gt;
CONCURRENT_SESSIONS=[Жесткое ограничение количества одновременных сессий]&lt;br /&gt;
&lt;br /&gt;
SIP_SERVER=[адрес Эры]&lt;br /&gt;
SIP_PORT=[порт SIP]&lt;br /&gt;
SIP_USERNAME=[Имя учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_PASSWORD=[Пароль учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_DOMAIN=[Полное имя домена, например robot.era-platform.ru]&lt;br /&gt;
#Детальные настройки SIP-клиента. В случае необходимости обхода NAT&lt;br /&gt;
SIP_TRANSPORT=udp&lt;br /&gt;
# NAT Traversal&lt;br /&gt;
SIP_STUN_SERVER=stun.l.google.com:19302&lt;br /&gt;
SIP_USE_ICE=false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
LLM_MODE=openai_api&lt;br /&gt;
#В случае использования сервиса инфереса vLLM на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LLM_OPENAI_API_BASE=http://localhost:16080/v1 &lt;br /&gt;
LLM_OPENAI_MODEL=qwen35-35b-a3b&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ASR_MODE=triton&lt;br /&gt;
#В случае использования сервиса инфереса tone-triton на другом хосте, необходимо изменить адреса/порты&lt;br /&gt;
ASR_TRITON_URL=http://localhost:17000&lt;br /&gt;
ASR_TRITON_GRPC=localhost:17001&lt;br /&gt;
ASR_TRITON_MODEL=streaming_acoustic&lt;br /&gt;
ASR_TRITON_TIMEOUT=10&lt;br /&gt;
ASR_DECODER_TYPE=beam_search&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
TTS_PROVIDER=lighttts&lt;br /&gt;
#В случае использования сервиса инфереса LightTTS на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LIGHTTTS_URL=http://localhost:8080/&lt;br /&gt;
LIGHTTTS_SAMPLE_RATE=24000&lt;br /&gt;
LIGHTTTS_STREAMING=false&lt;br /&gt;
LIGHTTTS_CONCURRENCY=4&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Плейсхолдер под подробное описание .env --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Запуск контейнера и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
docker load -i secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2428</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2428"/>
		<updated>2026-07-06T23:33:43Z</updated>

		<summary type="html">&lt;p&gt;AZykov: /* Этап 3. Настройка .env */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Установка и настройка голосового робота Эра (SecondChain) =&lt;br /&gt;
&lt;br /&gt;
Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 1. Подготовка|Подготовка]]&#039;&#039;&#039; — Docker, PostgreSQL, настройки в системе телефонии.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 2. Установка сервисов инференса (опционально)|Установка сервисов инференса]]&#039;&#039;&#039; — ASR, LLM, TTS. &#039;&#039;Опционально, только для развёртывания на собственном сервере с GPU.&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 3. Настройка .env|Настройка .env]]&#039;&#039;&#039; — параметры подключения.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 4. Запуск контейнера и создание робота|Запуск контейнера и создание робота]]&#039;&#039;&#039; — старт сервиса и конфигурация робота.&lt;br /&gt;
&lt;br /&gt;
= Глоссарий =&lt;br /&gt;
&#039;&#039;&#039;Модель&#039;&#039;&#039; — обученная нейросеть, задающая соответствие между входом и выходом (текст -&amp;gt; текст, звук -&amp;gt; текст и т.д.). Модель определяется архитектурой и набором весов, полученных при обучении. В стеке робота их четыре:VAD (детекция голосовой активности), ASR (распознавание речи), LLM (генерация ответа), TTS (синтез речи).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Веса&#039;&#039;&#039; — числовые параметры модели, полученные при обучении. Именно они хранятся в файлах модели и загружаются в VRAM при старте. «Загрузка весов» в логах vLLM — это чтение этих файлов с диска в память GPU.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Инференс&#039;&#039;&#039; — использование готовой модели для получения ответа на новый вход («прогон» данных через веса). В отличие от обучения, веса не меняются. Сервисы инференса в статье — Triton, vLLM, LightTTS.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Triton&#039;&#039;&#039; (NVIDIA Triton Inference Server) — сервер инференса от NVIDIA, обслуживающий модели по gRPC и HTTP. В стеке на нём крутится ASR-модель T-one.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TensorRT&#039;&#039;&#039; — библиотека NVIDIA для оптимизации моделей под конкретный GPU: она компилирует модель в специализированный «движок» ради ускорения инференса. Сборка такого движка — разовая операция под железо, поэтому в LightTTS и T-One Triton она выполняется на первой фазе и коммитится в образ.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;vLLM&#039;&#039;&#039; — движок инференса для больших языковых моделей (LLM), оптимизированный на пропускную способность и эффективную работу с памятью. Предоставляет OpenAI-совместимый API.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;nvidia-smi&#039;&#039;&#039; (NVIDIA System Management Interface) — консольная утилита для просмотра состояния GPU: модель карты, версия драйвера, загрузка, потребление VRAM, запущенные процессы. Используется для проверки, что драйвер установлен и GPU виден (в т.ч. изнутри контейнера).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;KV-Cache&#039;&#039;&#039; (кэш ключей и значений) — память, где LLM хранит промежуточные представления уже обработанных токенов, чтобы не пересчитывать их при генерации каждого нового токена. Ускоряет генерацию ценой VRAM. В конфиге ограничен параметром &amp;lt;code&amp;gt;--kv-cache-memory&amp;lt;/code&amp;gt; (3 GiB). Растёт с числом сессий и длиной контекста — поэтому его размер критичен на картах с малым запасом VRAM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;LightTTS&#039;&#039;&#039; — движок инференса для TTS-моделей (синтеза речи). В стеке запускает модель CosyVoice3, слушает порт 8080.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Токен&#039;&#039;&#039; —В &#039;&#039;контексте LLM&#039;&#039; — единица текста, которой оперирует модель (примерно часть слова / слово / знак). Именно в токенах измеряются окно контекста и объём генерации.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Окно контекста&#039;&#039;&#039; — максимальное количество токенов, которое LLM может учитывать за один запрос (вход + генерируемый ответ вместе). Чем больше окно, тем больше VRAM уходит под KV-Cache, поэтому на картах с ограниченным объёмом его сокращают.&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
Установка самого Docker:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установка Nvidia Container Toolkit (только для серверов с GPU):&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# репозиторий&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \&lt;br /&gt;
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \&lt;br /&gt;
  sed &#039;s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g&#039; | \&lt;br /&gt;
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-container-toolkit&lt;br /&gt;
sudo nvidia-ctk runtime configure --runtime=docker&lt;br /&gt;
sudo systemctl restart docker&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (опционально) =&lt;br /&gt;
&lt;br /&gt;
Инструкция для &#039;&#039;&#039;Ubuntu Server 24.04&#039;&#039;&#039;. Стек: ASR (T-one/Triton) → LLM (Qwen3.5-35B-A3B на vLLM) → TTS (LightTTS + CosyVoice3).&lt;br /&gt;
&lt;br /&gt;
Целевая машина — сервер с GPU: &#039;&#039;&#039;RTX PRO 5000 (48GB)&#039;&#039;&#039; или &#039;&#039;&#039;RTX PRO 6000 Blackwell (96GB)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
=== Бюджет VRAM ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Компонент !! VRAM&lt;br /&gt;
|-&lt;br /&gt;
| ASR (T-one/Triton) || 600–800 MB&lt;br /&gt;
|-&lt;br /&gt;
| LLM (Qwen3.5-35B-A3B) || 24–48 GB (зависит от числа сессий и длины контекста)&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS/CosyVoice3) || 10 GB&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Суммарное потребление в пике — ~36–60 GB.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 6000 (96GB):&#039;&#039;&#039; объёма достаточно с большим запасом. Допустимо использование максимального числа сессий и длинного контекста.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 5000 (48GB):&#039;&#039;&#039; запас минимальный. Фиксированная сумма ASR (~0.8 GB) и TTS (11 GB) составляет ~12 GB, на LLM остаётся ~36 GB. Это покрывает только нижнюю границу диапазона LLM (24 GB). Требуется ограничение параметров &amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt; во избежание ошибки OOM. Значение &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; (~24 GB на карте 48GB) для данного сценария допустимо при условии, что ASR и TTS инициализированы до старта LLM.&lt;br /&gt;
&lt;br /&gt;
Объем оперативной памяти не может быть меньше, чем VRAM, так как в процессе запуска веса моделей помещаются сначала в оперативную память, и только затем в VRAM.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Компиляция моделей может занимать больше VRAM, чем запущенный сервис, поэтому в случае дефицита видеопамяти, рекомендуется временно отключать свеже созданные контейнеры, собирать их по одному, после чего запускать по очереди уже в собранном виде.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton Inference Server) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
I0706 22:41:02.484518 1 grpc_server.cc:2562] &amp;quot;Started GRPCInferenceService at 0.0.0.0:8001&amp;quot;&lt;br /&gt;
I0706 22:41:02.484664 1 http_server.cc:4832] &amp;quot;Started HTTPService at 0.0.0.0:8000&amp;quot;&lt;br /&gt;
I0706 22:41:02.525792 1 http_server.cc:358] &amp;quot;Started Metrics Service at 0.0.0.0:8002&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
Установка выполняется из Docker Hub, следующей командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
* &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; — директория хост-машины, где будет храниться кеш весов модели (24gb)&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
После запуска vllm скачает веса модели для запуска (24gb). После завершения запуска и загрузки весов в логах можно наблюдать следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
(APIServer pid=1) INFO:     Started server process [1]&lt;br /&gt;
(APIServer pid=1) INFO:     Waiting for application startup.&lt;br /&gt;
(APIServer pid=1) INFO:     Application startup complete.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Как только они появятся, можно переходить к следующему шагу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080.&#039;&#039;&#039; Первый запрос к модели будет занимать достаточно много времени:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}],&lt;br /&gt;
    &amp;quot;chat_template_kwargs&amp;quot;: {&amp;quot;enable_thinking&amp;quot;: false}&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load -i lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;После запуска сервис скомпилирует веса, по аналогии с T-One. После завершения подготовки в логах будут следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:391] ✅ Startup health check passed!&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:395] ✅ Application ready! Server is now accepting requests&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:396] 🌐 Listening at: http://localhost:8080&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — 10 &#039;&#039;&#039;GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 8000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 8001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Контейнеры сервисов инференса голосового робота.png|центр|безрамки|1067x1067пкс]]&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
&lt;br /&gt;
Необходимо переименовать файл example.env в .env и изменить в нём следующие параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&lt;br /&gt;
POSTGRES_HOST=[хост postgresql]&lt;br /&gt;
POSTGRES_PORT=5432&lt;br /&gt;
POSTGRES_USER=[логин postgresql]&lt;br /&gt;
POSTGRES_PASSWORD=[пароль postgresql]&lt;br /&gt;
POSTGRES_DB=[имя БД, если укзаанная БД отсутствует - она будет автоматически создана]&lt;br /&gt;
&lt;br /&gt;
CONCURRENT_SESSIONS=[Жесткое ограничение количества одновременных сессий]&lt;br /&gt;
&lt;br /&gt;
SIP_SERVER=[адрес Эры]&lt;br /&gt;
SIP_PORT=[порт SIP]&lt;br /&gt;
SIP_USERNAME=[Имя учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_PASSWORD=[Пароль учетной записи абонента из пункта 1.4]&lt;br /&gt;
SIP_DOMAIN=[Полное имя домена, например robot.era-platform.ru]&lt;br /&gt;
#Детальные настройки SIP-клиента. В случае необходимости обхода NAT&lt;br /&gt;
SIP_TRANSPORT=udp&lt;br /&gt;
# NAT Traversal&lt;br /&gt;
SIP_STUN_SERVER=stun.l.google.com:19302&lt;br /&gt;
SIP_USE_ICE=false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
LLM_MODE=openai_api&lt;br /&gt;
#В случае использования сервиса инфереса vLLM на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LLM_OPENAI_API_BASE=http://localhost:16080/v1 &lt;br /&gt;
LLM_OPENAI_MODEL=qwen35-35b-a3b&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ASR_MODE=triton&lt;br /&gt;
#В случае использования сервиса инфереса tone-triton на другом хосте, необходимо изменить адреса/порты&lt;br /&gt;
ASR_TRITON_URL=http://localhost:17000&lt;br /&gt;
ASR_TRITON_GRPC=localhost:17001&lt;br /&gt;
ASR_TRITON_MODEL=streaming_acoustic&lt;br /&gt;
ASR_TRITON_TIMEOUT=10&lt;br /&gt;
ASR_DECODER_TYPE=beam_search&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
TTS_PROVIDER=lighttts&lt;br /&gt;
#В случае использования сервиса инфереса LightTTS на другом хосте, необходимо изменить адрес/порт&lt;br /&gt;
LIGHTTTS_URL=http://localhost:8080/&lt;br /&gt;
LIGHTTTS_SAMPLE_RATE=24000&lt;br /&gt;
LIGHTTTS_STREAMING=false&lt;br /&gt;
LIGHTTTS_CONCURRENCY=4&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Плейсхолдер под подробное описание .env --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Запуск контейнера и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
docker load -i secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2427</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2427"/>
		<updated>2026-07-06T23:21:53Z</updated>

		<summary type="html">&lt;p&gt;AZykov: /* 2.7. Финальная проверка стека */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Установка и настройка голосового робота Эра (SecondChain) =&lt;br /&gt;
&lt;br /&gt;
Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 1. Подготовка|Подготовка]]&#039;&#039;&#039; — Docker, PostgreSQL, настройки в системе телефонии.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 2. Установка сервисов инференса (опционально)|Установка сервисов инференса]]&#039;&#039;&#039; — ASR, LLM, TTS. &#039;&#039;Опционально, только для развёртывания на собственном сервере с GPU.&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 3. Настройка .env|Настройка .env]]&#039;&#039;&#039; — параметры подключения.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 4. Запуск контейнера и создание робота|Запуск контейнера и создание робота]]&#039;&#039;&#039; — старт сервиса и конфигурация робота.&lt;br /&gt;
&lt;br /&gt;
= Глоссарий =&lt;br /&gt;
&#039;&#039;&#039;Модель&#039;&#039;&#039; — обученная нейросеть, задающая соответствие между входом и выходом (текст -&amp;gt; текст, звук -&amp;gt; текст и т.д.). Модель определяется архитектурой и набором весов, полученных при обучении. В стеке робота их четыре:VAD (детекция голосовой активности), ASR (распознавание речи), LLM (генерация ответа), TTS (синтез речи).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Веса&#039;&#039;&#039; — числовые параметры модели, полученные при обучении. Именно они хранятся в файлах модели и загружаются в VRAM при старте. «Загрузка весов» в логах vLLM — это чтение этих файлов с диска в память GPU.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Инференс&#039;&#039;&#039; — использование готовой модели для получения ответа на новый вход («прогон» данных через веса). В отличие от обучения, веса не меняются. Сервисы инференса в статье — Triton, vLLM, LightTTS.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Triton&#039;&#039;&#039; (NVIDIA Triton Inference Server) — сервер инференса от NVIDIA, обслуживающий модели по gRPC и HTTP. В стеке на нём крутится ASR-модель T-one.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TensorRT&#039;&#039;&#039; — библиотека NVIDIA для оптимизации моделей под конкретный GPU: она компилирует модель в специализированный «движок» ради ускорения инференса. Сборка такого движка — разовая операция под железо, поэтому в LightTTS и T-One Triton она выполняется на первой фазе и коммитится в образ.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;vLLM&#039;&#039;&#039; — движок инференса для больших языковых моделей (LLM), оптимизированный на пропускную способность и эффективную работу с памятью. Предоставляет OpenAI-совместимый API.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;nvidia-smi&#039;&#039;&#039; (NVIDIA System Management Interface) — консольная утилита для просмотра состояния GPU: модель карты, версия драйвера, загрузка, потребление VRAM, запущенные процессы. Используется для проверки, что драйвер установлен и GPU виден (в т.ч. изнутри контейнера).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;KV-Cache&#039;&#039;&#039; (кэш ключей и значений) — память, где LLM хранит промежуточные представления уже обработанных токенов, чтобы не пересчитывать их при генерации каждого нового токена. Ускоряет генерацию ценой VRAM. В конфиге ограничен параметром &amp;lt;code&amp;gt;--kv-cache-memory&amp;lt;/code&amp;gt; (3 GiB). Растёт с числом сессий и длиной контекста — поэтому его размер критичен на картах с малым запасом VRAM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;LightTTS&#039;&#039;&#039; — движок инференса для TTS-моделей (синтеза речи). В стеке запускает модель CosyVoice3, слушает порт 8080.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Токен&#039;&#039;&#039; —В &#039;&#039;контексте LLM&#039;&#039; — единица текста, которой оперирует модель (примерно часть слова / слово / знак). Именно в токенах измеряются окно контекста и объём генерации.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Окно контекста&#039;&#039;&#039; — максимальное количество токенов, которое LLM может учитывать за один запрос (вход + генерируемый ответ вместе). Чем больше окно, тем больше VRAM уходит под KV-Cache, поэтому на картах с ограниченным объёмом его сокращают.&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
Установка самого Docker:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установка Nvidia Container Toolkit (только для серверов с GPU):&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# репозиторий&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \&lt;br /&gt;
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \&lt;br /&gt;
  sed &#039;s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g&#039; | \&lt;br /&gt;
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-container-toolkit&lt;br /&gt;
sudo nvidia-ctk runtime configure --runtime=docker&lt;br /&gt;
sudo systemctl restart docker&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (опционально) =&lt;br /&gt;
&lt;br /&gt;
Инструкция для &#039;&#039;&#039;Ubuntu Server 24.04&#039;&#039;&#039;. Стек: ASR (T-one/Triton) → LLM (Qwen3.5-35B-A3B на vLLM) → TTS (LightTTS + CosyVoice3).&lt;br /&gt;
&lt;br /&gt;
Целевая машина — сервер с GPU: &#039;&#039;&#039;RTX PRO 5000 (48GB)&#039;&#039;&#039; или &#039;&#039;&#039;RTX PRO 6000 Blackwell (96GB)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
=== Бюджет VRAM ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Компонент !! VRAM&lt;br /&gt;
|-&lt;br /&gt;
| ASR (T-one/Triton) || 600–800 MB&lt;br /&gt;
|-&lt;br /&gt;
| LLM (Qwen3.5-35B-A3B) || 24–48 GB (зависит от числа сессий и длины контекста)&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS/CosyVoice3) || 10 GB&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Суммарное потребление в пике — ~36–60 GB.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 6000 (96GB):&#039;&#039;&#039; объёма достаточно с большим запасом. Допустимо использование максимального числа сессий и длинного контекста.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 5000 (48GB):&#039;&#039;&#039; запас минимальный. Фиксированная сумма ASR (~0.8 GB) и TTS (11 GB) составляет ~12 GB, на LLM остаётся ~36 GB. Это покрывает только нижнюю границу диапазона LLM (24 GB). Требуется ограничение параметров &amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt; во избежание ошибки OOM. Значение &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; (~24 GB на карте 48GB) для данного сценария допустимо при условии, что ASR и TTS инициализированы до старта LLM.&lt;br /&gt;
&lt;br /&gt;
Объем оперативной памяти не может быть меньше, чем VRAM, так как в процессе запуска веса моделей помещаются сначала в оперативную память, и только затем в VRAM.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Компиляция моделей может занимать больше VRAM, чем запущенный сервис, поэтому в случае дефицита видеопамяти, рекомендуется временно отключать свеже созданные контейнеры, собирать их по одному, после чего запускать по очереди уже в собранном виде.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton Inference Server) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
I0706 22:41:02.484518 1 grpc_server.cc:2562] &amp;quot;Started GRPCInferenceService at 0.0.0.0:8001&amp;quot;&lt;br /&gt;
I0706 22:41:02.484664 1 http_server.cc:4832] &amp;quot;Started HTTPService at 0.0.0.0:8000&amp;quot;&lt;br /&gt;
I0706 22:41:02.525792 1 http_server.cc:358] &amp;quot;Started Metrics Service at 0.0.0.0:8002&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
Установка выполняется из Docker Hub, следующей командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
* &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; — директория хост-машины, где будет храниться кеш весов модели (24gb)&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
После запуска vllm скачает веса модели для запуска (24gb). После завершения запуска и загрузки весов в логах можно наблюдать следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
(APIServer pid=1) INFO:     Started server process [1]&lt;br /&gt;
(APIServer pid=1) INFO:     Waiting for application startup.&lt;br /&gt;
(APIServer pid=1) INFO:     Application startup complete.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Как только они появятся, можно переходить к следующему шагу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080.&#039;&#039;&#039; Первый запрос к модели будет занимать достаточно много времени:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}],&lt;br /&gt;
    &amp;quot;chat_template_kwargs&amp;quot;: {&amp;quot;enable_thinking&amp;quot;: false}&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load -i lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;После запуска сервис скомпилирует веса, по аналогии с T-One. После завершения подготовки в логах будут следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:391] ✅ Startup health check passed!&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:395] ✅ Application ready! Server is now accepting requests&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:396] 🌐 Listening at: http://localhost:8080&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — 10 &#039;&#039;&#039;GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 8000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 8001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Контейнеры сервисов инференса голосового робота.png|центр|безрамки|1067x1067пкс]]&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Базовые параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Плейсхолдер под подробное описание .env --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Запуск контейнера и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
docker load -i secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%9A%D0%BE%D0%BD%D1%82%D0%B5%D0%B9%D0%BD%D0%B5%D1%80%D1%8B_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B8%D0%BD%D1%84%D0%B5%D1%80%D0%B5%D0%BD%D1%81%D0%B0_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0.png&amp;diff=2426</id>
		<title>Файл:Контейнеры сервисов инференса голосового робота.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%9A%D0%BE%D0%BD%D1%82%D0%B5%D0%B9%D0%BD%D0%B5%D1%80%D1%8B_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B8%D0%BD%D1%84%D0%B5%D1%80%D0%B5%D0%BD%D1%81%D0%B0_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0.png&amp;diff=2426"/>
		<updated>2026-07-06T23:21:31Z</updated>

		<summary type="html">&lt;p&gt;AZykov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Контейнеры сервисов инференса голосового робота&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2425</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2425"/>
		<updated>2026-07-06T23:17:56Z</updated>

		<summary type="html">&lt;p&gt;AZykov: /* 2.5. TTS (LightTTS + CosyVoice3) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Установка и настройка голосового робота Эра (SecondChain) =&lt;br /&gt;
&lt;br /&gt;
Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 1. Подготовка|Подготовка]]&#039;&#039;&#039; — Docker, PostgreSQL, настройки в системе телефонии.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 2. Установка сервисов инференса (опционально)|Установка сервисов инференса]]&#039;&#039;&#039; — ASR, LLM, TTS. &#039;&#039;Опционально, только для развёртывания на собственном сервере с GPU.&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 3. Настройка .env|Настройка .env]]&#039;&#039;&#039; — параметры подключения.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 4. Запуск контейнера и создание робота|Запуск контейнера и создание робота]]&#039;&#039;&#039; — старт сервиса и конфигурация робота.&lt;br /&gt;
&lt;br /&gt;
= Глоссарий =&lt;br /&gt;
&#039;&#039;&#039;Модель&#039;&#039;&#039; — обученная нейросеть, задающая соответствие между входом и выходом (текст -&amp;gt; текст, звук -&amp;gt; текст и т.д.). Модель определяется архитектурой и набором весов, полученных при обучении. В стеке робота их четыре:VAD (детекция голосовой активности), ASR (распознавание речи), LLM (генерация ответа), TTS (синтез речи).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Веса&#039;&#039;&#039; — числовые параметры модели, полученные при обучении. Именно они хранятся в файлах модели и загружаются в VRAM при старте. «Загрузка весов» в логах vLLM — это чтение этих файлов с диска в память GPU.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Инференс&#039;&#039;&#039; — использование готовой модели для получения ответа на новый вход («прогон» данных через веса). В отличие от обучения, веса не меняются. Сервисы инференса в статье — Triton, vLLM, LightTTS.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Triton&#039;&#039;&#039; (NVIDIA Triton Inference Server) — сервер инференса от NVIDIA, обслуживающий модели по gRPC и HTTP. В стеке на нём крутится ASR-модель T-one.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TensorRT&#039;&#039;&#039; — библиотека NVIDIA для оптимизации моделей под конкретный GPU: она компилирует модель в специализированный «движок» ради ускорения инференса. Сборка такого движка — разовая операция под железо, поэтому в LightTTS и T-One Triton она выполняется на первой фазе и коммитится в образ.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;vLLM&#039;&#039;&#039; — движок инференса для больших языковых моделей (LLM), оптимизированный на пропускную способность и эффективную работу с памятью. Предоставляет OpenAI-совместимый API.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;nvidia-smi&#039;&#039;&#039; (NVIDIA System Management Interface) — консольная утилита для просмотра состояния GPU: модель карты, версия драйвера, загрузка, потребление VRAM, запущенные процессы. Используется для проверки, что драйвер установлен и GPU виден (в т.ч. изнутри контейнера).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;KV-Cache&#039;&#039;&#039; (кэш ключей и значений) — память, где LLM хранит промежуточные представления уже обработанных токенов, чтобы не пересчитывать их при генерации каждого нового токена. Ускоряет генерацию ценой VRAM. В конфиге ограничен параметром &amp;lt;code&amp;gt;--kv-cache-memory&amp;lt;/code&amp;gt; (3 GiB). Растёт с числом сессий и длиной контекста — поэтому его размер критичен на картах с малым запасом VRAM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;LightTTS&#039;&#039;&#039; — движок инференса для TTS-моделей (синтеза речи). В стеке запускает модель CosyVoice3, слушает порт 8080.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Токен&#039;&#039;&#039; —В &#039;&#039;контексте LLM&#039;&#039; — единица текста, которой оперирует модель (примерно часть слова / слово / знак). Именно в токенах измеряются окно контекста и объём генерации.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Окно контекста&#039;&#039;&#039; — максимальное количество токенов, которое LLM может учитывать за один запрос (вход + генерируемый ответ вместе). Чем больше окно, тем больше VRAM уходит под KV-Cache, поэтому на картах с ограниченным объёмом его сокращают.&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
Установка самого Docker:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установка Nvidia Container Toolkit (только для серверов с GPU):&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# репозиторий&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \&lt;br /&gt;
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \&lt;br /&gt;
  sed &#039;s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g&#039; | \&lt;br /&gt;
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-container-toolkit&lt;br /&gt;
sudo nvidia-ctk runtime configure --runtime=docker&lt;br /&gt;
sudo systemctl restart docker&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (опционально) =&lt;br /&gt;
&lt;br /&gt;
Инструкция для &#039;&#039;&#039;Ubuntu Server 24.04&#039;&#039;&#039;. Стек: ASR (T-one/Triton) → LLM (Qwen3.5-35B-A3B на vLLM) → TTS (LightTTS + CosyVoice3).&lt;br /&gt;
&lt;br /&gt;
Целевая машина — сервер с GPU: &#039;&#039;&#039;RTX PRO 5000 (48GB)&#039;&#039;&#039; или &#039;&#039;&#039;RTX PRO 6000 Blackwell (96GB)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
=== Бюджет VRAM ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Компонент !! VRAM&lt;br /&gt;
|-&lt;br /&gt;
| ASR (T-one/Triton) || 600–800 MB&lt;br /&gt;
|-&lt;br /&gt;
| LLM (Qwen3.5-35B-A3B) || 24–48 GB (зависит от числа сессий и длины контекста)&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS/CosyVoice3) || 10 GB&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Суммарное потребление в пике — ~36–60 GB.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 6000 (96GB):&#039;&#039;&#039; объёма достаточно с большим запасом. Допустимо использование максимального числа сессий и длинного контекста.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 5000 (48GB):&#039;&#039;&#039; запас минимальный. Фиксированная сумма ASR (~0.8 GB) и TTS (11 GB) составляет ~12 GB, на LLM остаётся ~36 GB. Это покрывает только нижнюю границу диапазона LLM (24 GB). Требуется ограничение параметров &amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt; во избежание ошибки OOM. Значение &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; (~24 GB на карте 48GB) для данного сценария допустимо при условии, что ASR и TTS инициализированы до старта LLM.&lt;br /&gt;
&lt;br /&gt;
Объем оперативной памяти не может быть меньше, чем VRAM, так как в процессе запуска веса моделей помещаются сначала в оперативную память, и только затем в VRAM.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Компиляция моделей может занимать больше VRAM, чем запущенный сервис, поэтому в случае дефицита видеопамяти, рекомендуется временно отключать свеже созданные контейнеры, собирать их по одному, после чего запускать по очереди уже в собранном виде.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton Inference Server) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
I0706 22:41:02.484518 1 grpc_server.cc:2562] &amp;quot;Started GRPCInferenceService at 0.0.0.0:8001&amp;quot;&lt;br /&gt;
I0706 22:41:02.484664 1 http_server.cc:4832] &amp;quot;Started HTTPService at 0.0.0.0:8000&amp;quot;&lt;br /&gt;
I0706 22:41:02.525792 1 http_server.cc:358] &amp;quot;Started Metrics Service at 0.0.0.0:8002&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
Установка выполняется из Docker Hub, следующей командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
* &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; — директория хост-машины, где будет храниться кеш весов модели (24gb)&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
После запуска vllm скачает веса модели для запуска (24gb). После завершения запуска и загрузки весов в логах можно наблюдать следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
(APIServer pid=1) INFO:     Started server process [1]&lt;br /&gt;
(APIServer pid=1) INFO:     Waiting for application startup.&lt;br /&gt;
(APIServer pid=1) INFO:     Application startup complete.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Как только они появятся, можно переходить к следующему шагу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080.&#039;&#039;&#039; Первый запрос к модели будет занимать достаточно много времени:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}],&lt;br /&gt;
    &amp;quot;chat_template_kwargs&amp;quot;: {&amp;quot;enable_thinking&amp;quot;: false}&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load -i lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;После запуска сервис скомпилирует веса, по аналогии с T-One. После завершения подготовки в логах будут следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:391] ✅ Startup health check passed!&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:395] ✅ Application ready! Server is now accepting requests&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:396] 🌐 Listening at: http://localhost:8080&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — 10 &#039;&#039;&#039;GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 8000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 8001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После проверки выполняется подключение пайплайна PjSIP → VAD → ASR → LLM → TTS с указанием эндпоинтов в конфигурации: ASR — &amp;lt;code&amp;gt;:8000/:8001&amp;lt;/code&amp;gt;, LLM — &amp;lt;code&amp;gt;:16080&amp;lt;/code&amp;gt;, TTS — &amp;lt;code&amp;gt;:8080&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Базовые параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Плейсхолдер под подробное описание .env --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Запуск контейнера и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
docker load -i secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2424</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2424"/>
		<updated>2026-07-06T23:17:24Z</updated>

		<summary type="html">&lt;p&gt;AZykov: /* 2.5. TTS (LightTTS + CosyVoice3) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Установка и настройка голосового робота Эра (SecondChain) =&lt;br /&gt;
&lt;br /&gt;
Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 1. Подготовка|Подготовка]]&#039;&#039;&#039; — Docker, PostgreSQL, настройки в системе телефонии.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 2. Установка сервисов инференса (опционально)|Установка сервисов инференса]]&#039;&#039;&#039; — ASR, LLM, TTS. &#039;&#039;Опционально, только для развёртывания на собственном сервере с GPU.&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 3. Настройка .env|Настройка .env]]&#039;&#039;&#039; — параметры подключения.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 4. Запуск контейнера и создание робота|Запуск контейнера и создание робота]]&#039;&#039;&#039; — старт сервиса и конфигурация робота.&lt;br /&gt;
&lt;br /&gt;
= Глоссарий =&lt;br /&gt;
&#039;&#039;&#039;Модель&#039;&#039;&#039; — обученная нейросеть, задающая соответствие между входом и выходом (текст -&amp;gt; текст, звук -&amp;gt; текст и т.д.). Модель определяется архитектурой и набором весов, полученных при обучении. В стеке робота их четыре:VAD (детекция голосовой активности), ASR (распознавание речи), LLM (генерация ответа), TTS (синтез речи).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Веса&#039;&#039;&#039; — числовые параметры модели, полученные при обучении. Именно они хранятся в файлах модели и загружаются в VRAM при старте. «Загрузка весов» в логах vLLM — это чтение этих файлов с диска в память GPU.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Инференс&#039;&#039;&#039; — использование готовой модели для получения ответа на новый вход («прогон» данных через веса). В отличие от обучения, веса не меняются. Сервисы инференса в статье — Triton, vLLM, LightTTS.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Triton&#039;&#039;&#039; (NVIDIA Triton Inference Server) — сервер инференса от NVIDIA, обслуживающий модели по gRPC и HTTP. В стеке на нём крутится ASR-модель T-one.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TensorRT&#039;&#039;&#039; — библиотека NVIDIA для оптимизации моделей под конкретный GPU: она компилирует модель в специализированный «движок» ради ускорения инференса. Сборка такого движка — разовая операция под железо, поэтому в LightTTS и T-One Triton она выполняется на первой фазе и коммитится в образ.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;vLLM&#039;&#039;&#039; — движок инференса для больших языковых моделей (LLM), оптимизированный на пропускную способность и эффективную работу с памятью. Предоставляет OpenAI-совместимый API.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;nvidia-smi&#039;&#039;&#039; (NVIDIA System Management Interface) — консольная утилита для просмотра состояния GPU: модель карты, версия драйвера, загрузка, потребление VRAM, запущенные процессы. Используется для проверки, что драйвер установлен и GPU виден (в т.ч. изнутри контейнера).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;KV-Cache&#039;&#039;&#039; (кэш ключей и значений) — память, где LLM хранит промежуточные представления уже обработанных токенов, чтобы не пересчитывать их при генерации каждого нового токена. Ускоряет генерацию ценой VRAM. В конфиге ограничен параметром &amp;lt;code&amp;gt;--kv-cache-memory&amp;lt;/code&amp;gt; (3 GiB). Растёт с числом сессий и длиной контекста — поэтому его размер критичен на картах с малым запасом VRAM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;LightTTS&#039;&#039;&#039; — движок инференса для TTS-моделей (синтеза речи). В стеке запускает модель CosyVoice3, слушает порт 8080.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Токен&#039;&#039;&#039; —В &#039;&#039;контексте LLM&#039;&#039; — единица текста, которой оперирует модель (примерно часть слова / слово / знак). Именно в токенах измеряются окно контекста и объём генерации.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Окно контекста&#039;&#039;&#039; — максимальное количество токенов, которое LLM может учитывать за один запрос (вход + генерируемый ответ вместе). Чем больше окно, тем больше VRAM уходит под KV-Cache, поэтому на картах с ограниченным объёмом его сокращают.&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
Установка самого Docker:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установка Nvidia Container Toolkit (только для серверов с GPU):&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# репозиторий&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \&lt;br /&gt;
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \&lt;br /&gt;
  sed &#039;s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g&#039; | \&lt;br /&gt;
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-container-toolkit&lt;br /&gt;
sudo nvidia-ctk runtime configure --runtime=docker&lt;br /&gt;
sudo systemctl restart docker&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (опционально) =&lt;br /&gt;
&lt;br /&gt;
Инструкция для &#039;&#039;&#039;Ubuntu Server 24.04&#039;&#039;&#039;. Стек: ASR (T-one/Triton) → LLM (Qwen3.5-35B-A3B на vLLM) → TTS (LightTTS + CosyVoice3).&lt;br /&gt;
&lt;br /&gt;
Целевая машина — сервер с GPU: &#039;&#039;&#039;RTX PRO 5000 (48GB)&#039;&#039;&#039; или &#039;&#039;&#039;RTX PRO 6000 Blackwell (96GB)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
=== Бюджет VRAM ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Компонент !! VRAM&lt;br /&gt;
|-&lt;br /&gt;
| ASR (T-one/Triton) || 600–800 MB&lt;br /&gt;
|-&lt;br /&gt;
| LLM (Qwen3.5-35B-A3B) || 24–48 GB (зависит от числа сессий и длины контекста)&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS/CosyVoice3) || 11 GB&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Суммарное потребление в пике — ~36–60 GB.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 6000 (96GB):&#039;&#039;&#039; объёма достаточно с большим запасом. Допустимо использование максимального числа сессий и длинного контекста.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 5000 (48GB):&#039;&#039;&#039; запас минимальный. Фиксированная сумма ASR (~0.8 GB) и TTS (11 GB) составляет ~12 GB, на LLM остаётся ~36 GB. Это покрывает только нижнюю границу диапазона LLM (24 GB). Требуется ограничение параметров &amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt; во избежание ошибки OOM. Значение &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; (~24 GB на карте 48GB) для данного сценария допустимо при условии, что ASR и TTS инициализированы до старта LLM.&lt;br /&gt;
&lt;br /&gt;
Объем оперативной памяти не может быть меньше, чем VRAM, так как в процессе запуска веса моделей помещаются сначала в оперативную память, и только затем в VRAM.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Компиляция моделей может занимать больше VRAM, чем запущенный сервис, поэтому в случае дефицита видеопамяти, рекомендуется временно отключать свеже созданные контейнеры, собирать их по одному, после чего запускать по очереди уже в собранном виде.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton Inference Server) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
I0706 22:41:02.484518 1 grpc_server.cc:2562] &amp;quot;Started GRPCInferenceService at 0.0.0.0:8001&amp;quot;&lt;br /&gt;
I0706 22:41:02.484664 1 http_server.cc:4832] &amp;quot;Started HTTPService at 0.0.0.0:8000&amp;quot;&lt;br /&gt;
I0706 22:41:02.525792 1 http_server.cc:358] &amp;quot;Started Metrics Service at 0.0.0.0:8002&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
Установка выполняется из Docker Hub, следующей командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
* &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; — директория хост-машины, где будет храниться кеш весов модели (24gb)&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
После запуска vllm скачает веса модели для запуска (24gb). После завершения запуска и загрузки весов в логах можно наблюдать следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
(APIServer pid=1) INFO:     Started server process [1]&lt;br /&gt;
(APIServer pid=1) INFO:     Waiting for application startup.&lt;br /&gt;
(APIServer pid=1) INFO:     Application startup complete.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Как только они появятся, можно переходить к следующему шагу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080.&#039;&#039;&#039; Первый запрос к модели будет занимать достаточно много времени:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}],&lt;br /&gt;
    &amp;quot;chat_template_kwargs&amp;quot;: {&amp;quot;enable_thinking&amp;quot;: false}&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker load -i lightts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;После запуска сервис скомпилирует веса, по аналогии с T-One. После завершения подготовки в логах будут следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:391] ✅ Startup health check passed!&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:395] ✅ Application ready! Server is now accepting requests&lt;br /&gt;
INFO 07-06 23:16:49.963 [server/api_http.py:396] 🌐 Listening at: http://localhost:8080&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — &#039;&#039;&#039;11 GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 8000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 8001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После проверки выполняется подключение пайплайна PjSIP → VAD → ASR → LLM → TTS с указанием эндпоинтов в конфигурации: ASR — &amp;lt;code&amp;gt;:8000/:8001&amp;lt;/code&amp;gt;, LLM — &amp;lt;code&amp;gt;:16080&amp;lt;/code&amp;gt;, TTS — &amp;lt;code&amp;gt;:8080&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Базовые параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Плейсхолдер под подробное описание .env --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Запуск контейнера и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
docker load -i secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2423</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2423"/>
		<updated>2026-07-06T23:04:11Z</updated>

		<summary type="html">&lt;p&gt;AZykov: /* Установка и настройка голосового робота Эра (SecondChain) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Установка и настройка голосового робота Эра (SecondChain) =&lt;br /&gt;
&lt;br /&gt;
Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 1. Подготовка|Подготовка]]&#039;&#039;&#039; — Docker, PostgreSQL, настройки в системе телефонии.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 2. Установка сервисов инференса (опционально)|Установка сервисов инференса]]&#039;&#039;&#039; — ASR, LLM, TTS. &#039;&#039;Опционально, только для развёртывания на собственном сервере с GPU.&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 3. Настройка .env|Настройка .env]]&#039;&#039;&#039; — параметры подключения.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 4. Запуск контейнера и создание робота|Запуск контейнера и создание робота]]&#039;&#039;&#039; — старт сервиса и конфигурация робота.&lt;br /&gt;
&lt;br /&gt;
= Глоссарий =&lt;br /&gt;
&#039;&#039;&#039;Модель&#039;&#039;&#039; — обученная нейросеть, задающая соответствие между входом и выходом (текст -&amp;gt; текст, звук -&amp;gt; текст и т.д.). Модель определяется архитектурой и набором весов, полученных при обучении. В стеке робота их четыре:VAD (детекция голосовой активности), ASR (распознавание речи), LLM (генерация ответа), TTS (синтез речи).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Веса&#039;&#039;&#039; — числовые параметры модели, полученные при обучении. Именно они хранятся в файлах модели и загружаются в VRAM при старте. «Загрузка весов» в логах vLLM — это чтение этих файлов с диска в память GPU.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Инференс&#039;&#039;&#039; — использование готовой модели для получения ответа на новый вход («прогон» данных через веса). В отличие от обучения, веса не меняются. Сервисы инференса в статье — Triton, vLLM, LightTTS.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Triton&#039;&#039;&#039; (NVIDIA Triton Inference Server) — сервер инференса от NVIDIA, обслуживающий модели по gRPC и HTTP. В стеке на нём крутится ASR-модель T-one.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TensorRT&#039;&#039;&#039; — библиотека NVIDIA для оптимизации моделей под конкретный GPU: она компилирует модель в специализированный «движок» ради ускорения инференса. Сборка такого движка — разовая операция под железо, поэтому в LightTTS и T-One Triton она выполняется на первой фазе и коммитится в образ.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;vLLM&#039;&#039;&#039; — движок инференса для больших языковых моделей (LLM), оптимизированный на пропускную способность и эффективную работу с памятью. Предоставляет OpenAI-совместимый API.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;nvidia-smi&#039;&#039;&#039; (NVIDIA System Management Interface) — консольная утилита для просмотра состояния GPU: модель карты, версия драйвера, загрузка, потребление VRAM, запущенные процессы. Используется для проверки, что драйвер установлен и GPU виден (в т.ч. изнутри контейнера).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;KV-Cache&#039;&#039;&#039; (кэш ключей и значений) — память, где LLM хранит промежуточные представления уже обработанных токенов, чтобы не пересчитывать их при генерации каждого нового токена. Ускоряет генерацию ценой VRAM. В конфиге ограничен параметром &amp;lt;code&amp;gt;--kv-cache-memory&amp;lt;/code&amp;gt; (3 GiB). Растёт с числом сессий и длиной контекста — поэтому его размер критичен на картах с малым запасом VRAM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;LightTTS&#039;&#039;&#039; — движок инференса для TTS-моделей (синтеза речи). В стеке запускает модель CosyVoice3, слушает порт 8080.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Токен&#039;&#039;&#039; —В &#039;&#039;контексте LLM&#039;&#039; — единица текста, которой оперирует модель (примерно часть слова / слово / знак). Именно в токенах измеряются окно контекста и объём генерации.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Окно контекста&#039;&#039;&#039; — максимальное количество токенов, которое LLM может учитывать за один запрос (вход + генерируемый ответ вместе). Чем больше окно, тем больше VRAM уходит под KV-Cache, поэтому на картах с ограниченным объёмом его сокращают.&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
Установка самого Docker:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установка Nvidia Container Toolkit (только для серверов с GPU):&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# репозиторий&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \&lt;br /&gt;
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \&lt;br /&gt;
  sed &#039;s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g&#039; | \&lt;br /&gt;
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-container-toolkit&lt;br /&gt;
sudo nvidia-ctk runtime configure --runtime=docker&lt;br /&gt;
sudo systemctl restart docker&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (опционально) =&lt;br /&gt;
&lt;br /&gt;
Инструкция для &#039;&#039;&#039;Ubuntu Server 24.04&#039;&#039;&#039;. Стек: ASR (T-one/Triton) → LLM (Qwen3.5-35B-A3B на vLLM) → TTS (LightTTS + CosyVoice3).&lt;br /&gt;
&lt;br /&gt;
Целевая машина — сервер с GPU: &#039;&#039;&#039;RTX PRO 5000 (48GB)&#039;&#039;&#039; или &#039;&#039;&#039;RTX PRO 6000 Blackwell (96GB)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
=== Бюджет VRAM ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Компонент !! VRAM&lt;br /&gt;
|-&lt;br /&gt;
| ASR (T-one/Triton) || 600–800 MB&lt;br /&gt;
|-&lt;br /&gt;
| LLM (Qwen3.5-35B-A3B) || 24–48 GB (зависит от числа сессий и длины контекста)&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS/CosyVoice3) || 11 GB&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Суммарное потребление в пике — ~36–60 GB.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 6000 (96GB):&#039;&#039;&#039; объёма достаточно с большим запасом. Допустимо использование максимального числа сессий и длинного контекста.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 5000 (48GB):&#039;&#039;&#039; запас минимальный. Фиксированная сумма ASR (~0.8 GB) и TTS (11 GB) составляет ~12 GB, на LLM остаётся ~36 GB. Это покрывает только нижнюю границу диапазона LLM (24 GB). Требуется ограничение параметров &amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt; во избежание ошибки OOM. Значение &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; (~24 GB на карте 48GB) для данного сценария допустимо при условии, что ASR и TTS инициализированы до старта LLM.&lt;br /&gt;
&lt;br /&gt;
Объем оперативной памяти не может быть меньше, чем VRAM, так как в процессе запуска веса моделей помещаются сначала в оперативную память, и только затем в VRAM.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Компиляция моделей может занимать больше VRAM, чем запущенный сервис, поэтому в случае дефицита видеопамяти, рекомендуется временно отключать свеже созданные контейнеры, собирать их по одному, после чего запускать по очереди уже в собранном виде.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton Inference Server) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
I0706 22:41:02.484518 1 grpc_server.cc:2562] &amp;quot;Started GRPCInferenceService at 0.0.0.0:8001&amp;quot;&lt;br /&gt;
I0706 22:41:02.484664 1 http_server.cc:4832] &amp;quot;Started HTTPService at 0.0.0.0:8000&amp;quot;&lt;br /&gt;
I0706 22:41:02.525792 1 http_server.cc:358] &amp;quot;Started Metrics Service at 0.0.0.0:8002&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
Установка выполняется из Docker Hub, следующей командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
* &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; — директория хост-машины, где будет храниться кеш весов модели (24gb)&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
После запуска vllm скачает веса модели для запуска (24gb). После завершения запуска и загрузки весов в логах можно наблюдать следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
(APIServer pid=1) INFO:     Started server process [1]&lt;br /&gt;
(APIServer pid=1) INFO:     Waiting for application startup.&lt;br /&gt;
(APIServer pid=1) INFO:     Application startup complete.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Как только они появятся, можно переходить к следующему шагу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080.&#039;&#039;&#039; Первый запрос к модели будет занимать достаточно много времени:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}],&lt;br /&gt;
    &amp;quot;chat_template_kwargs&amp;quot;: {&amp;quot;enable_thinking&amp;quot;: false}&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
docker load -i lighttts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;После запуска сервис скомпилирует веса, по аналогии с T-One. После завершения подготовки в логах будут следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
///////////////////////&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — &#039;&#039;&#039;11 GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 8000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 8001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После проверки выполняется подключение пайплайна PjSIP → VAD → ASR → LLM → TTS с указанием эндпоинтов в конфигурации: ASR — &amp;lt;code&amp;gt;:8000/:8001&amp;lt;/code&amp;gt;, LLM — &amp;lt;code&amp;gt;:16080&amp;lt;/code&amp;gt;, TTS — &amp;lt;code&amp;gt;:8080&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Базовые параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Плейсхолдер под подробное описание .env --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Запуск контейнера и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
docker load -i secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2422</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2422"/>
		<updated>2026-07-06T22:56:52Z</updated>

		<summary type="html">&lt;p&gt;AZykov: /* 2.6. Итоговая карта портов */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Установка и настройка голосового робота Эра (SecondChain) =&lt;br /&gt;
&lt;br /&gt;
Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 1. Подготовка|Подготовка]]&#039;&#039;&#039; — Docker, PostgreSQL, настройки в системе телефонии.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 2. Установка сервисов инференса (опционально)|Установка сервисов инференса]]&#039;&#039;&#039; — ASR, LLM, TTS. &#039;&#039;Опционально, только для развёртывания на собственном сервере с GPU.&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 3. Настройка .env|Настройка .env]]&#039;&#039;&#039; — параметры подключения.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 4. Запуск контейнера и создание робота|Запуск контейнера и создание робота]]&#039;&#039;&#039; — старт сервиса и конфигурация робота.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
Установка самого Docker:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установка Nvidia Container Toolkit (только для серверов с GPU):&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# репозиторий&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \&lt;br /&gt;
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \&lt;br /&gt;
  sed &#039;s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g&#039; | \&lt;br /&gt;
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-container-toolkit&lt;br /&gt;
sudo nvidia-ctk runtime configure --runtime=docker&lt;br /&gt;
sudo systemctl restart docker&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (опционально) =&lt;br /&gt;
&lt;br /&gt;
Инструкция для &#039;&#039;&#039;Ubuntu Server 24.04&#039;&#039;&#039;. Стек: ASR (T-one/Triton) → LLM (Qwen3.5-35B-A3B на vLLM) → TTS (LightTTS + CosyVoice3).&lt;br /&gt;
&lt;br /&gt;
Целевая машина — сервер с GPU: &#039;&#039;&#039;RTX PRO 5000 (48GB)&#039;&#039;&#039; или &#039;&#039;&#039;RTX PRO 6000 Blackwell (96GB)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
=== Бюджет VRAM ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Компонент !! VRAM&lt;br /&gt;
|-&lt;br /&gt;
| ASR (T-one/Triton) || 600–800 MB&lt;br /&gt;
|-&lt;br /&gt;
| LLM (Qwen3.5-35B-A3B) || 24–48 GB (зависит от числа сессий и длины контекста)&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS/CosyVoice3) || 11 GB&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Суммарное потребление в пике — ~36–60 GB.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 6000 (96GB):&#039;&#039;&#039; объёма достаточно с большим запасом. Допустимо использование максимального числа сессий и длинного контекста.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 5000 (48GB):&#039;&#039;&#039; запас минимальный. Фиксированная сумма ASR (~0.8 GB) и TTS (11 GB) составляет ~12 GB, на LLM остаётся ~36 GB. Это покрывает только нижнюю границу диапазона LLM (24 GB). Требуется ограничение параметров &amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt; во избежание ошибки OOM. Значение &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; (~24 GB на карте 48GB) для данного сценария допустимо при условии, что ASR и TTS инициализированы до старта LLM.&lt;br /&gt;
&lt;br /&gt;
Объем оперативной памяти не может быть меньше, чем VRAM, так как в процессе запуска веса моделей помещаются сначала в оперативную память, и только затем в VRAM.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Компиляция моделей может занимать больше VRAM, чем запущенный сервис, поэтому в случае дефицита видеопамяти, рекомендуется временно отключать свеже созданные контейнеры, собирать их по одному, после чего запускать по очереди уже в собранном виде.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton Inference Server) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
I0706 22:41:02.484518 1 grpc_server.cc:2562] &amp;quot;Started GRPCInferenceService at 0.0.0.0:8001&amp;quot;&lt;br /&gt;
I0706 22:41:02.484664 1 http_server.cc:4832] &amp;quot;Started HTTPService at 0.0.0.0:8000&amp;quot;&lt;br /&gt;
I0706 22:41:02.525792 1 http_server.cc:358] &amp;quot;Started Metrics Service at 0.0.0.0:8002&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
Установка выполняется из Docker Hub, следующей командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
* &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; — директория хост-машины, где будет храниться кеш весов модели (24gb)&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
После запуска vllm скачает веса модели для запуска (24gb). После завершения запуска и загрузки весов в логах можно наблюдать следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
(APIServer pid=1) INFO:     Started server process [1]&lt;br /&gt;
(APIServer pid=1) INFO:     Waiting for application startup.&lt;br /&gt;
(APIServer pid=1) INFO:     Application startup complete.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Как только они появятся, можно переходить к следующему шагу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080.&#039;&#039;&#039; Первый запрос к модели будет занимать достаточно много времени:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}],&lt;br /&gt;
    &amp;quot;chat_template_kwargs&amp;quot;: {&amp;quot;enable_thinking&amp;quot;: false}&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
docker load -i lighttts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;После запуска сервис скомпилирует веса, по аналогии с T-One. После завершения подготовки в логах будут следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
///////////////////////&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — &#039;&#039;&#039;11 GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 8000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;tone-triton&amp;lt;/code&amp;gt; || 8001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После проверки выполняется подключение пайплайна PjSIP → VAD → ASR → LLM → TTS с указанием эндпоинтов в конфигурации: ASR — &amp;lt;code&amp;gt;:8000/:8001&amp;lt;/code&amp;gt;, LLM — &amp;lt;code&amp;gt;:16080&amp;lt;/code&amp;gt;, TTS — &amp;lt;code&amp;gt;:8080&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Базовые параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Плейсхолдер под подробное описание .env --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Запуск контейнера и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
docker load -i secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2421</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2421"/>
		<updated>2026-07-06T22:56:23Z</updated>

		<summary type="html">&lt;p&gt;AZykov: /* 2.5. TTS (LightTTS + CosyVoice3) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Установка и настройка голосового робота Эра (SecondChain) =&lt;br /&gt;
&lt;br /&gt;
Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 1. Подготовка|Подготовка]]&#039;&#039;&#039; — Docker, PostgreSQL, настройки в системе телефонии.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 2. Установка сервисов инференса (опционально)|Установка сервисов инференса]]&#039;&#039;&#039; — ASR, LLM, TTS. &#039;&#039;Опционально, только для развёртывания на собственном сервере с GPU.&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 3. Настройка .env|Настройка .env]]&#039;&#039;&#039; — параметры подключения.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 4. Запуск контейнера и создание робота|Запуск контейнера и создание робота]]&#039;&#039;&#039; — старт сервиса и конфигурация робота.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
Установка самого Docker:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установка Nvidia Container Toolkit (только для серверов с GPU):&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# репозиторий&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \&lt;br /&gt;
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \&lt;br /&gt;
  sed &#039;s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g&#039; | \&lt;br /&gt;
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-container-toolkit&lt;br /&gt;
sudo nvidia-ctk runtime configure --runtime=docker&lt;br /&gt;
sudo systemctl restart docker&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (опционально) =&lt;br /&gt;
&lt;br /&gt;
Инструкция для &#039;&#039;&#039;Ubuntu Server 24.04&#039;&#039;&#039;. Стек: ASR (T-one/Triton) → LLM (Qwen3.5-35B-A3B на vLLM) → TTS (LightTTS + CosyVoice3).&lt;br /&gt;
&lt;br /&gt;
Целевая машина — сервер с GPU: &#039;&#039;&#039;RTX PRO 5000 (48GB)&#039;&#039;&#039; или &#039;&#039;&#039;RTX PRO 6000 Blackwell (96GB)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
=== Бюджет VRAM ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Компонент !! VRAM&lt;br /&gt;
|-&lt;br /&gt;
| ASR (T-one/Triton) || 600–800 MB&lt;br /&gt;
|-&lt;br /&gt;
| LLM (Qwen3.5-35B-A3B) || 24–48 GB (зависит от числа сессий и длины контекста)&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS/CosyVoice3) || 11 GB&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Суммарное потребление в пике — ~36–60 GB.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 6000 (96GB):&#039;&#039;&#039; объёма достаточно с большим запасом. Допустимо использование максимального числа сессий и длинного контекста.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 5000 (48GB):&#039;&#039;&#039; запас минимальный. Фиксированная сумма ASR (~0.8 GB) и TTS (11 GB) составляет ~12 GB, на LLM остаётся ~36 GB. Это покрывает только нижнюю границу диапазона LLM (24 GB). Требуется ограничение параметров &amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt; во избежание ошибки OOM. Значение &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; (~24 GB на карте 48GB) для данного сценария допустимо при условии, что ASR и TTS инициализированы до старта LLM.&lt;br /&gt;
&lt;br /&gt;
Объем оперативной памяти не может быть меньше, чем VRAM, так как в процессе запуска веса моделей помещаются сначала в оперативную память, и только затем в VRAM.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Компиляция моделей может занимать больше VRAM, чем запущенный сервис, поэтому в случае дефицита видеопамяти, рекомендуется временно отключать свеже созданные контейнеры, собирать их по одному, после чего запускать по очереди уже в собранном виде.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
I0706 22:41:02.484518 1 grpc_server.cc:2562] &amp;quot;Started GRPCInferenceService at 0.0.0.0:8001&amp;quot;&lt;br /&gt;
I0706 22:41:02.484664 1 http_server.cc:4832] &amp;quot;Started HTTPService at 0.0.0.0:8000&amp;quot;&lt;br /&gt;
I0706 22:41:02.525792 1 http_server.cc:358] &amp;quot;Started Metrics Service at 0.0.0.0:8002&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
Установка выполняется из Docker Hub, следующей командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
* &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; — директория хост-машины, где будет храниться кеш весов модели (24gb)&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
После запуска vllm скачает веса модели для запуска (24gb). После завершения запуска и загрузки весов в логах можно наблюдать следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
(APIServer pid=1) INFO:     Started server process [1]&lt;br /&gt;
(APIServer pid=1) INFO:     Waiting for application startup.&lt;br /&gt;
(APIServer pid=1) INFO:     Application startup complete.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Как только они появятся, можно переходить к следующему шагу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080.&#039;&#039;&#039; Первый запрос к модели будет занимать достаточно много времени:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}],&lt;br /&gt;
    &amp;quot;chat_template_kwargs&amp;quot;: {&amp;quot;enable_thinking&amp;quot;: false}&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
docker load -i lighttts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;После запуска сервис скомпилирует веса, по аналогии с T-One. После завершения подготовки в логах будут следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
///////////////////////&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — &#039;&#039;&#039;11 GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;*tone*&amp;lt;/code&amp;gt; || 8000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;*tone*&amp;lt;/code&amp;gt; || 8001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После проверки выполняется подключение пайплайна PjSIP → VAD → ASR → LLM → TTS с указанием эндпоинтов в конфигурации: ASR — &amp;lt;code&amp;gt;:8000/:8001&amp;lt;/code&amp;gt;, LLM — &amp;lt;code&amp;gt;:16080&amp;lt;/code&amp;gt;, TTS — &amp;lt;code&amp;gt;:8080&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Базовые параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Плейсхолдер под подробное описание .env --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Запуск контейнера и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
docker load -i secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2420</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2420"/>
		<updated>2026-07-06T22:54:22Z</updated>

		<summary type="html">&lt;p&gt;AZykov: /* 2.4. LLM (Qwen3.5-35B-A3B на vLLM) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Установка и настройка голосового робота Эра (SecondChain) =&lt;br /&gt;
&lt;br /&gt;
Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 1. Подготовка|Подготовка]]&#039;&#039;&#039; — Docker, PostgreSQL, настройки в системе телефонии.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 2. Установка сервисов инференса (опционально)|Установка сервисов инференса]]&#039;&#039;&#039; — ASR, LLM, TTS. &#039;&#039;Опционально, только для развёртывания на собственном сервере с GPU.&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 3. Настройка .env|Настройка .env]]&#039;&#039;&#039; — параметры подключения.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 4. Запуск контейнера и создание робота|Запуск контейнера и создание робота]]&#039;&#039;&#039; — старт сервиса и конфигурация робота.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
Установка самого Docker:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установка Nvidia Container Toolkit (только для серверов с GPU):&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# репозиторий&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \&lt;br /&gt;
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \&lt;br /&gt;
  sed &#039;s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g&#039; | \&lt;br /&gt;
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-container-toolkit&lt;br /&gt;
sudo nvidia-ctk runtime configure --runtime=docker&lt;br /&gt;
sudo systemctl restart docker&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (опционально) =&lt;br /&gt;
&lt;br /&gt;
Инструкция для &#039;&#039;&#039;Ubuntu Server 24.04&#039;&#039;&#039;. Стек: ASR (T-one/Triton) → LLM (Qwen3.5-35B-A3B на vLLM) → TTS (LightTTS + CosyVoice3).&lt;br /&gt;
&lt;br /&gt;
Целевая машина — сервер с GPU: &#039;&#039;&#039;RTX PRO 5000 (48GB)&#039;&#039;&#039; или &#039;&#039;&#039;RTX PRO 6000 Blackwell (96GB)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
=== Бюджет VRAM ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Компонент !! VRAM&lt;br /&gt;
|-&lt;br /&gt;
| ASR (T-one/Triton) || 600–800 MB&lt;br /&gt;
|-&lt;br /&gt;
| LLM (Qwen3.5-35B-A3B) || 24–48 GB (зависит от числа сессий и длины контекста)&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS/CosyVoice3) || 11 GB&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Суммарное потребление в пике — ~36–60 GB.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 6000 (96GB):&#039;&#039;&#039; объёма достаточно с большим запасом. Допустимо использование максимального числа сессий и длинного контекста.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 5000 (48GB):&#039;&#039;&#039; запас минимальный. Фиксированная сумма ASR (~0.8 GB) и TTS (11 GB) составляет ~12 GB, на LLM остаётся ~36 GB. Это покрывает только нижнюю границу диапазона LLM (24 GB). Требуется ограничение параметров &amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt; во избежание ошибки OOM. Значение &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; (~24 GB на карте 48GB) для данного сценария допустимо при условии, что ASR и TTS инициализированы до старта LLM.&lt;br /&gt;
&lt;br /&gt;
Объем оперативной памяти не может быть меньше, чем VRAM, так как в процессе запуска веса моделей помещаются сначала в оперативную память, и только затем в VRAM.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Компиляция моделей может занимать больше VRAM, чем запущенный сервис, поэтому в случае дефицита видеопамяти, рекомендуется временно отключать свеже созданные контейнеры, собирать их по одному, после чего запускать по очереди уже в собранном виде.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
I0706 22:41:02.484518 1 grpc_server.cc:2562] &amp;quot;Started GRPCInferenceService at 0.0.0.0:8001&amp;quot;&lt;br /&gt;
I0706 22:41:02.484664 1 http_server.cc:4832] &amp;quot;Started HTTPService at 0.0.0.0:8000&amp;quot;&lt;br /&gt;
I0706 22:41:02.525792 1 http_server.cc:358] &amp;quot;Started Metrics Service at 0.0.0.0:8002&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
Установка выполняется из Docker Hub, следующей командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
* &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; — директория хост-машины, где будет храниться кеш весов модели (24gb)&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
После запуска vllm скачает веса модели для запуска (24gb). После завершения запуска и загрузки весов в логах можно наблюдать следующие строки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
(APIServer pid=1) INFO:     Started server process [1]&lt;br /&gt;
(APIServer pid=1) INFO:     Waiting for application startup.&lt;br /&gt;
(APIServer pid=1) INFO:     Application startup complete.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Как только они появятся, можно переходить к следующему шагу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080.&#039;&#039;&#039; Первый запрос к модели будет занимать достаточно много времени:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}],&lt;br /&gt;
    &amp;quot;chat_template_kwargs&amp;quot;: {&amp;quot;enable_thinking&amp;quot;: false}&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
docker load -i lighttts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — &#039;&#039;&#039;11 GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;*tone*&amp;lt;/code&amp;gt; || 8000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;*tone*&amp;lt;/code&amp;gt; || 8001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После проверки выполняется подключение пайплайна PjSIP → VAD → ASR → LLM → TTS с указанием эндпоинтов в конфигурации: ASR — &amp;lt;code&amp;gt;:8000/:8001&amp;lt;/code&amp;gt;, LLM — &amp;lt;code&amp;gt;:16080&amp;lt;/code&amp;gt;, TTS — &amp;lt;code&amp;gt;:8080&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Базовые параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Плейсхолдер под подробное описание .env --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Запуск контейнера и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
docker load -i secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2419</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2419"/>
		<updated>2026-07-06T22:52:36Z</updated>

		<summary type="html">&lt;p&gt;AZykov: /* 2.4. LLM (Qwen3.5-35B-A3B на vLLM) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Установка и настройка голосового робота Эра (SecondChain) =&lt;br /&gt;
&lt;br /&gt;
Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 1. Подготовка|Подготовка]]&#039;&#039;&#039; — Docker, PostgreSQL, настройки в системе телефонии.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 2. Установка сервисов инференса (опционально)|Установка сервисов инференса]]&#039;&#039;&#039; — ASR, LLM, TTS. &#039;&#039;Опционально, только для развёртывания на собственном сервере с GPU.&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 3. Настройка .env|Настройка .env]]&#039;&#039;&#039; — параметры подключения.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 4. Запуск контейнера и создание робота|Запуск контейнера и создание робота]]&#039;&#039;&#039; — старт сервиса и конфигурация робота.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
Установка самого Docker:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установка Nvidia Container Toolkit (только для серверов с GPU):&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# репозиторий&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \&lt;br /&gt;
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \&lt;br /&gt;
  sed &#039;s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g&#039; | \&lt;br /&gt;
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-container-toolkit&lt;br /&gt;
sudo nvidia-ctk runtime configure --runtime=docker&lt;br /&gt;
sudo systemctl restart docker&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (опционально) =&lt;br /&gt;
&lt;br /&gt;
Инструкция для &#039;&#039;&#039;Ubuntu Server 24.04&#039;&#039;&#039;. Стек: ASR (T-one/Triton) → LLM (Qwen3.5-35B-A3B на vLLM) → TTS (LightTTS + CosyVoice3).&lt;br /&gt;
&lt;br /&gt;
Целевая машина — сервер с GPU: &#039;&#039;&#039;RTX PRO 5000 (48GB)&#039;&#039;&#039; или &#039;&#039;&#039;RTX PRO 6000 Blackwell (96GB)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
=== Бюджет VRAM ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Компонент !! VRAM&lt;br /&gt;
|-&lt;br /&gt;
| ASR (T-one/Triton) || 600–800 MB&lt;br /&gt;
|-&lt;br /&gt;
| LLM (Qwen3.5-35B-A3B) || 24–48 GB (зависит от числа сессий и длины контекста)&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS/CosyVoice3) || 11 GB&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Суммарное потребление в пике — ~36–60 GB.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 6000 (96GB):&#039;&#039;&#039; объёма достаточно с большим запасом. Допустимо использование максимального числа сессий и длинного контекста.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 5000 (48GB):&#039;&#039;&#039; запас минимальный. Фиксированная сумма ASR (~0.8 GB) и TTS (11 GB) составляет ~12 GB, на LLM остаётся ~36 GB. Это покрывает только нижнюю границу диапазона LLM (24 GB). Требуется ограничение параметров &amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt; во избежание ошибки OOM. Значение &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; (~24 GB на карте 48GB) для данного сценария допустимо при условии, что ASR и TTS инициализированы до старта LLM.&lt;br /&gt;
&lt;br /&gt;
Объем оперативной памяти не может быть меньше, чем VRAM, так как в процессе запуска веса моделей помещаются сначала в оперативную память, и только затем в VRAM.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Компиляция моделей может занимать больше VRAM, чем запущенный сервис, поэтому в случае дефицита видеопамяти, рекомендуется временно отключать свеже созданные контейнеры, собирать их по одному, после чего запускать по очереди уже в собранном виде.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
I0706 22:41:02.484518 1 grpc_server.cc:2562] &amp;quot;Started GRPCInferenceService at 0.0.0.0:8001&amp;quot;&lt;br /&gt;
I0706 22:41:02.484664 1 http_server.cc:4832] &amp;quot;Started HTTPService at 0.0.0.0:8000&amp;quot;&lt;br /&gt;
I0706 22:41:02.525792 1 http_server.cc:358] &amp;quot;Started Metrics Service at 0.0.0.0:8002&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
Установка выполняется из Docker Hub, следующей командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
* &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; — директория хост-машины, где будет храниться кеш весов модели (24gb)&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
После запуска vllm также будет компилировать веса модели под текущий GPU, это занимает от 5 до 20 минут. После завершения компиляции в логах будут следующие строчки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
(APIServer pid=1) INFO:     Started server process [1]&lt;br /&gt;
(APIServer pid=1) INFO:     Waiting for application startup.&lt;br /&gt;
(APIServer pid=1) INFO:     Application startup complete.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Как только они появятся, можно переходить к следующему шагу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080.&#039;&#039;&#039; Первый запрос к модели будет занимать достаточно много времени:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}],&lt;br /&gt;
    &amp;quot;chat_template_kwargs&amp;quot;: {&amp;quot;enable_thinking&amp;quot;: false}&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
docker load -i lighttts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — &#039;&#039;&#039;11 GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;*tone*&amp;lt;/code&amp;gt; || 8000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;*tone*&amp;lt;/code&amp;gt; || 8001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После проверки выполняется подключение пайплайна PjSIP → VAD → ASR → LLM → TTS с указанием эндпоинтов в конфигурации: ASR — &amp;lt;code&amp;gt;:8000/:8001&amp;lt;/code&amp;gt;, LLM — &amp;lt;code&amp;gt;:16080&amp;lt;/code&amp;gt;, TTS — &amp;lt;code&amp;gt;:8080&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Базовые параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Плейсхолдер под подробное описание .env --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Запуск контейнера и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
docker load -i secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2418</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2418"/>
		<updated>2026-07-06T22:43:55Z</updated>

		<summary type="html">&lt;p&gt;AZykov: /* 2.2. Порядок запуска */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Установка и настройка голосового робота Эра (SecondChain) =&lt;br /&gt;
&lt;br /&gt;
Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 1. Подготовка|Подготовка]]&#039;&#039;&#039; — Docker, PostgreSQL, настройки в системе телефонии.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 2. Установка сервисов инференса (опционально)|Установка сервисов инференса]]&#039;&#039;&#039; — ASR, LLM, TTS. &#039;&#039;Опционально, только для развёртывания на собственном сервере с GPU.&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 3. Настройка .env|Настройка .env]]&#039;&#039;&#039; — параметры подключения.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 4. Запуск контейнера и создание робота|Запуск контейнера и создание робота]]&#039;&#039;&#039; — старт сервиса и конфигурация робота.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
Установка самого Docker:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установка Nvidia Container Toolkit (только для серверов с GPU):&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# репозиторий&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \&lt;br /&gt;
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \&lt;br /&gt;
  sed &#039;s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g&#039; | \&lt;br /&gt;
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-container-toolkit&lt;br /&gt;
sudo nvidia-ctk runtime configure --runtime=docker&lt;br /&gt;
sudo systemctl restart docker&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (опционально) =&lt;br /&gt;
&lt;br /&gt;
Инструкция для &#039;&#039;&#039;Ubuntu Server 24.04&#039;&#039;&#039;. Стек: ASR (T-one/Triton) → LLM (Qwen3.5-35B-A3B на vLLM) → TTS (LightTTS + CosyVoice3).&lt;br /&gt;
&lt;br /&gt;
Целевая машина — сервер с GPU: &#039;&#039;&#039;RTX PRO 5000 (48GB)&#039;&#039;&#039; или &#039;&#039;&#039;RTX PRO 6000 Blackwell (96GB)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
=== Бюджет VRAM ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Компонент !! VRAM&lt;br /&gt;
|-&lt;br /&gt;
| ASR (T-one/Triton) || 600–800 MB&lt;br /&gt;
|-&lt;br /&gt;
| LLM (Qwen3.5-35B-A3B) || 24–48 GB (зависит от числа сессий и длины контекста)&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS/CosyVoice3) || 11 GB&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Суммарное потребление в пике — ~36–60 GB.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 6000 (96GB):&#039;&#039;&#039; объёма достаточно с большим запасом. Допустимо использование максимального числа сессий и длинного контекста.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 5000 (48GB):&#039;&#039;&#039; запас минимальный. Фиксированная сумма ASR (~0.8 GB) и TTS (11 GB) составляет ~12 GB, на LLM остаётся ~36 GB. Это покрывает только нижнюю границу диапазона LLM (24 GB). Требуется ограничение параметров &amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt; во избежание ошибки OOM. Значение &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; (~24 GB на карте 48GB) для данного сценария допустимо при условии, что ASR и TTS инициализированы до старта LLM.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Компиляция моделей может занимать больше VRAM, чем запущенный сервис, поэтому в случае дефицита видеопамяти, рекомендуется временно отключать свеже созданные контейнеры, собирать их по одному, после чего запускать по очереди уже в собранном виде.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
I0706 22:41:02.484518 1 grpc_server.cc:2562] &amp;quot;Started GRPCInferenceService at 0.0.0.0:8001&amp;quot;&lt;br /&gt;
I0706 22:41:02.484664 1 http_server.cc:4832] &amp;quot;Started HTTPService at 0.0.0.0:8000&amp;quot;&lt;br /&gt;
I0706 22:41:02.525792 1 http_server.cc:358] &amp;quot;Started Metrics Service at 0.0.0.0:8002&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
Установка выполняется из Docker Hub, следующей командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
* &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; — директория хост-машины, где будет храниться кеш весов модели (24gb)&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
После запуска vllm также будет компилировать веса модели под текущий GPU, это занимает от 5 до 20 минут. После завершения компиляции в логах будут следующие строчки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/////////////&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Как только они появятся, можно переходить к следующему шагу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}]&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
docker load -i lighttts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — &#039;&#039;&#039;11 GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;*tone*&amp;lt;/code&amp;gt; || 8000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;*tone*&amp;lt;/code&amp;gt; || 8001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После проверки выполняется подключение пайплайна PjSIP → VAD → ASR → LLM → TTS с указанием эндпоинтов в конфигурации: ASR — &amp;lt;code&amp;gt;:8000/:8001&amp;lt;/code&amp;gt;, LLM — &amp;lt;code&amp;gt;:16080&amp;lt;/code&amp;gt;, TTS — &amp;lt;code&amp;gt;:8080&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Базовые параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Плейсхолдер под подробное описание .env --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Запуск контейнера и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
docker load -i secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2417</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2417"/>
		<updated>2026-07-06T22:41:25Z</updated>

		<summary type="html">&lt;p&gt;AZykov: /* 2.3. ASR (T-one на Triton) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Установка и настройка голосового робота Эра (SecondChain) =&lt;br /&gt;
&lt;br /&gt;
Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 1. Подготовка|Подготовка]]&#039;&#039;&#039; — Docker, PostgreSQL, настройки в системе телефонии.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 2. Установка сервисов инференса (опционально)|Установка сервисов инференса]]&#039;&#039;&#039; — ASR, LLM, TTS. &#039;&#039;Опционально, только для развёртывания на собственном сервере с GPU.&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 3. Настройка .env|Настройка .env]]&#039;&#039;&#039; — параметры подключения.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 4. Запуск контейнера и создание робота|Запуск контейнера и создание робота]]&#039;&#039;&#039; — старт сервиса и конфигурация робота.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
Установка самого Docker:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установка Nvidia Container Toolkit (только для серверов с GPU):&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# репозиторий&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \&lt;br /&gt;
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \&lt;br /&gt;
  sed &#039;s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g&#039; | \&lt;br /&gt;
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-container-toolkit&lt;br /&gt;
sudo nvidia-ctk runtime configure --runtime=docker&lt;br /&gt;
sudo systemctl restart docker&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (опционально) =&lt;br /&gt;
&lt;br /&gt;
Инструкция для &#039;&#039;&#039;Ubuntu Server 24.04&#039;&#039;&#039;. Стек: ASR (T-one/Triton) → LLM (Qwen3.5-35B-A3B на vLLM) → TTS (LightTTS + CosyVoice3).&lt;br /&gt;
&lt;br /&gt;
Целевая машина — сервер с GPU: &#039;&#039;&#039;RTX PRO 5000 (48GB)&#039;&#039;&#039; или &#039;&#039;&#039;RTX PRO 6000 Blackwell (96GB)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
=== Бюджет VRAM ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Компонент !! VRAM&lt;br /&gt;
|-&lt;br /&gt;
| ASR (T-one/Triton) || 600–800 MB&lt;br /&gt;
|-&lt;br /&gt;
| LLM (Qwen3.5-35B-A3B) || 24–48 GB (зависит от числа сессий и длины контекста)&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS/CosyVoice3) || 11 GB&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Суммарное потребление в пике — ~36–60 GB.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 6000 (96GB):&#039;&#039;&#039; объёма достаточно с большим запасом. Допустимо использование максимального числа сессий и длинного контекста.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 5000 (48GB):&#039;&#039;&#039; запас минимальный. Фиксированная сумма ASR (~0.8 GB) и TTS (11 GB) составляет ~12 GB, на LLM остаётся ~36 GB. Это покрывает только нижнюю границу диапазона LLM (24 GB). Требуется ограничение параметров &amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt; во избежание ошибки OOM. Значение &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; (~24 GB на карте 48GB) для данного сценария допустимо при условии, что ASR и TTS инициализированы до старта LLM.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
I0706 22:41:02.484518 1 grpc_server.cc:2562] &amp;quot;Started GRPCInferenceService at 0.0.0.0:8001&amp;quot;&lt;br /&gt;
I0706 22:41:02.484664 1 http_server.cc:4832] &amp;quot;Started HTTPService at 0.0.0.0:8000&amp;quot;&lt;br /&gt;
I0706 22:41:02.525792 1 http_server.cc:358] &amp;quot;Started Metrics Service at 0.0.0.0:8002&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
Установка выполняется из Docker Hub, следующей командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
* &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; — директория хост-машины, где будет храниться кеш весов модели (24gb)&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
После запуска vllm также будет компилировать веса модели под текущий GPU, это занимает от 5 до 20 минут. После завершения компиляции в логах будут следующие строчки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/////////////&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Как только они появятся, можно переходить к следующему шагу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}]&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
docker load -i lighttts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — &#039;&#039;&#039;11 GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;*tone*&amp;lt;/code&amp;gt; || 8000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;*tone*&amp;lt;/code&amp;gt; || 8001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После проверки выполняется подключение пайплайна PjSIP → VAD → ASR → LLM → TTS с указанием эндпоинтов в конфигурации: ASR — &amp;lt;code&amp;gt;:8000/:8001&amp;lt;/code&amp;gt;, LLM — &amp;lt;code&amp;gt;:16080&amp;lt;/code&amp;gt;, TTS — &amp;lt;code&amp;gt;:8080&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Базовые параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Плейсхолдер под подробное описание .env --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Запуск контейнера и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
docker load -i secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2416</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2416"/>
		<updated>2026-07-06T22:35:42Z</updated>

		<summary type="html">&lt;p&gt;AZykov: /* 1.1. Установка Docker */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Установка и настройка голосового робота Эра (SecondChain) =&lt;br /&gt;
&lt;br /&gt;
Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 1. Подготовка|Подготовка]]&#039;&#039;&#039; — Docker, PostgreSQL, настройки в системе телефонии.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 2. Установка сервисов инференса (опционально)|Установка сервисов инференса]]&#039;&#039;&#039; — ASR, LLM, TTS. &#039;&#039;Опционально, только для развёртывания на собственном сервере с GPU.&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 3. Настройка .env|Настройка .env]]&#039;&#039;&#039; — параметры подключения.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 4. Запуск контейнера и создание робота|Запуск контейнера и создание робота]]&#039;&#039;&#039; — старт сервиса и конфигурация робота.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
Установка самого Docker:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установка Nvidia Container Toolkit (только для серверов с GPU):&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# репозиторий&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \&lt;br /&gt;
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \&lt;br /&gt;
  sed &#039;s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g&#039; | \&lt;br /&gt;
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-container-toolkit&lt;br /&gt;
sudo nvidia-ctk runtime configure --runtime=docker&lt;br /&gt;
sudo systemctl restart docker&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (опционально) =&lt;br /&gt;
&lt;br /&gt;
Инструкция для &#039;&#039;&#039;Ubuntu Server 24.04&#039;&#039;&#039;. Стек: ASR (T-one/Triton) → LLM (Qwen3.5-35B-A3B на vLLM) → TTS (LightTTS + CosyVoice3).&lt;br /&gt;
&lt;br /&gt;
Целевая машина — сервер с GPU: &#039;&#039;&#039;RTX PRO 5000 (48GB)&#039;&#039;&#039; или &#039;&#039;&#039;RTX PRO 6000 Blackwell (96GB)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
=== Бюджет VRAM ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Компонент !! VRAM&lt;br /&gt;
|-&lt;br /&gt;
| ASR (T-one/Triton) || 600–800 MB&lt;br /&gt;
|-&lt;br /&gt;
| LLM (Qwen3.5-35B-A3B) || 24–48 GB (зависит от числа сессий и длины контекста)&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS/CosyVoice3) || 11 GB&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Суммарное потребление в пике — ~36–60 GB.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 6000 (96GB):&#039;&#039;&#039; объёма достаточно с большим запасом. Допустимо использование максимального числа сессий и длинного контекста.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 5000 (48GB):&#039;&#039;&#039; запас минимальный. Фиксированная сумма ASR (~0.8 GB) и TTS (11 GB) составляет ~12 GB, на LLM остаётся ~36 GB. Это покрывает только нижнюю границу диапазона LLM (24 GB). Требуется ограничение параметров &amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt; во избежание ошибки OOM. Значение &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; (~24 GB на карте 48GB) для данного сценария допустимо при условии, что ASR и TTS инициализированы до старта LLM.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
Установка выполняется из Docker Hub, следующей командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
* &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; — директория хост-машины, где будет храниться кеш весов модели (24gb)&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
После запуска vllm также будет компилировать веса модели под текущий GPU, это занимает от 5 до 20 минут. После завершения компиляции в логах будут следующие строчки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/////////////&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Как только они появятся, можно переходить к следующему шагу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}]&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
docker load -i lighttts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — &#039;&#039;&#039;11 GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;*tone*&amp;lt;/code&amp;gt; || 8000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;*tone*&amp;lt;/code&amp;gt; || 8001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После проверки выполняется подключение пайплайна PjSIP → VAD → ASR → LLM → TTS с указанием эндпоинтов в конфигурации: ASR — &amp;lt;code&amp;gt;:8000/:8001&amp;lt;/code&amp;gt;, LLM — &amp;lt;code&amp;gt;:16080&amp;lt;/code&amp;gt;, TTS — &amp;lt;code&amp;gt;:8080&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Базовые параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Плейсхолдер под подробное описание .env --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Запуск контейнера и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
docker load -i secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2415</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2415"/>
		<updated>2026-07-06T22:35:05Z</updated>

		<summary type="html">&lt;p&gt;AZykov: /* 1.1. Установка Docker */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Установка и настройка голосового робота Эра (SecondChain) =&lt;br /&gt;
&lt;br /&gt;
Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 1. Подготовка|Подготовка]]&#039;&#039;&#039; — Docker, PostgreSQL, настройки в системе телефонии.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 2. Установка сервисов инференса (опционально)|Установка сервисов инференса]]&#039;&#039;&#039; — ASR, LLM, TTS. &#039;&#039;Опционально, только для развёртывания на собственном сервере с GPU.&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 3. Настройка .env|Настройка .env]]&#039;&#039;&#039; — параметры подключения.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 4. Запуск контейнера и создание робота|Запуск контейнера и создание робота]]&#039;&#039;&#039; — старт сервиса и конфигурация робота.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
Установка самого Docker:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установка Nvidia Container Toolkit (только для серверов с GPU):&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# репозиторий&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \&lt;br /&gt;
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \&lt;br /&gt;
  sed &#039;s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g&#039; | \&lt;br /&gt;
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-container-toolkit&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (опционально) =&lt;br /&gt;
&lt;br /&gt;
Инструкция для &#039;&#039;&#039;Ubuntu Server 24.04&#039;&#039;&#039;. Стек: ASR (T-one/Triton) → LLM (Qwen3.5-35B-A3B на vLLM) → TTS (LightTTS + CosyVoice3).&lt;br /&gt;
&lt;br /&gt;
Целевая машина — сервер с GPU: &#039;&#039;&#039;RTX PRO 5000 (48GB)&#039;&#039;&#039; или &#039;&#039;&#039;RTX PRO 6000 Blackwell (96GB)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
=== Бюджет VRAM ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Компонент !! VRAM&lt;br /&gt;
|-&lt;br /&gt;
| ASR (T-one/Triton) || 600–800 MB&lt;br /&gt;
|-&lt;br /&gt;
| LLM (Qwen3.5-35B-A3B) || 24–48 GB (зависит от числа сессий и длины контекста)&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS/CosyVoice3) || 11 GB&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Суммарное потребление в пике — ~36–60 GB.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 6000 (96GB):&#039;&#039;&#039; объёма достаточно с большим запасом. Допустимо использование максимального числа сессий и длинного контекста.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 5000 (48GB):&#039;&#039;&#039; запас минимальный. Фиксированная сумма ASR (~0.8 GB) и TTS (11 GB) составляет ~12 GB, на LLM остаётся ~36 GB. Это покрывает только нижнюю границу диапазона LLM (24 GB). Требуется ограничение параметров &amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt; во избежание ошибки OOM. Значение &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; (~24 GB на карте 48GB) для данного сценария допустимо при условии, что ASR и TTS инициализированы до старта LLM.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
Установка выполняется из Docker Hub, следующей командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
* &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; — директория хост-машины, где будет храниться кеш весов модели (24gb)&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
После запуска vllm также будет компилировать веса модели под текущий GPU, это занимает от 5 до 20 минут. После завершения компиляции в логах будут следующие строчки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/////////////&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Как только они появятся, можно переходить к следующему шагу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}]&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
docker load -i lighttts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — &#039;&#039;&#039;11 GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;*tone*&amp;lt;/code&amp;gt; || 8000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;*tone*&amp;lt;/code&amp;gt; || 8001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После проверки выполняется подключение пайплайна PjSIP → VAD → ASR → LLM → TTS с указанием эндпоинтов в конфигурации: ASR — &amp;lt;code&amp;gt;:8000/:8001&amp;lt;/code&amp;gt;, LLM — &amp;lt;code&amp;gt;:16080&amp;lt;/code&amp;gt;, TTS — &amp;lt;code&amp;gt;:8080&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Базовые параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Плейсхолдер под подробное описание .env --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Запуск контейнера и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
docker load -i secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2414</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2414"/>
		<updated>2026-07-06T22:34:39Z</updated>

		<summary type="html">&lt;p&gt;AZykov: /* 1.1. Установка Docker */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Установка и настройка голосового робота Эра (SecondChain) =&lt;br /&gt;
&lt;br /&gt;
Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 1. Подготовка|Подготовка]]&#039;&#039;&#039; — Docker, PostgreSQL, настройки в системе телефонии.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 2. Установка сервисов инференса (опционально)|Установка сервисов инференса]]&#039;&#039;&#039; — ASR, LLM, TTS. &#039;&#039;Опционально, только для развёртывания на собственном сервере с GPU.&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 3. Настройка .env|Настройка .env]]&#039;&#039;&#039; — параметры подключения.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 4. Запуск контейнера и создание робота|Запуск контейнера и создание робота]]&#039;&#039;&#039; — старт сервиса и конфигурация робота.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
Установка самого Docker:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установка Nvidia Container Toolkit (только для серверов с GPU):&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# репозиторий&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \&lt;br /&gt;
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \&lt;br /&gt;
  sed &#039;s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g&#039; | \&lt;br /&gt;
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y --allow-change-held-packages \&lt;br /&gt;
  nvidia-container-toolkit=1.19.1-1 \&lt;br /&gt;
  nvidia-container-toolkit-base=1.19.1-1 \&lt;br /&gt;
  libnvidia-container-tools=1.19.1-1 \&lt;br /&gt;
  libnvidia-container1=1.19.1-1&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (опционально) =&lt;br /&gt;
&lt;br /&gt;
Инструкция для &#039;&#039;&#039;Ubuntu Server 24.04&#039;&#039;&#039;. Стек: ASR (T-one/Triton) → LLM (Qwen3.5-35B-A3B на vLLM) → TTS (LightTTS + CosyVoice3).&lt;br /&gt;
&lt;br /&gt;
Целевая машина — сервер с GPU: &#039;&#039;&#039;RTX PRO 5000 (48GB)&#039;&#039;&#039; или &#039;&#039;&#039;RTX PRO 6000 Blackwell (96GB)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
=== Бюджет VRAM ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Компонент !! VRAM&lt;br /&gt;
|-&lt;br /&gt;
| ASR (T-one/Triton) || 600–800 MB&lt;br /&gt;
|-&lt;br /&gt;
| LLM (Qwen3.5-35B-A3B) || 24–48 GB (зависит от числа сессий и длины контекста)&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS/CosyVoice3) || 11 GB&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Суммарное потребление в пике — ~36–60 GB.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 6000 (96GB):&#039;&#039;&#039; объёма достаточно с большим запасом. Допустимо использование максимального числа сессий и длинного контекста.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 5000 (48GB):&#039;&#039;&#039; запас минимальный. Фиксированная сумма ASR (~0.8 GB) и TTS (11 GB) составляет ~12 GB, на LLM остаётся ~36 GB. Это покрывает только нижнюю границу диапазона LLM (24 GB). Требуется ограничение параметров &amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt; во избежание ошибки OOM. Значение &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; (~24 GB на карте 48GB) для данного сценария допустимо при условии, что ASR и TTS инициализированы до старта LLM.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
Установка выполняется из Docker Hub, следующей командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
* &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; — директория хост-машины, где будет храниться кеш весов модели (24gb)&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
После запуска vllm также будет компилировать веса модели под текущий GPU, это занимает от 5 до 20 минут. После завершения компиляции в логах будут следующие строчки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/////////////&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Как только они появятся, можно переходить к следующему шагу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}]&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
docker load -i lighttts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — &#039;&#039;&#039;11 GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;*tone*&amp;lt;/code&amp;gt; || 8000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;*tone*&amp;lt;/code&amp;gt; || 8001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После проверки выполняется подключение пайплайна PjSIP → VAD → ASR → LLM → TTS с указанием эндпоинтов в конфигурации: ASR — &amp;lt;code&amp;gt;:8000/:8001&amp;lt;/code&amp;gt;, LLM — &amp;lt;code&amp;gt;:16080&amp;lt;/code&amp;gt;, TTS — &amp;lt;code&amp;gt;:8080&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Базовые параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Плейсхолдер под подробное описание .env --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Запуск контейнера и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
docker load -i secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2413</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2413"/>
		<updated>2026-07-06T22:32:50Z</updated>

		<summary type="html">&lt;p&gt;AZykov: /* 1.1. Установка Docker */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Установка и настройка голосового робота Эра (SecondChain) =&lt;br /&gt;
&lt;br /&gt;
Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 1. Подготовка|Подготовка]]&#039;&#039;&#039; — Docker, PostgreSQL, настройки в системе телефонии.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 2. Установка сервисов инференса (опционально)|Установка сервисов инференса]]&#039;&#039;&#039; — ASR, LLM, TTS. &#039;&#039;Опционально, только для развёртывания на собственном сервере с GPU.&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 3. Настройка .env|Настройка .env]]&#039;&#039;&#039; — параметры подключения.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 4. Запуск контейнера и создание робота|Запуск контейнера и создание робота]]&#039;&#039;&#039; — старт сервиса и конфигурация робота.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
Установка самого Docker:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Установка Nvidia Container Toolkit (только для серверов с GPU):&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# репозиторий&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \&lt;br /&gt;
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \&lt;br /&gt;
  sed &#039;s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g&#039; | \&lt;br /&gt;
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-container-toolkit&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (опционально) =&lt;br /&gt;
&lt;br /&gt;
Инструкция для &#039;&#039;&#039;Ubuntu Server 24.04&#039;&#039;&#039;. Стек: ASR (T-one/Triton) → LLM (Qwen3.5-35B-A3B на vLLM) → TTS (LightTTS + CosyVoice3).&lt;br /&gt;
&lt;br /&gt;
Целевая машина — сервер с GPU: &#039;&#039;&#039;RTX PRO 5000 (48GB)&#039;&#039;&#039; или &#039;&#039;&#039;RTX PRO 6000 Blackwell (96GB)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
=== Бюджет VRAM ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Компонент !! VRAM&lt;br /&gt;
|-&lt;br /&gt;
| ASR (T-one/Triton) || 600–800 MB&lt;br /&gt;
|-&lt;br /&gt;
| LLM (Qwen3.5-35B-A3B) || 24–48 GB (зависит от числа сессий и длины контекста)&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS/CosyVoice3) || 11 GB&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Суммарное потребление в пике — ~36–60 GB.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 6000 (96GB):&#039;&#039;&#039; объёма достаточно с большим запасом. Допустимо использование максимального числа сессий и длинного контекста.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 5000 (48GB):&#039;&#039;&#039; запас минимальный. Фиксированная сумма ASR (~0.8 GB) и TTS (11 GB) составляет ~12 GB, на LLM остаётся ~36 GB. Это покрывает только нижнюю границу диапазона LLM (24 GB). Требуется ограничение параметров &amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt; во избежание ошибки OOM. Значение &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; (~24 GB на карте 48GB) для данного сценария допустимо при условии, что ASR и TTS инициализированы до старта LLM.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
Установка выполняется из Docker Hub, следующей командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
* &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; — директория хост-машины, где будет храниться кеш весов модели (24gb)&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
После запуска vllm также будет компилировать веса модели под текущий GPU, это занимает от 5 до 20 минут. После завершения компиляции в логах будут следующие строчки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/////////////&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Как только они появятся, можно переходить к следующему шагу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}]&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
docker load -i lighttts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — &#039;&#039;&#039;11 GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;*tone*&amp;lt;/code&amp;gt; || 8000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;*tone*&amp;lt;/code&amp;gt; || 8001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После проверки выполняется подключение пайплайна PjSIP → VAD → ASR → LLM → TTS с указанием эндпоинтов в конфигурации: ASR — &amp;lt;code&amp;gt;:8000/:8001&amp;lt;/code&amp;gt;, LLM — &amp;lt;code&amp;gt;:16080&amp;lt;/code&amp;gt;, TTS — &amp;lt;code&amp;gt;:8080&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Базовые параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Плейсхолдер под подробное описание .env --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Запуск контейнера и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
docker load -i secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2412</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2412"/>
		<updated>2026-07-06T22:26:37Z</updated>

		<summary type="html">&lt;p&gt;AZykov: /* Этап 2. Установка сервисов инференса (опционально) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Установка и настройка голосового робота Эра (SecondChain) =&lt;br /&gt;
&lt;br /&gt;
Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 1. Подготовка|Подготовка]]&#039;&#039;&#039; — Docker, PostgreSQL, настройки в системе телефонии.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 2. Установка сервисов инференса (опционально)|Установка сервисов инференса]]&#039;&#039;&#039; — ASR, LLM, TTS. &#039;&#039;Опционально, только для развёртывания на собственном сервере с GPU.&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 3. Настройка .env|Настройка .env]]&#039;&#039;&#039; — параметры подключения.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 4. Запуск контейнера и создание робота|Запуск контейнера и создание робота]]&#039;&#039;&#039; — старт сервиса и конфигурация робота.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (опционально) =&lt;br /&gt;
&lt;br /&gt;
Инструкция для &#039;&#039;&#039;Ubuntu Server 24.04&#039;&#039;&#039;. Стек: ASR (T-one/Triton) → LLM (Qwen3.5-35B-A3B на vLLM) → TTS (LightTTS + CosyVoice3).&lt;br /&gt;
&lt;br /&gt;
Целевая машина — сервер с GPU: &#039;&#039;&#039;RTX PRO 5000 (48GB)&#039;&#039;&#039; или &#039;&#039;&#039;RTX PRO 6000 Blackwell (96GB)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
=== Бюджет VRAM ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Компонент !! VRAM&lt;br /&gt;
|-&lt;br /&gt;
| ASR (T-one/Triton) || 600–800 MB&lt;br /&gt;
|-&lt;br /&gt;
| LLM (Qwen3.5-35B-A3B) || 24–48 GB (зависит от числа сессий и длины контекста)&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS/CosyVoice3) || 11 GB&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Суммарное потребление в пике — ~36–60 GB.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 6000 (96GB):&#039;&#039;&#039; объёма достаточно с большим запасом. Допустимо использование максимального числа сессий и длинного контекста.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 5000 (48GB):&#039;&#039;&#039; запас минимальный. Фиксированная сумма ASR (~0.8 GB) и TTS (11 GB) составляет ~12 GB, на LLM остаётся ~36 GB. Это покрывает только нижнюю границу диапазона LLM (24 GB). Требуется ограничение параметров &amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt; во избежание ошибки OOM. Значение &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; (~24 GB на карте 48GB) для данного сценария допустимо при условии, что ASR и TTS инициализированы до старта LLM.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
Установка выполняется из Docker Hub, следующей командой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
* &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; — директория хост-машины, где будет храниться кеш весов модели (24gb)&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
После запуска vllm также будет компилировать веса модели под текущий GPU, это занимает от 5 до 20 минут. После завершения компиляции в логах будут следующие строчки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/////////////&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Как только они появятся, можно переходить к следующему шагу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}]&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
docker load -i lighttts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — &#039;&#039;&#039;11 GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;*tone*&amp;lt;/code&amp;gt; || 8000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;*tone*&amp;lt;/code&amp;gt; || 8001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После проверки выполняется подключение пайплайна PjSIP → VAD → ASR → LLM → TTS с указанием эндпоинтов в конфигурации: ASR — &amp;lt;code&amp;gt;:8000/:8001&amp;lt;/code&amp;gt;, LLM — &amp;lt;code&amp;gt;:16080&amp;lt;/code&amp;gt;, TTS — &amp;lt;code&amp;gt;:8080&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Базовые параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Плейсхолдер под подробное описание .env --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Запуск контейнера и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
docker load -i secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2411</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2411"/>
		<updated>2026-07-06T21:25:28Z</updated>

		<summary type="html">&lt;p&gt;AZykov: /* 2.4. LLM (Qwen3.5-35B-A3B на vLLM) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Установка и настройка голосового робота Эра (SecondChain) =&lt;br /&gt;
&lt;br /&gt;
Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 1. Подготовка|Подготовка]]&#039;&#039;&#039; — Docker, PostgreSQL, настройки в системе телефонии.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 2. Установка сервисов инференса (опционально)|Установка сервисов инференса]]&#039;&#039;&#039; — ASR, LLM, TTS. &#039;&#039;Опционально, только для развёртывания на собственном сервере с GPU.&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 3. Настройка .env|Настройка .env]]&#039;&#039;&#039; — параметры подключения.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 4. Запуск контейнера и создание робота|Запуск контейнера и создание робота]]&#039;&#039;&#039; — старт сервиса и конфигурация робота.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (опционально) =&lt;br /&gt;
&lt;br /&gt;
{{Note|&#039;&#039;&#039;Опциональный этап.&#039;&#039;&#039; Выполняется только при развёртывании сервисов инференса на собственном сервере с GPU. Если ASR / LLM / TTS уже развёрнуты или используются внешние эндпоинты — перейдите к [[#Этап 3. Настройка .env|Этапу 3]].}}&lt;br /&gt;
&lt;br /&gt;
Инструкция для &#039;&#039;&#039;Ubuntu Server 24.04&#039;&#039;&#039;. Стек: ASR (T-one/Triton) → LLM (Qwen3.5-35B-A3B на vLLM) → TTS (LightTTS + CosyVoice3).&lt;br /&gt;
&lt;br /&gt;
Целевая машина — сервер с GPU: &#039;&#039;&#039;RTX PRO 5000 (48GB)&#039;&#039;&#039; или &#039;&#039;&#039;RTX PRO 6000 Blackwell (96GB)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
=== Бюджет VRAM ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Компонент !! VRAM&lt;br /&gt;
|-&lt;br /&gt;
| ASR (T-one/Triton) || 600–800 MB&lt;br /&gt;
|-&lt;br /&gt;
| LLM (Qwen3.5-35B-A3B) || 24–48 GB (зависит от числа сессий и длины контекста)&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS/CosyVoice3) || 11 GB&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Суммарное потребление в пике — ~36–60 GB.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 6000 (96GB):&#039;&#039;&#039; объёма достаточно с большим запасом. Допустимо использование максимального числа сессий и длинного контекста.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 5000 (48GB):&#039;&#039;&#039; запас минимальный. Фиксированная сумма ASR (~0.8 GB) и TTS (11 GB) составляет ~12 GB, на LLM остаётся ~36 GB. Это покрывает только нижнюю границу диапазона LLM (24 GB). Требуется ограничение параметров &amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt; во избежание ошибки OOM. Значение &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; (~24 GB на карте 48GB) для данного сценария допустимо при условии, что ASR и TTS инициализированы до старта LLM.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|При отсутствии ответа со стороны ASR диагностику следует начинать с проверки портов gRPC и логов контейнера.}}&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
{{Note|&#039;&#039;&#039;Перед запуском:&#039;&#039;&#039; значение &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; необходимо заменить на фактический путь к кэшу моделей (например &amp;lt;code&amp;gt;~/vllm-cache&amp;lt;/code&amp;gt;), иначе веса будут загружаться повторно при каждом старте.}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
* &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; — директория хост-машины, где будет храниться кеш весов модели (24gb)&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
После запуска vllm также будет компилировать веса модели под текущий GPU, это занимает от 5 до 20 минут. После завершения компиляции в логах будут следующие строчки:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/////////////&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Как только они появятся, можно переходить к следующему шагу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}]&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
docker load -i lighttts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — &#039;&#039;&#039;11 GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;*tone*&amp;lt;/code&amp;gt; || 8000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;*tone*&amp;lt;/code&amp;gt; || 8001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После проверки выполняется подключение пайплайна PjSIP → VAD → ASR → LLM → TTS с указанием эндпоинтов в конфигурации: ASR — &amp;lt;code&amp;gt;:8000/:8001&amp;lt;/code&amp;gt;, LLM — &amp;lt;code&amp;gt;:16080&amp;lt;/code&amp;gt;, TTS — &amp;lt;code&amp;gt;:8080&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
&lt;br /&gt;
{{TODO|Раздел будет описан отдельно.}}&lt;br /&gt;
&lt;br /&gt;
Базовые параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Плейсхолдер под подробное описание .env --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Запуск контейнера и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
docker load -i secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|Первый запуск занимает больше времени, чем последующие.}}&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2410</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2410"/>
		<updated>2026-07-06T21:23:00Z</updated>

		<summary type="html">&lt;p&gt;AZykov: /* 2.4. LLM (Qwen3.5-35B-A3B на vLLM) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Установка и настройка голосового робота Эра (SecondChain) =&lt;br /&gt;
&lt;br /&gt;
Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 1. Подготовка|Подготовка]]&#039;&#039;&#039; — Docker, PostgreSQL, настройки в системе телефонии.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 2. Установка сервисов инференса (опционально)|Установка сервисов инференса]]&#039;&#039;&#039; — ASR, LLM, TTS. &#039;&#039;Опционально, только для развёртывания на собственном сервере с GPU.&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 3. Настройка .env|Настройка .env]]&#039;&#039;&#039; — параметры подключения.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 4. Запуск контейнера и создание робота|Запуск контейнера и создание робота]]&#039;&#039;&#039; — старт сервиса и конфигурация робота.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (опционально) =&lt;br /&gt;
&lt;br /&gt;
{{Note|&#039;&#039;&#039;Опциональный этап.&#039;&#039;&#039; Выполняется только при развёртывании сервисов инференса на собственном сервере с GPU. Если ASR / LLM / TTS уже развёрнуты или используются внешние эндпоинты — перейдите к [[#Этап 3. Настройка .env|Этапу 3]].}}&lt;br /&gt;
&lt;br /&gt;
Инструкция для &#039;&#039;&#039;Ubuntu Server 24.04&#039;&#039;&#039;. Стек: ASR (T-one/Triton) → LLM (Qwen3.5-35B-A3B на vLLM) → TTS (LightTTS + CosyVoice3).&lt;br /&gt;
&lt;br /&gt;
Целевая машина — сервер с GPU: &#039;&#039;&#039;RTX PRO 5000 (48GB)&#039;&#039;&#039; или &#039;&#039;&#039;RTX PRO 6000 Blackwell (96GB)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
=== Бюджет VRAM ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Компонент !! VRAM&lt;br /&gt;
|-&lt;br /&gt;
| ASR (T-one/Triton) || 600–800 MB&lt;br /&gt;
|-&lt;br /&gt;
| LLM (Qwen3.5-35B-A3B) || 24–48 GB (зависит от числа сессий и длины контекста)&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS/CosyVoice3) || 11 GB&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Суммарное потребление в пике — ~36–60 GB.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 6000 (96GB):&#039;&#039;&#039; объёма достаточно с большим запасом. Допустимо использование максимального числа сессий и длинного контекста.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 5000 (48GB):&#039;&#039;&#039; запас минимальный. Фиксированная сумма ASR (~0.8 GB) и TTS (11 GB) составляет ~12 GB, на LLM остаётся ~36 GB. Это покрывает только нижнюю границу диапазона LLM (24 GB). Требуется ограничение параметров &amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt; во избежание ошибки OOM. Значение &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; (~24 GB на карте 48GB) для данного сценария допустимо при условии, что ASR и TTS инициализированы до старта LLM.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|При отсутствии ответа со стороны ASR диагностику следует начинать с проверки портов gRPC и логов контейнера.}}&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
{{Note|&#039;&#039;&#039;Перед запуском:&#039;&#039;&#039; значение &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; необходимо заменить на фактический путь к кэшу моделей (например &amp;lt;code&amp;gt;~/vllm-cache&amp;lt;/code&amp;gt;), иначе веса будут загружаться повторно при каждом старте.}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
* &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; — директория хост-машины, где будет храниться кеш весов модели (24gb)&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}]&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
docker load -i lighttts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — &#039;&#039;&#039;11 GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;*tone*&amp;lt;/code&amp;gt; || 8000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;*tone*&amp;lt;/code&amp;gt; || 8001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После проверки выполняется подключение пайплайна PjSIP → VAD → ASR → LLM → TTS с указанием эндпоинтов в конфигурации: ASR — &amp;lt;code&amp;gt;:8000/:8001&amp;lt;/code&amp;gt;, LLM — &amp;lt;code&amp;gt;:16080&amp;lt;/code&amp;gt;, TTS — &amp;lt;code&amp;gt;:8080&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
&lt;br /&gt;
{{TODO|Раздел будет описан отдельно.}}&lt;br /&gt;
&lt;br /&gt;
Базовые параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Плейсхолдер под подробное описание .env --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Запуск контейнера и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
docker load -i secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|Первый запуск занимает больше времени, чем последующие.}}&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
	<entry>
		<id>https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2409</id>
		<title>Установка сервисов голосового робота</title>
		<link rel="alternate" type="text/html" href="https://wiki.era-platform.ru/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%B0&amp;diff=2409"/>
		<updated>2026-07-06T21:20:49Z</updated>

		<summary type="html">&lt;p&gt;AZykov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Установка и настройка голосового робота Эра (SecondChain) =&lt;br /&gt;
&lt;br /&gt;
Пошаговая инструкция по развёртыванию голосового робота. Процесс разбит на четыре этапа:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 1. Подготовка|Подготовка]]&#039;&#039;&#039; — Docker, PostgreSQL, настройки в системе телефонии.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 2. Установка сервисов инференса (опционально)|Установка сервисов инференса]]&#039;&#039;&#039; — ASR, LLM, TTS. &#039;&#039;Опционально, только для развёртывания на собственном сервере с GPU.&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 3. Настройка .env|Настройка .env]]&#039;&#039;&#039; — параметры подключения.&lt;br /&gt;
# &#039;&#039;&#039;[[#Этап 4. Запуск контейнера и создание робота|Запуск контейнера и создание робота]]&#039;&#039;&#039; — старт сервиса и конфигурация робота.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Этап 1. Подготовка =&lt;br /&gt;
&lt;br /&gt;
Установка Docker, базы данных и настройка проброса заголовков и абонента в системе телефонии.&lt;br /&gt;
&lt;br /&gt;
== 1.1. Установка Docker ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2. Создать БД в PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
Установить или взять существующий инстанс Postgres, создать нового пользователя и базу для робота.&lt;br /&gt;
&lt;br /&gt;
Пример с Docker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name postgres \&lt;br /&gt;
  --network host \&lt;br /&gt;
  -e POSTGRES_USER=secondchain \&lt;br /&gt;
  -e POSTGRES_PASSWORD=changeme \&lt;br /&gt;
  -e POSTGRES_DB=secondchain \&lt;br /&gt;
  -v pgdata:/var/lib/postgresql/data \&lt;br /&gt;
  postgres:17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.3. Настройка проброса заголовка в B2B ==&lt;br /&gt;
[[Файл:Дополнительный заголовок в конфигурации b2b.png|мини]]&lt;br /&gt;
Мастер-домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. В конфигурации, в нодах B2B добавить проброс заголовка &amp;lt;code&amp;gt;X-Robot-Session&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;fwd_headers&amp;quot;: [&amp;quot;X-Robot-Session&amp;quot;],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Активировать новую конфигурацию.&lt;br /&gt;
&lt;br /&gt;
== 1.4. Создать абонента для робота ==&lt;br /&gt;
[[Файл:Абонент для робота.png|мини|215x215пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать нового абонента, под которым будет регистрироваться робот.&lt;br /&gt;
&lt;br /&gt;
Робот будет использовать данную учетную запись для приема звонков.&lt;br /&gt;
&lt;br /&gt;
== 1.5. Создать канал интеграции для робота ==&lt;br /&gt;
[[Файл:Канал интеграции для робота.png|мини|214x214пкс]]&lt;br /&gt;
Проектный домен → приложение &#039;&#039;&#039;Настройки&#039;&#039;&#039;. Создать новый канал интеграции:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Тип&#039;&#039;&#039; — Подписчик&lt;br /&gt;
* &#039;&#039;&#039;Права&#039;&#039;&#039; — &amp;lt;code&amp;gt;ai_admin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ai_voicebot_admin&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Режим активности&#039;&#039;&#039; — постоянный&lt;br /&gt;
&lt;br /&gt;
== 1.6. Создать движок в приложении ИИ ==&lt;br /&gt;
[[Файл:Движок в приложении ИИ.png|мини]]&lt;br /&gt;
Задать произвольные название и код. В поле &#039;&#039;&#039;Номер телефона&#039;&#039;&#039; указать внутренний номер абонента, созданного на шаге [[#1.4. Создать абонента для робота|1.4]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Количество сессий&#039;&#039;&#039; по умолчанию = 8. Точное число зависит от оборудования, на котором размещаются сервисы робота.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Этап 2. Установка сервисов инференса (опционально) =&lt;br /&gt;
&lt;br /&gt;
{{Note|&#039;&#039;&#039;Опциональный этап.&#039;&#039;&#039; Выполняется только при развёртывании сервисов инференса на собственном сервере с GPU. Если ASR / LLM / TTS уже развёрнуты или используются внешние эндпоинты — перейдите к [[#Этап 3. Настройка .env|Этапу 3]].}}&lt;br /&gt;
&lt;br /&gt;
Инструкция для &#039;&#039;&#039;Ubuntu Server 24.04&#039;&#039;&#039;. Стек: ASR (T-one/Triton) → LLM (Qwen3.5-35B-A3B на vLLM) → TTS (LightTTS + CosyVoice3).&lt;br /&gt;
&lt;br /&gt;
Целевая машина — сервер с GPU: &#039;&#039;&#039;RTX PRO 5000 (48GB)&#039;&#039;&#039; или &#039;&#039;&#039;RTX PRO 6000 Blackwell (96GB)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 2.1. Предварительные требования ==&lt;br /&gt;
&lt;br /&gt;
Убедиться, что установлены драйверы NVIDIA, Docker и NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nvidia-smi                          # драйвер и GPU видны&lt;br /&gt;
docker --version                    # Docker установлен&lt;br /&gt;
docker run --rm --gpus all ubuntu nvidia-smi   # GPU проброшен в контейнер&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если последняя команда не отображает GPU, требуется установить NVIDIA Container Toolkit и перезапустить Docker.&lt;br /&gt;
&lt;br /&gt;
=== Бюджет VRAM ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Компонент !! VRAM&lt;br /&gt;
|-&lt;br /&gt;
| ASR (T-one/Triton) || 600–800 MB&lt;br /&gt;
|-&lt;br /&gt;
| LLM (Qwen3.5-35B-A3B) || 24–48 GB (зависит от числа сессий и длины контекста)&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS/CosyVoice3) || 11 GB&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Суммарное потребление в пике — ~36–60 GB.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 6000 (96GB):&#039;&#039;&#039; объёма достаточно с большим запасом. Допустимо использование максимального числа сессий и длинного контекста.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTX PRO 5000 (48GB):&#039;&#039;&#039; запас минимальный. Фиксированная сумма ASR (~0.8 GB) и TTS (11 GB) составляет ~12 GB, на LLM остаётся ~36 GB. Это покрывает только нижнюю границу диапазона LLM (24 GB). Требуется ограничение параметров &amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt; во избежание ошибки OOM. Значение &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; (~24 GB на карте 48GB) для данного сценария допустимо при условии, что ASR и TTS инициализированы до старта LLM.&lt;br /&gt;
&lt;br /&gt;
== 2.2. Порядок запуска ==&lt;br /&gt;
&lt;br /&gt;
Модели независимы. Рекомендуемый порядок развёртывания для упрощения диагностики: &#039;&#039;&#039;ASR → LLM → TTS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 2.3. ASR (T-one на Triton) ==&lt;br /&gt;
&lt;br /&gt;
Необходимо скачать и загрузить образ контейнера, создать контейнер и дождаться сборки ML-движка. Первый запуск может проходить долго, 5-15 минут, в зависимости от оборудования. Во время первого запуска система собирает движок модели с оптимизациями под текущий GPU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/tone-triton.tar.gz&lt;br /&gt;
docker load &amp;lt; tone-triton.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --name tone-triton --gpus all --restart unless-stopped \&lt;br /&gt;
    -p 17000:8000 -p 17001:8001 -p 17002:8002 \&lt;br /&gt;
    -v tone-engine:/models/streaming_acoustic/1 \&lt;br /&gt;
    tone-triton:dist-trt-b32&lt;br /&gt;
&lt;br /&gt;
docker logs -f tone-triton&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После появления данного сообщения можно считать что движок собран и переходить к следующему шагу установки:&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после старта Triton слушает gRPC (стандартно 8001) и HTTP (стандартно 8000). Потребление VRAM — &#039;&#039;&#039;600–800 MB&#039;&#039;&#039;. Статус контейнера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep -i tone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|При отсутствии ответа со стороны ASR диагностику следует начинать с проверки портов gRPC и логов контейнера.}}&lt;br /&gt;
&lt;br /&gt;
== 2.4. LLM (Qwen3.5-35B-A3B на vLLM) ==&lt;br /&gt;
&lt;br /&gt;
{{Note|&#039;&#039;&#039;Перед запуском:&#039;&#039;&#039; значение &amp;lt;code&amp;gt;/path/to/cache&amp;lt;/code&amp;gt; необходимо заменить на фактический путь к кэшу моделей (например &amp;lt;code&amp;gt;~/vllm-cache&amp;lt;/code&amp;gt;), иначе веса будут загружаться повторно при каждом старте.}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run -d \&lt;br /&gt;
  --name vllm-qwen35-moe \&lt;br /&gt;
  --gpus all \&lt;br /&gt;
  --ipc=host \&lt;br /&gt;
  -v /path/to/cache:/root/.cache \&lt;br /&gt;
  -p 16080:8000 \&lt;br /&gt;
  vllm/vllm-openai:cu130-nightly \&lt;br /&gt;
  --model Qwen/Qwen3.5-35B-A3B-GPTQ-Int4 \&lt;br /&gt;
  --served-model-name qwen35-35b-a3b \&lt;br /&gt;
  --quantization moe_wna16 \&lt;br /&gt;
  --max-num-seqs 6 \&lt;br /&gt;
  --max-model-len 4096 \&lt;br /&gt;
  --kv-cache-memory 3221225472 \&lt;br /&gt;
  --gpu-memory-utilization 0.50 \&lt;br /&gt;
  --enable-prefix-caching \&lt;br /&gt;
  --host 0.0.0.0 --port 8000 \&lt;br /&gt;
  --reasoning-parser qwen3 \&lt;br /&gt;
  --enable-auto-tool-choice \&lt;br /&gt;
  --tool-call-parser qwen3_coder \&lt;br /&gt;
  --language-model-only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
docker logs vllm-qwen35-moe -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ключевые параметры:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-model-len 8192&amp;lt;/code&amp;gt; — максимальное окно контекста в токенах.&lt;br /&gt;
* &amp;lt;code&amp;gt;--max-num-seqs 6&amp;lt;/code&amp;gt; — максимум одновременно обрабатываемых запросов.&lt;br /&gt;
* &amp;lt;code&amp;gt;--gpu-memory-utilization 0.50&amp;lt;/code&amp;gt; — 50% VRAM выделено под LLM.&lt;br /&gt;
* &amp;lt;code&amp;gt;--kv-cache-memory 3221225472&amp;lt;/code&amp;gt; — 3 GiB под KV-кэш.&lt;br /&gt;
&lt;br /&gt;
Минимальный объём VRAM для запуска — &#039;&#039;&#039;24 GB&#039;&#039;&#039;. Фактическое потребление — &#039;&#039;&#039;24–48 GB&#039;&#039;&#039; в зависимости от числа допустимых сессий (&amp;lt;code&amp;gt;--max-num-seqs&amp;lt;/code&amp;gt;) и длины контекста (&amp;lt;code&amp;gt;--max-model-len&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Проверка:&#039;&#039;&#039; после загрузки весов проверить OpenAI-совместимый эндпоинт на порту &#039;&#039;&#039;16080&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker logs -f vllm-qwen35-moe        # ожидать &amp;quot;Application startup complete&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/models&lt;br /&gt;
&lt;br /&gt;
curl http://localhost:16080/v1/chat/completions \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d &#039;{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;qwen35-35b-a3b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [{&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Привет&amp;quot;}]&lt;br /&gt;
  }&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.5. TTS (LightTTS + CosyVoice3) ==&lt;br /&gt;
&lt;br /&gt;
По аналогии с T-One, установка выполняется из образа docker-контейнера&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/lightts-weights.tar.gz&lt;br /&gt;
docker load -i lighttts-weights.tar.gz&lt;br /&gt;
&lt;br /&gt;
docker run -d --gpus all -p 8080:8080 --shm-size 4g \&lt;br /&gt;
  --restart unless-stopped --name lighttts \&lt;br /&gt;
  -v lighttts-engines:/opt/models/Fun-CosyVoice3-0.5B \&lt;br /&gt;
  lighttts/light-tts:weights&lt;br /&gt;
&lt;br /&gt;
docker logs -f lighttts&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Проверка:&#039;&#039;&#039; TTS слушает порт &#039;&#039;&#039;8080&#039;&#039;&#039;, потребление VRAM — &#039;&#039;&#039;11 GB&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps | grep lighttts&lt;br /&gt;
nvidia-smi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.6. Итоговая карта портов ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Сервис !! Контейнер !! Внешний порт&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton HTTP) || &amp;lt;code&amp;gt;*tone*&amp;lt;/code&amp;gt; || 8000&lt;br /&gt;
|-&lt;br /&gt;
| ASR (Triton gRPC) || &amp;lt;code&amp;gt;*tone*&amp;lt;/code&amp;gt; || 8001&lt;br /&gt;
|-&lt;br /&gt;
| LLM (vLLM) || &amp;lt;code&amp;gt;vllm-qwen35-moe&amp;lt;/code&amp;gt; || 16080&lt;br /&gt;
|-&lt;br /&gt;
| TTS (LightTTS) || &amp;lt;code&amp;gt;lighttts&amp;lt;/code&amp;gt; || 8080&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2.7. Финальная проверка стека ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps        # все три контейнера (ASR / vLLM / TTS) в статусе Up&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После проверки выполняется подключение пайплайна PjSIP → VAD → ASR → LLM → TTS с указанием эндпоинтов в конфигурации: ASR — &amp;lt;code&amp;gt;:8000/:8001&amp;lt;/code&amp;gt;, LLM — &amp;lt;code&amp;gt;:16080&amp;lt;/code&amp;gt;, TTS — &amp;lt;code&amp;gt;:8080&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
= Этап 3. Настройка .env =&lt;br /&gt;
&lt;br /&gt;
{{TODO|Раздел будет описан отдельно.}}&lt;br /&gt;
&lt;br /&gt;
Базовые параметры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXTERNAL_TEMPLATES_URL=https://[адрес инстанса эры]/rest/v1/model/ai/robot&lt;br /&gt;
EXTERNAL_TEMPLATES_TOKEN=[локальный токен из шага 1.5]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также настройки Postgres (из шага [[#1.2. Создать БД в PostgreSQL|1.2]]) и подключения SIP к учётной записи абонента (из шага [[#1.4. Создать абонента для робота|1.4]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Плейсхолдер под подробное описание .env --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Этап 4. Запуск контейнера и создание робота =&lt;br /&gt;
&lt;br /&gt;
== 4.1. Загрузка образа и запуск контейнера ==&lt;br /&gt;
&lt;br /&gt;
Скопировать на сервер архив с образом контейнера и файл &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; в одну директорию.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://ai02.era-platform.ru/secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
docker load -i secondchain-1.0.3a-cpu.tar.gz&lt;br /&gt;
mkdir -p ./logs&lt;br /&gt;
docker run -d --name secondchain \&lt;br /&gt;
  --network host \&lt;br /&gt;
  --env-file .env \&lt;br /&gt;
  --restart unless-stopped \&lt;br /&gt;
  -v secondchain-data:/data \&lt;br /&gt;
  -v ./logs:/app/logs \&lt;br /&gt;
  secondchain:1.0.3a-cpu&lt;br /&gt;
&lt;br /&gt;
docker logs secondchain -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Когда сервис загрузится и проинициализируется, в консоли появится сообщение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Registration: OK (code=200)    [pjsip.account]&lt;br /&gt;
[info     ] SIP client registered successfully [voip.sip]&lt;br /&gt;
[info     ] VoIP health monitor started    [src.api.app]&lt;br /&gt;
[info     ] SecondChain started successfully [src.api.app]&lt;br /&gt;
[info     ] Application startup complete.  [uvicorn.error]&lt;br /&gt;
[info     ] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|Первый запуск занимает больше времени, чем последующие.}}&lt;br /&gt;
&lt;br /&gt;
== 4.2. Создать робота в приложении ИИ ==&lt;br /&gt;
&lt;br /&gt;
=== Загрузить голос ===&lt;br /&gt;
&lt;br /&gt;
Необходим аудиофайл &amp;lt;code&amp;gt;.mp3&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;.wav&amp;lt;/code&amp;gt; длительностью ~10 секунд, без лишних шумов и эхо. При загрузке указать точную транскрипцию произнесённого текста (со знаками препинания).&lt;br /&gt;
&lt;br /&gt;
Для быстрого старта можно импортировать демо-голос (импорт + загрузка файла).&lt;br /&gt;
&lt;br /&gt;
=== Создать инструменты ===&lt;br /&gt;
&lt;br /&gt;
Базовые инструменты работы со звонком.&lt;br /&gt;
&lt;br /&gt;
==== drop_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;drop_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Завершение звонка по инициативе робота&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== transfer_call ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Параметр !! Значение&lt;br /&gt;
|-&lt;br /&gt;
| Имя || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Код || &amp;lt;code&amp;gt;transfer_call&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| description || Перевод звонка на оператора&lt;br /&gt;
|-&lt;br /&gt;
| toolType || &amp;lt;code&amp;gt;callManagement&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| callAction || &amp;lt;code&amp;gt;transfer&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| transferDestination || Короткий номер для перевода звонков (например, номер очереди)&lt;br /&gt;
|-&lt;br /&gt;
| enabled || Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Создать робота ===&lt;br /&gt;
&lt;br /&gt;
Импортировать шаблон (&amp;lt;code&amp;gt;Роботы.json&amp;lt;/code&amp;gt;). На вкладке &#039;&#039;&#039;Инструкции&#039;&#039;&#039; изучить рекомендуемый шаблон системного промпта, а также промпта пост-обработки звонка.&lt;br /&gt;
&lt;br /&gt;
== 4.3. Проверить создание пользователя ==&lt;br /&gt;
&lt;br /&gt;
После создания робота должен автоматически создаться пользователь &amp;lt;code&amp;gt;Робот_имяРобота&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 4.4. Проверить и установить статус пользователя ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Супервизор контакт-центра&#039;&#039;&#039; → раздел &#039;&#039;&#039;Операторы → Текущие статусы&#039;&#039;&#039;. Убрать фильтры, найти пользователя робота и убедиться, что у него установлен статус &#039;&#039;&#039;Готов&#039;&#039;&#039;. При необходимости установить этот статус.&lt;br /&gt;
&lt;br /&gt;
== 4.5. Добавить робота в очередь ==&lt;br /&gt;
&lt;br /&gt;
Приложение &#039;&#039;&#039;Администратор контакт-центра&#039;&#039;&#039; → добавить робота как участника очереди. &#039;&#039;&#039;Тип участника&#039;&#039;&#039; = Робот. В остальном настройки идентичны.&lt;br /&gt;
&lt;br /&gt;
== 4.6. Осуществить звонок ==&lt;br /&gt;
&lt;br /&gt;
Настройка завершена. Можно совершить звонок в очередь и протестировать работу робота.&lt;br /&gt;
&lt;br /&gt;
[[Category:Эра]]&lt;br /&gt;
[[Category:Голосовой робот]]&lt;br /&gt;
[[Category:Развёртывание]]&lt;/div&gt;</summary>
		<author><name>AZykov</name></author>
	</entry>
</feed>