Wer im September 2026 wissen will, welches Sprachmodell für den eigenen Anwendungsfall wirklich taugt, stößt schnell an die Grenzen klassischer Benchmarks. Ein MMLU-Score sagt wenig darüber aus, ob ein Modell deutsche Vertragsklauseln sauber zusammenfasst oder ob es bei einer Kundenanfrage auf Schweizerdeutsch ins Straucheln gerät. Genau hier setzt eine LLM Arena an: Zwei Modelle treten anonym gegeneinander an, ein Mensch stimmt blind ab, und aus tausenden solcher Duelle entsteht ein Rating, das echte Präferenzen abbildet statt nur Multiple-Choice-Antworten. Dieses Tutorial zeigt in zwölf Schritten, wie du mit dem Open-Source-Framework FastChat (39.550 Sterne auf GitHub, Stand 27. September 2026) eine eigene, private LLM Arena aufbaust und aktuelle Modelle wie DeepSeek V4.1 Flash, Gemini 3.8 Flash und Claude Opus 5.5 gegeneinander testest.

Am Ende dieses Tutorials hast du ein lauffähiges Projekt: einen Controller, mindestens zwei Model Worker, eine Web-Oberfläche für Blind-Votes, ein eigenes Set deutscher Testprompts und ein Python-Skript, das aus den gesammelten Abstimmungen ein belastbares Bradley-Terry-Rating berechnet. Zusätzlich zeigen wir eine Docker-Variante für Teams, die das Setup nicht auf einer einzelnen Entwicklermaschine, sondern auf einem gemeinsam genutzten Server betreiben wollen.

Warum eine eigene LLM Arena mehr verrät als ein einzelner Benchmark-Score

Öffentliche Leaderboards wie lmarena.ai sind ein guter Startpunkt, taugen für den betrieblichen Alltag aber nur bedingt. Die dort verwendeten Prompts stammen von einer globalen, überwiegend englischsprachigen Nutzerbasis. Wer wissen will, wie ein Modell mit deutschen Rechtsbegriffen, DSGVO-Anfragen oder österreichischem Amtsdeutsch umgeht, findet dort kaum verwertbare Daten. Eine selbst gehostete Arena löst dieses Problem, weil du die Prompts, die Kategorien und die Tester selbst bestimmst.

Der zweite Grund ist Vertraulichkeit. Sobald interne Dokumente, Kundendaten oder unveröffentlichter Code als Testprompts dienen sollen, verbietet sich eine öffentliche Plattform von selbst. Eine private Arena läuft auf eigener Infrastruktur, protokolliert nichts nach außen und lässt sich an DSGVO-Vorgaben anpassen. Drittens liefert der direkte Vergleich zweier Antworten robustere Signale als ein isolierter Score. Menschen sind beim Vergleichen zuverlässiger als beim absoluten Bewerten, das ist ein alter Befund aus der Psychometrie und der Grund, warum Bradley-Terry-Modelle in der Praxis so gut funktionieren.

Für Teams, die bereits einen klassischen Benchmark mit lm-evaluation-harness betreiben, ist die Arena keine Konkurrenz, sondern eine Ergänzung. Standardisierte Aufgaben zeigen, ob ein Modell grundsätzlich rechnen oder Code schreiben kann. Die Arena zeigt, welches von zwei fähigen Modellen ein Mensch tatsächlich bevorzugt, wenn die Antwort in einem echten Gespräch ankommt. Beide Ansätze zusammen ergeben ein deutlich vollständigeres Bild als jeder für sich allein.

Ein vierter, oft unterschätzter Vorteil betrifft die Modellauswahl selbst. Viele Teams entscheiden sich für ein Modell, weil es in einem öffentlichen Ranking vorne steht, obwohl dieses Ranking auf völlig anderen Aufgaben beruht als die eigene Anwendung. Eine eigene Arena macht diese Lücke sichtbar, bevor ein teurer API-Vertrag unterschrieben wird. Gerade bei Modellen mit unterschiedlicher Preisstruktur pro Million Token lohnt sich der Aufwand: Ein Modell, das im öffentlichen Leaderboard drei Plätze weiter unten steht, aber in der eigenen Kategorie besser abschneidet und günstiger ist, spart über Monate hinweg reale Kosten.

Wie eine LLM Arena funktioniert: Blind-Votes, Bradley-Terry und Elo

Das Prinzip ist simpel und genau deshalb so wirksam. Ein Nutzer stellt eine Frage, zwei zufällig ausgewählte Modelle antworten parallel, die Modellnamen bleiben bis zur Abstimmung verborgen. Der Nutzer wählt die bessere Antwort, erklärt ein Unentschieden oder verwirft beide. Erst nach der Abstimmung werden die echten Modellnamen eingeblendet. Diese Reihenfolge ist entscheidend: Kennt der Tester das Modell vorher, färbt der Markenname das Urteil, ein Effekt, der in der UX-Forschung gut belegt ist.

Aus den gesammelten Sieg-, Niederlage- und Unentschieden-Ergebnissen berechnet das System ein Rating. LMArena, früher als LMSYS Chatbot Arena bekannt, ist am 13. Juni 2025 offiziell vom klassischen Online-Elo-Update auf ein Bradley-Terry-Modell umgestiegen, um robustere Konfidenzintervalle zu erhalten. Die Wahrscheinlichkeit, dass Modell i gegen Modell j gewinnt, wird dabei über folgende Formel geschätzt:

