Selbst gehostetes Open-Source-LLM für DiscourseAI

Das Discourse AI-Plugin verfügt über viele Funktionen, die ein LLM erfordern, um aktiviert zu werden – Zusammenfassung, AI Helper, semantische Suche, AI Bot und dessen Agents. Du kannst eine API von Drittanbietern nutzen, wie API-Schlüssel für OpenAI konfigurieren oder API-Schlüssel für Anthropic konfigurieren, aber Discourse AI wurde von Anfang an so entwickelt, dass du nicht an diese Anbieter gebunden bist.

Dieser Leitfaden behandelt die lokale Bereitstellung eines offenen Modells (Open-Weight) und dessen Verbindung zu Discourse.

Hier verwendetes Modell: Qwen/Qwen3.8-27B – ein dichtes 27B-Modell, das im August 2026 veröffentlicht wurde. Es verfügt über ein natives Kontextfenster von 256K, Bild-/Videoverständnis, Tool-Aufrufe (Tool Calling) und einen standardmäßig aktivierten Denkmodus. Es ist derzeit der ideale Kompromiss für selbst gehostete Umgebungen: stark genug für echte Zusammenfassungs-/Agent-Arbeiten und klein genug für eine einzelne GPU. Ersetze es durch ein anderes Modell deiner Wahl; die Flags, die sich ändern, sind unten aufgeführt.

Was Discourse von deinem Inferenzserver benötigt

  • Ein OpenAI-kompatibler POST /v1/chat/completions-Endpunkt (Streaming unterstützt).
  • Natives Tool-/Function Calling, wenn AI Bot, Agents oder strukturierte Ausgaben gut funktionieren sollen. Ohne dies fällt Discourse auf XML-basierte Tool-Aufrufe zurück, die von schwächeren Modellen schlecht verarbeitet werden.
  • Ein echtes Kontextfenster – strebe mindestens 16K Tokens an, bevorzugt 32K+. Die Prompt-Größen von Discourse für Zusammenfassungen und RAG (Retrieval-Augmented Generation) wachsen schnell.
  • Optional: Bildeingabe, wenn das Modell Bilder lesen soll, die an Beiträge angehängt sind.

Alles, was die ersten drei Punkte erfüllt, funktioniert. Die Wahl unten hängt daher tatsächlich von deiner Hardware ab.

Setup Geeignet für
vLLM Dedizierter GPU-Server, ≥24GB VRAM (quantisiert) / 80GB (volle Präzision), anhaltender Traffic, mehrere Benutzer
llama.cpp Consumer-GPUs, Apple Silicon, rein CPU-basierte Systeme, einzelne kleine Foren
Gemanagt / Cloud Du möchtest das Modell nicht auf deinem Laptop hosten, aber auch nicht auf deiner eigenen Hardware: jeder OpenAI-kompatible Endpunkt

Bereitstellung mit vLLM

vLLM ist die empfohlene Engine für GPU-Server: Apache-lizenziert, OpenAI-kompatibler Server out-of-the-box und erstklassige Unterstützung für die Qwen-Familie.

mkdir -p /opt/vllm-cache
export VLLM_API_KEY="$(openssl rand -hex 24)"

docker run -d --name vllm \
  --runtime nvidia --gpus all \
  -v /opt/vllm-cache:/root/.cache/huggingface \
  -e HF_HOME=/root/.cache/huggingface \
  -e "HF_TOKEN=${HF_TOKEN}" \
  -p 8080:8000 \
  --ipc=host \
  vllm/vllm-openai:latest \
  Qwen/Qwen3.8-27B \
  --host 0.0.0.0 \
  --port 8000 \
  --max-model-len 32768 \
  --reasoning-parser qwen3 \
  --enable-auto-tool-choice \
  --tool-call-parser qwen3_xml \
  --api-key "$VLLM_API_KEY"

