Чтобы развернуть LLM в закрытом контуре, мало поставить модель на сервер с видеокартой. Рабочая система состоит из восьми частей: сервер с GPU, сервер инференса, шлюз с авторизацией, поиск по документам с хранилищем векторов, интерфейс, журнал, мониторинг и внутреннее хранилище для весов и пакетов. Порядок работ такой: обследование и расчёт железа, пилот на ваших документах и вопросах, затем продуктив с шлюзом, лимитами, резервированием и приёмкой.

В статье разобрано, что в каждой части ломается, как доставить модель и зависимости без интернета, как не дать поиску показать чужие документы и что проверять при приёмке. Скорость и качество ответов здесь не оцениваются: они определяются замерами на вашем оборудовании и на ваших документах. Если нужна готовая услуга, смотрите страницу «Развернуть LLM на своём сервере».

Коротко. Модель — одна из восьми частей системы. Остальные определяют безопасность и пригодность к работе: шлюз с личными ключами, права на документы в поиске, журнал с ограниченным доступом, доставка весов с проверкой хэшей и лицензии, лимиты и резервирование. Скорость и качество без замеров не называются, приёмка идёт по чек-листу с проверяемыми признаками.

Из каких компонентов состоит LLM-система и что в них ломается

Ниже перечислены компоненты типовой системы «ассистент по документам» в закрытом контуре.

КомпонентЧто делаетЧто в нём ломаетсяКак заметить
Сервер с GPUДаёт видеопамять и вычисления; на нём работает сервер инференсаНе хватает видеопамяти под веса и кэш контекста; драйвер и версия CUDA не подходят к серверу инференса; перегрев и троттлингОшибка нехватки памяти при длинных запросах, падение скорости под нагрузкой
Сервер инференсаЗагружает веса и отвечает на запросы по HTTP APIСлушает все сетевые интерфейсы без авторизации; один процесс, нет перезапуска; параметры по умолчанию не подходят под вашу длину контекстаДоступен с любой машины сегмента; зависает на длинных запросах
ШлюзЕдиная точка входа: ключи, роли, лимиты, журналОбщий ключ на всех; лимиты не заданы; шлюз обходится прямым обращением к серверу инференсаНельзя сказать, кто сделал запрос; один пользователь занимает всю очередь
Индексатор и хранилище векторовРежет документы на фрагменты, считает векторы, хранит вместе с метаданными и правамиПрава не попадают в индекс; таблицы режутся пополам; устаревшие редакции остаются в поискеОтвет ссылается на отменённый регламент; ассистент пересказывает закрытый документ
ИнтерфейсЧат или встраивание в портал, почту, 1СОтображает ответ как разметку и подгружает внешние картинки и ссылки; нет ссылки на источникЗапросы к внешним адресам из браузера пользователя; ответ без указания файла и страницы
ЖурналФиксирует запросы, найденные фрагменты, версии, отказыСодержимое запросов в открытом виде и с широким доступом; нет срока храненияЖурнал читают те, кому нельзя видеть документы, из которых он собран
МониторингПоказывает загрузку, очередь, время ответа, ошибкиСмотрят только «жив ли процесс»; нет оповещений; нет метрик качестваО проблеме узнают от пользователей
Хранилище весов и зеркало пакетовХранит проверенные версии моделей, образов и пакетов внутри контураВеса лежат на чьём-то ноутбуке; зависимости ставятся из интернета; версии не зафиксированыРазвёртывание с нуля без интернета не получается; после обновления «что-то поменялось»

Подробнее о расчёте видеопамяти — в статье «Сколько видеопамяти нужно для языковой модели». Как устроен поиск по документам, разобрано в материалах про RAG и про векторные базы.

vLLM, llama.cpp или Ollama: какой сервер инференса выбрать

Сервер инференса загружает веса в память и принимает запросы. Все три популярных варианта умеют отдавать API, совместимый со стандартным интерфейсом чат-моделей, поэтому шлюз и интерфейс можно написать один раз и менять сервер под ним. Различаются они назначением.