P(i schlägt j) = exp(β_i) / (exp(β_i) + exp(β_j))

Dabei stehen β_i und β_j für die geschätzte Stärke der beiden Modelle. Das Verfahren passt diese Stärkewerte iterativ an alle beobachteten Duelle an, meist per Maximum-Likelihood-Schätzung. Die auf dem Dashboard angezeigte Zahl wirkt wie ein Schach-Elo, ist aber eine kalibrierte Darstellung dieser Bradley-Terry-Stärke und kein klassisches Online-Update nach jeder einzelnen Partie. Für eine eigene Arena reicht ein einfacher iterativer Minorization-Maximization-Algorithmus, den wir in Schritt 11 selbst implementieren, ganz ohne externe Rating-API.

Was die öffentliche LMArena zeigt und wo ihre Grenzen liegen

Die öffentliche Plattform lmarena.ai, aus dem LMSYS-Forschungsprojekt der UC Berkeley hervorgegangen, sammelt seit Jahren Millionen Nutzer-Votes und gilt vielen als informelle Referenz dafür, welches Modell gerade führt. Das FastChat-Repository von lm-sys bildet dabei technisch die Grundlage: Es trägt im offiziellen GitHub-Beschreibungstext den Hinweis, das Release-Repository für Vicuna und Chatbot Arena zu sein, und steht unter Apache-2.0-Lizenz. Genau dieser Code liegt auch dem Tutorial in diesem Artikel zugrunde, nur eben in einer privaten, nicht öffentlich zugänglichen Konfiguration.

Der wichtigste Kritikpunkt an öffentlichen Arenen betrifft die Zusammensetzung der Prompts. Wer freiwillig auf einer öffentlichen Website abstimmt, stellt andere Fragen als ein Fachanwender in einem Unternehmen. Kreative Schreibaufgaben, Trivia-Fragen und kurze Coding-Snippets dominieren solche Plattformen erfahrungsgemäß stärker als mehrseitige Vertragsanalysen oder branchenspezifische Fachtexte. Das erklärt, warum ein Modell in einem öffentlichen Leaderboard weit vorne stehen kann und im eigenen Fachtest trotzdem enttäuscht. Für eine belastbare interne Entscheidung bleibt deshalb kein Weg an einer eigenen, kleineren, aber thematisch passenden Arena vorbei.

Hinzu kommt ein methodischer Punkt: Öffentliche Leaderboards aktualisieren sich laufend, weil ständig neue Modellversionen hinzukommen und alte aus der aktiven Rotation fallen. Ein Rang, der heute gilt, kann in vier Wochen durch ein neues Modell-Release bereits überholt sein. Eine private Arena unterliegt diesem Trubel nicht in gleicher Form, weil du selbst festlegst, welche Modellversionen aktuell im Test stehen, und die Ergebnisse damit über den Zeitraum deiner Evaluierung stabil und nachvollziehbar bleiben.

Voraussetzungen: Hardware, Software und Accounts

Bevor es an die Installation geht, folgt eine ehrliche Bestandsaufnahme. Eine LLM Arena lässt sich in zwei Varianten betreiben: rein API-basiert ohne eigene GPU, oder hybrid mit mindestens einem lokal gehosteten Modell für Kostenkontrolle und Offline-Tests. Für den Einstieg reicht die API-Variante, für das komplette Beispielprojekt in diesem Tutorial nutzen wir beide.

KomponenteMinimumEmpfohlen
Python3.103.11
RAM (Controller + UI, reine API-Variante)8 GB16 GB
GPU (nur bei lokalem Modell-Worker)keine (API-only)8 GB+ VRAM für ein quantisiertes 7B-Modell
BetriebssystemLinux, macOS oder WSL2Linux (Ubuntu 24.04 oder neuer)
Speicherplatz5 GB30 GB+ bei lokalen Modellgewichten

Zusätzlich brauchst du API-Zugänge zu den Modellen, die du testen willst. Für das Beispielprojekt in diesem Artikel sind das ein DeepSeek-Account für DeepSeek V4.1 Flash, ein Google-AI-Studio- oder Vertex-Zugang für Gemini 3.8 Flash sowie ein Anthropic-Konto für Claude Opus 5.5. Alle drei Anbieter stellen Pay-as-you-go-Abrechnung bereit, ein Startguthaben von 20 bis 30 US-Dollar reicht für mehrere hundert Testrunden. Halte außerdem git und pip in aktueller Version bereit, denn FastChat installiert sich am zuverlässigsten aus dem Quellcode-Repository statt über eine ältere PyPI-Version.

Software-Pakete im Überblick

Neben FastChat selbst installiert das Tutorial folgende Kernpakete: numpy für die Bradley-Terry-Berechnung in Schritt 11, gradio als Basis für die Web-UI (wird von FastChat automatisch mitgezogen), sowie die jeweiligen HTTP-Bibliotheken für die drei API-Anbieter. Ein sauberer Weg, den Zustand deiner Umgebung jederzeit nachvollziehbar zu halten, ist ein Freeze der installierten Pakete direkt nach der Einrichtung.

