# vLLM

Hochdurchsatz-LLM-Inferenzserver für Produktions-Workloads auf CLORE.AI-GPUs.

{% hint style="success" %}
Alle Beispiele können auf GPU-Servern ausgeführt werden, die über [CLORE.AI Marketplace](https://clore.ai/marketplace).
{% endhint %}

{% hint style="info" %}
**Aktuelle Version: v0.7.x** — Dieser Leitfaden behandelt vLLM v0.7.3+. Neue Funktionen umfassen DeepSeek-R1-Unterstützung, strukturierte Ausgaben mit automatischer Werkzeugwahl, Multi-LoRA-Bereitstellung und verbesserte Speichereffizienz.
{% endhint %}

## Serveranforderungen

| Parameter | Minimum      | Empfohlen |
| --------- | ------------ | --------- |
| RAM       | **16GB**     | 32GB+     |
| VRAM      | 16GB (7B)    | 24GB+     |
| Netzwerk  | 500Mbps      | 1Gbps+    |
| Startzeit | 5–15 Minuten | -         |

{% hint style="danger" %}
**Wichtig:** vLLM benötigt erheblichen RAM und VRAM. Server mit weniger als 16GB RAM können nicht einmal 7B-Modelle ausführen.
{% endhint %}

{% hint style="warning" %}
**Startzeit:** Beim ersten Start wird das Modell von HuggingFace heruntergeladen (5–15 Minuten, abhängig von Modellgröße und Netzwerkgeschwindigkeit). HTTP 502 während dieser Zeit ist normal.
{% endhint %}

## Warum vLLM?

* **Höchster Durchsatz** - PagedAttention für bis zu 24x höheren Durchsatz
* **Produktionsreif** - OpenAI-kompatible API sofort einsatzbereit
* **Kontinuierliches Batching** - Effizientes Serving für mehrere Benutzer
* **Streaming** - Echtzeit-Token-Generierung
* **Multi-GPU** - Tensorparallelismus für große Modelle
* **Multi-LoRA** - Gleichzeitiges Bereitstellen mehrerer feinabgestimmter Adapter (v0.7+)
* **Strukturierte Ausgaben** - JSON-Schema-Validierung und Tool-Calls (v0.7+)

## Schnelle Bereitstellung auf CLORE.AI

**Docker-Image:**

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

**Ports:**

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

**Befehl:**

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

### Überprüfen, ob es funktioniert

Nach der Bereitstellung finden Sie Ihre `http_pub` URL in **Meine Bestellungen**:

```bash
# Prüfe Gesundheit (kann beim ersten Lauf 5–15 Min dauern)
curl https://your-http-pub.clorecloud.net/health

# Modelle auflisten (funktioniert erst, nachdem das Modell geladen ist)
curl https://your-http-pub.clorecloud.net/v1/models
```

{% hint style="warning" %}
Wenn Sie länger als 15 Minuten HTTP 502 erhalten, prüfen Sie:

1. Server hat 16GB+ RAM
2. Server hat genug VRAM für das Modell
3. HuggingFace-Token ist für gesperrte Modelle gesetzt
   {% endhint %}

## Zugriff auf Ihren Dienst

Bei Bereitstellung auf CLORE.AI greifen Sie auf vLLM über die `http_pub` URL:

```bash
# Chat-Vervollständigung
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" %}
Alle `localhost:8000` Die untenstehenden Beispiele funktionieren, wenn über SSH verbunden. Für externen Zugriff ersetzen Sie durch Ihre `https://your-http-pub.clorecloud.net/` URL.
{% endhint %}

## Installation

### Verwendung von Docker (empfohlen)

```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
```

### Verwendung von pip

```bash
pip install vllm==0.7.3

# Server starten
python -m vllm.entrypoints.openai.api_server \
    --model mistralai/Mistral-7B-Instruct-v0.2
```

## Unterstützte Modelle

| Modell                        | Parameter | Benötigter VRAM     | Benötigter RAM |
| ----------------------------- | --------- | ------------------- | -------------- |
| Mistral 7B                    | 7B        | 14GB                | 16GB+          |
| Llama 3.1 8B                  | 8B        | 16GB                | 16GB+          |
| Llama 3.1 70B                 | 70B       | 140GB (oder 2x80GB) | 64GB+          |
| Mixtral 8x7B                  | 47B       | 90GB                | 32GB+          |
| Qwen2.5 7B                    | 7B        | 14GB                | 16GB+          |
| Qwen2.5 72B                   | 72B       | 145GB               | 64GB+          |
| DeepSeek-V3                   | 236B MoE  | Multi-GPU           | 128GB+         |
| DeepSeek-R1-Distill-Qwen-7B   | 7B        | 14GB                | 16GB+          |
| DeepSeek-R1-Distill-Qwen-32B  | 32B       | 64GB                | 32GB+          |
| DeepSeek-R1-Distill-Llama-70B | 70B       | 140GB               | 64GB+          |
| Phi-4                         | 14B       | 28GB                | 32GB+          |
| Gemma 2 9B                    | 9B        | 18GB                | 16GB+          |
| CodeLlama 34B                 | 34B       | 68GB                | 32GB+          |

## Serveroptionen

### Basiser Server

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

### Produktionsserver

```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
```

### Mit Quantisierung (geringerer VRAM)

```bash
# AWQ-quantisiertes Modell (verwendet weniger VRAM)
vllm serve TheBloke/Mistral-7B-Instruct-v0.2-AWQ \
    --host 0.0.0.0 \
    --quantization awq
```

### Strukturierte Ausgaben und Tool-Calls (v0.7+)

Automatische Werkzeugwahl und strukturierte JSON-Ausgaben aktivieren:

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

Verwendung in 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": "Hole die aktuelle Wetterlage für eine Stadt",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {"type": "string", "description": "Stadtname"},
                    "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
                },
                "required": ["city"]
            }
        }
    }
]

