Token导航 LogoToken导航TokenDH.com
MCP Speaker Diarization logo
音视频stdio官方级别未说明来源级核验

MCP Speaker Diarization

MCP Server

GPU加速的说话人分割、转录和情感识别服务,支持REST API和WebSocket流式传输。

工具数

11

提示词数

0

GitHub Stars

5

资源数

0
语音识别PythonClaude情感分析Claude DesktopClaude

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

作者 / 组织

snailbrainx

提供方

snailbrainx

最后核验

2026/5/17 20:19

运行时

Python

快速接入

先看主来源和安装命令,再打开仓库或文档;下面只保留这个条目的关键接入事实。

命令预览

python -m venv venv && source venv/bin/activate

详细介绍

扬声器日记服务器

![License: MIT](https://opensource.org/licenses/MIT) ![Python 3.11+](https://www.python.org/downloads/) ![CUDA 12.8](https://developer.nvidia.com/cuda-toolkit)

GPU通过REST API、WebSocket流和用于AI代理的MCP服务器加速了说话者的日记化、转录和情绪识别。将pyannote.audio+更快的耳语+emotion2vec组合成一个FastAPI服务,在对话中保持说话者身份。

截图

示例 Next.js前端:

Voice Profile Management

Process Audio

Conversation Detail

Conversations List

Speaker Management

Live Recording

特性

  • 持续的说话者身份 --注册一次语音,在未来的每次录音中都能识别。
  • 追溯更新 --识别一个片段,并自动重新标记该语音的每个过去片段。
  • 转录 --更快的耳语(large-v3-turbo 默认值,任何Whisper变体),单词级时间戳,99种语言。
  • 双探测器情绪识别 --emotion2vec+(通用)与每个说话者的语音配置文件(个性化)相结合。9个类别。
  • 直播 --使用VAD门控段刷新进行WebSocket音频摄取。
  • 批量处理 --用于批量摄取的多GPU脚本(run_batch.sh).
  • REST API/api/v1/* 交互式Swagger文档位于 /docs.
  • MCP服务器/mcp (JSON-RPC 2.0/HTTP)为Claude Desktop、Flowise或任何MCP客户端提供了11个工具。
  • 备份/恢复 --将扬声器+分段+设置导出为JSON配置文件和检查点。
  • SQLite WAL --处理数千个并发读取的对话。

技术栈

组件实施
差异化 pyannote/speaker-diarization-community-1 (pyannote.audio 4.0.1)
扬声器嵌入pyannote/embedding (512-D)
转录更快的耳语1.2.1/C翻译2, large-v3-turbo 默认值
情感通过FunASR获取情感2vec_plus_large(1024-D,9个类别)
APIFastAPI 0.115.5+WebSockets+uvicorn
数据库SQLAlchemy 2.0/SQLite(WAL)
ML运行时PyTorch 2.10+CUDA 12.8(Blackwell/RTX 5090 sm_120 准备就绪)
MCP传输JSON-RPC 2.0通过HTTP(+可选SSE),无外部MCP库

需求

  • GPU: NVIDIA搭载CUDA 12.x。已在RTX 3090(24 GB)和RTX 5090上测试。如果您选择较小的Whisper型号,则可以在6 GB+卡上运行。
  • VRAM球场: 2-3GB的日记/嵌入+2GB的emotion2vec+耳语(0.5-4GB,取决于型号)。 large-v3-turbo +情感总计≈6-7GB。
  • 操作系统: Linux(在Ubuntu上测试)。macOS/Windows通过Docker桌面+WSL2。
  • 其他: ffmpeg、git。Python 3.11或3.12,如果在Docker之外运行。
  • 拥抱脸令牌 接受pyannote条款(见下文)。

快速开始

1.拥抱脸部通道

在以下位置创建帐户+令牌 huggingface.co/settings/tokens,然后接受以下条款:

2.Docker(推荐)

git clone https://github.com/snailbrainx/speaker-diarization-server.git
cd speaker-diarization-server
cp .env.example .env           # then edit .env and set HF_TOKEN
docker compose up --build      # first run downloads ~3-5 GB of models

3.地方发展

sudo apt-get install -y ffmpeg git
python -m venv venv && source venv/bin/activate
pip install -r requirements.txt
cp .env.example .env           # edit HF_TOKEN
./run_local.sh

4.验证

  • Swagger用户界面: http://:8418/docs
  • 健康: curl http://:8418/api/v1/status
  • MCP: http://:8418/mcp

远程访问

没有内置身份验证。为远程主机使用SSH隧道:

ssh -L 8418:localhost:8418 user@host

对于网络部署,将其置于反向代理(nginx+HTTPS+auth)之后。浏览器中的WebSocket麦克风捕获 需要HTTPS/WSS --地点 cert.pem/key.pemcerts/ 服务器自动以HTTPS模式启动。

配置

所有配置都是环境变量(请参见 .env.example 对于策划的列表)。一切都是可选的,除了 HF_TOKEN.

必需

变量目的
HF_TOKEN用于pyannote模型访问的HuggingFace令牌

存储和网络

变量默认值用途
DATABASE_URLsqlite:////app/volumes/speakers.dbSQLAlchemy URL。默认情况下采用Docker卷布局。
DATA_PATH./data录制、流片段、临时文件的根。
VOLUMES_PATH./volumesDB+模型缓存的根。
PORT8418HTTP/HTTPS端口
CORS_ORIGINS*(未设置)*逗号分隔的起源。留空仅供内部使用。
LOG_LEVELINFOPython日志级别。

语音和情感调节(也可在运行时通过以下方式编辑 /api/v1/settings/voice)

变量默认值用途
SPEAKER_THRESHOLD0.30扬声器匹配的余弦阈值。降低→ 更严格。
CONTEXT_PADDING0.15嵌入前在片段周围添加的音频秒数。
SILENCE_DURATION0.5流媒体:刷新片段前的几秒钟静音。
FILTER_HALLUCINATIONStrue放下耳语填充短语(“谢谢”等)。
EMOTION_THRESHOLD0.6全球情绪匹配敏感度。更高→ 更严格。

模型

变量默认值用途
WHISPER_MODELlarge-v3-turbo任何更快的耳语型号ID。请参阅 .env.example.
WHISPER_LANGUAGEenauto 用于99语言检测或ISO-639代码。
EMOTION_MODELiic/emotion2vec_plus_largeFunASR情感模型ID
ENABLE_PERSONALIZED_EMOTIONStrue在情绪匹配中使用每个说话者的语音配置文件。
OFFLINE_MODEfalse仅强制缓存模型;永远不要撞到轮毂。

图形处理器

变量默认值用途
CUDA_VISIBLE_DEVICES*(未设置)*选择物理GPU。 0, 0,2等等。
CUDA_DEVICE_ORDERPCI_BUS_ID被钉住 run_local.shdocker-compose.yml 所以指数匹配 nvidia-smi 而不是CUDA的“最快第一”改组。
CLEANUP_VRAM_THRESHOLD_GB12仅当分配的内存超过此值时,才运行VRAM清理循环。

原理

upload / WS chunk
      │
      ▼
┌─────────────────┐   ┌──────────────────┐
│ Whisper         │   │ pyannote         │
│ transcription   │   │ diarization      │   run in parallel
│ (text + words)  │   │ (speaker turns)  │   (ThreadPoolExecutor)
└────────┬────────┘   └────────┬─────────┘
         └────────────┬────────┘
                      ▼
        segment alignment by timestamp
                      │
                      ▼
        pyannote embedding (512-D) per segment
                      │
                      ▼
        cosine match vs known speaker profiles
        │                              │
        ▼                              ▼
   known speaker                 Unknown_NN  (auto-enrolled)
                      │
                      ▼
        emotion2vec (1024-D) + optional voice-profile emotion match
                      │
                      ▼
             ConversationSegment  →  SQLite (WAL)

关键行为:

  • 平行耳语+pyannote --比顺序快约2倍。
  • 上下文填充 --片段每侧0.15秒的音频使嵌入对背景噪声具有鲁棒性。
  • 自动注册 --不明声音 Unknown_N 立即分析,以便他们积累样本。重命名/识别和每个过去 Unknown_N 分段重新标记。
  • 错误识别的标志 --标记的细分市场 is_misidentified 不包括嵌入平均值,保持配置文件干净。
  • 双探测器情绪 --emotion2vec总是运行;如果说话者对一种情绪有≥3个语音样本,则语音简档检测器也会运行。根据确定性的决胜规则,最佳比赛获胜。
  • 个性化学习 --用户情绪校正将1024-D情绪嵌入和512-D语音嵌入与加权平均合并到说话者的简档中。

情感识别

类别(9)

emotion2vec+large将每个片段分为以下标签之一:

angry · disgusted · fearful · happy · neutral · other · sad · surprised · unknown

双探测器决策

每个片段都运行着emotion2vec基础检测器。如果扬声器有 ≥3个用户校正样本 对于任何情绪,每个说话者的第二个语音简档检测器都会并行运行。这两个分数相加:

案例最终情绪
只有emotion2vec有一场自信的比赛
emotion2vec回归 neutral 或 ``neutral
两个探测器都同意一致的情绪(更高的置信度)
探测器不一致neutral (保守派的退路)
语音轮廓检测器获胜(≥阈值)轮廓获胜者

服务器从两个检测器返回原始分数,以便客户端可以根据需要覆盖回退。

个性化流程

  1. 用户上传音频→ 段7被标记 neutral emotion2vec的置信度为0.94。
  2. 用户不同意, POST /api/v1/conversations/{id}/segments/7/correct-emotion 随着 {"emotion_category": "surprised"}.
  3. 服务器同时存储 1024-D情感向量嵌入 和那个 512-D pyannote语音嵌入 进入演讲者的 surprised 轮廓,与任何先前样本平均(EWMA风格)。
  4. 一旦该简档达到3个样本,语音简档检测器就会为该说话者的未来片段激活。
  5. 当后面的片段具有相似的声音特征时,声音轮廓检测器返回 surprised 超过阈值,赢得了emotion2vec的猜测。

还设置了更正 emotion_corrected=true 因此,它们被排除在个性化训练循环之外(没有反馈污染)。

示例——双探测器输出

来自一段10秒的大笑片段,该说话者之前没有语音配置文件:

{
  "text": "Oh my god that is funny. Oh wow. Oh that's brilliant.",
  "emotion_category": "neutral",
  "emotion_confidence": 0.937,
  "detector_breakdown": {
    "emotion2vec_detector": { "emotion": "surprised", "confidence": 0.937 },
    "voice_profile_detector": null,
    "final_decision": {
      "emotion": "neutral",
      "confidence": 0.937,
      "reason": "Disagree: surprised vs neutral",
      "voice_profile_available": false
    }
  }
}

emotion2vec说 *惊讶的* 但是个性化检测器不可用(还没有3+个样本),因此服务器退回到 neutral经过三次修正后 surprised 对于这位演讲者,轮廓检测器会同意,最终的决定也会改变。

REST API

完整的交互式文档,请访问 /docs (Swagger用户界面)。OpenAPI JSON位于 /openapi.json.端点组:

  • GET /api/v1/status --健康+GPU。
  • GET/POST /api/v1/speakers, PATCH/DELETE /api/v1/speakers/{id} --演讲者CRUD、注册、重命名。
  • GET /api/v1/speakers/{id}/emotion-profiles,每种情绪阈值——情绪档案CRUD。
  • GET/POST /api/v1/conversations, PATCH/DELETE /api/v1/conversations/{id} --对话CRUD。
  • POST /api/v1/conversations/{id}/reprocess, POST /api/v1/conversations/{id}/recalculate-emotions --重新运行管道。
  • POST /api/v1/conversations/{id}/segments/{sid}/{identify,correct-emotion}, PATCH .../misidentified --分段校正。
  • GET /api/v1/conversations/segments/{sid}/audio --提取分段音频。
  • POST /api/v1/process --上传并处理整个文件。
  • GET/POST /api/v1/settings/voice, POST /api/v1/settings/voice/reset --运行时可调语音设置。
  • GET/POST /api/v1/profiles,检查点,下载,导入,还原--备份/还原。
  • WS /api/v1/streaming/ws --实时音频摄取。

示例——上传+处理

curl -X POST http://localhost:8418/api/v1/process \
  -F "audio_file=@meeting.wav"

响应(为了可读性,修剪成一段):

{
  "id": 42,
  "title": "Uploaded: meeting.wav",
  "duration": 137.39,
  "status": "completed",
  "num_segments": 24,
  "num_speakers": 2,
  "transcript_segments": [
    {
      "id": 911,
      "conversation_id": 42,
      "speaker_id": 17,
      "speaker_name": "Unknown_1776798145477718",
      "text": "Call me Ishmael. Some years ago, never mind how long precisely...",
      "start_offset": 0.05,
      "end_offset": 6.71,
      "confidence": 1.0,
      "emotion_category": "neutral",
      "emotion_confidence": 1.0,
      "emotion_corrected": false,
      "emotion_misidentified": false,
      "detector_breakdown": null,
      "words": [
        { "word": " Call",    "start": 0.05, "end": 0.57, "probability": 0.91 },
        { "word": " me",      "start": 0.57, "end": 0.75, "probability": 0.99 },
        { "word": " Ishmael.","start": 0.75, "end": 1.37, "probability": 0.99 }
      ]
    }
  ]
}

身份不明的声音会自动注册为 Unknown_ 因此它们积累样本。追溯重命名:

# Identify an unknown speaker (retroactively labels every past segment with that voice)
curl -X POST http://localhost:8418/api/v1/conversations/42/segments/911/identify \
  -H 'Content-Type: application/json' \
  -d '{"speaker_name": "Alice", "enroll": true}'

# Correct an emotion (feeds personalization)
curl -X POST http://localhost:8418/api/v1/conversations/42/segments/911/correct-emotion \
  -H 'Content-Type: application/json' \
  -d '{"emotion_category": "surprised"}'

MCP服务器

基于HTTP的JSON-RPC 2.0 /mcp兼容Claude Desktop、Flowise和任何符合规范的客户端。

{
  "mcpServers": {
    "speaker-diarization": {
      "url": "http://localhost:8418/mcp",
      "transport": "http"
    }
  }
}

十一种工具: list_conversations, get_conversation, get_latest_segments, list_speakers, rename_speaker, delete_speaker, delete_all_unknown_speakers, identify_speaker_in_segment, update_conversation_title, reprocess_conversation, search_conversations_by_speaker所有突变(识别/重命名)都会追溯更新过去的片段,因此AI不必手动协调身份。

数据持久层

speaker-diarization-server/
├── data/
│   ├── recordings/           # permanent audio (uploads + concatenated streams)
│   ├── stream_segments/      # per-conversation live-segment WAVs
│   └── temp/                 # transient
├── volumes/
│   ├── speakers.db           # SQLite (WAL)
│   └── huggingface_cache/    # pyannote + Whisper + emotion2vec
└── backups/
    ├── profile_.json            # full speaker + segment + settings snapshot
    └── checkpoint__.json    # timestamped state capture

Docker绑定挂载 ./volumes, ./data, ./backups,以及 ./certs (只读)放入容器中。两次跑步之间没有其他东西。

故障排除

“未找到HuggingFace令牌” --确认 HF_TOKEN.env,无引号/空格,接受模型术语。

“无法加载libcunn_cnn.so.9”run_local.shLD_LIBRARY_PATH 自动。手册: pip install nvidia-cudnn-cu12==9.* nvidia-cublas-cu12.

Docker权限错误 data/, volumes/, backups/ --容器以uid 1000运行。如果您的主机uid不同, sudo chown -R 1000:1000 data/ volumes/ backups/ 一次。

Docker GPU不可见 --验证 docker run --rm --gpus all nvidia/cuda:12.4.0-base-ubuntu22.04 nvidia-smi 作品;如果没有,请重新安装NVIDIA容器工具包。

选择了错误的GPU --set CUDA_VISIBLE_DEVICES 以匹配 nvidia-smi 你想要的索引; CUDA_DEVICE_ORDER=PCI_BUS_ID 已经为你钉好了。

“CUDA内存不足” --开关 WHISPER_MODEL 到一个较小的变体(smallbase)或提高 CLEANUP_VRAM_THRESHOLD_GB 因此,清理工作更加频繁。

无法识别说话者 --注册时提供10-30秒的纯净音频。降低 SPEAKER_THRESHOLD 对于具有挑战性的音频(电影、音乐),约为0.20。

浏览器麦克风不工作 --WebSocket麦克风捕获需要HTTPS。生成证书/密钥或将其放入 certs/.

许可证

麻省理工学院——见 LICENSE所有捆绑的依赖项(pyannote.audio、快速耳语、FastAPI、PyTorch、SQLAlchemy、Pydantic)都在MIT或BSD下。pyannote 模型 要求HuggingFace账户+代币+条款接受;该软件仍然是开源的。

学分

计划的

  • 人工智能在定稿时生成对话摘要和标题。
  • 在转录本上进行矢量搜索,以查找语义对话。

免责声明

按原样提供,不提供任何保证。说话人识别是概率性的——手动验证重要身份,并在记录其他身份之前获得同意。该代码库的部分内容与AI助手进行了配对编程;在关键设置中部署之前进行审查。

目录标签

目录标签

语音识别PythonClaude情感分析本地部署多说话人分割GPU加速语音转文字

支持客户端

Claude DesktopClaude

接入字段

传输方式(transport,传输协议)

stdio

鉴权方式(authType,认证方式)

none

运行时(runtime,运行环境)

Python

工具数量(toolCount,工具数)

11

资源数量(resourceCount,资源数)

0

提示词数量(promptCount,提示词数)

0

权限和风险

stdionone部署方式未说明

接入前请确认传输方式、认证方式和部署位置,并根据实际工具能力限制访问范围。

安装前确认

不要直接授予不必要的文件、网络或账号权限;先核对安装命令和配置内容。

来源信息

继续浏览同类 MCP