pip3 freeze > requirements-arena.txt
# Enthält u.a.: fschat, gradio, numpy, requests, uvicorn

Diese Datei landet zusammen mit deinem Projekt im Repository und sorgt dafür, dass ein Kollege oder eine spätere Version des Setups exakt dieselbe Paketkombination reproduzieren kann. Gerade bei einem Framework, das sich wie FastChat schnell weiterentwickelt, ist das kein optionaler Schritt, sondern die Grundlage für nachvollziehbare Ergebnisse.

Schritt 1 und 2: Python-Umgebung einrichten und FastChat installieren

Lege zunächst eine isolierte virtuelle Umgebung an, damit die Arena-Abhängigkeiten nicht mit anderen Projekten kollidieren. Danach klonst du das FastChat-Repository und installierst es im editierbaren Modus mit den Zusatzpaketen für Model Worker und Web-UI.

# Schritt 1: Virtuelle Umgebung anlegen
python3 -m venv llm-arena-env
source llm-arena-env/bin/activate
python3 -m pip install --upgrade pip

# Schritt 2: FastChat aus dem Quellcode installieren
git clone https://github.com/lm-sys/FastChat.git
cd FastChat
pip3 install -e ".[model_worker,webui]"

Alternativ funktioniert auch die direkte PyPI-Installation mit pip3 install "fschat[model_worker,webui]", allerdings hinkt das veröffentlichte Paket dem Quellcode oft hinterher. Wer zusätzlich die Auswertungsfunktionen für automatisiertes Richten (LLM-as-Judge) nutzen möchte, installiert stattdessen mit dem Extra llm_judge anstelle von webui. Prüfe nach der Installation mit python3 -c "import fastchat; print(fastchat.__version__)", ob das Paket sauber geladen wird, bevor du fortfährst.

Schritt 3 und 4: Controller starten und ersten Model Worker registrieren

FastChats Arena-Architektur besteht aus drei Prozessen: einem Controller, der als zentrale Registrierungsstelle dient, einem oder mehreren Model Workern, die die eigentlichen Anfragen verarbeiten, und der Web-UI, die Nutzer sehen. Starte zuerst den Controller in einem eigenen Terminal-Fenster oder als Hintergrundprozess.

# Schritt 3: Controller starten
python3 -m fastchat.serve.controller --host 0.0.0.0 --port 21001

# Schritt 4: Ersten lokalen Model Worker registrieren (Terminal 2)
python3 -m fastchat.serve.model_worker \
  --model-path lmsys/vicuna-7b-v1.5 \
  --controller-address http://localhost:21001 \
  --port 31000 \
  --worker-address http://localhost:31000

Für dieses erste lokale Modell nennt die FastChat-Dokumentation als historisches Referenzbeispiel rund 14 GB GPU-Speicher für die 7B-Variante von Vicuna und rund 28 GB für die 13B-Variante. Für aktuelle, quantisierte 7B- bis 8B-Modelle liegt der reale Bedarf heute oft deutlich niedriger, hängt aber stark vom gewählten Quantisierungsformat, der Kontextlänge und der Inferenz-Engine ab. Miss den tatsächlichen Speicherbedarf für dein Modell lieber selbst mit nvidia-smi, statt dich auf einen pauschalen Richtwert zu verlassen.

Schritt 5 und 6: Arena-Web-UI starten und zweites Modell hinzufügen

Mit laufendem Controller und mindestens einem Worker startest du die Gradio-basierte Arena-Oberfläche. Sie zeigt zwei Antwortfenster nebeneinander, ordnet die Modelle bei jeder Runde zufällig links oder rechts an und blendet die Namen erst nach der Abstimmung ein.

# Schritt 5: Arena-UI starten (Terminal 3)
python3 -m fastchat.serve.gradio_web_server_multi \
  --controller-url http://localhost:21001 \
  --share

# Schritt 6: Zweiten Worker auf anderem Port registrieren (Terminal 4)
python3 -m fastchat.serve.model_worker \
  --model-path mistralai/Mistral-7B-Instruct-v0.3 \
  --controller-address http://localhost:21001 \
  --port 31001 \
  --worker-address http://localhost:31001

Der Parameter --share erzeugt einen temporären öffentlichen Gradio-Link, praktisch für einen schnellen Test, aber für den Produktivbetrieb ungeeignet, weil die Verbindung nicht durch eure eigene Zugriffskontrolle läuft. Für interne Tests solltest du stattdessen einen Reverse Proxy mit Basic Auth oder SSO davorschalten und den Parameter weglassen. Sobald zwei Worker beim Controller registriert sind, zeigt die UI beide Modelle als wählbare Kandidaten für den Blind-Vergleich an.

Schritt 7 und 8: API-Modelle einbinden (DeepSeek, Gemini, Claude)

Der eigentliche Mehrwert einer eigenen Arena zeigt sich, wenn proprietäre API-Modelle gegen offene Gewichte antreten. FastChat unterstützt das über eine api_endpoints.json-Konfigurationsdatei, in der jedes API-Modell mit einer eigenen Provider-Funktion registriert wird, statt über einen lokalen Model Worker zu laufen.

