# vLLM Embeddings API: локальные векторы для поиска по документам

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

vLLM обслуживает специально обученные embedding-модели через OpenAI-совместимый `/v1/embeddings`: в ответе на текст приходит числовой вектор. Для локального RAG сначала запустите подходящую модель, затем получите векторы запросов и фрагментов и проверьте ранжирование на собственных примерах. Совместимый API сам по себе не гарантирует качество поиска или отсутствие сетевых обращений при первом скачивании весов.

**Проверка источников: 28 сентября 2026 года.** Инструкция основана на документации и коде vLLM v0.30.0 (`ced6857`) и карточке модели Qwen3-Embedding-0.6B (`97b0c61`). Modelium не скачивал веса, не запускал сервер и не измерял качество поиска: приведённые проверки должен выполнить читатель на своём стенде. [s1](#src-s1) [s7](#src-s7)

## Что выдаёт Embeddings API и чем он отличается от чат-модели?

Endpoint `/v1/embeddings` превращает входные последовательности в числовые векторы. Он применим к совместимой embedding-модели, а не к произвольной чат-модели; маршрут vLLM возвращает ошибку для модели без поддержки Embeddings API. Векторы позволяют сравнивать смысловую близость запроса и фрагментов, но сам endpoint не хранит документы и не генерирует ответ с цитатами. Для RAG затем потребуется хранение/поиск и отдельная генеративная модель, а релевантность надо проверять на примерах. [s1](#src-s1) [s2](#src-s2) [s5](#src-s5)

Маршрут решения: **задача поиска → специально обученная embedding-модель → подходящее железо → vLLM → векторы → поиск по тестовым фрагментам → ручная проверка результата**. Начните с изолированного теста, а не с загрузки клиентских документов. Вес файла не является требованием к RAM/VRAM; перед запуском проверьте свой GPU, версию сервера и доступное пространство для кеша модели. [s1](#src-s1) [s2](#src-s2)

## Как выбрать модель и подготовить сервер?

В списке vLLM v0.30.0 явно присутствует `Qwen/Qwen3-Embedding-0.6B`; в карточке авторы называют её текстовой моделью с 0,6 млрд параметров, верхней размерностью 1024 и поддержкой более 100 языков. Это **характеристики и заявления авторов**, не гарантия качества русского поиска. Для запуска фиксируйте ревизию HF `97b0c614be4d77ee51c0cef4e5f07c00f9eb65b3` и версию vLLM v0.30.0. API HF помечает модель `apache-2.0`, но перед коммерческим внедрением отдельно прочитайте применимые условия, лицензию зависимостей и политику данных. [s1](#src-s1) [s7](#src-s7) [s8](#src-s8)

На машине с **совместимой установленной** версией vLLM по официальной документации запустите сервер на loopback. Первый запуск по имени HF может скачивать модель: сеть и локальный кеш надо подготовить заранее, если нужен закрытый контур. Не подменяйте `--revision` указанием несуществующего локального файла. [s2](#src-s2) [s3](#src-s3)

vllm serve Qwen/Qwen3-Embedding-0.6B \  --revision 97b0c614be4d77ee51c0cef4e5f07c00f9eb65b3 \  --host 127.0.0.1 --port 8000

Подтвердите, что сервер завершил загрузку, и запросите `curl -fsS http://127.0.0.1:8000/v1/models`. Идентификатор модели в ответе используйте в запросах без переименования. Если загрузка не удалась, проверьте лог совместимости архитектуры, доступ к HF/кешу и аппаратные условия; не считайте молчаливый CPU fallback гарантированным. `Qwen3-Embedding-0.6B` включена в список моделей vLLM, однако конкретное устройство и версия драйвера здесь не проверялись. [s2](#src-s2) [s3](#src-s3) [s4](#src-s4)

`--api-key` защищает `/v1/embeddings`, но не все остальные пути того же сервера (в частности, `/invocations`). Для работы с внутренними документами не открывайте порт напрямую в интернет: ограничьте доступ сетью или проверенным прокси с allowlist маршрутов. Loopback сам по себе не означает отсутствие исходящих соединений при загрузке модели. [s3](#src-s3) [s6](#src-s6)

## Как получить векторы без внешнего API?

Пример ниже адресует **свой** `127.0.0.1`, а не облачный endpoint. Официальный клиент vLLM также направляет OpenAI Python SDK на локальный `base_url`, но для первого теста достаточно HTTP. Подавайте только вымышленные примеры; в ответе ожидайте массив `data` с числовым `embedding` у каждого элемента. [s1](#src-s1) [s4](#src-s4) [s5](#src-s5)

curl -fsS http://127.0.0.1:8000/v1/embeddings \  -H 'Content-Type: application/json' \  -d '{"model":"Qwen/Qwen3-Embedding-0.6B","input":["УПД содержит итоговую сумму и ИНН поставщика.","График дежурств команды на следующую неделю."]}' \  | jq '{model, count: (.data | length), dimensions: (.data[0].embedding | length)}'

`count` должен соответствовать числу входов, размерность для этой модели — не больше 1024 по карточке автора; точное значение определите по **реальному** ответу. Проверяйте не только форму, но и порядок элементов массива `data`, конечность чисел, отсутствие ошибок и совпадение версии модели при индексации и поиске. Не назначайте произвольную меньшую `dimensions`: vLLM разрешает менять размерность только при распознанной поддержке Matryoshka, а метаданные HF и фактические настройки runtime нужно сверять отдельно. [s1](#src-s1) [s7](#src-s7)

## Как проверить, что поиск возвращает нужный фрагмент?

Соберите мини-набор из трёх коротких **вымышленных** документов: «В счёте указан ИНН поставщика», «Команда составила график отпусков» и «Акт содержит итоговую сумму». Для запроса «где узнать ИНН поставщика?» заранее зафиксируйте ожидаемый первый фрагмент. Для запроса «какая итоговая сумма в акте?» ожидайте третий. Для точных идентификаторов позже сравните с [гибридным поиском](/zhurnal/gibridnyy-poisk-rag/): семантическая близость не заменяет посимвольное совпадение артикулов. [s1](#src-s1) [s7](#src-s7)

Карточка Qwen рекомендует добавлять к **запросам**, но не к документам, инструкцию с задачей (пример автора: `Instruct: ...\nQuery: ...`). Не предполагается, что сырая строка `input` автоматически получает тот же `prompt_name="query"`, что в примере Sentence Transformers: проверьте шаблон своей конфигурации vLLM и зафиксируйте фактически переданный текст. Сравните оба режима на одном и том же наборе; заявление автора о приросте качества от инструкции не является измерением на ваших русских документах. [s7](#src-s7) [s1](#src-s1)

Отправьте документы одним запросом `input: [d1,d2,d3]`, затем запросы — отдельно, с выбранным одинаковым форматом `Instruct/Query`. Сопоставляйте векторы **одной модели, ревизии, размерности и версии нормализации**; для каждого запроса ранжируйте документы по косинусной близости `sum(q_i*d_i)/(sqrt(sum(q_i²))*sqrt(sum(d_i²)))`, только если нормы ненулевые. Это расчётная процедура, а не обещание конкретного балла: заранее размеченный фрагмент должен оказаться первым в обоих тестовых вопросах. При провале посмотрите ошибку фрагментации, тексты, шаблон запроса и полноту индекса, а не меняйте модель вслепую. [s2](#src-s2) [s7](#src-s7)

Небольшой тест формы ответа не доказывает качества RAG. Для пилота подготовьте набор вопросов с ожидаемыми источниками и отрицательными примерами, посчитайте recall@k по формуле `вопросы с правильным фрагментом в top-k / все размеченные вопросы`, разберите ошибки вручную и лишь потом подключайте генерирующую модель и цитаты. Следующий шаг — [протокол оценки качества RAG](/zhurnal/ocenka-kachestva-rag/). [s1](#src-s1) [s7](#src-s7)

## Когда другой стек или дополнительные проверки нужны раньше?

Если нужна только генерация текста, embedding-endpoint — не замена `/v1/chat/completions`. Если индексу важны точные номера документов, добавьте лексический компонент и проверьте [гибридный поиск](/zhurnal/gibridnyy-poisk-rag/). Если модель недоступна вашему устройству, вернитесь к [гайду запуска vLLM](/zhurnal/vllm/) и подберите совместимый runtime/модель; не выводите порог VRAM из размера весов. [s1](#src-s1) [s3](#src-s3)

Перед выключением сервера сохраните версию vLLM, ревизию модели, шаблон запроса, тексты тестовых документов, размерность и топ выдачи. Завершите процесс vLLM штатным `Ctrl+C` и проверьте, что локальный порт закрыт. Такой журнал позволит повторить испытание и отличить проблему модели от изменения данных, но **не** заменяет самостоятельную проверку изоляции сети и прав на документы. [s3](#src-s3) [s6](#src-s6)

## Источники

1. [vLLM v0.30.0 — embedding usages и OpenAI-compatible API](https://github.com/vllm-project/vllm/blob/ced6857afa0ea7b2e3f0846a62e1394e90f15607/docs/models/pooling_models/embed.md) — получено 2026-09-28
2. [vLLM v0.30.0 — совместимые embedding-модели](https://github.com/vllm-project/vllm/blob/ced6857afa0ea7b2e3f0846a62e1394e90f15607/docs/models/pooling_models/README.md) — получено 2026-09-28
3. [vLLM v0.30.0 — OpenAI-compatible server](https://github.com/vllm-project/vllm/blob/ced6857afa0ea7b2e3f0846a62e1394e90f15607/docs/serving/online_serving/openai_compatible_server.md) — получено 2026-09-28
4. [vLLM v0.30.0 — официальный Python-клиент embeddings](https://github.com/vllm-project/vllm/blob/ced6857afa0ea7b2e3f0846a62e1394e90f15607/examples/pooling/embed/openai_embedding_client.py) — получено 2026-09-28
5. [vLLM v0.30.0 — маршрут embeddings](https://github.com/vllm-project/vllm/blob/ced6857afa0ea7b2e3f0846a62e1394e90f15607/vllm/entrypoints/pooling/embed/api_router.py) — получено 2026-09-28
6. [vLLM v0.30.0 — ограничения аутентификации и безопасность](https://github.com/vllm-project/vllm/blob/ced6857afa0ea7b2e3f0846a62e1394e90f15607/docs/usage/security.md) — получено 2026-09-28
7. [Qwen3-Embedding-0.6B — карточка автора на закреплённой ревизии](https://huggingface.co/Qwen/Qwen3-Embedding-0.6B/blob/97b0c614be4d77ee51c0cef4e5f07c00f9eb65b3/README.md) — получено 2026-09-28
8. [Qwen3-Embedding-0.6B — API метаданные закреплённой ревизии](https://huggingface.co/api/models/Qwen/Qwen3-Embedding-0.6B/revision/97b0c614be4d77ee51c0cef4e5f07c00f9eb65b3) — получено 2026-09-28
