# vLLM Multimodal API: локальный анализ изображения без открытых URL

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

vLLM принимает изображение в Chat Completions API только вместе с совместимой vision-моделью: в сообщении пользователя нужны текстовый вопрос и часть image_url. Для локального пробного запроса передайте обезличенный JPEG как data URL на сервер, слушающий 127.0.0.1, затем сравните описание с оригиналом. Успешный HTTP-ответ не подтверждает точность модели или отсутствие исходящего трафика; внешние медиа-URL и доступ других пользователей проверяйте отдельно.

**Срез документации:** vLLM закреплён на Git-коммите `f98d1fc` от 4 октября 2026 года, модель Qwen/Qwen2.5-VL-7B-Instruct — на HF SHA `cc594898`; сведения проверены 5 октября 2026 года. Это протокол для вашего стенда, а не отчёт о запуске Modelium. [s1](#src-s1) [s6](#src-s6)

## Что делает vLLM Multimodal API и кому он нужен?

vLLM даёт OpenAI-совместимый `POST /v1/chat/completions`, в котором совместимой vision-модели можно передать текст и изображение в одном сообщении. Для входа по HTTP используется часть `image_url`; это **формат поля**, а не требование размещать файл в открытом интернете: документация и клиентский пример показывают также `data:image/jpeg;base64,...`. Если у вас уже есть сервер vLLM и нужна проверка картинки через API, этот путь удобен. Если вам нужен простой запуск одной модели на ноутбуке, сначала сравните [Ollama Vision API](/zhurnal/ollama-vision-api/) и [llama.cpp multimodal](/zhurnal/llama-cpp-multimodal-api/). [s1](#src-s1) [s2](#src-s2) [s7](#src-s7)

Один выполнимый сценарий: **обезличенный JPEG с двумя заранее известными объектами → Qwen2.5-VL-7B-Instruct → подходящий Linux GPU и память, проверенные на конкретном стенде → vLLM → Chat API → ручное сравнение ответа с изображением**. vLLM относит Qwen2.5-VL к поддерживаемым vision-language моделям; карточка 7B-варианта помечена Apache-2.0. Это сведения о модели и лицензии из карточки, не гарантия качества русского ответа, экономичности размещения или разрешение использовать любые входные данные. Утверждения о распознавании документов и результаты бенчмарков в карточке принадлежат автору модели; Modelium их не воспроизводил. [s4](#src-s4) [s6](#src-s6)

## Какие версия, устройство и изображение нужны до запроса?

На закреплённой ревизии документация GPU-установки vLLM указывает Linux и Python 3.10–3.13; нативный Windows не поддерживается, предусмотрен путь через WSL с совместимой средой. У разных GPU разные инструкции установки и возможности; откройте [стартовый гайд vLLM](/zhurnal/vllm/), проверьте свой backend, драйвер и доступную память **до** загрузки Qwen2.5-VL-7B-Instruct. «7B» — размер варианта в имени, а не минимальный объём VRAM. Ни карточка модели, ни файлы весов не дают универсального порога RAM/VRAM для конкретного контекста и разрешения картинки. [s4](#src-s4) [s5](#src-s5) [s6](#src-s6)

Используйте только изображение, которое вы вправе передать своему тестовому сервису: без персональных данных, секретов и чужих документов. Подготовьте `sample.jpg`, запишите два видимых объекта и один признак, который **не** виден на снимке: последнее поможет заметить додумывание. Сохраните точную версию установленного vLLM, ОС, backend, модель, ревизию весов и размер/разрешение файла. Git-коммит документации не является версией пакета, установленного у читателя. [s1](#src-s1) [s5](#src-s5) [s6](#src-s6)

## Как поднять локальный сервер и отправить один JPEG?

После установки vLLM на **вашем** совместимом Linux-стенде используйте пример запуска: `vllm serve Qwen/Qwen2.5-VL-7B-Instruct --revision cc594898137f460bfe9f0759e9844b3ce807cfb5 --host 127.0.0.1 --port 8000 --limit-mm-per-prompt.image 1`. CLI принимает `--revision`, а документация multimodal показывает синтаксис лимита изображений; явный `127.0.0.1` ограничивает слушающий интерфейс тестового HTTP-сервера. Команда **не проверялась запуском Modelium**: закреплённая ревизия модели, версия установленного vLLM и архитектура GPU должны быть совместимы на вашем стенде. Первый старт может скачать веса, поэтому «локальный API» не равен полностью офлайн-установке. [s1](#src-s1) [s5](#src-s5) [s6](#src-s6) [s8](#src-s8)

Не добавляйте `--trust-remote-code` наугад: официальный мультимодальный пример требует его для **другой** модели Phi-3.5-Vision. Для выбранной Qwen2.5-VL такой флаг не следует переносить без отдельного обоснования. Получите список моделей запросом `curl -sS http://127.0.0.1:8000/v1/models`, убедитесь в точном идентификаторе. Успешный `/health` или список моделей говорит о доступности, а не о том, что зрительный ответ верен. [s1](#src-s1) [s2](#src-s2) [s8](#src-s8)

Для JPEG в **локальном Linux-терминале** сформируйте одну строку base64: `base64 -w 0 sample.jpg > sample.b64`. Затем создайте `request.json` с полями `model: "Qwen/Qwen2.5-VL-7B-Instruct"`, `messages: [{"role":"user","content":[{"type":"text","text":"Назови два предмета на снимке и укажи, что нельзя установить по изображению"},{"type":"image_url","image_url":{"url":"data:image/jpeg;base64,<BASE64_СОДЕРЖИМОЕ>"}}]}]` и `max_tokens: 128`; **замените** `<BASE64_СОДЕРЖИМОЕ>` содержимым файла `sample.b64`, без угловых скобок и без переноса строки. Отправьте `curl -sS --fail-with-body http://127.0.0.1:8000/v1/chat/completions -H 'Content-Type: application/json' --data-binary @request.json`. Пример соответствует структуре официального `image_url` и примеру передачи base64; `request.json` хранит исходное изображение в кодированном виде — не публикуйте его, удалите после теста. Для другого формата файла меняйте MIME в data URL и проверяйте поддержку модели. [s1](#src-s1) [s2](#src-s2) [s7](#src-s7)

`file://` — не равнозначная замена: такой URL требует явно разрешённого `--allowed-local-media-path`, который расширяет доступ к локальным файлам сервера. Не открывайте всему серверу корневой каталог ради одного снимка. Для одиночного теста data URL избегает этого разрешения и внешней загрузки изображения; он всё равно отправляет байты на адрес сервера и может остаться в логах клиента или инфраструктуры. [s1](#src-s1) [s3](#src-s3)

## Почему нельзя бездумно дать серверу внешний URL картинки?

Если клиент передаёт HTTP(S)-ссылку, **vLLM скачивает медиа со стороны сервера**: при доступе недоверенного клиента это открывает SSRF-риск к внутренним адресам и риск истощения ресурсов от больших или медленно загружаемых файлов. Документация vLLM рекомендует ограничивать разрешённые домены через `--allowed-media-domains`, отдельно учитывать редиректы (`VLLM_MEDIA_URL_ALLOW_REDIRECTS=0`) и пределы размера загрузки/декодирования. Не считайте произвольный внешний URL безопасным только потому, что сама модель работает локально. Для закрытого теста используйте data URL, ограничение сети и известный вход; для общего сервера добавьте проверенную политику источников и ограничение ресурсов. [s1](#src-s1) [s3](#src-s3)

`--api-key` при настройке защищает `/v1/chat/completions` и другие документированные префиксы, **но не все маршруты сервера**: например, `/health` и ряд операционных endpoint остаются за пределами этой проверки. На разделяемом или сетевом стенде поместите сервер за сетевым фильтром/reverse proxy с явным списком доступных маршрутов, TLS и политикой пользователей; не публикуйте порт напрямую и не называйте API-ключ полной изоляцией. На `127.0.0.1` доступ других локальных процессов всё ещё возможен. Если требуется отсутствие исходящих соединений, заранее подготовьте веса и проведите отдельную [проверку офлайн-контура](/zhurnal/proverka-offline-kontura-ii/), а не делайте вывод из адреса `localhost`. [s3](#src-s3) [s5](#src-s5)

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

Откройте `choices[0].message.content` из JSON-ответа и отдельно отметьте HTTP-статус, точную модель, два совпавших/ошибочных объекта и придуманный невидимый признак. Затем измените картинку, оставив вопрос прежним: ответ должен зависеть от **её** содержимого; не выдавайте связный текст или `HTTP 200` за доказательство корректного visual inference. Если ответ галлюцинирует или игнорирует кадр, перепроверьте data URL и MIME, реальный model ID, chat template, разрешение картинки и сам исходник; документация vLLM указывает, что Chat API требует шаблон чата. Сверка человеком важнее авторских бенчмарков. [s1](#src-s1) [s2](#src-s2) [s6](#src-s6)

Если сервер не стартует или сообщает о нехватке памяти, проверьте совместимость backend и фактическое использование ресурсов на **вашей** машине, уменьшите выбранную нагрузку/контекст либо возьмите более подходящий размер модели; не выводите требование из объёма файлов весов. При отказе на URL входе проверьте allowlist и редиректы; при отказе на локальном пути — настройку `--allowed-local-media-path`, но не расширяйте доступ слепо. Для воспроизводимости сохраните версию среды и обезличенный результат, затем остановите тестовый сервер и удалите `request.json` и `sample.b64` по своей политике хранения. Собственного прогона vLLM, Qwen2.5-VL и измерений памяти у Modelium нет. [s1](#src-s1) [s3](#src-s3) [s5](#src-s5)

**Основной следующий шаг:** [подготовить vLLM на совместимом устройстве](/zhurnal/vllm/), затем отправить один разрешённый `sample.jpg` по описанному протоколу и сверить ответ с оригиналом. Если задача — не общая серверная очередь, а один локальный снимок, сравните также [альтернативный путь Ollama](/zhurnal/ollama-vision-api/); если цель — приватность, проведите [сетевую проверку](/zhurnal/proverka-offline-kontura-ii/). [s1](#src-s1) [s3](#src-s3)

## Источники

1. [vLLM Multimodal Inputs: image_url, data URL, file path и ограничения](https://github.com/vllm-project/vllm/blob/f98d1fc49361cb50457f6109c3c01a5c77e415b4/docs/features/multimodal_inputs.md) — получено 2026-10-05
2. [vLLM OpenAI-Compatible Server: Chat API и ограничения](https://github.com/vllm-project/vllm/blob/f98d1fc49361cb50457f6109c3c01a5c77e415b4/docs/serving/online_serving/openai_compatible_server.md) — получено 2026-10-05
3. [vLLM Security: загрузка медиа, SSRF и границы API-ключа](https://github.com/vllm-project/vllm/blob/f98d1fc49361cb50457f6109c3c01a5c77e415b4/docs/usage/security.md) — получено 2026-10-05
4. [vLLM Supported Models: Qwen2.5-VL и модальности](https://github.com/vllm-project/vllm/blob/f98d1fc49361cb50457f6109c3c01a5c77e415b4/docs/models/supported_models.md) — получено 2026-10-05
5. [vLLM GPU Installation: ОС, Python и аппаратная совместимость](https://github.com/vllm-project/vllm/blob/f98d1fc49361cb50457f6109c3c01a5c77e415b4/docs/getting_started/installation/gpu.md) — получено 2026-10-05
6. [Qwen/Qwen2.5-VL-7B-Instruct: карточка модели и Apache-2.0](https://huggingface.co/Qwen/Qwen2.5-VL-7B-Instruct/blob/cc594898137f460bfe9f0759e9844b3ce807cfb5/README.md) — получено 2026-10-05
7. [vLLM: официальный клиентский пример с base64-изображением](https://github.com/vllm-project/vllm/blob/f98d1fc49361cb50457f6109c3c01a5c77e415b4/examples/generate/multimodal/openai_chat_completion_client_for_multimodal.py) — получено 2026-10-05
8. [vLLM CLI EngineArgs: --revision и разрешённые медиа-домены](https://github.com/vllm-project/vllm/blob/f98d1fc49361cb50457f6109c3c01a5c77e415b4/vllm/engine/arg_utils.py) — получено 2026-10-05