// api_endpoints.json
{
  "deepseek-v4.1-flash": {
    "model_name": "deepseek-v4.1-flash",
    "api_base": "https://api.deepseek.com/v1",
    "api_key": "DEEPSEEK_API_KEY",
    "anony_only": false,
    "context_length": 131072
  },
  "gemini-3.8-flash": {
    "model_name": "gemini-3.8-flash",
    "api_base": "https://generativelanguage.googleapis.com/v1beta",
    "api_key": "GEMINI_API_KEY",
    "anony_only": false,
    "context_length": 131072
  },
  "claude-opus-5.5": {
    "model_name": "claude-opus-5.5",
    "api_base": "https://api.anthropic.com/v1",
    "api_key": "ANTHROPIC_API_KEY",
    "anony_only": false,
    "context_length": 131072
  }
}

Setze die tatsächlichen Kontextfenster-Werte auf das, was der jeweilige Anbieter aktuell offiziell dokumentiert, die Werte oben sind bewusst konservativ gewählt und dienen nur als Platzhalter für die Anfragelogik. Starte die UI anschließend mit dem Zusatzparameter --register-api-endpoint-file api_endpoints.json. API-Schlüssel gehören dabei niemals direkt in die Datei, sondern in Umgebungsvariablen, die die Datei zur Laufzeit referenziert. Nutze für produktive Setups einen Secrets-Manager statt Klartext-Dateien auf der Festplatte.

Docker-Deployment: Arena im Team gemeinsam betreiben

Sobald mehrere Kollegen gleichzeitig abstimmen sollen, lohnt sich ein zentraler Server statt einer lokalen Entwicklermaschine. Ein einfacher Weg dahin führt über Docker Compose, das Controller, Worker und UI als getrennte Dienste startet und über ein gemeinsames Netzwerk verbindet.

# docker-compose.yml
services:
  controller:
    build: .
    command: python3 -m fastchat.serve.controller --host 0.0.0.0 --port 21001
    ports:
      - "21001:21001"

  arena-ui:
    build: .
    command: >
      python3 -m fastchat.serve.gradio_web_server_multi
      --controller-url http://controller:21001
      --register-api-endpoint-file config/api_endpoints.json
    ports:
      - "7860:7860"
    depends_on:
      - controller
    env_file:
      - .env

Die Datei .env enthält die API-Schlüssel als Umgebungsvariablen und wird über .gitignore vom Repository ausgeschlossen. Das Docker-Image selbst baust du aus einem schlanken Python-3.11-Basis-Image mit den gleichen Installationsbefehlen aus Schritt 2. Für interne Nutzer reicht danach ein Reverse Proxy mit TLS-Zertifikat und Basic Auth vor Port 7860, damit die Arena nicht offen im Netz erreichbar ist.

Wächst das Team oder steigt die Zahl der gleichzeitig laufenden Duelle, lässt sich der Controller unverändert lassen und stattdessen die Anzahl der Worker-Container horizontal erhöhen. Jeder zusätzliche Worker meldet sich beim selben Controller mit eigenem Port an, sodass mehrere Instanzen desselben Modells parallel Anfragen bedienen können. Für ein kleines internes Setup mit fünf bis zehn gleichzeitigen Testern reicht in der Regel ein einzelner Worker pro Modell, größere Rollouts mit mehreren Abteilungen profitieren dagegen von zwei oder drei Workern je stark genutztem Modell, um Warteschlangen zu vermeiden.

Schritt 9 und 10: Eigene deutschsprachige Testkategorien anlegen

Ein generischer Prompt-Pool bringt wenig, wenn du wissen willst, wie sich ein Modell im deutschen Geschäftsalltag schlägt. Lege deshalb eigene Kategorien an und sammle pro Kategorie mindestens 15 bis 20 Prompts, damit die spätere Auswertung statistisch tragfähig ist.

# test_prompts_de.py
KATEGORIEN = {
    "recht_compliance": [
        "Fasse diese DSGVO-Auftragsverarbeitungsvereinbarung in 5 Punkten zusammen.",
        "Erkläre den Unterschied zwischen Art. 6 und Art. 9 DSGVO in einfacher Sprache.",
    ],
    "code_refactoring": [
        "Refaktoriere diese Python-Funktion für bessere Lesbarkeit, ohne das Verhalten zu ändern.",
        "Finde den Bug in diesem SQL-Statement und erkläre die Ursache.",
    ],
    "kundensupport_dach": [
        "Formuliere eine höfliche Antwort auf eine Reklamation zu einer verspäteten Lieferung nach Österreich.",
        "Übersetze diese technische Fehlermeldung in verständliches Deutsch für Endkunden.",
    ],
    "long_context": [
        "Lies dieses 40-seitige Whitepaper und liste alle genannten Risiken mit Seitenzahl auf.",
    ],
}

Speichere zu jedem Prompt zusätzlich Metadaten wie Kategorie, Schwierigkeitsgrad und ob eine referenzierbare Musterantwort existiert. Diese Metadaten brauchst du später, um die Ratings nicht nur global, sondern auch pro Kategorie zu berechnen, denn ein Modell kann bei Long-Context-Aufgaben führen und bei Recht-Prompts zurückfallen. Ein einziges globales Rating würde diesen Unterschied verschleiern.