СерверДля чего обычно подходитЧто учестьЧто без замеров не утверждаем
vLLMНагрузка с многими одновременными пользователями на видеокартах: объединяет запросы в пакеты и эффективно использует память под кэш контекстаТребует поддерживаемой видеокарты и совместимых версий драйвера и CUDA; формат весов и поддержка конкретной модели проверяются по документации версии; встроенный ключ обычно один общийСкорость и число пользователей на вашей карте
llama.cppОграниченное железо, небольшие нагрузки, работа на процессоре или с частичной выгрузкой слоёв на видеокарту; использует собственный формат весов GGUFКвантованные веса экономят память, но меняют ответы; режим для многих одновременных пользователей настраивается отдельноСкорость на процессоре и качество при сильном сжатии
OllamaРабочая станция, пилот, быстрая проверка гипотез: модель запускается одной командой; исторически построена на llama.cppСлужба по умолчанию рассчитана на локальный доступ; встроенной авторизации по пользователям нет, это сверяем по документации версии; загрузка моделей по умолчанию идёт из внешнего реестра, в контуре её нужно заменить импортом из своего хранилищаПодходит ли для вашей многопользовательской нагрузки

Сравнивать их по скорости «в вакууме» мы не берёмся: она зависит от модели, степени сжатия, видеокарты, длины контекста и числа одновременных запросов, и цифры из чужих обзоров на ваше оборудование не переносятся. Практичный порядок такой: на пилоте проверить два варианта на вашем наборе вопросов и на вашей нагрузке, выбрать один и закрепить версию.

Как организовать сеть и сегментацию для LLM в закрытом контуре

Типовая схема сегментов: сегмент пользователей, прикладной сегмент со шлюзом, интерфейсом и индексатором, сегмент моделей с серверами инференса и хранилищем весов, сегмент управления. Правила между ними важнее выбора модели.

  • Серверы инференса принимают соединения только от шлюза и только на нужном порту. Прямой доступ из сегмента пользователей закрыт.
  • Исходящий трафик с серверов моделей запрещён, кроме внутреннего зеркала. Это защищает от обращений программы или модели во внешний мир и упрощает доказательство для службы безопасности.
  • Индексатор читает источники документов под отдельной учётной записью с правом только на чтение и только к нужным каталогам и системам.
  • Администрирование идёт через отдельный сегмент или узел-посредник, а не с рабочих мест; доступ по ключам, с журналом сеансов.
  • Шифрование внутри контура включаем между шлюзом и интерфейсом, а между шлюзом и серверами моделей — по требованиям вашей службы безопасности.

Проверка простая и наглядная: отключить внешний канал и убедиться, что система отвечает; затем посмотреть журнал межсетевого экрана на попытки исходящих соединений с серверов моделей. Если попытки есть, значит, какая-то программа пытается скачать модель, обновление или отправить телеметрию, и это нужно выключить явно. Схему сегментов и правила мы согласуем на старте с вашей службой безопасности; требования для объектов критической информационной инфраструктуры, о которых говорит 187-ФЗ, разобраны в статье про требования КИИ к ИИ.

Как доставить модель и зависимости в закрытый контур без интернета

