ADG Оставить заявку
Блог Данные и аналитика 5 мин чтения

Llama 2 на A10G внутри DMZ: замеряем латентность и убеждаемся, что модель не звонит домой

Разворачиваем Llama 2 13B на GPU-сервере внутри закрытого сегмента: считаем токены в секунду, проверяем сетевые соединения и разбираемся, что работает, а что нет.

Контекст момента

Meta выпустила Llama 2 с коммерческой лицензией - открытая LLM для деплоя в закрытом контуре предприятий, 18 июля 2023

18 июля Meta опубликовала Llama 2 - и это был уже не академический релиз «посмотрите, как мы умеем». Модель вышла с лицензией, которая разрешает коммерческое использование при численности пользователей продукта до 700 миллионов человек в месяц. Для подавляющего большинства предприятий это «разрешено». Плюс - доступны веса для 7B, 13B и 70B, а не только через API.

У нас к тому моменту уже лежал оформленный запрос от клиента: развернуть языковой ассистент для внутреннего helpdesk внутри DMZ, без какого-либо трафика наружу. В июле мы разбирались с общей механикой изолированного деплоя, и Llama 2 давала повод перейти от экспериментов к чему-то ближе к production.

Стенд и исходная задача

Сервер - физическая машина в DMZ с одной NVIDIA A10G 24 GB. A10G - не самая топовая карта, но распространённая в enterprise: есть в линейке Dell PowerEdge, HPE ProLiant и в нескольких отечественных серверных конфигурациях. Для 13B в float16 нужно около 26 GB - не влезает. Для 13B в 4-bit GPTQ - около 9 GB, с запасом.

Выбрали 13B в 4-bit квантовании (Q4_K_M): 7B выдаёт заметно более слабые ответы на технические вопросы, 70B на одной A10G запустить нельзя в принципе.

Стек:

  • llama.cpp как основной рантайм - C++, компилируется на месте, без тяжёлых Python-зависимостей;
  • llama-cpp-python поверх, чтобы выставить совместимый с OpenAI API HTTP-эндпоинт;
  • всё это на Rocky Linux 8, CUDA 11.8, драйвер 525.x.

Установка в изолированном сегменте - отдельная история. Веса 13B весят около 7 GB в GGML-формате (llama.cpp использует собственный бинарный формат вместо safetensors). Скачали заранее, перенесли по внутренней сети. Python-зависимости - через заранее собранный wheel-архив, как мы это уже делали в прошлый раз.

Замеры латентности

Первое, что интересовало - сколько токенов в секунду модель выдаёт на A10G. Без нагрузочного тестирования, просто ориентир для одного пользователя:

  • Prefill (обработка промпта): быстро, для промпта в 200-300 токенов - меньше секунды.
  • Генерация (decode): в районе 25-35 токенов в секунду для 13B Q4_K_M на CUDA.

Для диалогового интерфейса 25-35 tok/s - это уже вполне читабельно. Ответ на короткий вопрос появляется за 2-4 секунды полностью. Для сравнения: на том же железе без GPU-ускорения (pure CPU, 32 ядра) те же 13B выдают 3-5 токенов в секунду - разница на порядок, и это сразу ощущается пользователем.

Контекст влияет сильнее, чем мы ожидали. При контексте в 2000 токенов prefill-фаза растягивается, и суммарное время первого ответа ощутимо растёт. Для helpdesk-сценария с короткими вопросами это некритично, но для summarization длинных тикетов - уже заметно.

Главный вопрос: звонит ли модель домой

Это был принципиальный пункт от клиента: убедиться, что llama.cpp с Llama 2 не устанавливает никаких внешних соединений - ни при загрузке, ни в процессе инференса.

Проверяли несколькими способами одновременно:

tcpdump на сетевом интерфейсе сервера во время загрузки весов и во время генерации. Из исходящего трафика - только DNS-запрос при старте python-сервера (системный резолвер искал локальный хост, ничего подозрительного) и трафик к нашему же фронтенду в той же подсети.

iptables с логированием - настроили правило DROP на всё, что уходит за пределы DMZ, с записью в syslog. За несколько часов работы - ни одного заблокированного пакета от процесса инференса.

strace на процессе - на предмет неожиданных syscall к сокетам. Ничего, кроме unix-сокета для IPC между воркерами.

Результат предсказуемый, но его важно было зафиксировать документально: llama.cpp - это локальный рантайм, он не знает ни о каких облачных сервисах Meta. Веса грузятся с диска, всё происходит локально. Никаких телеметрических коллбэков в базовой конфигурации нет. Это не то что нужно принимать на веру - это то, что проверяется за полчаса.

Качество на реальных задачах

Llama 2 13B Chat на английских технических запросах - хорошо. Объяснить stacktrace, написать SQL-запрос, сгенерировать Ansible-таску под описание - справляется без особых нареканий.

На русском - терпимо, но с оговорками. Понимает русский текст достаточно, чтобы отвечать по существу, но сам ответ иногда съезжает в английский на середине, особенно при технических формулировках. Для helpdesk-сценария, где пользователи пишут вопросы по-русски, это ощутимый минус. Есть дообученные варианты с улучшенной поддержкой русского - до них руки ещё не дошли, это следующий шаг.

Галлюцинации никуда не делись. Локальный деплой не делает модель точнее - она такой же вероятностный генератор текста. Просто данные не уходят наружу.

Где мы сейчас

Стенд работает, клиент смотрит. Ближайшая задача - интеграция с внутренней базой знаний через RAG: сейчас модель отвечает только из своих весов, без доступа к корпоративным документам. Это существенно ограничивает применимость для helpdesk.

Дедлайн по КИИ в 2025-м добавляет вопрос об импортозамещении в эту картину: Llama 2 - американская модель с лицензией Meta. Для систем, попадающих под требования КИИ, это отдельный юридический вопрос, который мы пока оставляем клиентам разбирать с их правовыми командами. Технически деплой работает - дальше вопрос не к нам.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.