Für DACH-Unternehmen lohnt sich zusätzlich eine eigene Kategorie für regionale Sprachvarianten. Ein Modell, das bei Standarddeutsch überzeugt, liefert bei Schweizerdeutsch-Anfragen oder österreichischem Amtsdeutsch teils spürbar schwächere Ergebnisse. Wer Kundenkontakt in mehreren deutschsprachigen Ländern hat, sollte diese Variante explizit als eigene Kategorie führen, statt sie unter „Kundensupport“ zu vermischen. So zeigt die spätere Auswertung klar, ob ein Modell für den gesamten DACH-Raum geeignet ist oder nur für den deutschen Markt.

Schritt 11 und 12: Voting-Daten auswerten und Bradley-Terry-Rating berechnen

Jede Abstimmung in der Arena-UI landet standardmäßig in einer JSONL-Logdatei. Für die Auswertung genügt ein kompaktes eigenes Skript, das die Bradley-Terry-Stärken per iterativer Maximum-Likelihood-Schätzung berechnet, ganz ohne externe Rating-Bibliothek.

# bradley_terry.py
import json
from collections import defaultdict
import numpy as np

def lade_votes(pfad):
    duelle = []
    with open(pfad, encoding="utf-8") as f:
        for zeile in f:
            eintrag = json.loads(zeile)
            if eintrag.get("winner") in ("model_a", "model_b", "tie"):
                duelle.append(eintrag)
    return duelle

def bradley_terry_mm(duelle, iterationen=200):
    modelle = sorted({d["model_a"] for d in duelle} | {d["model_b"] for d in duelle})
    idx = {m: i for i, m in enumerate(modelle)}
    staerke = np.ones(len(modelle))

    for _ in range(iterationen):
        zaehler = np.zeros(len(modelle))
        nenner = np.zeros(len(modelle))
        for d in duelle:
            a, b = idx[d["model_a"]], idx[d["model_b"]]
            gewichte_summe = staerke[a] + staerke[b]
            if d["winner"] == "model_a":
                zaehler[a] += 1
            elif d["winner"] == "model_b":
                zaehler[b] += 1
            else:
                zaehler[a] += 0.5
                zaehler[b] += 0.5
            nenner[a] += staerke[a] / gewichte_summe
            nenner[b] += staerke[b] / gewichte_summe
        staerke = zaehler / np.maximum(nenner, 1e-9)
        staerke /= staerke.sum()

    rating = {m: round(1000 + 400 * np.log10(staerke[idx[m]] * len(modelle)), 1) for m in modelle}
    return dict(sorted(rating.items(), key=lambda x: -x[1]))

if __name__ == "__main__":
    duelle = lade_votes("arena_votes.jsonl")
    print(bradley_terry_mm(duelle))

Der Minorization-Maximization-Algorithmus (MM) konvergiert für Datensätze mit einigen hundert Duellen meist nach 100 bis 200 Iterationen zuverlässig. Die letzte Zeile skaliert die rohen Stärkewerte auf eine Elo-ähnliche Anzeige-Skala, damit die Zahlen intuitiv vergleichbar sind. Wichtig: Mit weniger als etwa 30 Duellen pro Modellpaar bleiben die Konfidenzintervalle so breit, dass Rangunterschiede von wenigen Punkten reine Zufallsstreuung sein können. Plane für belastbare Ergebnisse mindestens 300 bis 500 Duelle über alle Modellpaare hinweg ein.

Komplettes Beispielprojekt: Vier aktuelle Modelle im Blind-Test

Um alle bisherigen Schritte zusammenzuführen, folgt hier ein durchgängiges Beispiel mit vier aktuellen Modellen: DeepSeek V4.1 Flash (veröffentlicht am 10. September 2026, rund 1 Million Token Kontextfenster, etwa 0,20 US-Dollar je Million Input-Token und 0,60 US-Dollar je Million Output-Token), Gemini 3.8 Flash (veröffentlicht am 2. September 2026, rund 1.048.576 Token Kontextfenster, etwa 0,75 US-Dollar je Million Input-Token und 3,75 US-Dollar je Million Output-Token), Claude Opus 5.5 (veröffentlicht am 22. September 2026, rund 1 Million Token Kontextfenster, etwa 4 US-Dollar je Million Input-Token und 20 US-Dollar je Million Output-Token) sowie ein viertes Modell aus der GPT-6-Generation von OpenAI als Vergleichspunkt.

Die Projektstruktur gliedert sich in vier Ordner: config/ für die api_endpoints.json und Umgebungsvariablen, prompts/ für die kategorisierten deutschen Testfragen aus Schritt 9, logs/ für die von der Arena erzeugten JSONL-Voting-Dateien und analysis/ für das Bradley-Terry-Skript aus Schritt 11.

llm-arena-projekt/
├── config/
│   ├── api_endpoints.json
│   └── .env
├── prompts/
│   └── test_prompts_de.py
├── logs/
│   └── arena_votes.jsonl
├── analysis/
│   └── bradley_terry.py
├── docker-compose.yml
└── requirements-arena.txt