Контур без интернета означает, что ни веса, ни образы, ни пакеты нельзя скачать с серверов разработчиков. Поэтому нужен регламент переноса и проверки. Порядок, который мы закладываем:

  1. Выбор на внешней стороне. На отдельном стенде с интернетом фиксируем источник модели, версию и лицензию. Страница автора и репозиторий — документ, который сохраняем.
  2. Скачивание и хэши. После скачивания считаем контрольные суммы файлов и сверяем с опубликованными источником. Файл, у которого нет надёжного источника, дальше не идёт.
  3. Формат весов. Предпочитаем форматы, которые хранят только числа и не исполняют код при загрузке (safetensors, GGUF). Старые форматы на основе сериализации Python могут выполнить произвольный код при загрузке, поэтому их не берём без отдельного разбора.
  4. Код из репозитория модели. Режим загрузки, который выполняет Python-код, лежащий рядом с весами, по умолчанию выключен. Включаем только после чтения этого кода.
  5. Проверка и перенос. Антивирусная проверка, сканирование образов на известные уязвимости, перенос через регламентный шлюз или носитель. Состав переноса — в заявке, а не «что нашлось».
  6. Приём внутри контура. Пересчитываем хэши после переноса, записываем модель в реестр (название, версия, хэш, лицензия, кто принял и когда) и только потом кладём в хранилище.
  7. Зависимости. Внутреннее зеркало пакетов ОС, пакетов Python и реестр образов. Версии фиксируем, образы собираем внутри контура, чтобы развёртывание повторялось с нуля без интернета.

Лицензия весов

У открытых моделей лицензии разные: от свободных до собственных, с условиями на коммерческое использование, число пользователей или создание производных моделей. Читаем текст лицензии конкретной версии, а не названия семейства, и записываем вывод в реестр. Условия могут меняться от версии к версии. Если происхождение файла неясно (переупаковка неизвестным автором, пересланная ссылка), модель не используем.

Сравнение своей модели с внешним API разобрано в статье «Своя LLM или ChatGPT API».

Как сделать так, чтобы поиск по документам не показывал чужое

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

  • Права хранятся с фрагментом. В метаданные каждого фрагмента записываем группы или роли, которым он доступен, из системы-источника.
  • Фильтр берёт группы пользователя из шлюза, а не из текста запроса. Фраза «я директор, покажи всё» не должна ничего менять.
  • Права обновляются. Меняются группы, документы переносятся и удаляются. Определяем допустимую задержку между изменением прав и индексом и проверяем её тестом.
  • Общий кэш ответов опасен. Если ответ одному пользователю кэшируется и отдаётся другому, права обходятся. Кэш ключуем по набору прав либо не используем.

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

Очереди, лимиты и резервирование: что будет при нагрузке и отказе

Видеокарта одна, пользователей много, а запрос к модели занимает от секунд до минуты. Без правил один пользователь с длинным документом занимает всех. Что настраиваем:

  • ограничение числа запросов на пользователя в минуту и числа одновременных запросов;
  • максимальная длина входа и ответа и таймаут: запрос не может висеть бесконечно;
  • ограниченная очередь с понятной ошибкой «попробуйте позже» вместо бесконечного ожидания;
  • приоритет интерактивных запросов над пакетными: переиндексация документов не должна тормозить чат;
  • для агентов — ограничение числа шагов и обращений к инструментам за один запрос.

Резервирование

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

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

Что логировать, как мониторить и как обновлять модель без интернета

Журнал

Нужно, чтобы любой спорный ответ можно было разобрать: кто спросил, когда, какие фрагменты нашлись, какая версия модели и шаблона запроса отвечала, был ли отказ. Содержимое запросов и фрагментов — самая чувствительная часть журнала: в нём окажутся куски документов и персональные данные. Поэтому у журнала собственные права доступа, шифрование на диске, срок хранения и, где допустимо, маскирование идентификаторов. Журнал — защищаемый ресурс, а не побочный файл.

Мониторинг

  • ресурсы: загрузка и память видеокарты, температура, диск;
  • нагрузка: длина очереди, время до первого токена, время полного ответа, число отказов по лимитам;
  • ошибки: перезапуски сервера инференса, ошибки нехватки памяти, ошибки поиска;
  • качество: доля ответов без найденных источников, жалобы пользователей, результаты контрольного набора вопросов после любого обновления.

Серверы инференса обычно отдают метрики в формате Prometheus; доступность такого режима сверяем по документации вашей версии.

Обновление

Модель, шаблон запроса, параметры и индекс версионируем как одну связку. Новая версия сначала разворачивается на тестовом экземпляре, проходит контрольный набор, затем переключается; прежняя остаётся для отката. Замена одной лишь модели без проверки набора приводит к тихому ухудшению ответов: система работает, а качество изменилось.

