# vLLM batch inference: обработать документы без API-сервера

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

Для пакетной обработки в vLLM не требуется поднимать HTTP-сервер: Python-класс LLM принимает список запросов через chat() или generate(). Для инструкционной модели используйте chat(), чтобы применился её шаблон диалога, а ответы сопоставляйте с исходными идентификаторами. Нужны совместимая установка и модель; отсутствие API-сервера само по себе не доказывает отсутствие сетевых обращений при загрузке весов.

**Срез источников — 7 октября 2026 года.** Исходники vLLM закреплены на Git-ревизии `956960f`, Qwen2.5-0.5B-Instruct — на HF-ревизии `7ae5576`. Modelium не запускал модель и не измерял память, скорость, качество или сетевой трафик. Ниже — инструкция для самостоятельного теста, не отчёт об успешном прогоне. [s1](#src-s1) [s6](#src-s6)

## Когда нужен именно offline batch inference?

Если у вас уже есть набор текстов, который нужно обработать одной локальной моделью, можно передать список запросов прямо в Python-класс `LLM`. `generate()` работает с промптами, а `chat()` — с диалогами; отдельный `vllm serve` и HTTP-клиент в этом варианте не нужны. Это **пакетный инференс**, не асинхронное API и не обещание ускорения для любого размера партии. [s1](#src-s1) [s2](#src-s2) [s4](#src-s4)

Практический маршрут: два обезличенных фрагмента документов → конкретная instruction-модель Qwen2.5-0.5B-Instruct → совместимое устройство и vLLM → список диалогов → по одному `RequestOutput` на вход → ручная сверка извлечённых фактов. Маленький вариант удобен для проверки механики, но карточка автора не доказывает его качество на ваших русских документах. Если ваша задача требует большей точности, повторите **тот же** тест на подходящем варианте модели, не подменяя эталон. [s2](#src-s2) [s4](#src-s4) [s6](#src-s6)

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

В закреплённом quickstart vLLM базовые предусловия — Linux и Python 3.10–3.13; инструкции для конкретных GPU и других платформ вынесены отдельно. Для NVIDIA CUDA руководство предлагает изолированное окружение `uv venv --python 3.12 --seed`, затем `source .venv/bin/activate` и `uv pip install vllm --torch-backend=auto`. Это **документированный вариант**, а не подтверждение совместимости вашего драйвера и GPU. Начните с [гайда запуска vLLM](/zhurnal/vllm/), если окружение ещё не проверено. [s2](#src-s2)

Для теста зафиксируйте репозиторий `Qwen/Qwen2.5-0.5B-Instruct` и ревизию `7ae557604adf67be50417f59c2c2f167def9a775`; карточка описывает именно instruction-вариант, а LICENSE этого репозитория содержит Apache License 2.0. Это не утверждение об остальных моделях Qwen и не юридическое заключение по вашим данным. vLLM может скачать модель с Hugging Face при первом обращении: **отсутствие HTTP-сервера не означает автоматически офлайн-сеть**. Для изолированного контура предварительно подготовьте файлы и отдельно проверьте отсутствие исходящего трафика по [протоколу проверки](/zhurnal/proverka-offline-kontura-ii/). [s2](#src-s2) [s6](#src-s6) [s7](#src-s7)

Подготовьте две короткие обезличенные строки, у каждой собственный `id`, заранее запишите правильный ответ. Например: `A: акт №7, дата 12.04, сумма 100` и `B: акт №8, дата 13.04, сумма 200`. Числа и документы здесь **вымышлены для теста**; реальную первичку и персональные данные не передавайте в эксперимент, пока не подтвердили границы окружения.

## Как передать пакет в vLLM без API-сервера?

Проверьте первоначальную установку на официальном `examples/basic/offline_inference/chat.py`: пример вызывает `LLM.chat()` на списке диалогов и читает `output.outputs[0].text`. При запуске из клона на закреплённой Git-ревизии укажите `--model Qwen/Qwen2.5-0.5B-Instruct --revision 7ae557604adf67be50417f59c2c2f167def9a775 --tokenizer-revision 7ae557604adf67be50417f59c2c2f167def9a775`; перед выполнением сверьте синтаксис аргументов с `--help` этого скрипта. Его штатный тест повторяет один диалог десять раз; **он не проверяет ваши документы**. [s3](#src-s3) [s4](#src-s4)

Для собственного набора соберите `rows` из пар `(id, text)`; преобразуйте каждый `text` в отдельный список сообщений `[{'role': 'user', 'content': 'Извлеки номер акта и сумму; если нет поля — укажи неизвестно. Текст: ' + text}]`. Создайте один `LLM(model='Qwen/Qwen2.5-0.5B-Instruct', revision='7ae557604adf67be50417f59c2c2f167def9a775', tokenizer_revision='7ae557604adf67be50417f59c2c2f167def9a775')`, затем вызовите `llm.chat(messages_list, SamplingParams(temperature=0, max_tokens=96))`. Импорт классов — `from vllm import LLM, SamplingParams`. Значения `temperature` и `max_tokens` заданы как параметры этого примера, а не как универсально оптимальная настройка. [s3](#src-s3) [s4](#src-s4) [s5](#src-s5)

В отличие от `generate()` для сырой строки, `chat()` применяет шаблон диалога модели. Если всё же используете `generate()` с instruction-моделью, документация требует применить соответствующий chat template самостоятельно; иначе неверный формат промпта может исказить сравнение. Не путайте этот режим с серверным Batch API: здесь результат возвращает локальный вызов Python. [s2](#src-s2) [s4](#src-s4)

Сопоставьте каждый вход и выход через `zip(rows, outputs)` и запишите `id`, исходную короткую строку, `outputs[i].outputs[0].text`, модель, ревизию и параметры. Контракт `LLM.chat()` обещает тот же порядок результатов, что и входных диалогов; дополнительно проверьте равенство длин, отсутствие пустых ответов и уникальность ID **до** записи. При аварийном завершении не считайте частичный файл подтверждением полной партии. [s3](#src-s3) [s4](#src-s4)

## Как проверить результат и не перепутать его с успехом вызова?

Для двух вымышленных актов сверяйте **номер и сумму по каждому ID**, отмечайте пропуски и придуманные поля. Наличие непустого `RequestOutput` означает лишь, что модель сгенерировала текст; правильность извлечения нужно оценить на эталонных строках вручную. Если ответы перепутаны, проверьте сохранение порядка и вашу логику связывания `id` с `outputs`; если числовые поля неверны, не отправляйте результат в учётную систему автоматически. [s4](#src-s4)

Зафиксируйте версию vLLM, точную ревизию весов, GPU/драйвер, размер партии, входной набор, параметры и результат ручной сверки. Для сравнения скорости повторяйте один и тот же набор на одной конфигурации, а не берите чужой benchmark за гарантию. Modelium не проводил такой замер; размер файлов весов не является минимальной VRAM. [s2](#src-s2) [s6](#src-s6)

## Что делать при ошибках и как убрать стенд?

Если установка не проходит, сначала сопоставьте Python, платформу, GPU и драйвер с [гайдом vLLM](/zhurnal/vllm/): быстрый старт относится не ко всем backend. Если модель не загружается, отдельно проверьте выбранную ревизию, доступ к весам, токенизатор и доступную память; не делайте вывода о минимальном объёме RAM по размеру файла. Если диалог выдаёт пустой или бессвязный текст, проверьте шаблон chat и лимит `max_tokens`, затем разберите расхождение с эталоном. [s2](#src-s2) [s4](#src-s4) [s5](#src-s5)

Для отката удалите только своё тестовое виртуальное окружение и собственные результаты после проверки содержимого путей; общие кэши моделей и данные иных проектов не удаляйте автоматически. Первая загрузка весов может обращаться в сеть, поэтому перед производственной обработкой конфиденциальных документов отдельно проведите [проверку сетевого контура](/zhurnal/proverka-offline-kontura-ii/). [s2](#src-s2)

**Следующий шаг:** обработайте два обезличенных фрагмента, сохраните соответствие `id → ответ`, сверьте оба ответа с эталоном. Если ещё нет проверенного окружения, сначала пройдите [установку vLLM](/zhurnal/vllm/). [s2](#src-s2) [s4](#src-s4)

## Источники

1. [vLLM: Offline Inference, закреплённый исходник](https://github.com/vllm-project/vllm/blob/956960f85fd9b5ae0de9faa004738b7a1c81c437/docs/serving/offline_inference.md) — получено 2026-10-07
2. [vLLM: Quickstart, offline batched inference](https://github.com/vllm-project/vllm/blob/956960f85fd9b5ae0de9faa004738b7a1c81c437/docs/getting_started/quickstart.md) — получено 2026-10-07
3. [vLLM: пример пакетного chat](https://github.com/vllm-project/vllm/blob/956960f85fd9b5ae0de9faa004738b7a1c81c437/examples/basic/offline_inference/chat.py) — получено 2026-10-07
4. [vLLM: LLM.generate и LLM.chat, контракт Python API](https://github.com/vllm-project/vllm/blob/956960f85fd9b5ae0de9faa004738b7a1c81c437/vllm/entrypoints/llm.py) — получено 2026-10-07
5. [vLLM: SamplingParams](https://github.com/vllm-project/vllm/blob/956960f85fd9b5ae0de9faa004738b7a1c81c437/vllm/sampling_params.py) — получено 2026-10-07
6. [Qwen2.5-0.5B-Instruct: карточка конкретной модели](https://huggingface.co/Qwen/Qwen2.5-0.5B-Instruct/blob/7ae557604adf67be50417f59c2c2f167def9a775/README.md) — получено 2026-10-07
7. [Qwen2.5-0.5B-Instruct: текст лицензии](https://huggingface.co/Qwen/Qwen2.5-0.5B-Instruct/blob/7ae557604adf67be50417f59c2c2f167def9a775/LICENSE) — получено 2026-10-07