response = client.chat.completions.create(
    model="mistralai/Mistral-7B-Instruct-v0.2",
    messages=[{"role": "user", "content": "Wie ist das Wetter in Paris?"}],
    tools=tools,
    tool_choice="auto"
)

# Tool-Call parsen
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}")
```

Strukturierte JSON-Ausgabe via response\_format:

```python
response = client.chat.completions.create(
    model="mistralai/Mistral-7B-Instruct-v0.2",
    messages=[{"role": "user", "content": "Extrahiere: John Smith, 30 Jahre alt, Softwareingenieur"}],
    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-Serving (v0.7+)

Stellen Sie ein Basismodell mit mehreren LoRA-Adaptern gleichzeitig bereit:

```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
```

Einen bestimmten LoRA-Adapter per Modellnamen abfragen:

```python
# Verwende den SQL-Adapter
response = client.chat.completions.create(
    model="sql-adapter",
    messages=[{"role": "user", "content": "Schreibe eine SQL-Abfrage, um die Top-10-Kunden zu finden"}]
)

# Verwende den Code-Adapter
response = client.chat.completions.create(
    model="code-adapter",
    messages=[{"role": "user", "content": "Schreibe eine Python-Funktion, um eine Liste zu sortieren"}]
)
```

## DeepSeek-R1-Unterstützung (v0.7+)

vLLM v0.7+ hat native Unterstützung für DeepSeek-R1-Distillmodelle. Diese reasoning-Modelle erzeugen `<think>` Tags, die ihren Denkprozess anzeigen.

### DeepSeek-R1-Distill-Qwen-7B (Single 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 (Dual 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 (Quad 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 abfragen

```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": "Löse: Wenn ein Zug 120 km in 1,5 Stunden fährt, wie hoch ist seine Geschwindigkeit in m/s?"
        }
    ],
    max_tokens=2048,
    temperature=0.6
)

content = response.choices[0].message.content
# Antwort enthält <think>...</think>-Denkblock gefolgt von der Antwort
print(content)
```

Think-Tags parsen:

```python
import re

def parse_deepseek_r1_response(content: str) -> dict:
    """Extrahiere Denken und Antwort aus einer DeepSeek-R1-Antwort."""
    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-Nutzung

### Chat-Completions (OpenAI-kompatibel)

```python
from openai import OpenAI

# Für externen Zugriff verwenden Sie Ihre http_pub-URL:
client = OpenAI(
    base_url="https://your-http-pub.clorecloud.net/v1",
    api_key="nicht benötigt"
)

# Oder über SSH-Tunnel:
# 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": "Erkläre Quantencomputing"}
    ],
    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": "Schreibe ein Gedicht"}],
    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": "Hallo!"}],
    "max_tokens": 100
  }'