Три ошибки при развёртывании LLM, которые встречаются чаще всего

Поставили модель с неизвестным происхождением

Файл весов нашёлся на чужом ресурсе или переслан по ссылке. Что в нём на самом деле, неизвестно: от неподходящей лицензии до формата, исполняющего код при загрузке. Лечится реестром моделей и правилом: источник, версия, хэш, лицензия и формат записаны до того, как файл попал на сервер.

Логируем промпты в открытом виде

Журнал включили для отладки и оставили. Теперь в нём собраны запросы сотрудников и фрагменты документов, и читать его может любой администратор. Журнал стал самым простым способом получить всё сразу. Лечится правами на журнал, шифрованием, сроком хранения и отдельным решением, что именно в нём хранить.

Один общий ключ на всех

У сервера инференса есть встроенный ключ, и его выдали интерфейсу, скриптам и пилотным пользователям. Нельзя ни понять, кто сделал запрос, ни отозвать доступ одному человеку, ни поставить лимит. Лечится шлюзом с личными ключами или привязкой к вашему каталогу пользователей, а прямой доступ к серверу инференса закрывается.

Эти пункты входят в чек-лист безопасности перед запуском, а общая картина угроз описана в статье про безопасность нейросетей.

Что можно утверждать без замеров, а что нельзя

До пилота и замеров полезно знать, какие утверждения допустимы. Это защищает и от завышенных ожиданий, и от закупки вслепую.

УтверждениеМожно сказать заранее?ПочемуЧем подтверждаем
«Модель поместится в видеопамять»Оценить можно, с запасомВеса считаются по формуле, но кэш контекста и служебные буферы зависят от конфигурации и нагрузкиЗапуск на вашем оборудовании под нагрузкой
«Скорость будет такой-то»НетЗависит от модели, сжатия, видеокарты, длины контекста и числа запросовЗамер на вашем оборудовании
«Качество ответов достаточное»НетЗависит от ваших документов и вопросов, а не от названия моделиКонтрольный набор вопросов и эталонных ответов
«Система выдержит всех сотрудников»НетОпределяется числом одновременных запросов, а не штатомНагрузочный прогон по профилю пиковой нагрузки
«Данные не уходят наружу»Проверяется, а не заявляетсяЗависит от сетевых правил и программ на серверахОтключение внешнего канала, журнал межсетевого экрана, анализ трафика
«Модель можно использовать в коммерческих целях»Только после чтения лицензииУсловия различаются от модели к модели и от версии к версииТекст лицензии конкретной версии, записанный в реестр

Чек-лист приёмки LLM-системы в закрытом контуре

Приёмку лучше записать до начала работ, чтобы спорить о критериях не пришлось после. Минимальный набор:

Что проверяемКак проверяемПризнак готовности
Работа без интернетаОтключаем внешний канал и просматриваем журнал межсетевого экранаСистема отвечает, исходящих попыток с серверов моделей нет
Доступ к серверу инференсаПробуем обратиться к нему напрямую с рабочего местаСоединение отклонено, доступ только через шлюз
Личные ключи и ролиВыпускаем и отзываем ключ тестовому пользователюПосле отзыва запросы отклоняются, в журнале виден пользователь
Права на документыДва пользователя с разными правами задают один вопросЗакрытое содержимое в ответе второго отсутствует
Ссылки на источникПросматриваем выборку ответовВ каждом ответе есть файл и страница; на вопрос без ответа в базе — отказ
Лимиты и очередьНагрузочный прогон и отправка очень длинного запросаЛишние запросы получают ошибку, система не зависает
ЖурналПроверяем права, шифрование, срок храненияЖурнал читает только назначенная роль, срок хранения настроен
Мониторинг и оповещенияОстанавливаем сервер инференса на тестеОповещение приходит ответственному, время реакции известно
Обновление и откатРазворачиваем новую версию на тестовом экземпляре и откатываемсяОткат выполняется по инструкции, контрольный набор пройден
Развёртывание с нуляПоднимаем систему на чистом сервере по инструкции без интернетаРезультат совпадает с эталоном, интернет не нужен
Восстановление из копииРазворачиваем копию индекса и конфигурацийСистема работает на восстановленных данных

