# SGLang LoRA serving: базовая модель и проверка адаптера

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

SGLang может обслуживать базовую модель и несколько LoRA-адаптеров на одном сервере: задайте `--lora-paths`, а в OpenAI-совместимом запросе выбирайте базу или `имя-базы:имя-адаптера` через поле `model`. До запуска проверьте соответствие адаптера конкретной базе, а после — отправьте одинаковый контрольный запрос обоими маршрутами. Разница текстов не доказывает качество дообучения; результат оценивайте на собственном наборе задач.

**Срез 7 октября 2026 года:** документация SGLang закреплена на коммите `aa5551d9`, PEFT — на `190f9873`. Ни SGLang, ни GPU, ни модель с адаптером Modelium не запускал; ниже — план проверки на вашем компьютере, а не наш тест. Версии установленного пакета, GPU, базовых весов и адаптера нужно записать отдельно. [s1](#src-s1) [s3](#src-s3)

## Когда стоит обслуживать адаптер вместе с базой?

Если для одной задачи нужен ответ исходной модели, а для другой — её специально обученного варианта, SGLang даёт маршрутизацию LoRA поверх базы, не требуя отдельного полного набора базовых весов в каждом адаптере. В формате PEFT адаптер хранит только собственные параметры, а исходная модель поставляется отдельно [s1](#src-s1) [s5](#src-s5). Это решение для обслуживания **уже полученной и совместимой** пары, не инструкция по обучению и не гарантия улучшения ответов. Задача → пара база/адаптер → соответствующий GPU и runtime → два проверенных маршрута → сравнение по своим данным.

Если адаптер не нужен, начните с [запуска SGLang](/zhurnal/sglang/). Если цель — добавить знания из изменяемых документов, сначала сравните LoRA с RAG в [разборе дообучения](/zhurnal/doobuchenie-i-lora/): наличие адаптера не делает базу источником актуальных сведений.

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

В базовом репозитории выберите конкретный идентификатор и сохраните revision файла модели. Документация SGLang для первого API-запроса использует `qwen/qwen2.5-0.5b-instruct`; исходный репозиторий Qwen2.5-0.5B-Instruct существует, но это **не значит**, что произвольный опубликованный LoRA подходит к нему [s2](#src-s2) [s7](#src-s7). Учебная пара в официальном разделе LoRA использует *другую* базу — `meta-llama/Meta-Llama-3.1-8B-Instruct` — и адаптер от неё; не переносите этот адаптер на Qwen только потому, что Qwen фигурирует в соседнем примере API [s1](#src-s1) [s2](#src-s2).

У своего адаптера найдите `adapter_config.json` и `adapter_model.safetensors` или `adapter_model.bin`. PEFT описывает эти файлы как конфигурацию и параметры адаптера, но **не** полные веса базовой модели. В конфигурации проверьте `peft_type`, `base_model_name_or_path`, `revision` при наличии, `r` и целевые модули; сравните с фактически загруженной базой и происхождением адаптера. Совпадение строки имени — предварительная проверка, а не гарантия архитектурной совместимости или прав на использование. Формат `.bin` использует pickle, поэтому не десериализуйте непроверенные файлы ради теста [s5](#src-s5). При сомнениях в лицензии, источнике или соответствии — не включайте адаптер в публичный сервис.

Для показанного ниже сценария нужны Linux, совместимое окружение SGLang и GPU; официальная инструкция установки отдельно описывает CUDA, Docker и версии Python для своего среза. Универсальный минимум VRAM в этих документах не задан, а размер весов на диске не равен требуемой памяти при инференсе [s3](#src-s3). Фиксируйте реальный GPU, драйвер, пакет, контекст, число запросов и место под веса. Команда `sglang serve` без LoRA и один запрос по [стартовому гайду](/zhurnal/sglang/) — первая диагностическая точка [s4](#src-s4).

## Как подключить один собственный LoRA статически?

После проверки совместимости запуск из документации имеет вид: `python -m sglang.launch_server --model-path <BASE> --host 127.0.0.1 --port 30000 --enable-lora --lora-paths trial=<ADAPTER> --max-loras-per-batch 2`. **Это шаблон, а не готовая команда**: подставьте идентификатор или локальный путь *своей* базы вместо `<BASE>` и каталог *своего* проверенного PEFT-адаптера вместо `<ADAPTER>`. Не вводите угловые скобки в оболочку буквально: она воспримет их как перенаправление. Здесь localhost указан явно; сервер для удалённых клиентов требует самостоятельных правил доступа [s1](#src-s1) [s2](#src-s2) [s4](#src-s4).

Руководство SGLang принимает `--lora-paths` в форме `имя=путь`; этот аргумент сам может включить LoRA для обратной совместимости, но явный `--enable-lora` соответствует примерам. `--max-loras-per-batch 2` выбран **для этого сценария**, потому что официальный пример считает слот адаптера и слот базы. По документации значение по умолчанию — 8; число и rank влияют на резерв GPU-памяти, так что оно не означает «ровно два пользователя» или гарантированный объём памяти [s1](#src-s1). Не выставляйте `--max-lora-rank` произвольно: при стартовых адаптерах SGLang выводит его из загруженных файлов, а для последующей динамической загрузки потребуется заранее проверить и явно задать допустимый rank и набор целевых модулей [s1](#src-s1).

Не публикуйте сетевой адрес `0.0.0.0` для проверки на своей машине. Даже привязка к `127.0.0.1` не гарантирует приватность от других процессов на том же хосте; данные и доступ к весам оценивайте отдельно. Руководство установки показывает внешнюю привязку как вариант деплоя, а не обязательное условие локального теста [s3](#src-s3) [s4](#src-s4).

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

В отдельном терминале на том же компьютере отправьте два одинаковых POST на `http://127.0.0.1:30000/v1/chat/completions` с `Content-Type: application/json`. Для базового запроса тело: `{"model":"<BASE>","messages":[{"role":"user","content":"Коротко классифицируй: входящий счёт"}],"temperature":0,"max_tokens":80}`. Для адаптера сохраните **тот же** текст и параметры, поменяйте только `model` на `"<BASE>:trial"`. Подставляйте ровно то имя базы, с которым подняли сервер; эти JSON — иллюстрации для *своего* клиента, а не работающий ответ Modelium. Документация SGLang рекомендует форму `base-model:adapter-name` для OpenAI-compatible API; без суффикса выбирается база [s2](#src-s2) [s4](#src-s4).

Проверяйте HTTP-статус, отсутствие `error`, `choices[0].message.content` и идентификатор запрошенного маршрута в своём журнале. Один ответ базы и один ответ адаптера показывают только доступность маршрутов; одинаковый или разный текст не подтверждает эффективность LoRA. Соберите небольшой одинаковый набор примеров из своей задачи с ожидаемым результатом, сохраните версию обоих наборов весов и сравните ответы по явному критерию, не смешивая тест маршрутизации с оценкой качества. SGLang иллюстрирует и нативный `/generate`: его `lora_path` — имя адаптера, а `None` обозначает базу в пакетном запросе; не подставляйте этот параметр вместо поля `model` в рекомендуемом OpenAI-compatible методе [s1](#src-s1) [s2](#src-s2).

## Что делать, если один из двух маршрутов не отвечает?

- **База не отвечает:** проверьте доступность сервера, точный `--model-path`, фактическую версию SGLang и локальный запрос **без** LoRA; пока база не работает, вывод об адаптере преждевременен [s4](#src-s4).

- **База отвечает, адаптер отклонён:** перепроверьте путь/имя `trial`, наличие PEFT-файлов, базу в конфигурации, rank и целевые слои. `adapter_model.*` не содержит базу и не заменяет её. Сверьте ошибку сервера; не меняйте одновременно модель, backend и adapter [s1](#src-s1) [s5](#src-s5) [s6](#src-s6).

- **API принял запрос, но результат неожиданен:** проверьте строку `model`: `base:trial` и `base` выбирают разные маршруты. Старый способ через `extra_body.lora_path` сохранён для совместимости, но при одновременном задании суффикс `model` имеет приоритет. Не считайте наличие полезного текста доказательством применения нужного адаптера без проверенного запроса и лога [s2](#src-s2).

- **Не хватает ресурсов:** уменьшите нагрузку или число одновременных адаптеров, проверьте реальные метрики и параметры сервера. Нельзя вывести минимум GPU-памяти только из размера файла LoRA или документационного примера на другом железе [s1](#src-s1) [s3](#src-s3).

После проверки остановите сервер в его терминале. Если нужны горячая загрузка и выгрузка, документация описывает `/load_lora_adapter` и `/unload_lora_adapter`; это **другой сценарий** с дополнительными ограничениями rank/модулей и отдельной поверхностью доступа, не шаг обязательного первого запуска [s1](#src-s1). Для эксплуатации разных локальных runtime сравните с [vLLM LoRA serving](/zhurnal/vllm-lora-adapters/); для первой диагностики вернитесь к [базовому SGLang](/zhurnal/sglang/). Ни одного результата прогона Modelium не заявляет.

## Источники

1. [SGLang LoRA Serving — закреплённая документация](https://raw.githubusercontent.com/sgl-project/sglang/aa5551d9b6ebe133427a8a0b368c2643f79d5440/docs/docs/advanced_features/lora.mdx) — получено 2026-10-07
2. [SGLang OpenAI APIs: Using LoRA Adapters](https://raw.githubusercontent.com/sgl-project/sglang/aa5551d9b6ebe133427a8a0b368c2643f79d5440/docs/docs/basic_usage/openai_api_completions.mdx) — получено 2026-10-07
3. [SGLang Installation](https://raw.githubusercontent.com/sgl-project/sglang/aa5551d9b6ebe133427a8a0b368c2643f79d5440/docs/docs/get-started/install.mdx) — получено 2026-10-07
4. [SGLang Quickstart](https://raw.githubusercontent.com/sgl-project/sglang/aa5551d9b6ebe133427a8a0b368c2643f79d5440/docs/docs/get-started/quickstart.mdx) — получено 2026-10-07
5. [Hugging Face PEFT checkpoint format](https://raw.githubusercontent.com/huggingface/peft/190f9873b15660d9092f70065c18e4993fe10d5b/docs/source/developer_guides/checkpoint.md) — получено 2026-10-07
6. [SGLang LoRA manager source](https://raw.githubusercontent.com/sgl-project/sglang/aa5551d9b6ebe133427a8a0b368c2643f79d5440/python/sglang/srt/lora/lora_manager.py) — получено 2026-10-07
7. [Qwen/Qwen2.5-0.5B-Instruct — Hugging Face API snapshot](https://huggingface.co/api/models/Qwen/Qwen2.5-0.5B-Instruct/revision/7ae557604adf67be50417f59c2c2f167def9a775) — получено 2026-10-07
