Selbsthosteter Discourse AI Sentiment: GPU- und CPU-Optionen

# Selbsthosteter Discourse AI Sentiment: GPU- und CPU-Optionen

Einrichtung der Stimmungs- und Emotionsanalyse von Posts in Discourse AI über den selbsthosteten HuggingFace Text Embeddings Inference (TEI).

Was ist das

Sentiment in Discourse AI ist kein chat/completions LLM. Unter der Haube laufen zwei kleine klassifizierende RoBERTa-Modelle (~125 Mio. Parameter jedes), die über HuggingFace TEI ausgeführt werden. Die Modellnamen sind im Code verankert und können in SQL-Abfragen der Discourse-Dashboards nicht geändert werden.

Quelle: Self-Hosting Sentiment and Emotion for DiscourseAI (Falco, Discourse-Team).

Modell model_name (genau wie im Code) Zweck
Sentiment cardiffnlp/twitter-roberta-base-sentiment-latest positive / negative / neutral
Emotion SamLowe/roberta-base-go_emotions 28 Emotionen (joy, anger, surprise…)

API-Format: POST {\"inputs\": \"text\", \"truncate\": true} → Array [{\"label\": \"...\", \"score\": 0.95}, ...]

Besonderheit: Das Modell cardiffnlp hat keinen tokenizer.json

TEI erfordert tokenizer.json, aber cardiffnlp/twitter-roberta-base-sentiment-latest hat keinen (alter Format: vocab.json + merges.txt). Lösung: Laden Sie die Modell-Dateien lokal herunter und fügen Sie tokenizer.json aus SamLowe/roberta-base-go_emotions hinzu (gleicher RoBERTa-base Tokenizer).

Vorbereitung (einmalig)

sudo mkdir -p /opt/tei-sentiment-cache/model
cd /opt/tei-sentiment-cache/model

for f in config.json vocab.json merges.txt special_tokens_map.json pytorch_model.bin; do
  sudo curl -sL -o "$f"     "https://huggingface.co/cardiffnlp/twitter-roberta-base-sentiment-latest/resolve/main/$f"
done

sudo curl -sL -o tokenizer.json   "https://huggingface.co/SamLowe/roberta-base-go_emotions/resolve/main/tokenizer.json"
sudo curl -sL -o tokenizer_config.json   "https://huggingface.co/SamLowe/roberta-base-go_emotions/resolve/main/tokenizer_config.json"

Variante A: GPU

Bild: ghcr.io/huggingface/text-embeddings-inference:cuda-1.9.3

Der Standard-Tag :latest (und :1.9) wurde für compute cap 80 (Ampere) kompiliert und funktioniert nicht auf Blackwell (RTX 50x0, compute cap 120). Verwenden Sie genau cuda-1.9.3

docker pull ghcr.io/huggingface/text-embeddings-inference:cuda-1.9.3
sudo mkdir -p /opt/tei-emotion-cache

docker run -d --name tei-sentiment   --gpus all --shm-size 1g   -p 8081:80   -v /opt/tei-sentiment-cache/model:/data/model   --restart unless-stopped   ghcr.io/huggingface/text-embeddings-inference:cuda-1.9.3   --model-id /data/model

docker run -d --name tei-emotion   --gpus all --shm-size 1g   -p 8082:80   -v /opt/tei-emotion-cache:/data   --restart unless-stopped   ghcr.io/huggingface/text-embeddings-inference:cuda-1.9.3   --model-id SamLowe/roberta-base-go_emotions

Erster Start auf Blackwell: Die JIT-Kompilierung der CUDA-Kerne dauert ca. 5 Minuten pro Container. Dies ist einmalig.

Leistung GPU (RTX 5060 Ti)

Metrik Wert
Sentiment-Inferenz ~14ms
Emotion-Inferenz ~60ms
VRAM pro Container ~428 MB
VRAM insgesamt ~856 MB

Variante B: CPU (Fallback)

Bild: ghcr.io/huggingface/text-embeddings-inference:cpu-1.9

Geeignet, wenn kein GPU verfügbar ist oder nicht genügend VRAM vorhanden ist. Erfordert keine NVIDIA-Treiber.

docker pull ghcr.io/huggingface/text-embeddings-inference:cpu-1.9
sudo mkdir -p /opt/tei-emotion-cache

docker run -d --name tei-sentiment   --shm-size 1g   -p 8081:80   -v /opt/tei-sentiment-cache/model:/data/model   --restart unless-stopped   ghcr.io/huggingface/text-embeddings-inference:cpu-1.9   --model-id /data/model --dtype float32

docker run -d --name tei-emotion   --shm-size 1g   -p 8082:80   -v /opt/tei-emotion-cache:/data   --restart unless-stopped   ghcr.io/huggingface/text-embeddings-inference:cpu-1.9   --model-id SamLowe/roberta-base-go_emotions --dtype float32
```Bei hohem LA kann der CPU-Beschleunigung eingeschränkt werden:

```bash
docker update --cpus=0.1 tei-sentiment tei-emotion

CPU-Leistung

Metrik Wert
Sentiment-Inferenz ~270 ms
Emotion-Inferenz ~205 ms
RAM pro Container ~500 MB
Mit --cpus=0.1 ~2–3 Sekunden pro Beitrag

Wechsel GPU ↔ CPU

docker stop tei-sentiment tei-emotion
docker rm tei-sentiment tei-emotion

Starten Sie anschließend die Container entsprechend Ihrer Wahl. Es müssen keine Einstellungen in Discourse geändert werden – die Endpoints bleiben gleich.

Prüfung

curl -s http://localhost:8081/   -X POST -H 'Content-Type: application/json'   -d '{"inputs": "I am happy"}'

curl -s http://localhost:8082/   -X POST -H 'Content-Type: application/json'   -d '{"inputs": "I am happy"}'

Erwarteter Antwortwert für Sentiment: [{\"label\":\"positive\",\"score\":0.96},...]

Discourse-Einstellungen

In /admin/plugins/discourse-ai/settings?filter=sentiment:

  1. discourse_ai_enabled = true
  2. ai_sentiment_enabled = true
  3. ai_sentiment_model_configs – zwei Objekte:
Feld Modell 1 Modell 2
model_name cardiffnlp/twitter-roberta-base-sentiment-latest SamLowe/roberta-base-go_emotions
endpoint http://<your-host>:8081 http://<your-host>:8082
api_key (leer) (leer)

Dashboards

  • /admin/reports/overall_sentiment – allgemeines Stimmungsbild (positive – negative)
  • /admin/reports/emotion_joy (und weitere 27 Emotionen)
  • Backfill: ~2500 Beiträge pro Stunde, Beiträge nicht älter als 60 Tage

Bedingungen und Risiken

  • Die Modelle wurden auf Englisch trainiert. Für russischen Text ist das Ergebnis nur approximativ, aber der grundlegende Sentiment-Test funktioniert.
  • Der Endpoint ist ohne API-Key offen – für Produktivumgebungen sollte er über einen Reverse-Proxy geschützt werden.
  • VRAM-Monitoring: nvidia-smi --query-compute-apps=pid,name,used_memory --format=csv,noheader