Hinweise zu den Flags:

  • --max-model-len begrenzt den Kontext für Prompt+Ausgabe und somit den KV-Cache. Das Modell unterstützt native 256K; 32K sind für Foren-Arbeit ausreichend und halten den VRAM-Verbrauch vorhersehbar. Erhöhe diesen Wert (oder verwende auto), wenn du genug Speicher hast.
  • --reasoning-parser qwen3 trennt das Denken des Modells in ein separates reasoning-Feld, anstatt es in die Antwort zu werfen. Du musst diese Wahl in den Discourse-LLM-Einstellungen spiegeln (siehe unten).
  • --enable-auto-tool-choice --tool-call-parser ... aktiviert natives Function Calling. Die Namen der Parser ändern sich zwischen vLLM-Releases – prüfe python3 -m vllm.entrypoints.openai.api_server --help in deinem Image, wenn Tool-Aufrufe als reiner Text zurückkommen.
  • HF_TOKEN ist nur für gesperrte Modelle (Gated Models) erforderlich; --api-key schützt deinen eigenen Endpunkt. Caveat aus der vLLM-Dokumentation: --api-key schützt nur die /v1-Routes, also halte den Server weiterhin vom öffentlichen Internet fern.
  • Wenig VRAM? Probiere --quantization fp8 (oder ein vorgequantisiertes AWQ-Checkpoint), bevor du den Kontext reduzierst. Multi-GPU: füge --tensor-parallel-size N hinzu.

Teste es:

curl http://localhost:8080/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $VLLM_API_KEY" \
  -d '{
    "model": "Qwen/Qwen3.8-27B",
    "messages": [{"role": "user", "content": "What is Discourse?"}],
    "max_tokens": 200
  }'

Du solltest einen normalen Chat-Completion-JSON-Body zurückbekommen, mit message.reasoning neben message.content.

Bereitstellung mit llama.cpp

llama.cpp ist das richtige Werkzeug, wenn das Modell weniger VRAM verbrauchen muss, als vLLM bevorzugen würde, oder wenn du Apple Silicon, AMD, Vulkan oder CPU nutzt. Sein llama-server stellt ebenfalls eine OpenAI-kompatible API bereit.

Ziehe den offiziellen GGUF-Build und führe ihn mit dem Container-Image für dein Backend aus (server-cuda hier; server, server-rocm, server-vulkan usw. existieren ebenfalls):

export LLAMA_API_KEY="$(openssl rand -hex 24)"

docker run -d --name llama-server \
  --gpus all \
  -p 8080:8080 \
  -v /opt/llama-models:/models \
  ghcr.io/ggml-org/llama.cpp:server-cuda \
  -hf ggml-org/Qwen3.8-27B-GGUF:Q4_K_M \
  --host 0.0.0.0 \
  --port 8080 \
  --alias qwen3.8-27b \
  --api-key "$LLAMA_API_KEY" \
  --ctx-size 16384 \
  --n-gpu-layers auto \
  --flash-attn auto \
  --jinja \
  --reasoning auto
  • Q4_K_M benötigt etwa 16GB Gewichte; gemessen werden ca. 18,4 GiB VRAM bei 8K-Kontext und ~20 GiB bei 32K, sodass eine 24GB-Karte mit einem moderaten --ctx-size funktioniert. Unloth’s unsloth/Qwen3.8-27B-GGUF:UD-Q4_K_M ist eine beliebte Alternative.
  • --jinja verwendet das eigene Chat-Template des Modells – das ist es, was natives Tool Calling ermöglicht.
  • --alias setzt den Namen, den die API berichtet, sodass der Modellname, den du in Discourse eingibst, übereinstimmt.
  • --reasoning auto berichtet das Denken separat und entspricht damit dem Verhalten von vLLM’s --reasoning-parser.
  • Für Bildeingaben wird der multimodale Projektor benötigt; mit -hf wird er normalerweise automatisch abgerufen, andernfalls übergebe --mmproj /models/mmproj-...gguf (oder --no-mmproj, um VRAM für reine Textausgabe zu sparen).

Teste es:

curl http://localhost:8080/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $LLAMA_API_KEY" \
  -d '{
    "model": "qwen3.8-27b",
    "messages": [{"role": "user", "content": "What is Discourse?"}],
    "max_tokens": 200
  }'

Etwas anderes bereitstellen

Jeder Server, der OpenAI Chat Completions spricht – SGLang, TensorRT-LLM, LM Studio, ein Enterprise-Gateway, eine Cloud-dedizierte Bereitstellung – funktioniert wie er ist: Konfiguriere ihn in Discourse mit dem vLLM-Provider, unserer generischen OpenAI-kompatiblen Client-Lösung mit nativer Tool-Unterstützung.

