RepoDaily · 2026-07-30 · Infrastructure / Runtime

Hugging Face speech-to-speech:兼容 OpenAI Realtime 的模块化本地语音管线

#5 Infrastructure / Runtime Python +837 huggingface/speech-to-speech 打开仓库

一个 Apache-2.0 的语音代理运行时,把 VAD、STT、LLM、TTS 串成一条 WebSocket 服务,并以 OpenAI Realtime 协议对外暴露,已有 Realtime 客户端无需重写即可接入。

项目类型Infrastructure / Runtime
最适合需要自托管、又希望兼容 OpenAI Realtime 客户端的团队,或希望在不重写对话主循环的前提下替换 STT/LLM/TTS 单个阶段的团队。
风险等级中等——包仍是 Alpha 状态、默认依赖 GPU、macOS 与 Linux 依赖版本并不一致。
评估时间默认 pip 安装加一个本地或托管 LLM 约 2–4 小时;再加上 Docker 与 llama.cpp GPU 栈则约需一天。

核心问题: 这个兼容 OpenAI Realtime 的服务能否在保留每阶段可替换模型的同时,取代托管语音 API?

92/100

RepoDaily 采用评分

RepoDaily 将该项目的采用分评为 92/100(强):分数来自文章来源、安装路径、生产风险、差异化、许可证清晰度以及 AI/Agent 适配度。

基于 RepoDaily 来源和采用说明的方向性评分,不是基准测试。风险: 中
100证据质量

包含 5 个来源、覆盖 3 类来源;如有 RepoDaily 独有模块,会进一步提高证据分。

100可安装/可试用性

检测到 6 个工作流步骤、5 个下一步动作,以及 6 个命令/安装信号。

67维护可信度

趋势热度为 +837 stars;如内容中有 release、issue 或维护信号,会提高维护可信度。

93生产准备度

采纳风险标记为 medium,并包含 5 条安全说明与 4 条跳过条件。

100差异化

3 个机会视角、4 个替代方案,以及 3 个类型化模块支撑差异化判断。

82许可证清晰度

文章中包含许可证来源或许可证表述。

90Agent / AI 适配度

文章正文和元数据中检测到 8 个 AI/Agent 相关信号。

项目概览

