# SGLang data parallel: как распределить запросы между двумя GPU

Источник: https://modelium.tech/zhurnal/sglang-data-parallel/

Data parallel в SGLang означает отдельную копию модели на каждом GPU: разные запросы обрабатываются независимо. Для маршрутизации между копиями документация рекомендует SGLang Model Gateway, а не встроенный режим `--dp-size`. Ниже — инженерный пример для Linux и двух видеокарт NVIDIA (GPU): он позволяет проверить, получили ли обе копии запросы, но редакция его не запускала.

**Инженерная настройка, не домашний рецепт.** Нужны Linux, два совместимых NVIDIA GPU, терминал и отдельное место для двух копий модели. Инструкция сверена с документацией SGLang на Git-коммите `7760d526` и карточкой Qwen на ревизии `c1899de`; Modelium не устанавливал SGLang, не скачивал модель и не запускал тест. Сначала нужны сеть и загрузка зависимостей/весов; работа с `127.0.0.1` после установки не доказывает полной сетевой изоляции. [s1](#src-s1) [s3](#src-s3) [s5](#src-s5)

## Зачем две копии одной модели?

Допустим, два сотрудника одновременно просят пересказать разные короткие заметки. **Data parallel (DP)** даёт каждой видеокарте полную копию языковой модели, чтобы запросы могли идти к разным копиям. Если модель не помещается на *одной* карте с нужным контекстом, DP этого не исправит: потребуется другой размер модели или способ разделить её по нескольким GPU (**tensor parallel, TP**). Это статья о серверной обработке независимых запросов, а не об ускорении одного ответа. [s1](#src-s1)

В документации SGLang есть `python -m sglang.launch_server --dp-size 2`, но разработчики прямо называют встроенный **native DP** неподходящим для production: у него ограничены наблюдаемость и отказоустойчивость. Основной маршрут здесь — два отдельных worker (процесса с моделью) и **SGLang Model Gateway (SMG)**: он принимает запросы по одному адресу и распределяет их между worker. Для учебной проверки выберем политику `round_robin` — запросы поочерёдно назначаются доступным worker. **DP attention / **`**--attn-dp-size**` — иной механизм внутри модели; не подменяйте им две копии. [s1](#src-s1) [s2](#src-s2)

## Что проверить перед установкой?

Этот конкретный путь рассчитан на Linux с NVIDIA и CUDA 13-совместимым драйвером; инструкция установки SGLang показывает `uv` и Python 3.12. Откройте терминал и выполните `nvidia-smi --query-gpu=index,name,memory.total --format=csv`: убедитесь, что видны **две** подходящие карты. Точные минимумы VRAM, RAM и диска для двух копий и вашей нагрузки в источниках не указаны. Сначала запустите одну копию на одной карте по [базовому гайду SGLang](/zhurnal/sglang/) и убедитесь, что она отвечает и помещается; не выводите память из размера файла весов. [s3](#src-s3) [s4](#src-s4)

Для примера взята `Qwen/Qwen3-0.6B`: это конкретная модель из Quickstart SGLang, а закреплённая карточка Qwen отмечает Apache-2.0. Не путайте метку лицензии этой модели с правами других моделей. Команды с именем репозитория скачивают текущие файлы, **не закрепляют веса** на ревизии `c1899de` автоматически. Для воспроизводимого замера сохраните локальный snapshot конкретной ревизии, версии SGLang/router, драйвера и точные настройки. [s4](#src-s4) [s5](#src-s5)

## Как поднять две реплики и один вход?

- В рабочем каталоге установите `uv` по [официальному руководству SGLang](/zhurnal/sglang/) и выполните `uv venv --python 3.12`, `source .venv/bin/activate`, `uv pip install --prerelease=allow sglang` и `uv pip install sglang-router`. Установку Gateway отдельным пакетом описывает его документация; для несовпадающих версий проверьте справку `python -m sglang_router.launch_router --help` до запуска. Нужна сеть для пакетов и первого получения модели. [s1](#src-s1) [s2](#src-s2) [s3](#src-s3)

- В **первом** терминале с активированным окружением запустите `CUDA_VISIBLE_DEVICES=0 python -m sglang.launch_server --model-path Qwen/Qwen3-0.6B --host 127.0.0.1 --port 30001 --enable-metrics`. В **другом** терминале с тем же окружением, но другой картой: `CUDA_VISIBLE_DEVICES=1 python -m sglang.launch_server --model-path Qwen/Qwen3-0.6B --host 127.0.0.1 --port 30002 --enable-metrics`. Дождитесь сообщения о готовности каждого сервера; `curl -sS http://127.0.0.1:30001/metrics` и тот же адрес с портом `30002` должны отвечать. Запускайте вторую копию только если первая успешно загрузилась. Порты и `CUDA_VISIBLE_DEVICES` — выбранная для этого учебного стенда схема, не гарантия совместимости любого железа. [s2](#src-s2) [s4](#src-s4) [s6](#src-s6)

- В **третьем** терминале после готовности обоих worker запустите `python -m sglang_router.launch_router --worker-urls http://127.0.0.1:30001 http://127.0.0.1:30002 --policy round_robin --host 127.0.0.1 --port 30000`. В четвёртом терминале `curl -sS http://127.0.0.1:30000/workers` должен показать обе зарегистрированные копии. Если справка вашей установленной версии не знает параметр или Gateway не видит worker, не выдавайте дальнейший тест за состоявшийся. Все адреса здесь доступны лишь через loopback на этой машине; это не руководство по открытию API в сеть. [s1](#src-s1) [s2](#src-s2)

- Для маленького теста во **четвёртом** терминале отправьте четыре запроса **через порт Gateway **`**30000**`, меняя цифру в конце фразы: `curl -sS -X POST http://127.0.0.1:30000/v1/chat/completions -H 'Content-Type: application/json' -d '{"model":"Qwen/Qwen3-0.6B","messages":[{"role":"user","content":"Заметка 1: встреча в четверг. Назови день встречи одним словом."}],"max_tokens":80}'`. Повторите с «Заметка 2/3/4»; не обращайтесь напрямую к `30001` или `30002` на этом этапе. В каждом HTTP-ответе проверьте отсутствие `error` и наличие непустого `choices[0].message.content`. Ожидаемый смысл учебного ответа — «четверг», но конкретный текст модели **не получен редакцией**; сверяйте свой ответ с входом. [s2](#src-s2) [s4](#src-s4) [s5](#src-s5)

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

Перед четырьмя учебными запросами снимите показания `curl -sS http://127.0.0.1:30001/metrics` и `curl -sS http://127.0.0.1:30002/metrics` в отдельные файлы (`-o before-1.txt` и `-o before-2.txt`); после запросов снимите их в `after-1.txt` и `after-2.txt`. В каждом файле найдите ряд `sglang:e2e_request_latency_seconds_count` и сравните значение **одного и того же ряда с теми же метками** до/после отдельно на каждом порту. Документация метрик описывает этот счётчик завершённых запросов; если ряды есть и оба выросли, а ответы успешны, обе копии обработали запросы. Снимок `/workers` доказывает регистрацию, но **не** сам по себе распределение. При отсутствии ряда проверьте формат реально установленной версии и журналы обоих worker; не приписывайте распределение лишь двум процессам в `nvidia-smi`. [s2](#src-s2) [s6](#src-s6) [s7](#src-s7)

Затем на вашем стенде сравните одну и две копии при одинаковых модели, входах, числе клиентов и длине ответа; фиксируйте версию, занятость каждой карты, успешность, задержки и число обработанных запросов. Четыре последовательных коротких запроса проверяют маршрут, **не** доказывают выигрыш по скорости при параллельной нагрузке. Отдельно почитайте [руководство по метрикам SGLang](/zhurnal/sglang-metrics-prometheus/). Рекламируемые в документации результаты тестов Gateway относятся к авторскому стенду и не являются измерением Modelium. [s1](#src-s1) [s2](#src-s2)

## Если проверка не получилась

- Одна из карт не видна или первый worker не загрузился: проверьте драйвер и совместимость установленного SGLang; при нехватке памяти не добавляйте DP, а сначала уменьшите модель/контекст. Минимум памяти для этой машины источники не задают. [s1](#src-s1) [s3](#src-s3)

- `/workers` показывает одну копию: проверьте, что оба порта worker отвечают **до** запуска маршрутизатора, а адреса в `--worker-urls` совпадают с ними. [s2](#src-s2)

- Ответы есть, но счётчик одной копии не растёт: убедитесь, что запросы проходили через `30000`, обе копии были доступны, и метрики сравнивались с одинаковыми метками; не делайте вывод из одной проверки без рабочего счётчика. [s2](#src-s2) [s6](#src-s6) [s7](#src-s7)

- Попытка заменить `--dp-size` на `--attn-dp-size` не решает задачу двух независимых копий: это режим распределения вычислений внимания, а не синоним двух worker; начните с приведённого здесь пути SMG. [s1](#src-s1)

Остановите учебные процессы через `Ctrl+C` в трёх серверных терминалах. **Следующий шаг:** [сверьте метрики каждого worker](/zhurnal/sglang-metrics-prometheus/) перед нагрузочным сравнением; не открывайте учебный API наружу без отдельной защиты. [s2](#src-s2)

## Источники

1. [SGLang: DP, DPA and SGLang DP Router (закреплённый Git)](https://raw.githubusercontent.com/sgl-project/sglang/7760d5264ac16b85392aefb1bf5c13ce38d9632e/docs/docs/advanced_features/dp_dpa_smg_guide.mdx) — получено 2026-10-08
2. [SGLang: Model Gateway и маршрутизация (закреплённый Git)](https://raw.githubusercontent.com/sgl-project/sglang/7760d5264ac16b85392aefb1bf5c13ce38d9632e/docs/docs/advanced_features/sgl_model_gateway.mdx) — получено 2026-10-08
3. [SGLang: Installation (закреплённый Git)](https://raw.githubusercontent.com/sgl-project/sglang/7760d5264ac16b85392aefb1bf5c13ce38d9632e/docs/docs/get-started/install.mdx) — получено 2026-10-08
4. [SGLang: Quickstart (закреплённый Git)](https://raw.githubusercontent.com/sgl-project/sglang/7760d5264ac16b85392aefb1bf5c13ce38d9632e/docs/docs/get-started/quickstart.mdx) — получено 2026-10-08
5. [Qwen/Qwen3-0.6B: карточка автора (закреплённая ревизия)](https://huggingface.co/Qwen/Qwen3-0.6B/resolve/c1899de289a04d12100db370d81485cdf75e47ca/README.md) — получено 2026-10-08
6. [SGLang: Observability и /metrics (закреплённый Git)](https://raw.githubusercontent.com/sgl-project/sglang/7760d5264ac16b85392aefb1bf5c13ce38d9632e/docs/docs/advanced_features/observability.mdx) — получено 2026-10-08
7. [SGLang: Production Metrics (закреплённый Git)](https://raw.githubusercontent.com/sgl-project/sglang/7760d5264ac16b85392aefb1bf5c13ce38d9632e/docs/docs/references/production_metrics.mdx) — получено 2026-10-08