Wenn du die Inferenz lieber nicht selbst betreiben möchtest, aber trotzdem die Abhängigkeit von großen API-Anbietern vermeiden willst, funktionieren Hugging Face Inference Endpoints (die jetzt standardmäßig vLLM als Engine nutzen) mit dem Hugging Face-Provider – zeige auf die /v1/chat/completions-URL des Endpunkts.

Es deiner Discourse-Instanz verfügbar machen

Du wirst dies normalerweise aufgrund der GPU-Anforderungen auf einer dedizierten Maschine betreiben. Wenn du das tust:

  1. Stelle einen Reverse Proxy vor den Server und beende dort TLS – Discourse kommuniziert gerne HTTPS damit.
  2. Beschränke den Endpunkt durch Firewall oder Client-Zertifikate, sodass nur deine Discourse-Hosts eine Verbindung herstellen können. Ein API-Key ist Authentifizierung, keine Netzwerkbarriere.
  3. Halte den Modell-Cache auf einem persistenten Volume, damit bei Neustarts nicht Dutzende von Gigabytes erneut heruntergeladen werden.

Discourse AI konfigurieren

LLM-Verbindungen werden über die Admin-Oberfläche konfiguriert, nicht über Site-Einstellungen. Gehe zu /admin/plugins/discourse-ai/ai-llms und füge ein neues LLM hinzu:

  1. Anzeigename – was deine Admins und Benutzer sehen.
  2. Name – wird in der API-Anfrage gesendet; muss mit dem übereinstimmen, was der Server erwartet (Qwen/Qwen3.8-27B für vLLM, dein --alias für llama.cpp).
  3. Provider – vLLM für vLLM, llama.cpp und jeden anderen OpenAI-kompatiblen Server; Hugging Face für HF-gehostete Endpunkte.
  4. URL – die vollständige Endpunkt-URL inklusive Pfad, z. B. https://llm.example.com/v1/chat/completions.
  5. API-Key – gib ihn ein oder verweise auf einen gespeicherten Schlüssel auf der Seite „AI Secrets“.
  6. Tokenizer – Qwen für Qwen3.8 (wähle den Tokenizer, der zu deiner Modellfamilie passt).
  7. Max Prompt Tokens / Max Output Tokens – halte die Summe unter oder gleich dem --max-model-len / --ctx-size deines Servers. Beispiel bei einem 32768-Token-Server: 28000 Prompt und 4096 Output. Reasoning-Modelle verbrauchen einen Teil dieses Ausgabe-Budgets für das Denken, also übe keinen zu starken Druck aus.
  8. Vision – aktiviere natives Vision, wenn du das Modell mit Bildunterstützung bereitgestellt hast und möchtest, dass es Bilder liest.
  9. Provider-Optionen (vLLM): Setze vLLM reasoning parser auf qwen3, damit es mit dem Server-Flag übereinstimmt, und nutze die Felder für Thinking-Override / Reasoning-Intensität / Thinking-Token-Budget, wenn du möchtest, dass Discourse das Denken pro Anfrage steuert. Lass „Disable native tools“ deaktiviert, es sei denn, die Function Calling-Funktion des Modells ist defekt.

Klicke auf Test ausführen vor dem Speichern: Es sendet sowohl eine Streaming- als auch eine Nicht-Streaming-Anfrage und teilt dir mit, welche fehlgeschlagen ist.

Nach dem Speichern mache es zum Site-Standard mit der Site-Einstellung ai_default_llm_model, oder weise es jeder Funktion unter /admin/plugins/discourse-ai/ai-features zu. Individuelle Agents werden auf der Agents-Seite konfiguriert.

Ein Caveat: Semantische Such-Einbettungen (Embeddings) stammen nicht von diesem Modell. Embeddings verwenden ihr eigenes Embedding-Modell, das separat konfiguriert wird (ein API-Embedding-Modell oder ein selbst gehosteter Text Embeddings Inference-Server über die ai_hugging_face_tei_endpoint-Einstellungen). Wenn du AI Search vollständig selbst hosten möchtest, starte ein kleines Embedding-Modell wie bge-m3 neben deinem LLM.

Fehlersuche