huggingface/speech-to-speech 是一个 Python 语音代理运行时,把 VAD、语音转写、大语言模型、文本转语音四个阶段打包到一个 WebSocket 服务背后。README 把这条链路写成 VAD -> STT -> LLM -> TTS,每个组件运行在独立线程中、以队列相连,最终通过 OpenAI Realtime 兼容的 WebSocket API(ws://localhost:8765/v1/realtime)对外暴露,因此任何基于 OpenAI Realtime 的客户端都能直接指向自托管实例。

该仓库的定位是“完全模块化”。LLM 槽位使用 OpenAI 兼容协议,可以指向托管服务商、Hugging Face Inference Providers,也可以指向本地的 vLLM 或 llama.cpp 服务,组成完全本地的开源栈。默认安装使用 Parakeet TDT 做转写、Qwen3-TTS 做语音合成、Silero VAD v5 做端点检测;在 macOS 上 TTS 走 mlx-audio 后端,在 Linux 与 Windows 上默认走 GGML 后端。

项目还给出了具体的“生产身份”:README 明确指出这条管线已作为数千台 Reachy Mini 机器人的对话后端在运行。包以 speech-to-speech 的名字发布到 PyPI,当前版本为 0.2.11,在 pyproject.toml 中的 Development Status 分类为 3 - Alpha。许可证为 Apache 2.0,仓库内同时提供了 Dockerfile 与 docker-compose.yml,把这条管线与一个跑在 CUDA 上的 llama.cpp 服务组合在一起,默认 LLM 是 Gemma 4。

本周值得关注之处在于:OpenAI Realtime 线缆兼容、每个阶段可替换、默认本地优先这三点同时成立。多数语音代理仓库会强迫你早早锁定单一 STT 或 TTS 厂商,而本项目把这些选择都做成 CLI 参数,并允许 LLM 通过本地 OpenAI 兼容端点留在你自己的 GPU 上。

解决什么问题

  • 搭建语音代理通常需要自己缝合 VAD、STT、LLM、TTS 多个库,并处理队列、流式、打断逻辑。
  • 托管 Realtime 类 API 会造成厂商锁定,且每段语音(包括音频本身)都要发给第三方。
  • 替换某一阶段(例如把 Qwen3-TTS 换成 kokoro)通常需要重写对话主循环与传输层。
  • 本地优先的栈并不少,但很少有项目愿意对外暴露已有 Realtime 客户端通用的线缆协议。

工作原理

  1. 使用 pip install speech-to-speech 安装(需 Python 3.10+),并设置 OPENAI_API_KEY,或把 LLM 后端指向本地 llama.cpp / vLLM 服务。
  2. 运行 speech-to-speech,在 ws://localhost:8765/v1/realtime 启动 WebSocket 服务,默认使用 Parakeet TDT 做转写、OpenAI 兼容 LLM、Qwen3-TTS 做合成。
  3. VAD(Silero VAD v5)检测语音边界并处理轮次,STT 转写用户回合并可选输出实时 partial。
  4. LLM 阶段通过 OpenAI 兼容的 responses API 流式返回文本与工具调用。
  5. TTS 合成音频并流式回传客户端;macOS 上后端为 mlx-audio,非 macOS 上为 GGML 后端。
  6. 接入任意 OpenAI Realtime 兼容客户端,或在源码目录下运行 python scripts/listen_and_play_realtime.py --host 127.0.0.1 --port 8765 本地对话。

产品演示与界面预览

把 OpenAI Realtime 客户端端点从托管 OpenAI 切换到自托管的 speech-to-speech 服务
替换 Realtime 客户端端点 — README 的端点切换动图直观展示了核心价值:把 Realtime 客户端从托管 OpenAI 重新指向本地 speech-to-speech 服务,且无需改动客户端代码。 README.md image

架构阅读:四个线程、一个 Realtime 形状的线缆

这条管线由 VAD、STT、LLM、TTS 四个组件构成,各自运行在独立线程、以队列相连。README 列出 Silero VAD v5 负责端点检测,STT 支持实时 partial 转写,LLM 流式返回文本与工具调用,TTS 合成并流式回放。对外则是一个 OpenAI Realtime 兼容的 WebSocket:ws://localhost:8765/v1/realtime。

可替换性正是其架构要点。每个阶段都有多个可互换后端,通过 CLI 参数选择。LLM 槽位明确使用 OpenAI 兼容协议,因此托管服务商、Hugging Face Inference Providers、vLLM 服务、llama.cpp 服务在管线看来都一样。README 给出的 llama.cpp 示例使用 llama-server -hf ggml-org/gemma-4-E4B-it-GGUF -np 2 -c 65536 -fa on --swa-full 启动 Gemma 4,再用 --responses_api_base_url http://127.0.0.1:8080/v1 与空 API key 指向它。

docker-compose.yml 完全镜像这一设计:先跑一个 ghcr.io/ggml-org/llama.cpp:server-cuda 容器承载 Gemma 4 并暴露 8080 端口,再跑 speech-to-speech 管线,传 --llm_backend responses-api、--model_name ggml-org/gemma-4-E4B-it-GGUF、--responses_api_base_url http://llama:8080/v1。管线容器暴露 12345 与 12346 两个 socket 端口,两个容器都以 device_ids: ['0'] 预留 NVIDIA GPU。

部署笔记:Dockerfile、CUDA 基础镜像与 compose 接线

  • Dockerfile 基础镜像是 nvidia/cuda:12.8.1-cudnn-runtime-ubuntu24.04——GPU 是默认假设,不是可选项。
  • 容器会安装 libportaudio2、libsndfile1、python3、python3-pip、python3-venv,再用 uv 按 pyproject.toml 同步依赖。
  • Dockerfile 在构建期执行 nltk.download('punkt_tab') 与 nltk.download('averaged_perceptron_tagger_eng'),这是句子与词性处理所必需的。
  • docker-compose.yml 把 llama.cpp 服务(8080 端口)与管线容器(12345、12346 端口)配对,二者都把 ./cache/ 挂载到 /root/.cache/ 以共享模型下载。
  • compose 中默认初始提示词是字符串 'You are a helpful assistant',通过 --init_chat_prompt 传入,--init_chat_role 设为 system。
  • Dockerfile 使用 uv sync --python /usr/bin/python3 --no-dev,运行镜像中不会包含 ruff、mypy、pytest、pytest-asyncio 等开发依赖。

集成面:CLI 参数与可选附加项

pyproject.toml 中的入口点是 speech_to_speech.s2s_pipeline:main,安装后会生成 speech-to-speech 命令。README 展示的默认调用会启动 realtime 服务;compose 文件则展示 socket 模式:--mode socket、--recv_host 0.0.0.0、--send_host 0.0.0.0、--llm_backend responses-api。

pyproject.toml 定义的可选依赖组同时也是功能开关:chattts、facebook-mms、faster-whisper、kokoro、language-detection、mlx-lm、paraformer、pocket、webrtc、websocket、whisper-mlx。其中若干带有平台限制——kokoro 明确在 macOS 上排除,whisper-mlx 与整条 mlx 栈仅限 macOS,paraformer 会引入 funasr、modelscope 与带 Python 版本约束的 onnxruntime。

核心依赖很重且很具体:openai==2.28.0,transformers 在 macOS 上为 5.6.2、其他平台为 >=4.57.0,torch 在 macOS 上为 2.11.0、其他平台为 >=2.4.0,再加上 fastapi、httpx、uvicorn、websockets、sounddevice。numpy 与 soundfile 在 Darwin 与非 Darwin 上版本不同,这对构建多架构镜像的团队尤其需要注意。

谁适合关注

适合关注

  • 正在把 OpenAI Realtime 客户端迁移到自托管端点、又不愿重写客户端代码的团队。
  • 能提供 NVIDIA GPU、需要本地语音闭环的机器人与自助终端厂商。
  • 希望在稳定对话面背后对比不同 STT 或 TTS 后端的算法工程师。
  • 愿意使用 mlx-audio 与 mlx-lm 栈在 Apple Silicon 上做全本地语音代理的开发者。

可以先跳过

  • 仅有 CPU 或内存紧张的服务器——Dockerfile 假设 CUDA 12.8.1 并预留 NVIDIA 设备。
  • 需要稳定、非 Alpha API 契约的项目;包的分类是 Development Status :: 3 - Alpha。
  • 需要单一静态二进制或非 Python 嵌入目标的场景。
  • 需要企业级支持、SLA 或长期兼容承诺的用途。

风险与注意事项

许可证 Apache-2.0、已发布到 PyPI、并有真实生产背书,但 Alpha 状态、GPU 默认假设以及平台分叉的依赖版本会带来集成与升级风险。

  • pyproject.toml 把包分类为 Development Status :: 3 - Alpha,API 与 CLI 参数仍可能变动。
  • Dockerfile 基础镜像为 nvidia/cuda:12.8.1-cudnn-runtime-ubuntu24.04,compose 也预留 NVIDIA GPU,CPU 主机无法开箱即用。
  • torch、torchaudio、transformers、numpy、sounddevice、soundfile 等在 macOS 与其他平台版本不同,会拖累多架构 CI。
  • 0.2.11 是较新的版本,README 还引用了 Gemma 4、Qwen3-TTS 这类本身迭代极快的组件。
  • 生产验证目前绑定在 Reachy Mini 机器人上,尚无公开基准覆盖通用硬件上的延迟与准确率。
  • Apache 2.0 许可证,仓库内附 LICENSE 文件,pyproject.toml 中以 license-files = ["LICENSE"] 指明。
  • README 快速开始默认绑定 localhost(ws://localhost:8765/v1/realtime),但 docker-compose 中 recv 与 send 主机都设为 0.0.0.0,部署前请复核网络暴露面。
  • 本地 llama.cpp 后端示例传入空 API key(--responses_api_api_key ""),这对本地服务正确,但不要复用到托管端点上。
  • README 没有描述鉴权层;任何能连到 WebSocket 的 Realtime 兼容客户端都能与管线对话。
  • 依赖中包含 openai==2.28.0、transformers、torch、websockets,生产使用前应做常规供应链审查与版本锁定。

替代方案比较

方案适用场景代价
OpenAI Realtime API(托管)
希望零基础设施,且能接受把音频发给第三方端点。按分钟计费;无需自备 GPU。
已经在 WebRTC 传输上标准化于 LiveKit,并希望使用其可编程语音代理框架。开源;需自建基础设施。
pipecat
需要一个比 Realtime 线缆格式更宽的多阶段语音与视频管线 Python 框架。开源;需自建基础设施。
vLLM 或 llama.cpp(仅 LLM)
已有 STT 与 TTS,只缺一个本地 OpenAI 兼容 LLM 后端。开源;为可用延迟建议使用 GPU。

这个趋势说明了什么

Realtime 客户端迁移工具

因为服务对外说 OpenAI Realtime,做一个薄迁移垫片,把现有客户端重新指向 ws://localhost:8765/v1/realtime 并按阶段记录延迟,就能把它变成离开托管 API 时的审计工具。

用默认 pip 安装加一个本地 llama.cpp 服务,以同一 Realtime 客户端驱动两端,对比首音频延迟与成本。

阶段替换基准台

可选附加项(faster-whisper、kokoro、paraformer、pocket、chattts、facebook-mms)让在固定对话主循环下基准对比不同 STT 与 TTS 后端变得很便宜。

固定 LLM,挑两组 STT 附加项与两组 TTS 附加项,在同一组提示词上测量端到端延迟与音质。

机器人与自助终端基线

README 称管线已在数千台 Reachy Mini 机器人背后运行,为硬件厂商提供了设备端对话的参考架构。

在一台 NVIDIA 设备上复现 docker-compose 栈,再按终端镜像实际需要把 compose 精简到最小参数集。

下一步建议

在一台 GPU 机器上复现默认 realtime 栈

先走 pip 安装路径,先感受默认延迟,再引入 Docker 或 llama.cpp 的复杂度,这样能把管线本身的行为与 LLM 后端隔离开。

  1. 在装有 Python 3.10+ 的主机上执行 pip install speech-to-speech。
  2. 导出 OPENAI_API_KEY(或准备好本地 llama.cpp URL),运行 speech-to-speech,在 ws://localhost:8765/v1/realtime 启动服务。
  3. 在源码目录运行 python scripts/listen_and_play_realtime.py --host 127.0.0.1 --port 8765,确认能正常对话。
  4. 用 llama-server -hf ggml-org/gemma-4-E4B-it-GGUF -np 2 -c 65536 -fa on --swa-full 启动本地 LLM,再把管线用 --responses_api_base_url 指向 http://127.0.0.1:8080/v1,并传空 --responses_api_api_key。
  5. 可选地执行 docker-compose up,在自定义前先验证 GPU compose 接线是否正常。

RepoDaily 判断

huggingface/speech-to-speech 是一条可信的本地优先语音代理运行时:Apache-2.0、兼容 Realtime、设计上模块化、并有具体生产背书。请把它当作带有真实 GPU 与平台分叉约束的 Alpha 基础设施看待;但在今天,它是搭建“已有 OpenAI Realtime 客户端无需重写即可对话”的自托管语音闭环最快的方式之一。

信息来源