Zum Inhalt springen
← Alle Beiträge
· 5 Min. Lesezeit·Emre Yurtbay

Hermes von Nous Research selbst hosten: vLLM, Tool-Calling und Self-Hosting in der Praxis

Praxisleitfaden zum Self-Hosting der Open-Weight-Modelle Hermes 3 von Nous Research: vLLM mit OpenAI-kompatibler API, Function-Calling, Ollama und VRAM-Planung.

LLMSelf-HostingvLLMHermesNous ResearchFunction CallingOpen WeightsOllamaLlama 3.1Inferenz

Wer Sprachmodelle in eigene Anwendungen integrieren möchte, ohne sich an einen externen API-Anbieter zu binden, kommt an Open-Weight-Modellen kaum vorbei. Die Hermes-Reihe von Nous Research ist dabei eine interessante Wahl: feinjustierte Modelle mit ausgeprägten Fähigkeiten beim Tool-Calling, bei strukturierten JSON-Ausgaben und bei der Steuerung über den System-Prompt. Dieser Artikel zeigt, wie Sie Hermes mit vLLM produktionsnah selbst betreiben, inklusive Function-Calling-Beispiel und einer schlanken Alternative über Ollama.

Was Hermes ist

Hermes ist eine Familie von Open-Weight-Modellen, die Nous Research auf Basis bestehender Foundation-Modelle feinjustiert (Fine-Tuning, kein eigenes Pre-Training). Die aktuell relevante Generation ist Hermes 3, das auf Meta Llama 3.1 aufsetzt und in mehreren Größen verfügbar ist, unter anderem als 8B, 70B und 405B. Ältere Varianten wie Hermes 2 Pro existieren auf Basis von Llama 3 (8B) sowie Mistral (7B).

Charakteristisch für Hermes ist der Fokus auf:

  • Function- und Tool-Calling: zuverlässiges Erzeugen strukturierter Aufrufe, die Ihre Anwendung ausführen kann.
  • Strukturierte Ausgaben: stabile JSON-Generierung, gut geeignet für maschinelle Weiterverarbeitung.
  • Steuerbarkeit per System-Prompt: das Modell folgt Rollen- und Formatvorgaben vergleichsweise konsequent.

Die Gewichte liegen öffentlich im HuggingFace-Namespace NousResearch, etwa unter NousResearch/Hermes-3-Llama-3.1-8B.

Lizenz

Da Hermes 3 auf Llama 3.1 basiert, gilt die Llama 3.1 Community License von Meta. Diese erlaubt kommerzielle Nutzung, enthält jedoch Bedingungen (unter anderem eine Schwelle bei sehr großen Nutzerzahlen sowie Namens- und Attributionsvorgaben). Prüfen Sie die Llama-3.1-Lizenz vor dem produktiven Einsatz. "Open Weights" bedeutet hier offene Gewichte unter einer Lizenz mit Auflagen, nicht uneingeschränktes Open Source.

Self-Hosting-Optionen im Überblick

Weg Eignung Bemerkung
vLLM Produktion, hoher Durchsatz OpenAI-kompatible API, natives Tool-Parsing
Ollama Lokale Entwicklung, kleinere Hardware GGUF, quantisiert, sehr einfacher Einstieg
llama.cpp CPU/Edge, maximale Kontrolle Basis vieler GGUF-Setups
TGI Alternative im HF-Ökosystem Text Generation Inference

Der empfohlene Hauptweg für den Server-Betrieb ist vLLM: hoher Durchsatz durch Continuous Batching und PagedAttention sowie eine zur OpenAI-API kompatible Schnittstelle, sodass bestehende Clients ohne Umbau funktionieren.

Hardware und VRAM grob einordnen

Eine exakte VRAM-Angabe hängt von Kontextlänge, Batch-Größe und KV-Cache ab. Als grobe Größenordnung in halber Präzision (FP16/BF16) gilt: rund zwei GB VRAM pro einer Milliarde Parameter, zuzüglich Reserve für den KV-Cache.

  • 8B: läuft auf einer einzelnen Consumer- bzw. Workstation-GPU; quantisiert (4-Bit) auch auf deutlich kleineren Karten.
  • 70B: erfordert mehrere GPUs oder aggressive Quantisierung.
  • 405B: Multi-GPU-Cluster mit Tensor-Parallelismus, nichts für einzelne Maschinen.

Quantisierung (etwa 8-Bit oder 4-Bit) senkt den Speicherbedarf erheblich, kann aber Genauigkeit kosten. Für erste Tests ist die 8B-Variante der pragmatische Einstieg.

Architektur

+---------------------+      OpenAI-kompatibel       +---------------------+
|     Eigene App      | ---------------------------> |   vLLM Inferenz-    |
|  (Backend/Client)   |   POST /v1/chat/completions  |       Server        |
|                     | <--------------------------- |                     |
+---------------------+        JSON / tool_calls     +---------------------+
        |    ^                                                  |
        |    |                                                  v
        |    |                                        +---------------------+
        |    |                                        |  GPU + Hermes-      |
        |    |                                        |       Modell        |
        |    |                                        +---------------------+
        |    |
        |    |   Tool-Calling-Schleife
        v    |
+---------------------+
|   Tool ausfuehren   |   1. Modell fordert Tool an (tool_calls)
|   (Funktion, API,   |   2. App fuehrt Funktion aus
|    DB, Suche ...)   |   3. Ergebnis als role=tool zurueck
+---------------------+   4. Modell formuliert finale Antwort

