# vLLM LoRA: как обслуживать адаптеры рядом с базовой моделью

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

vLLM может обслуживать базовую модель и совместимый LoRA-адаптер в одном сервере: укажите `--enable-lora` и локальный путь через `--lora-modules`, затем выбирайте базу или адаптер полем `model` в запросе. Сначала сверьте базовую модель, конфигурацию адаптера и его rank; `/v1/models` подтверждает регистрацию, но не качество ответа. Динамическую загрузку не включайте на доступном недоверенным клиентам сервере.

**Проверено по исходникам и документации vLLM v0.30.0 на ревизии **`**ced6857**`** 29 сентября 2026 года.** Ниже — воспроизводимый план для вашего сервера, не протокол эксперимента Modelium: модель, GPU, память и качество ответов нами не проверялись. Примеры путей `/srv/models/...` нужно заменить собственными уже полученными файлами. Частотность запроса Wordstat не измерялась.

## Когда нужен LoRA serving, а не ещё одна базовая модель?

Адаптер LoRA — отдельные параметры дообучения поверх конкретной базовой модели. В PEFT-файле адаптера нет исходных весов базы: чтобы обслуживать его, нужны и база, и совместимая конфигурация/веса адаптера [s5](#src-s5). vLLM обслуживает несколько адаптеров **для модели с поддержкой **`**SupportsLoRA**` и позволяет выбрать нужный вариант по полю `model` каждого запроса [s1](#src-s1). Это путь для двух согласованных сценариев на одном сервере, например базового ответа и ответа отраслевого адаптера; из архитектуры нельзя вывести, что дообученный вариант лучше. Качество проверяется на собственных контрольных запросах.

Путь решения: ваша задача → выбранная пара «базовая модель + адаптер» → совместимое железо → vLLM → проверка регистрации обоих идентификаторов → две пары ответов на одном наборе запросов. Для первого запуска без адаптера начните с [общего гайда vLLM](/zhurnal/vllm/). Не берите произвольный LoRA-файл от другой архитектуры, даже если имена выглядят похоже.

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

Сначала уточните версию установленного vLLM: эта инструкция привязана к документации тега v0.30.0, а новые выпуски могут менять параметры и поддерживаемые архитектуры [s1](#src-s1)[s6](#src-s6). GPU-инструкция для этого тега указывает Linux и Python 3.10–3.13 для основного пути установки; Windows нативно не поддерживается, для неё описан WSL. Поддержка GPU зависит от конкретного backend — название CUDA/ROCm/XPU само по себе не доказывает, что ваша модель с данным адаптером загрузится [s6](#src-s6).

Укажите **конкретную архитектуру** базы, а не только маркетинговое семейство: в перечне v0.30.0 для `LlamaForCausalLM` и `Qwen3ForCausalLM` отмечена LoRA-поддержка. Это не обещание совместимости каждого репозитория, кванта, целевого слоя или версии адаптера [s7](#src-s7). Документация vLLM допускает LoRA только для моделей, реализующих `SupportsLoRA` [s1](#src-s1).

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

Минимальная проверка **своего локального** PEFT-каталога без загрузки модели:

ADAPTER=/srv/models/my-lorapython3 - "$ADAPTER" <<'PY'import json, pathlib, syspath = pathlib.Path(sys.argv[1])cfg = json.loads((path / "adapter_config.json").read_text(encoding="utf-8"))assert cfg.get("peft_type") == "LORA", "ожидался LoRA-адаптер"assert isinstance(cfg.get("r"), int) and cfg["r"] > 0, "нужен положительный rank"assert any((path / name).is_file() for name in ("adapter_model.safetensors", "adapter_model.bin")), "нет файла весов"print("base:", cfg.get("base_model_name_or_path"), "revision:", cfg.get("revision"), "rank:", cfg["r"])PY

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

## Как поднять базу и один адаптер?

Установите vLLM по официальной [GPU-инструкции соответствующей версии](/zhurnal/vllm/) в отдельном окружении и убедитесь, что базовая модель уже отвечает на локальном API; список поддерживаемых архитектур и пути установки различаются по backend [s6](#src-s6)[s7](#src-s7). Запишите точное имя модели, версии весов и адаптера в журнал собственного испытания. Не превращайте размер файлов весов в «минимум VRAM»: загрузка также зависит от длины контекста, KV-кеша, числа одновременных запросов и конфигурации адаптера.

После предварительной проверки подставьте **реальные локальные каталоги** (пример ниже намеренно не скачивает модель), а `--max-lora-rank` установите не ниже ранга вашего адаптера. Документация рекомендует выбирать максимальный rank среди применяемых адаптеров, а не завышать его ради запаса: завышение тратит память и может ухудшить производительность [s1](#src-s1). В коде v0.30.0 значения по умолчанию — `max_lora_rank=16` и `max_loras=1`; если у вашего адаптера rank больше, укажите его явно [s2](#src-s2).

BASE=/srv/models/baseADAPTER=/srv/models/my-loraRANK=$(python3 -c 'import json,sys; print(json.load(open(sys.argv[1], encoding="utf-8"))["r"])' "$ADAPTER/adapter_config.json")# Выполняйте только после проверки совместимости и разрешения на использование обоих наборов весов.vllm serve "$BASE" --host 127.0.0.1 --port 8000 \  --enable-lora --max-lora-rank "$RANK" \  --lora-modules "trial-lora=$ADAPTER"

Команда запускает сервер в текущем терминале; проверки ниже выполняйте в другом. `--lora-modules name=path` — документированный статический способ передать адаптер. Именованный адаптер появится в `/v1/models` наряду с базой; при необходимости в версии v0.30.0 поддерживается JSON-форма с отдельным `base_model_name` — она обозначает метаданные связи, но сама не исправляет неподходящие веса [s1](#src-s1). Адрес `127.0.0.1` ограничивает слушающий HTTP-сервер loopback, но **не** заменяет анализ сетевой поверхности и изоляцию других процессов на узле [s3](#src-s3).

Если нужны несколько адаптеров, vLLM принимает несколько `--lora-modules`; `max_loras` ограничивает число одновременно активных адаптеров. Прежде чем повышать его, измерьте память, очередь и задержки именно у своей конфигурации, а не переносите показатели чужого GPU [s1](#src-s1)[s2](#src-s2). Для эксплуатационного контроля пригодятся [метрики vLLM](/zhurnal/vllm-metrics-prometheus/).

## Как доказать, что ответил нужный маршрут?

Сначала выполните `curl -fsS http://127.0.0.1:8000/v1/models`: успешный ответ должен перечислить идентификатор базы и `trial-lora`; если адаптера нет, **не** трактуйте 200 от базовой модели как доказательство его работы [s1](#src-s1). Скопируйте точный `id` базы из ответа: если в вашей установке он отличается от локального пути, используйте именно возвращённый ID. Completions API документирован для текстовой генерации; Chat Completions дополнительно требует совместимый chat template [s4](#src-s4). Для первого контроля используйте один и тот же текстовый prompt в `/v1/completions`:

curl -fsS http://127.0.0.1:8000/v1/completions \  -H 'Content-Type: application/json' \  -d '{"model":"/srv/models/base","prompt":"Ответь одним словом: тест","max_tokens":32,"temperature":0}'curl -fsS http://127.0.0.1:8000/v1/completions \  -H 'Content-Type: application/json' \  -d '{"model":"trial-lora","prompt":"Ответь одним словом: тест","max_tokens":32,"temperature":0}'

В первой строке замените `/srv/models/base` на точный `id` базы из `/v1/models`; `trial-lora` — имя из команды запуска [s1](#src-s1). Зафиксируйте HTTP-статус, возвращённое поле `model`, два ответа и отсутствие ошибок. Наличие разницы в текстах не доказывает улучшения, а одинаковый ответ не доказывает, что адаптер не применился: нужны контрольные входы из задачи, проверка правильности человеком и повторные попытки при зафиксированных настройках. У vLLM могут применяться параметры из `generation_config.json` репозитория, поэтому не сравнивайте результаты при незаметно разных конфигурациях генерации [s4](#src-s4).

Для отдельного performance-теста сначала подтвердите функциональную корректность, потом сравните одинаковые версии модели, длины prompt, число запросов и параметры генерации на одной машине. Методика [vLLM bench serve](/zhurnal/vllm-bench-serve/) позволяет оформить результаты своего сервера, но в этой статье нет «измеренного ускорения» или обещания снижения VRAM.

## Почему не стоит открывать динамическую загрузку?

Кроме стартовой конфигурации vLLM документирует `/v1/load_lora_adapter` и `/v1/unload_lora_adapter`, которые требуют `VLLM_ALLOW_RUNTIME_LORA_UPDATING=True`. Официальное предупреждение: это рискованный режим, его не следует использовать в production вне изолированной полностью доверенной среды [s1](#src-s1). В security-документации уточняется, что такие маршруты меняют поведение модели и должны быть доступны лишь доверенным администраторам; даже `--api-key` не защищает **все** пути того же HTTP-сервера [s3](#src-s3). Для обычного контролируемого пилота оставьте переменную выключенной, закрепите список адаптеров при запуске и ограничьте доступ сетью. Не принимайте путь до адаптера от непроверенного клиента.

Если сервер не стартует, сначала отдельно проверьте базу без `--enable-lora`, затем структуру адаптера и rank; несовместимую архитектуру или неверную ревизию нельзя лечить увеличением `max_loras` [s1](#src-s1)[s2](#src-s2)[s5](#src-s5). Если `/v1/models` видит оба ID, но приложение всегда отправляет `model` базы, исправьте маршрутизацию клиента, а не перезаливайте веса [s1](#src-s1). Для отката завершите тестовый процесс vLLM и поднимите прежнюю конфигурацию **без** `--lora-modules` и `--enable-lora`; сохраните результат контрольного запроса к базе до и после. Это операционный план, а не выполненный Modelium откат.

**Основной следующий шаг:** откройте [проверенный путь запуска базовой модели в vLLM](/zhurnal/vllm/), запустите её без LoRA и запишите точный `model id` и исходный ответ. Только после этого включайте совместимый адаптер и сравнивайте пару ответов на своём тестовом наборе.

## Источники

1. [vLLM v0.30.0 — LoRA Adapters](https://raw.githubusercontent.com/vllm-project/vllm/ced6857afa0ea7b2e3f0846a62e1394e90f15607/docs/features/lora.md) — получено 2026-09-29
2. [vLLM v0.30.0 — LoRA configuration source](https://raw.githubusercontent.com/vllm-project/vllm/ced6857afa0ea7b2e3f0846a62e1394e90f15607/vllm/config/lora.py) — получено 2026-09-29
3. [vLLM v0.30.0 — Security](https://raw.githubusercontent.com/vllm-project/vllm/ced6857afa0ea7b2e3f0846a62e1394e90f15607/docs/usage/security.md) — получено 2026-09-29
4. [vLLM v0.30.0 — OpenAI-Compatible Server](https://raw.githubusercontent.com/vllm-project/vllm/ced6857afa0ea7b2e3f0846a62e1394e90f15607/docs/serving/online_serving/openai_compatible_server.md) — получено 2026-09-29
5. [Hugging Face PEFT — checkpoint format](https://huggingface.co/docs/peft/main/en/developer_guides/checkpoint) — получено 2026-09-29
6. [vLLM v0.30.0 — GPU Installation](https://raw.githubusercontent.com/vllm-project/vllm/ced6857afa0ea7b2e3f0846a62e1394e90f15607/docs/getting_started/installation/gpu.md) — получено 2026-09-29
7. [vLLM v0.30.0 — Supported Models](https://raw.githubusercontent.com/vllm-project/vllm/ced6857afa0ea7b2e3f0846a62e1394e90f15607/docs/models/supported_models.md) — получено 2026-09-29