Nach rund 60 Testrunden mit fünf internen Testern über zwei Wochen könnte eine beispielhafte Auswertung so aussehen. Die Zahlen in der folgenden Tabelle sind illustrative Platzhalter aus einem Testlauf und ersetzen keine eigene Messung.

ModellArena-Rating (Beispiel)DuelleStärkste Kategorie
Claude Opus 5.5118792Recht & Compliance
Gemini 3.8 Flash114288Long-Context-Auswertung
DeepSeek V4.1 Flash110890Code-Refactoring
GPT-6-Modell109685Kundensupport DACH

Entscheidend ist nicht die Rangfolge selbst, sondern die Streuung pro Kategorie. In diesem Beispiel würde ein Team, das vorrangig Compliance-Texte verarbeitet, eine andere Wahl treffen als ein Team mit Fokus auf Long-Context-Dokumentenanalyse, obwohl das globale Rating eine klare Reihenfolge suggeriert. Genau dieser Effekt geht in einem einzelnen aggregierten Benchmark-Score verloren, taucht in einer kategorisierten Arena-Auswertung aber sofort auf.

Häufige Stolperfallen beim Arena-Aufbau

  • Zu wenige Duelle pro Modellpaar: Unter 30 Vergleichen pro Paar sind Ranganpassungen oft reines Rauschen. Plane die Testphase entsprechend länger ein, statt nach einem Tag ein Ergebnis zu verkünden.
  • Reihenfolge-Bias ignoriert: Wird Modell A immer links angezeigt, bevorzugen Tester messbar häufiger die linke Seite. FastChats UI randomisiert das automatisch, ein selbst gebautes UI muss das explizit nachbilden.
  • API-Schlüssel im Klartext committed: Die api_endpoints.json landet schnell versehentlich im Git-Repository. Nutze eine .gitignore-Regel und Umgebungsvariablen von Anfang an.
  • Prompts ohne Kategorien gesammelt: Ohne Metadaten lässt sich später nicht mehr rekonstruieren, warum ein Modell in bestimmten Situationen schlechter abschneidet.
  • Tester kennen die Modellnamen vorab: Sobald im Team bekannt ist, wer welches Modell testet, verzerrt Markenpräferenz die Abstimmung. Halte auch die Konfiguration vor den Testern selbst geheim.
  • Kontextfenster-Werte aus Beispielcode ungeprüft übernommen: Die Platzhalterwerte aus Schritt 7 gehören durch die aktuellen, offiziell dokumentierten Werte des jeweiligen Anbieters ersetzt, bevor lange Dokumente getestet werden.

Troubleshooting: Die häufigsten Probleme und Lösungen

Auch bei sorgfältiger Vorbereitung tauchen beim Arena-Betrieb wiederkehrende Fehler auf. Die folgende Übersicht sammelt die häufigsten Fälle aus der Praxis mit FastChat-basierten Setups und ordnet jedem Problem eine konkrete, sofort umsetzbare Lösung zu, damit du nicht selbst im FastChat-Quellcode nach der Ursache suchen musst.

  • Worker erscheint nicht in der UI: Prüfe mit curl http://localhost:21001/list_models, ob der Controller den Worker überhaupt registriert hat. Häufigste Ursache ist eine falsche --controller-address beim Worker-Start.
  • Gradio-UI lädt, zeigt aber keine Modelle: Der Cache der UI aktualisiert sich nicht automatisch bei jedem neuen Worker. Ein Neustart der Gradio-Instanz nach dem Hinzufügen weiterer Modelle behebt das in den meisten Fällen.
  • API-Modell antwortet mit Timeout: Prüfe zuerst, ob der API-Schlüssel noch gültig ist, und danach, ob das Rate-Limit des jeweiligen Anbieters erreicht wurde. Viele Anbieter drosseln neue Accounts in den ersten Tagen stärker.
  • CUDA out of memory beim lokalen Worker: Reduziere die Kontextlänge oder wechsle auf ein quantisiertes GGUF- oder AWQ-Modell mit kleinerem Speicherbedarf, statt die Batch-Größe blind zu erhöhen.
  • Bradley-Terry-Skript konvergiert nicht: Meist liegt es an zu wenigen Duellen für ein bestimmtes Modellpaar, wodurch die MM-Iteration instabil wird. Stelle sicher, dass jedes Modell gegen jedes andere mindestens einige Male angetreten ist.
  • Voting-Log bleibt leer: Kontrolliere die Schreibrechte im Log-Verzeichnis und ob die UI im richtigen Modus (nicht im reinen Vorschau-Modus) läuft.
  • Zwei Modelle liefern identische Antworten: Bei sehr deterministischen Einstellungen mit Temperatur 0 und einfachen Prompts kann das vorkommen. Erhöhe die Temperatur leicht oder nutze anspruchsvollere Prompts für aussagekräftigere Unterschiede.
  • Reverse Proxy blockiert Server-Sent Events: Streaming-Antworten brechen ab, wenn der vorgeschaltete Proxy Buffering für die Antwort aktiviert hat. Deaktiviere Buffering für den entsprechenden Pfad explizit in der Proxy-Konfiguration.
  • Rating schwankt stark zwischen zwei Auswertungsläufen: Setze einen festen Zufalls-Seed für die Initialisierung und prüfe, ob zwischen den Läufen neue Duelle hinzugekommen sind, die die Verteilung verschieben.
  • Docker-Container startet, aber UI ist von außen nicht erreichbar: Prüfe, ob der Port im docker-compose.yml korrekt nach außen gemappt ist und ob eine Firewall-Regel oder Security Group den Zugriff blockiert. Ein häufiger Fehler ist ein Port-Mapping, das nur innerhalb des Docker-Netzwerks, aber nicht auf dem Host-Interface bindet.