vLLM starten

Nach der Installation (pip install vllm) starten Sie den Server. Wichtig für Hermes ist der dedizierte Tool-Parser hermes zusammen mit --enable-auto-tool-choice, damit vLLM die vom Modell erzeugten Tool-Aufrufe korrekt in das OpenAI-Format überführt.

vllm serve NousResearch/Hermes-3-Llama-3.1-8B \
  --enable-auto-tool-choice \
  --tool-call-parser hermes \
  --host 0.0.0.0 \
  --port 8000 \
  --max-model-len 8192

Der Server stellt anschließend unter http://localhost:8000/v1 die bekannten Endpunkte /chat/completions, /completions und /models bereit. Details zum Tool-Parsing finden Sie in der vLLM-Dokumentation zu Tool Calling.

OpenAI-kompatibler Aufruf

Da die API kompatibel ist, können Sie den offiziellen openai-Client verwenden und lediglich base_url und einen Platzhalter-Key setzen.

from openai import OpenAI

client = OpenAI(base_url="http://localhost:8000/v1", api_key="dummy")

resp = client.chat.completions.create(
    model="NousResearch/Hermes-3-Llama-3.1-8B",
    messages=[
        {"role": "system", "content": "Du antwortest praezise auf Deutsch."},
        {"role": "user", "content": "Nenne drei Vorteile von Self-Hosting."},
    ],
    temperature=0.3,
)

print(resp.choices[0].message.content)

Ein einfacher Test ohne SDK funktioniert mit curl:

curl http://localhost:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "NousResearch/Hermes-3-Llama-3.1-8B",
    "messages": [{"role": "user", "content": "Sag kurz Hallo."}]
  }'

Function-Calling-Beispiel

Beim Tool-Calling übergeben Sie ein tools-Array. Fordert das Modell einen Aufruf an, liefert die Antwort tool_calls statt content. Ihre Anwendung führt die Funktion aus und gibt das Ergebnis als Nachricht mit role: "tool" zurück.

import json
from openai import OpenAI

client = OpenAI(base_url="http://localhost:8000/v1", api_key="dummy")

tools = [{
    "type": "function",
    "function": {
        "name": "get_weather",
        "description": "Liefert die aktuelle Temperatur fuer einen Ort.",
        "parameters": {
            "type": "object",
            "properties": {
                "city": {"type": "string", "description": "Stadtname"}
            },
            "required": ["city"],
        },
    },
}]

messages = [{"role": "user", "content": "Wie warm ist es gerade in Hamburg?"}]

first = client.chat.completions.create(
    model="NousResearch/Hermes-3-Llama-3.1-8B",
    messages=messages,
    tools=tools,
    tool_choice="auto",
)

msg = first.choices[0].message

if msg.tool_calls:
    call = msg.tool_calls[0]
    args = json.loads(call.function.arguments)

    # Funktion in Ihrer App ausfuehren (hier nur simuliert)
    result = {"city": args["city"], "temp_c": 18}

    messages.append(msg)  # Assistenten-Nachricht mit tool_calls
    messages.append({
        "role": "tool",
        "tool_call_id": call.id,
        "content": json.dumps(result),
    })

    final = client.chat.completions.create(
        model="NousResearch/Hermes-3-Llama-3.1-8B",
        messages=messages,
        tools=tools,
    )
    print(final.choices[0].message.content)

Das tool_calls-Objekt enthält eine id, den Funktionsnamen und die Argumente als JSON-String. Genau diese id muss in der role: "tool"-Antwort als tool_call_id referenziert werden, damit das Modell Aufruf und Ergebnis zuordnen kann.

Schlanke Alternative: Ollama

Für lokale Experimente oder kleinere Hardware ist Ollama der einfachste Weg. Es nutzt quantisierte GGUF-Modelle und bringt eine eigene API mit. Verfügbare Tags variieren; prüfen Sie die Bibliothek vor dem Pull.

# Beispielhaft eine Hermes-Variante ziehen und starten
ollama run hermes3

# oder explizit eine Groesse
ollama run hermes3:8b

Ollama eignet sich gut zum Ausprobieren, für hohen parallelen Durchsatz in der Produktion ist vLLM jedoch klar im Vorteil.

Praxis-Empfehlung

Beginnen Sie mit Hermes-3-Llama-3.1-8B auf einer einzelnen GPU unter vLLM. Verifizieren Sie zuerst die Tool-Calling-Schleife mit einer simulierten Funktion, bevor Sie echte Systeme anbinden. Achten Sie auf eine sinnvolle --max-model-len (der KV-Cache ist der häufigste VRAM-Engpass) und validieren Sie strukturierte Ausgaben serverseitig per Schema, statt dem Modell blind zu vertrauen. Prüfen Sie die Llama-3.1-Lizenz, bevor Sie produktiv gehen. Skalieren Sie erst auf 70B oder Quantisierung, wenn die 8B-Variante Ihre Qualitätsanforderungen messbar nicht erfüllt.

Wenn Sie ein Hermes- oder vLLM-Setup planen oder bestehende LLM-Infrastruktur optimieren möchten, schreiben Sie gern an info@yurtbay.dev. Ich unterstütze Sie bei Architektur, Tool-Calling-Integration und Deployment.

Projekt besprechen