Symptom Wahrscheinliche Ursache
404 vom Endpunkt URL fehlt /v1/chat/completions
model not found Name stimmt nicht mit der bereitgestellten Modell-ID / dem --alias überein
401 / 403 API-Key-Abweichung zwischen --api-key und dem LLM-Eintrag
Tool-Aufrufe erscheinen als JSON-Text im Beitrag Server wurde ohne Tool-Call-Parsing gestartet; Discourse fiel auf XML-Tools zurück
Denketext „leckt“ in die Antwort --reasoning-parser fehlt auf dem Server, oder die Discourse-Reasoning-Parser-Einstellung stimmt nicht damit überein
CUDA out of memory Reduziere --max-model-len, füge --quantization fp8 hinzu oder reduziere --gpu-memory-utilization
Requests laufen bei langen Zusammenfassungen in den Timeout Reasoning-Modelle sind langsam; unser HTTP-Timeout beträgt 6 Minuten – reduziere den Kontext, senke die Thinking-Intensität oder deaktiviere Thinking
Abgeschnittene Antworten max output tokens in Discourse ist zu klein, wenn Thinking-Tokens mitgezählt werden
17 „Gefällt mir“

Für alle, die dieses Thema mit/für suchen:
#Llava-Api-keys

Ich benutze auch vLLM. Ich würde auch das OpenChat v3.5 0106-Modell empfehlen, ein Modell mit 7 Milliarden Parametern, das sehr gut funktioniert.

Ich lasse es tatsächlich in 4-Bit quantisiert laufen, damit es schneller läuft.

Ich weise diese Aufgabe einem Praktikanten zu. Gibt es Empfehlungen von jemandem, für welchen spezifischen Dienst er sich anmelden soll? Dies ist für einen Test. Der Praktikant hat derzeit einen Test mit OpenAI konfiguriert. Es funktioniert gut. Er ist daran interessiert, den HuggingFace TGI auszuprobieren, aber es scheint, dass ich ihm einen dedizierten Server mit GPU geben muss? Was sind die minimalen Spezifikationen für einen Test?

Gibt es Links, die ich dem Praktikanten geben kann?

Ich habe mich noch nicht eingehend mit diesem Projekt befasst. Ich antizipiere nur, dass der Praktikant einige Ressourcen benötigen wird, und ich versuche, einige vernünftige Empfehlungen zu Diensten für den Praktikanten bei der Recherche zu geben.

Hallo, während der Bereitstellung mit einem selbstsignierten Zertifikat vllm-Container auf einer GPU-Box on-prem, habe ich keine gute Möglichkeit gefunden, die Root CA zum Discourse-Container hinzuzufügen, damit er sicher auf diesen On-Prem-Dienst über HTTPS zugreifen kann.

z.B.:

./launcher enter app
curl -L https://vllm.infra.example.com/v1/models
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.se/docs/sslcerts.html

curl konnte die Legitimität des Servers nicht überprüfen und konnte daher keine sichere Verbindung zu ihm herstellen. Weitere Informationen zu dieser Situation und wie Sie sie beheben können, finden Sie auf der oben genannten Webseite.

Gibt es eine gute Möglichkeit, ein selbstsigniertes Root-CA-Zertifikat in den Discourse-Container einzufügen, das Container-Image-Updates übersteht?

Soweit ich weiß, würde das Hinzufügen in der app.yml

run:
  - exec: wget ... && update-ca-certificates

nur beim Erstellen/Neuerstellen der App gut funktionieren.

Jeder Hinweis ist willkommen.

14 Beiträge wurden in ein neues Thema aufgeteilt: Getting discourse ai to work with ollama locally

Gäbe es eine Möglichkeit, den Discourse AI-Anfragen einen benutzerdefinierten HTTP-Header hinzuzufügen? Wir haben einen Server mit GPU-Ausstattung, den wir für verschiedene Zwecke nutzen. Er verfügt über eine OpenAI-kompatible API, die wir jedoch aus Sicherheitsgründen hinter einem API-Management-Gateway platziert haben, welches einen benutzerdefinierten HTTP-Header (etwas wie SubscriptionKey) erfordert, und wir übergeben unseren Authentifizierungsschlüssel hier.

Beachten Sie, dass dieser Authentifizierungsschlüssel für die Durchreise durch den APIM dient und sich von dem API-Schlüssel unterscheidet, den man für einen Dienst wie die OpenAI API übergeben würde.