Fortgeschrittene Tipps: Kategorien, Caching und DSGVO-konformes Logging

Sobald die Grundversion läuft, lohnen sich drei Erweiterungen. Erstens: gewichtete Kategorien. Nicht jede Kategorie ist gleich wichtig für dein Geschäft, also kannst du das finale Rating als gewichteten Durchschnitt der Kategorie-Ratings berechnen, statt alle Duelle undifferenziert in einen Topf zu werfen.

Zweitens: Prompt-Caching für wiederholte Präfixe. Wenn mehrere Testrunden auf demselben langen Dokument aufbauen, reduziert Prompt-Caching bei den meisten Anbietern die Kosten für wiederholte Kontextteile spürbar. Das lohnt sich besonders bei Long-Context-Kategorien, in denen dasselbe 40-seitige Dokument gegen mehrere Modelle getestet wird.

Drittens: DSGVO-konformes Logging. Sobald echte Kundendaten oder personenbezogene Informationen in Testprompts vorkommen, brauchst du eine klare Löschfrist für die JSONL-Logs, eine Zugriffskontrolle auf das Log-Verzeichnis und im Zweifel eine Anonymisierung der Prompt-Inhalte vor der Speicherung. Ziehe bei sensiblen Datenkategorien frühzeitig eure Datenschutzbeauftragte hinzu, bevor die Arena in den produktiven Testbetrieb geht. Wer zusätzlich prüfen will, wie stabil das Setup gegenüber manipulierten Eingaben ist, sollte die Arena-Prompts auch gegen bekannte Prompt-Injection-Muster testen, bevor interne Nutzer freien Zugriff erhalten.

Ein vierter, fortgeschrittener Punkt betrifft die Unsicherheit im Rating selbst. Statt nur eine einzelne Zahl auszugeben, lohnt sich ein Bootstrap-Verfahren: Ziehe aus den vorhandenen Duellen mehrfach zufällige Teilmengen mit Zurücklegen, berechne für jede Teilmenge ein eigenes Bradley-Terry-Rating und betrachte anschließend die Streuung dieser wiederholten Berechnungen. Überschneiden sich die resultierenden Wertebereiche zweier Modelle deutlich, ist der beobachtete Rangunterschied statistisch nicht gesichert, selbst wenn die Punktwerte auf den ersten Blick klar getrennt aussehen.

Kosten und Zeitaufwand realistisch einschätzen

Bevor du ein Arena-Projekt aufsetzt, lohnt sich ein nüchterner Blick auf den tatsächlichen Aufwand. Die technische Einrichtung ist in wenigen Stunden erledigt, der größere Kostenblock entsteht bei den API-Aufrufen und bei der Zeit der Tester.

PostenGeschätzter AufwandAnmerkung
Technisches Setup (Schritte 1 bis 8)1 bis 2 StundenEinmalig, bei bekannter Docker-Umgebung schneller
Prompt-Sammlung (Schritt 9)2 bis 4 StundenAbhängig von Anzahl der Kategorien
API-Kosten pro 100 DuelleWenige US-Dollar bis niedriger zweistelliger BetragStark abhängig von Prompt-Länge und gewählten Modellen
Testerzeit für 300 bis 500 Duelle1 bis 2 Wochen bei 5 TesternParallel zum Tagesgeschäft realistisch
Auswertung (Schritt 11 und 12)Wenige MinutenLäuft automatisiert über das Bradley-Terry-Skript

Der größte Hebel zur Kostensenkung liegt in der Prompt-Länge. Lange Dokumente in der Kategorie Long-Context treiben die Token-Kosten pro Duell deutlich nach oben, während kurze Support- oder Recht-Prompts kaum ins Gewicht fallen. Wer das Budget knapp halten muss, testet lange Dokumente zuerst mit wenigen, dafür sorgfältig ausgewählten Modellkandidaten, statt von Anfang an alle vier Modelle gegen jedes lange Dokument antreten zu lassen.

Wichtiger als die reinen API-Kosten ist am Ende die vermiedene Fehlentscheidung. Ein Modellwechsel, der erst nach der Einführung in der Produktion auffällt, kostet in der Regel ein Vielfaches dessen, was eine zwei Wochen dauernde Arena-Testphase im Vorfeld gekostet hätte. Betrachte die Testphase deshalb nicht als zusätzlichen Aufwand, sondern als vergleichsweise günstige Versicherung gegen eine teure Fehlentscheidung bei der Modellwahl.

LLM Arena vs. Standard-Benchmark: Kosten, Zeit und Aussagekraft im Vergleich

Beide Ansätze haben ihren Platz, aber sie beantworten unterschiedliche Fragen zu unterschiedlichen Kosten. Ein standardisierter Benchmark mit einer Harness wie lm-evaluation-harness läuft vollautomatisch durch und liefert reproduzierbare Zahlen in wenigen Stunden. Eine Arena braucht Menschen, die Zeit investieren, dafür aber ein Urteil, das näher an der echten Nutzung liegt.

