自托管 Discourse AI 情感分析:GPU 与 CPU 方案

# 自托管 Discourse AI 情感分析:GPU 与 CPU 方案

通过自托管 HuggingFace 文本嵌入推理(TEI) 实现 Discourse AI 中帖子的情感与情绪分析。

什么是它

Discourse AI 中的 Sentiment 并非聊天/生成式 LLM。其底层是两个小型的 分类 RoBERTa 模型(每个约 1.25 亿参数),通过 HuggingFace TEI 启动。模型名称已在 Discourse 的仪表板 SQL 查询中硬编码,不可更改。

来源:Self-Hosting Sentiment and Emotion for DiscourseAI(Falco,Discourse 团队)。

模型 model_name(必须与代码中一致) 用途
Sentiment cardiffnlp/twitter-roberta-base-sentiment-latest 正面 / 负面 / 中性
Emotion SamLowe/roberta-base-go_emotions 28 种情绪(喜悦、愤怒、惊讶等)

API 格式:POST {\"inputs\": \"text\", \"truncate\": true} → 返回数组 [{\"label\": \"...\", \"score\": 0.95}, ...]

特殊说明:cardiffnlp 模型无 tokenizer.json

TEI 需要 tokenizer.json,但 cardiffnlp/twitter-roberta-base-sentiment-latest 没有(旧格式为 vocab.json + merges.txt)。解决方案:本地下载模型文件,并从 SamLowe/roberta-base-go_emotions 中复制 tokenizer.json(二者使用相同的 RoBERTa-base 分词器)。

准备(仅需一次)

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"

方案 A:GPU

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

标准标签 :latest(及 :1.9)编译用于 compute cap 80(Ampere),不兼容 Blackwell(RTX 50x0,compute cap 120)。请务必使用 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

在 Blackwell 上首次运行时,CUDA 内核的 JIT 编译约需 5 分钟(仅首次运行)

GPU 性能(RTX 5060 Ti)

指标
Sentiment 推理 约 14ms
Emotion 推理 约 60ms
单容器显存占用 约 428 MB
两个容器总显存占用 约 856 MB

方案 B:CPU(备用)

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

适用于无 GPU 或显存不足的情况,无需 NVIDIA 驱动。

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
```当 LA 较高时,可以限制 CPU:

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

CPU 性能

指标 数值
情感推理 ~270ms
情绪推理 ~205ms
容器内存 ~500 MB
使用 --cpus=0.1 每条帖子约 2-3 秒

切换 GPU ↔ CPU

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

然后根据需要启动容器。无需更改 Discourse 设置 —— endpoint 保持不变。

验证

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

预期情感响应:[{"label":"positive","score":0.96},...]

Discourse 设置

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

  1. discourse_ai_enabled = true
  2. ai_sentiment_enabled = true
  3. ai_sentiment_model_configs - 两个对象:
字段 模型 1 模型 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 (空) (空)

仪表板

  • /admin/reports/overall_sentiment —— 整体情绪(积极 - 消极)
  • /admin/reports/emotion_joy(及其他 27 种情绪)
  • 数据回填:约 2500 条帖子/小时,帖子不超过 60 天

条件与风险

  • 模型仅在 英文 上训练。对于俄语文本,结果为近似值,但基础情感分析仍可运行。
  • Endpoint 未启用 API 密钥保护 —— 生产环境建议通过反向代理关闭。
  • 显存监控:nvidia-smi --query-compute-apps=pid,name,used_memory --format=csv,noheader