```

### Textvervollständigungen

```bash
curl https://your-http-pub.clorecloud.net/v1/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "mistralai/Mistral-7B-Instruct-v0.2",
    "prompt": "Die Hauptstadt von Frankreich ist",
    "max_tokens": 50
  }'
```

## Vollständige API-Referenz

vLLM bietet OpenAI-kompatible Endpunkte plus zusätzliche Dienstendpunkte.

### Standardendpunkte

| Endpunkt               | Methode | Beschreibung                         |
| ---------------------- | ------- | ------------------------------------ |
| `/v1/models`           | GET     | Verfügbare Modelle auflisten         |
| `/v1/chat/completions` | POST    | Chat-Vervollständigung               |
| `/v1/completions`      | POST    | Textvervollständigung                |
| `/health`              | GET     | Health-Check (kann leer zurückgeben) |

### Zusätzliche Endpunkte

| Endpunkt      | Methode | Beschreibung             |
| ------------- | ------- | ------------------------ |
| `/tokenize`   | POST    | Text tokenisieren        |
| `/detokenize` | POST    | Tokens in Text umwandeln |
| `/version`    | GET     | vLLM-Version abrufen     |
| `/docs`       | GET     | Swagger-UI-Dokumentation |
| `/metrics`    | GET     | Prometheus-Metriken      |

#### Text tokenisieren

Nützlich zum Zählen von Tokens vor dem Senden von Anfragen:

```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"
  }'
```

Antwort:

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

#### Detokenize

Token-IDs zurück in Text konvertieren:

```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]
  }'
```

Antwort:

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

#### Version abrufen

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

Antwort:

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

#### Swagger-Dokumentation

Öffnen Sie im Browser für interaktive API-Dokumentation:

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

#### Prometheus-Metriken

Zur Überwachung:

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

{% hint style="info" %}
**Reasoning-Modelle:** DeepSeek-R1 und ähnliche Modelle enthalten `<think>` Tags in Antworten, die den Denkprozess des Modells vor der finalen Antwort zeigen.
{% endhint %}

## Benchmarks

### Durchsatz (Tokens/Sek pro Benutzer)

| Modell             | 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)   |

*Benchmarks aktualisiert Januar 2026.*

### Kontextlänge vs. VRAM

| Modell   | 4K Kontext | 8K Kontext | 16K Kontext | 32K Kontext |
| -------- | ---------- | ---------- | ----------- | ----------- |
| 8B FP16  | 18GB       | 22GB       | 30GB        | 46GB        |
| 8B AWQ   | 8GB        | 10GB       | 14GB        | 22GB        |
| 70B FP16 | 145GB      | 160GB      | 190GB       | 250GB       |
| 70B AWQ  | 42GB       | 50GB       | 66GB        | 98GB        |

## Hugging Face Authentifizierung

Für gesperrte Modelle (Llama usw.):

```bash
# Token im Befehl setzen
vllm serve meta-llama/Meta-Llama-3.1-8B-Instruct \
    --host 0.0.0.0 \
    --env HUGGING_FACE_HUB_TOKEN=hf_xxxxx