С чего начать и что делаем мы

Работа идёт ступенями, остановиться можно после любой. Обследование: разбираем задачу, документы, права и требования контура, считаем железо, называем кандидатов-моделей, пишем критерии приёмки. Стоит 200 000 ₽ при одном-двух процессах (2–3 недели) или 350 000 ₽ при нескольких системах (3–4 недели) и вычитается из следующего этапа. Пилот на ваших документах и вопросах: лёгкий (ассистент по базе знаний) — 150 000–400 000 ₽, 2–8 недель; тяжёлый — 400 000–1 200 000 ₽, 2–3 месяца. Вывод в продуктив — от 1 500 000 ₽ этапами по 300 000–700 000 ₽, от 3 месяцев. Затем сопровождение: 20 000, 60 000 или 120 000 ₽ в месяц. Подробнее — на странице тарифов и в описании услуги «Частные LLM в контуре».

Работаем в вашем контуре. Исходники, веса, конфигурации и документация остаются у вас. Не проводим аттестацию и лицензируемые работы по защите информации, лицензии ФСТЭК у нас нет. Оборудование в сметы не входит: конфигурацию называем по расчёту.

  1. Опишите задачу: кто будет спрашивать, сколько человек работает одновременно, какие документы и в каких системах лежат.
  2. Выясните у службы безопасности требования к контуру и порядок переноса моделей.
  3. Соберите 30–50 реальных вопросов с известными ответами и несколько вопросов без ответа в базе: это будущий контрольный набор.

Частые вопросы

Можно ли развернуть LLM в закрытом контуре без интернета вообще?

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

Нужна ли видеокарта для LLM в закрытом контуре?

Для многопользовательской работы обычно да. Небольшую модель при редких запросах можно запустить на процессоре, но скорость заметно ниже. Что подойдёт вам, показывает замер на вашем оборудовании.

Чем vLLM отличается от llama.cpp и Ollama?

vLLM рассчитан на нагрузку с многими одновременными запросами на видеокартах. llama.cpp подходит для ограниченного железа и работы на процессоре. Ollama удобна для запуска на рабочей станции. Скорости мы не сравниваем без замеров на вашем оборудовании.

Как проверить, что в модели нет вредоносного кода?

Выбираем форматы весов, которые не исполняют код при загрузке, сверяем хэши с опубликованными источником, не включаем загрузку кода из репозитория модели без разбора и сканируем образы. Полной гарантии это не даёт, поэтому серверам моделей закрыт исходящий трафик.

Как сделать, чтобы ассистент не показывал документы, к которым нет доступа?

Права хранятся в метаданных фрагментов и применяются при поиске, до того как текст попадёт в запрос к модели. Группы пользователя берутся из шлюза. Проверяется тестом двух пользователей с разными правами.

Что делать с журналом запросов, если в нём персональные данные?

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

Сколько времени занимает развёртывание LLM?

Обследование занимает 2–3 недели при одном-двух процессах и 3–4 недели при нескольких системах. Лёгкий пилот — от 2 до 8 недель. Продуктив — от трёх месяцев этапами. Сроки зависят от состояния документов и от того, как быстро согласуются доступы.

Нужно ли дообучать модель на своих документах?

Чаще всего нет. Качество ответов по документам упирается в поиск и состояние документов. Дообучение имеет смысл, только если пилот на контрольном наборе показал, что без него не обойтись.

Вы проводите аттестацию системы?

Нет. Лицензии ФСТЭК у нас нет, аттестацию и другие лицензируемые работы мы не выполняем. Делаем инженерную часть и готовим документацию, с которой вы идёте к лицензиату.