# vLLM

Высокопроизводительный сервер вывода LLM для рабочих нагрузок в продакшене на GPU CLORE.AI.

{% hint style="success" %}
Все примеры можно запускать на GPU-серверах, арендуемых через [CLORE.AI Marketplace](https://clore.ai/marketplace).
{% endhint %}

{% hint style="info" %}
**Текущая версия: v0.7.x** — Это руководство охватывает vLLM v0.7.3+. Новые функции включают поддержку DeepSeek-R1, структурированные выводы с автоматическим выбором инструментов, обслуживание нескольких LoRA и повышенную эффективность использования памяти.
{% endhint %}

## Требования к серверу

| Параметр      | Минимум    | Рекомендуется |
| ------------- | ---------- | ------------- |
| ОЗУ           | **16GB**   | 32 ГБ+        |
| VRAM          | 16 ГБ (7B) | 24 ГБ+        |
| Сеть          | 500 Мбит/с | 1 Гбит/с+     |
| Время запуска | 5–15 минут | -             |

{% hint style="danger" %}
**Важно:** vLLM требует значительного объёма RAM и VRAM. Сервера с менее чем 16 ГБ оперативной памяти не смогут запустить даже модели 7B.
{% endhint %}

{% hint style="warning" %}
**Время запуска:** Первый запуск скачивает модель с HuggingFace (5–15 минут в зависимости от размера модели и скорости сети). HTTP 502 в это время нормален.
{% endhint %}

## Почему vLLM?

* **Самая высокая пропускная способность** - PagedAttention для в 24 раза большей пропускной способности
* **Готов к продакшену** - Совместимый с OpenAI API из коробки
* **Непрерывная пакетная обработка** - Эффективное обслуживание многопользовательских запросов
* **Потоковая передача (Streaming)** - Генерация токенов в реальном времени
* **Мульти-GPU** - Тензорный параллелизм для больших моделей
* **Multi-LoRA** - Обслуживание нескольких тонко настроенных адаптеров одновременно (v0.7+)
* **Структурированные выводы** - Принуждение к JSON-схеме и вызов инструментов (v0.7+)

## Быстрое развертывание на CLORE.AI

**Docker-образ:**

```
vllm/vllm-openai:v0.7.3
```

**Порты:**

```
22/tcp
8000/http
```

**Команда:**

```bash
vllm serve mistralai/Mistral-7B-Instruct-v0.2 --host 0.0.0.0 --port 8000
```

### Проверьте, что всё работает

После развертывания найдите ваш `http_pub` URL в **Моих заказах**:

```bash
# Проверить состояние (может занять 5–15 минут при первом запуске)
curl https://your-http-pub.clorecloud.net/health

# Список моделей (работает только после загрузки модели)
curl https://your-http-pub.clorecloud.net/v1/models
```

{% hint style="warning" %}
Если вы получаете HTTP 502 более 15 минут, проверьте:

1. Сервер имеет 16 ГБ+ RAM
2. На сервере достаточно VRAM для модели
3. Токен HuggingFace установлен для закрытых моделей
   {% endhint %}

## Доступ к вашему сервису

При развертывании на CLORE.AI обращайтесь к vLLM через `http_pub` URL:

```bash
# Chat completion
curl https://your-http-pub.clorecloud.net/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "mistralai/Mistral-7B-Instruct-v0.2",
    "messages": [{"role": "user", "content": "Hello!"}]
  }'
```

{% hint style="info" %}
Все `localhost:8000` примеры ниже работают при подключении через SSH. Для внешнего доступа замените на ваш `https://your-http-pub.clorecloud.net/` URL.
{% endhint %}

## Установка

### Использование Docker (рекомендуется)

```bash
docker run -d --gpus all \
    -p 8000:8000 \
    --ipc=host \
    vllm/vllm-openai:v0.7.3 \
    --model mistralai/Mistral-7B-Instruct-v0.2 \
    --host 0.0.0.0
```

### Использование pip

```bash
pip install vllm==0.7.3

# Запустить сервер
python -m vllm.entrypoints.openai.api_server \
    --model mistralai/Mistral-7B-Instruct-v0.2
```

## Поддерживаемые модели

| Модель                        | Параметры | Требуемая VRAM       | Требуемая RAM |
| ----------------------------- | --------- | -------------------- | ------------- |
| Mistral 7B                    | 7B        | 14GB                 | 16 ГБ+        |
| Llama 3.1 8B                  | 8B        | 16GB                 | 16 ГБ+        |
| Llama 3.1 70B                 | 70B       | 140 ГБ (или 2x80 ГБ) | 64 ГБ+        |
| Mixtral 8x7B                  | 47B       | 90 ГБ                | 32 ГБ+        |
| Qwen2.5 7B                    | 7B        | 14GB                 | 16 ГБ+        |
| Qwen2.5 72B                   | 72B       | 145 ГБ               | 64 ГБ+        |
| DeepSeek-V3                   | 236B MoE  | Мульти-GPU           | 128 ГБ+       |
| DeepSeek-R1-Distill-Qwen-7B   | 7B        | 14GB                 | 16 ГБ+        |
| DeepSeek-R1-Distill-Qwen-32B  | 32B       | 64GB                 | 32 ГБ+        |
| DeepSeek-R1-Distill-Llama-70B | 70B       | 140 ГБ               | 64 ГБ+        |
| Phi-4                         | 14B       | 28 ГБ                | 32 ГБ+        |
| Gemma 2 9B                    | 9B        | 18GB                 | 16 ГБ+        |
| CodeLlama 34B                 | 34B       | 68 ГБ                | 32 ГБ+        |

## Параметры сервера

### Базовый сервер

```bash
vllm serve mistralai/Mistral-7B-Instruct-v0.2 \
    --host 0.0.0.0 \
    --port 8000
```

### Сервер для продакшена

```bash
vllm serve mistralai/Mistral-7B-Instruct-v0.2 \
    --host 0.0.0.0 \
    --port 8000 \
    --tensor-parallel-size 1 \
    --max-model-len 8192 \
    --gpu-memory-utilization 0.9 \
    --max-num-seqs 256 \
    --enable-prefix-caching
```

### С квантованием (меньше VRAM)

```bash
# AWQ квантизированная модель (использует меньше VRAM)
vllm serve TheBloke/Mistral-7B-Instruct-v0.2-AWQ \
    --host 0.0.0.0 \
    --quantization awq
```

### Структурированные выводы и вызов инструментов (v0.7+)

Включите автоматический выбор инструментов и структурированные JSON-выходы:

```bash
vllm serve mistralai/Mistral-7B-Instruct-v0.2 \
    --host 0.0.0.0 \
    --enable-auto-tool-choice \
    --tool-call-parser mistral
```

Использование в Python:

```python
from openai import OpenAI
import json

client = OpenAI(base_url="http://localhost:8000/v1", api_key="not-needed")

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "Получить текущую погоду для города",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {"type": "string", "description": "Название города"},
                    "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
                },
                "required": ["city"]
            }
        }
    }
]

response = client.chat.completions.create(
    model="mistralai/Mistral-7B-Instruct-v0.2",
    messages=[{"role": "user", "content": "Какая погода в Париже?"}],
    tools=tools,
    tool_choice="auto"
)

# Разбор вызова инструмента
tool_call = response.choices[0].message.tool_calls[0]
args = json.loads(tool_call.function.arguments)
print(f"Tool: {tool_call.function.name}, Args: {args}")
```

Структурированный JSON-выход через формат ответа:

```python
response = client.chat.completions.create(
    model="mistralai/Mistral-7B-Instruct-v0.2",
    messages=[{"role": "user", "content": "Извлечь: John Smith, 30 лет, инженёр-программист"}],
    response_format={
        "type": "json_schema",
        "json_schema": {
            "name": "person",
            "schema": {
                "type": "object",
                "properties": {
                    "name": {"type": "string"},
                    "age": {"type": "integer"},
                    "occupation": {"type": "string"}
                },
                "required": ["name", "age", "occupation"]
            }
        }
    }
)
print(response.choices[0].message.content)
```

### Обслуживание Multi-LoRA (v0.7+)

Обслуживайте базовую модель с несколькими LoRA адаптерами одновременно:

```bash
vllm serve meta-llama/Meta-Llama-3.1-8B-Instruct \
    --host 0.0.0.0 \
    --enable-lora \
    --lora-modules \
        sql-adapter=path/to/sql-lora \
        code-adapter=path/to/code-lora \
        chat-adapter=path/to/chat-lora \
    --max-lora-rank 64
```

Запрос конкретного LoRA адаптера по имени модели:

```python
# Использовать SQL адаптер
response = client.chat.completions.create(
    model="sql-adapter",
    messages=[{"role": "user", "content": "Напишите SQL-запрос, чтобы найти топ-10 клиентов"}]
)

# Использовать code адаптер
response = client.chat.completions.create(
    model="code-adapter",
    messages=[{"role": "user", "content": "Напишите функцию на Python для сортировки списка"}]
)
```

## Поддержка DeepSeek-R1 (v0.7+)

vLLM v0.7+ имеет нативную поддержку дистиллированных моделей DeepSeek-R1. Эти модели рассуждения генерируют `<think>` теги, показывающие их процесс рассуждения.

### DeepSeek-R1-Distill-Qwen-7B (один GPU)

```bash
vllm serve deepseek-ai/DeepSeek-R1-Distill-Qwen-7B \
    --host 0.0.0.0 \
    --port 8000 \
    --max-model-len 16384
```

### DeepSeek-R1-Distill-Qwen-32B (два GPU)

```bash
vllm serve deepseek-ai/DeepSeek-R1-Distill-Qwen-32B \
    --host 0.0.0.0 \
    --port 8000 \
    --tensor-parallel-size 2 \
    --max-model-len 32768 \
    --gpu-memory-utilization 0.90
```

### DeepSeek-R1-Distill-Llama-70B (четыре GPU)

```bash
vllm serve deepseek-ai/DeepSeek-R1-Distill-Llama-70B \
    --host 0.0.0.0 \
    --port 8000 \
    --tensor-parallel-size 4 \
    --max-model-len 32768
```

### Запрос DeepSeek-R1

```python
from openai import OpenAI

client = OpenAI(base_url="http://localhost:8000/v1", api_key="not-needed")

response = client.chat.completions.create(
    model="deepseek-ai/DeepSeek-R1-Distill-Qwen-32B",
    messages=[
        {
            "role": "user",
            "content": "Решите: если поезд проходит 120 км за 1.5 часа, какова его скорость в м/с?"
        }
    ],
    max_tokens=2048,
    temperature=0.6
)

content = response.choices[0].message.content
# Ответ включает блок рассуждений <think>...</think>, за которым следует ответ
print(content)
```

Разбор тегов think:

```python
import re

def parse_deepseek_r1_response(content: str) -> dict:
    """Извлечь рассуждение и ответ из ответа DeepSeek-R1."""
    think_match = re.search(r'<think>(.*?)</think>', content, re.DOTALL)
    thinking = think_match.group(1).strip() if think_match else ""
    answer = re.sub(r'<think>.*?</think>', '', content, flags=re.DOTALL).strip()
    return {"thinking": thinking, "answer": answer}

result = parse_deepseek_r1_response(content)
print("Thinking:", result["thinking"][:200], "...")
print("Answer:", result["answer"])
```

## Использование API

### Chat Completions (совместимо с OpenAI)

```python
from openai import OpenAI

# Для внешнего доступа используйте ваш http_pub URL:
client = OpenAI(
    base_url="https://your-http-pub.clorecloud.net/v1",
    api_key="не_требуется"
)

# Или через SSH-туннель:
# client = OpenAI(base_url="http://localhost:8000/v1", api_key="not-needed")

response = client.chat.completions.create(
    model="mistralai/Mistral-7B-Instruct-v0.2",
    messages=[
        {"role": "user", "content": "Объясните квантовые вычисления"}
    ],
    max_tokens=500,
    temperature=0.7
)

print(response.choices[0].message.content)
```

### Потоковая передача (Streaming)

```python
stream = client.chat.completions.create(
    model="mistralai/Mistral-7B-Instruct-v0.2",
    messages=[{"role": "user", "content": "Напишите стихотворение"}],
    stream=True
)

for chunk in stream:
    if chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="")
```

### cURL

```bash
curl https://your-http-pub.clorecloud.net/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "mistralai/Mistral-7B-Instruct-v0.2",
    "messages": [{"role": "user", "content": "Здравствуйте!"}],
    "max_tokens": 100
  }'
```

### Текстовые дополнения

```bash
curl https://your-http-pub.clorecloud.net/v1/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "mistralai/Mistral-7B-Instruct-v0.2",
    "prompt": "Столицей Франции является",
    "max_tokens": 50
  }'
```

## Полная справочная документация API

vLLM предоставляет совместимые с OpenAI конечные точки плюс дополнительные утилитные эндпоинты.

### Стандартные конечные точки

| Эндпоинт               | Метод | Описание                                        |
| ---------------------- | ----- | ----------------------------------------------- |
| `/v1/models`           | GET   | Показать доступные модели                       |
| `/v1/chat/completions` | POST  | Чат-завершение                                  |
| `/v1/completions`      | POST  | Завершение текста                               |
| `/health`              | GET   | Проверка состояния (может вернуть пустой ответ) |

### Дополнительные эндпоинты

| Эндпоинт      | Метод | Описание                     |
| ------------- | ----- | ---------------------------- |
| `/tokenize`   | POST  | Токенизация текста           |
| `/detokenize` | POST  | Преобразовать токены в текст |
| `/version`    | GET   | Получить версию vLLM         |
| `/docs`       | GET   | Документация Swagger UI      |
| `/metrics`    | GET   | Метрики Prometheus           |

#### Токенизировать текст

Полезно для подсчёта токенов перед отправкой запросов:

```bash
curl https://your-http-pub.clorecloud.net/tokenize \
  -H "Content-Type: application/json" \
  -d '{
    "model": "mistralai/Mistral-7B-Instruct-v0.2",
    "prompt": "Hello world"
  }'
```

Ответ:

```json
{"count": 2, "max_model_len": 32768, "tokens": [9707, 1879]}
```

#### Детокенизация

Преобразовать идентификаторы токенов обратно в текст:

```bash
curl https://your-http-pub.clorecloud.net/detokenize \
  -H "Content-Type: application/json" \
  -d '{
    "model": "mistralai/Mistral-7B-Instruct-v0.2",
    "tokens": [9707, 1879]
  }'
```

Ответ:

```json
{"prompt": "Hello world"}
```

#### Получить версию

```bash
curl https://your-http-pub.clorecloud.net/version
```

Ответ:

```json
{"version": "0.7.3"}
```

#### Документация Swagger

Откройте в браузере для интерактивной документации API:

```
https://your-http-pub.clorecloud.net/docs
```

#### Метрики Prometheus

Для мониторинга:

```bash
curl https://your-http-pub.clorecloud.net/metrics
```

{% hint style="info" %}
**Модели рассуждения:** DeepSeek-R1 и подобные модели включают `<think>` теги в ответах, показывающие процесс рассуждения модели перед окончательным ответом.
{% endhint %}

## Бенчмарки

### Пропускная способность (токенов/с на пользователя)

| Модель             | RTX 3090 | RTX 4090 | A100 40GB | A100 80GB |
| ------------------ | -------- | -------- | --------- | --------- |
| Mistral 7B         | 100      | 170      | 210       | 230       |
| Llama 3.1 8B       | 95       | 150      | 200       | 220       |
| Llama 3.1 8B (AWQ) | 130      | 190      | 260       | 280       |
| Mixtral 8x7B       | -        | 45       | 70        | 85        |
| Llama 3.1 70B      | -        | -        | 25 (2x)   | 45 (2x)   |
| DeepSeek-R1 7B     | 90       | 145      | 190       | 210       |
| DeepSeek-R1 32B    | -        | -        | 40        | 70 (2x)   |

*Бенчмарки обновлены в январе 2026.*

### Длина контекста vs VRAM

| Модель   | 4K контекст | 8K контекст | 16K контекст | 32K контекст |
| -------- | ----------- | ----------- | ------------ | ------------ |
| 8B FP16  | 18GB        | 22GB        | 30GB         | 46 ГБ        |
| 8B AWQ   | 8GB         | 10GB        | 14GB         | 22GB         |
| 70B FP16 | 145 ГБ      | 160GB       | 190 ГБ       | 250GB        |
| 70B AWQ  | 42GB        | 50GB        | 66 ГБ        | 98 ГБ        |

## Аутентификация Hugging Face

Для закрытых моделей (Llama и др.):

```bash
# Установите токен в командной строке
vllm serve meta-llama/Meta-Llama-3.1-8B-Instruct \
    --host 0.0.0.0 \
    --env HUGGING_FACE_HUB_TOKEN=hf_xxxxx
```

Или установите как переменную окружения:

```bash
export HUGGING_FACE_HUB_TOKEN=hf_xxxxx
```

## Требования к GPU

| Модель | Мин. VRAM | Мин. RAM | Рекомендуется         |
| ------ | --------- | -------- | --------------------- |
| 7–8B   | 16GB      | **16GB** | 24 ГБ VRAM, 32 ГБ RAM |
| 13B    | 26 ГБ     | 32GB     | 40 ГБ VRAM            |
| 34B    | 70GB      | 32GB     | 80 ГБ VRAM            |
| 70B    | 140 ГБ    | 64GB     | 2x80 ГБ               |

## Оценка стоимости

Типичные расценки на маркетплейсе CLORE.AI:

| GPU      | VRAM  | Цена/день  | Лучше всего для |
| -------- | ----- | ---------- | --------------- |
| RTX 3090 | 24 ГБ | $0.30–1.00 | Модели 7–8B     |
| RTX 4090 | 24 ГБ | $0.50–2.00 | 7–13B, быстро   |
| A100     | 40GB  | $1.50–3.00 | Модели 13–34B   |
| A100     | 80GB  | $2.00–4.00 | Модели 34–70B   |

*Цены в USD/день. Тарифы зависят от провайдера — проверьте* [*CLORE.AI Marketplace*](https://clore.ai/marketplace) *для текущих тарифов.*

## Устранение неполадок

### HTTP 502 длительное время

1. **Проверьте RAM:** Сервер должен иметь 16 ГБ+ RAM
2. **Проверьте VRAM:** Должно помещаться в модель
3. **Загрузка модели:** Первый запуск загружает с HuggingFace (5–15 мин)
4. **HF токен:** Закрытые модели требуют аутентификации

### Недостаточно памяти

```bash
# Снизить использование памяти
--gpu-memory-utilization 0.8
--max-model-len 4096
--max-num-seqs 64

# Или используйте квантизацию
--quantization awq
```

### Загрузка модели не удалась

```bash
# Проверьте HF токен
echo $HUGGING_FACE_HUB_TOKEN

# Предварительно загрузить модель
huggingface-cli download mistralai/Mistral-7B-Instruct-v0.2
```

## vLLM против других

| Функция                | vLLM       | llama.cpp  | Ollama     |
| ---------------------- | ---------- | ---------- | ---------- |
| Пропускная способность | Лучшее     | Хорошо     | Хорошо     |
| Использование VRAM     | Высокий    | Низкая     | Средне     |
| Удобство использования | Средне     | Средне     | Лёгкий     |
| Время запуска          | 5–15 мин   | 1–2 мин    | 30 сек     |
| Мульти-GPU             | Нативно    | Ограничено | Ограничено |
| Вызов инструментов     | Да (v0.7+) | Ограничено | Ограничено |
| Multi-LoRA             | Да (v0.7+) | Нет        | Нет        |

**Используйте vLLM, когда:**

* В приоритете высокая пропускная способность
* Обслуживание нескольких пользователей
* Имеется достаточно VRAM и RAM
* Развёртывание в продакшене
* Нужен вызов инструментов / структурированные выводы

**Используйте Ollama, когда:**

* Требуется быстрая настройка
* Один пользователь
* Меньше доступных ресурсов

## Дальнейшие шаги

* [Ollama](https://docs.clore.ai/guides/guides_v2-ru/yazykovye-modeli/ollama) - Более простая альтернатива с более быстрым запуском
* [DeepSeek-R1](https://docs.clore.ai/guides/guides_v2-ru/yazykovye-modeli/deepseek-r1) - Руководство по моделям рассуждения
* [DeepSeek-V3](https://docs.clore.ai/guides/guides_v2-ru/yazykovye-modeli/deepseek-v3) - Лучшая общая модель
* [Qwen2.5](https://docs.clore.ai/guides/guides_v2-ru/yazykovye-modeli/qwen25) - Многоязычные модели
* [Llama.cpp](https://docs.clore.ai/guides/guides_v2-ru/yazykovye-modeli/llamacpp-server) - Вариант с меньшим VRAM