Es wäre großartig, wenn es eine Möglichkeit gäbe, benutzerdefinierte Header in der Einrichtung jedes LLM auf der Seite admin/plugins/discourse-ai/ai-llms hinzuzufügen. Vielleicht eine Option „Benutzerdefiniert“ im Dropdown-Menü „Anbieter“ mit zusätzlichen Optionen für Anwendungsfälle wie diesen?

1 „Gefällt mir“

Die schnelle Antwort ist ein Plugin, um diesen Header hinzuzufügen. Eine Übergangslösung könnte ein lokaler Proxy-Server sein, den Sie von Discourse aus ansprechen würden und der den Header hinzufügt und die Daten zurück an Discourse weiterleitet. Eine unbestätigte Quelle deutet darauf hin, dass Sie NGINX dazu bringen könnten, dies für Sie mit etwas wie

server {
    listen 80;
    
    location / {
        proxy_pass https://api.example.com;
        proxy_set_header SubscriptionKey xyz;
        proxy_set_header Host $host;
    }
}

Es könnte einen cleveren Weg geben, dies zur NGINX-Konfiguration von Discourse an einem geheimen Pfad hinzuzufügen (der auch nur auf Ihren Server hört).

1 „Gefällt mir“

Hallo,

Ich kann diese Einstellungen nicht finden:

Gibt es einen Vorschlag, wie ich die KI-Übersetzungsfunktion mit einem Ollama-Backend ausprobieren kann?

Erstelle eine neue LLM unter /admin/plugins/discourse-ai/ai-llms/new?llmTemplate=none, wähle OpenAI als Anbieter, da Ollama OpenAI compatibility - Ollama unterstützt.

1 „Gefällt mir“

Danke! Mir ist auch aufgefallen, dass die URL nur funktioniert, wenn das AI-Plugin aktiviert ist :person_facepalming:

Für den neu hinzugefügten Anbieter, habt ihr Vorschläge, was man für die folgenden erforderlichen Einstellungen wählen/einstellen sollte?

  1. Tokenizer
  2. Kontextfenster

Für das Modell dachte ich vielleicht an stablelm2:1.6b oder translategemma:4b, aber ich bin mir noch nicht sicher.
In der README des letzteren gibt es eine Beschreibung eines Eingabe-Prompts. Ich frage mich, welche Abfrage die Übersetzungs-AI-Funktion an Ollama sendet. s. /admin/plugins/discourse-ai/ai-agents/-28/edit

:sweat_smile:

Am nächsten zum Modell, das du auswählst. Für Gemma kannst du den von Gemini verwenden.

Hier legst du den maximalen Kontext deiner Bereitstellung fest.

Bitte nicht. Dieses Modell ist sehr, sehr, sehr, sehr, sehr alt. Es ist die schlechteste Wahl, die du treffen kannst.

Dieses Modell ist eine Generation zurück und hat sehr strenge Prompt-Anforderungen, die nicht mit Discourse kompatibel sind. Wir erwarten ein Standard-LLM für allgemeine Zwecke.

In dieser Größenordnung empfehle ich entweder Qwen 3.5 oder Gemma 4.

3 „Gefällt mir“

Nochmal vielen Dank. Ich habe die Einstellungen vorgenommen, das Modell heruntergeladen, den Agenten angepasst und die KI-Übersetzungsfunktion gestartet. Mal sehen, was dabei herauskommt.

Noch eine Frage. Wir haben zuvor das Übersetzer-Plugin mit einer großzügig bereitgestellten LibreTranslate-Instanz verwendet. Ist es nicht möglich, die Discourse-KI-Übersetzungsfunktion an diesen LibreTranslate-Endpunkt anzubinden? Letztendlich wäre das viel einfacher, als eine Ollama-Instanz auf einem Server ohne echte LLM-Fähigkeiten hosten zu müssen.

Warum nutzt ihr das dann nicht einfach weiter? Wir aktualisieren es zwar nicht mehr, aber es wird weiterhin so funktionieren, wie es ist.

Die Discourse AI-Übersetzung arbeitet mit einer völlig anderen Reihe von Einschränkungen als das ursprüngliche Translator-Plugin, daher haben wir es von Grund auf neu entwickelt, um dieser neuen Welt gerecht zu werden, in der LLM-basierte Übersetzungen besser und günstiger sind als das, was zuvor mit ML-Übersetzungs-APIs möglich war.

1 „Gefällt mir“