KriteriumStandard-BenchmarkEigene LLM Arena
Zeitaufwand bis erstes ErgebnisWenige Stunden, vollautomatischMehrere Tage bis Wochen, abhängig von Testerzahl
PersonalaufwandGering, einmalige KonfigurationFortlaufend, echte Abstimmungen nötig
Aussagekraft für FachaufgabenBegrenzt auf definierte TestsätzeHoch, wenn eigene Prompts verwendet werden
ReproduzierbarkeitSehr hoch bei fixierten SeedsMittel, abhängig von Testerpool und Prompt-Set
Eignung für proprietäre API-ModelleMöglich, aber oft teurer bei großen TestsätzenGut geeignet, da gezielt wenige Prompts pro Duell nötig sind

In der Praxis bewährt sich eine Kombination: den automatisierten Benchmark als schnellen Vorfilter nutzen, um offensichtlich schwache Kandidaten früh auszusortieren, und die Arena erst für die verbliebenen zwei bis vier ernsthaften Kandidaten einsetzen. Das spart Testerzeit und liefert trotzdem ein belastbares, alltagsnahes Ergebnis am Ende des Auswahlprozesses.

Häufig gestellte Fragen

Brauche ich zwingend eine GPU, um eine eigene LLM Arena zu betreiben?

Nein. Eine reine API-Variante mit DeepSeek, Gemini und Claude läuft komplett ohne eigene GPU, weil die Inferenz beim jeweiligen Anbieter stattfindet. Eine GPU wird nur nötig, wenn zusätzlich lokal gehostete offene Modelle als Vergleichspunkt mitlaufen sollen.

Wie viele Duelle brauche ich für ein statistisch belastbares Rating?

Als grobe Faustregel gelten mindestens 30 direkte Duelle pro Modellpaar, insgesamt also 300 bis 500 Duelle bei vier Modellen, was bei sechs möglichen Modellpaaren rein rechnerisch etwa 50 bis 85 Duelle je Paar bedeutet. Darunter bleiben die Konfidenzintervalle so breit, dass kleine Rangunterschiede kaum interpretierbar sind. Nutze das Bootstrap-Verfahren aus dem Abschnitt zu den fortgeschrittenen Tipps, um die tatsächliche Unsicherheit für dein konkretes Datenset zu prüfen, statt dich allein auf eine pauschale Faustregel zu verlassen.

Kann ich meine private Arena mit dem öffentlichen LMArena-Leaderboard vergleichen?

Nur eingeschränkt. Die absoluten Rating-Zahlen sind nicht direkt übertragbar, weil sie von der jeweiligen Testerpopulation und dem Prompt-Mix abhängen. Sinnvoll ist der Vergleich der relativen Rangfolge zwischen den Modellen, nicht der exakten Punktzahl.

Ist FastChat für den produktiven internen Einsatz kostenlos nutzbar?

FastChat steht unter der Apache-2.0-Lizenz, die eine kommerzielle Nutzung grundsätzlich erlaubt. Kosten entstehen ausschließlich durch die angebundenen API-Modelle sowie durch eigene Infrastruktur, nicht durch das Framework selbst.

Wie unterscheidet sich eine LLM Arena von einem klassischen A/B-Test?

Ein A/B-Test misst meist ein einzelnes Geschäftsziel wie Klickrate über einen längeren Zeitraum mit vielen Nutzern. Die Arena misst eine direkte, blinde Präferenzentscheidung zwischen zwei Antworten im selben Moment, was schneller belastbare Signale liefert, aber kein Verhalten über die Zeit abbildet.

Was mache ich, wenn zwei Modelle in meiner Kategorie fast gleich abschneiden?

Prüfe die Konfidenzintervalle statt nur den Punktwert. Liegen sie deutlich überschneidend, entscheidet oft der Preis pro Million Token oder die Latenz über die praktische Wahl, nicht das Rating allein.

Lässt sich die Arena auch für die Bewertung von fine-getunten eigenen Modellen nutzen?

Ja, ein eigenes fine-getuntes Modell lässt sich wie jedes andere lokale Modell als Worker registrieren und direkt gegen kommerzielle API-Modelle testen. Das ist einer der häufigsten Anwendungsfälle für eine private Arena in Unternehmen.

Wie lange dauert der komplette Aufbau laut diesem Tutorial?

Die technische Einrichtung aus den zwölf Schritten lässt sich in 60 bis 90 Minuten abschließen. Die anschließende Sammlung von 300 bis 500 belastbaren Duellen nimmt je nach Teamgröße eher ein bis zwei Wochen in Anspruch.

Lohnt sich eine eigene Arena auch für ein kleines Team ohne dediziertes ML-Budget?

Ja, gerade bei der reinen API-Variante ohne eigene GPU bleiben die laufenden Kosten überschaubar. Ein kleines Team mit drei bis fünf Testern kann in ein bis zwei Wochen genug Duelle sammeln, um eine fundierte Modellentscheidung für die eigene Anwendung zu treffen, ohne in eigene Infrastruktur zu investieren.