```

Oder als Umgebungsvariable setzen:

```bash
export HUGGING_FACE_HUB_TOKEN=hf_xxxxx
```

## GPU-Anforderungen

| Modell | Min. VRAM | Min. RAM | Empfohlen           |
| ------ | --------- | -------- | ------------------- |
| 7-8B   | 16GB      | **16GB** | 24GB VRAM, 32GB RAM |
| 13B    | 26GB      | 32GB     | 40GB VRAM           |
| 34B    | 70GB      | 32GB     | 80GB VRAM           |
| 70B    | 140GB     | 64GB     | 2x80GB              |

## Kostenabschätzung

Typische CLORE.AI-Marktplatzpreise:

| GPU      | VRAM | Preis/Tag  | Am besten geeignet für |
| -------- | ---- | ---------- | ---------------------- |
| RTX 3090 | 24GB | $0.30–1.00 | 7-8B-Modelle           |
| RTX 4090 | 24GB | $0.50–2.00 | 7-13B, schnell         |
| A100     | 40GB | $1.50–3.00 | 13-34B-Modelle         |
| A100     | 80GB | $2.00–4.00 | 34-70B-Modelle         |

*Preise in USD/Tag. Die Tarife variieren je nach Anbieter — prüfen Sie* [*CLORE.AI Marketplace*](https://clore.ai/marketplace) *auf aktuelle Preise.*

## Fehlerbehebung

### HTTP 502 über lange Zeit

1. **Prüfe RAM:** Server muss 16GB+ RAM haben
2. **Prüfe VRAM:** Muss in das Modell passen
3. **Modell-Download:** Beim ersten Lauf wird von HuggingFace heruntergeladen (5–15 Min)
4. **HF-Token:** Gesperrte Modelle erfordern Authentifizierung

### Kein Speicher mehr

```bash
# Speicherverbrauch reduzieren
--gpu-memory-utilization 0.8
--max-model-len 4096
--max-num-seqs 64

# Oder Quantisierung verwenden
--quantization awq
```

### Modell-Download schlägt fehl

```bash
# HF-Token prüfen
echo $HUGGING_FACE_HUB_TOKEN

# Modell vorab herunterladen
huggingface-cli download mistralai/Mistral-7B-Instruct-v0.2
```

## vLLM vs Andere

| Funktion               | vLLM       | llama.cpp | Ollama   |
| ---------------------- | ---------- | --------- | -------- |
| Durchsatz              | Am besten  | Gut       | Gut      |
| VRAM-Nutzung           | Hoch       | Gering    | Mittel   |
| Benutzerfreundlichkeit | Mittel     | Mittel    | Einfach  |
| Startzeit              | 5–15 min   | 1–2 Min   | 30 Sek.  |
| Multi-GPU              | Nativ      | Begrenzt  | Begrenzt |
| Tool-Aufrufe           | Ja (v0.7+) | Begrenzt  | Begrenzt |
| Multi-LoRA             | Ja (v0.7+) | Nein      | Nein     |

**Verwenden Sie vLLM, wenn:**

* Hoher Durchsatz Priorität hat
* Mehrere Benutzer bedient werden sollen
* Genug VRAM und RAM vorhanden sind
* Produktionsbereitstellung
* Tool-Calls / strukturierte Ausgaben benötigt werden

**Verwenden Sie Ollama, wenn:**

* Schnelle Einrichtung benötigt wird
* Einzelner Benutzer
* Weniger Ressourcen verfügbar sind

## Nächste Schritte

* [Ollama](https://docs.clore.ai/guides/guides_v2-de/sprachmodelle/ollama) - Einfachere Alternative mit schnellerem Start
* [DeepSeek-R1](https://docs.clore.ai/guides/guides_v2-de/sprachmodelle/deepseek-r1) - Leitfaden für Reasoning-Modelle
* [DeepSeek-V3](https://docs.clore.ai/guides/guides_v2-de/sprachmodelle/deepseek-v3) - Bestes Generalmodell
* [Qwen2.5](https://docs.clore.ai/guides/guides_v2-de/sprachmodelle/qwen25) - Mehrsprachige Modelle
* [Llama.cpp](https://docs.clore.ai/guides/guides_v2-de/sprachmodelle/llamacpp-server) - Option mit geringerem VRAM
