Build voice agents with open-source models
一个低延迟、完全模块化的语音智能体流水线:VAD -> STT -> LLM -> TTS,通过 WebSocket 与 WebRTC 上的 OpenAI Realtime GA 核心事件集 对外提供。所有组件均可替换。LLM 槽位支持 OpenAI 兼容协议,因此你可以将其指向托管服务商、HF Inference Providers,或指向运行在自有硬件上的 vLLM / llama.cpp 服务器,打造全本地、全开放的技术栈。
该流水线已在生产环境中作为数千台 Reachy Mini 机器人的对话后端运行。
快速开始
pip install speech-to-speech
export OPENAI_API_KEY=...
speech-to-speech serve
这将启动一个位于 ws://localhost:8765/v1/realtime 的 OpenAI Realtime 兼容服务器,使用 Parakeet TDT 进行本地 STT、一个 OpenAI 兼容 LLM,以及 Qwen3-TTS 进行本地语音输出。
在第二个终端中与之对话:
speech-to-speech talk --url ws://127.0.0.1:8765/v1/realtime
使用一条命令启动服务器以及打包好的麦克风/扬声器客户端:
speech-to-speech local
您希望将 LLM 保留在自己的机器上吗?使用 llama.cpp 部署 Gemma 4:
llama-server -hf ggml-org/gemma-4-E4B-it-GGUF -np 2 -c 65536 -fa on --swa-full
然后,将兼容 OpenAI 的 LLM 后端指向它:
speech-to-speech serve \
--model_name "ggml-org/gemma-4-E4B-it-GGUF" \
--responses_api_base_url "http://127.0.0.1:8080/v1" \
--responses_api_api_key ""
使用已实现的核心 Realtime 事件集的客户端可以建立连接。官方 OpenAI Agents SDK 已在两种标准传输上完成测试;有关受测范围,请参见 Realtime API,有关提供商和本地服务器选项,请参见 LLM 后端。
目录
工作原理
该流水线由四个组件级联组成,每个组件在独立线程中运行,并通过队列相连:
- 语音活动检测(VAD):Silero VAD v5 用于检测语音边界和对话轮换。
- 语音转文本(STT):转写用户的当前语音片段,支持可选的实时部分转写。
- 语言模型(LLM):生成响应,并以流式方式输出文本和工具调用。
- 文本转语音(TTS):合成音频,并将音频流式传回客户端。
每个阶段均提供多个可互换的后端,可通过 CLI 参数进行选择。代码易于修改,重点关注可通过 Transformers 和 Hugging Face Hub 获取的模型。
安装
需要 Python 3.10+。
pip install speech-to-speech
默认安装覆盖标准实时路径:
- Parakeet TDT 用于 STT
- OpenAI 兼容 API 用于语言模型
- Qwen3-TTS 用于语音输出,在非 macOS 平台上默认使用 GGML 后端,在 Apple Silicon 上使用
mlx-audio - 本地音频和实时服务器模式
macOS 与非 macOS 依赖会通过 pyproject.toml 中的平台标记自动解析。
Qwen3-TTS 的 CUDA 说明
在 Linux 上,Qwen3-TTS 的 GGML 后端由 faster-qwen3-tts[ggml] 提供。PyPI 上默认的 qwentts-cpp-python wheel 包面向 CUDA 12.8 和 manylinux_2_39(例如 Ubuntu 24.04)。如果你的 CUDA 运行时或 glibc 版本较旧,请先从 Hugging Face 的 wheel 仓库安装匹配的 wheel 包,再安装 speech-to-speech:
# CUDA 13.x
pip install "qwentts-cpp-python==0.3.1+cu130" \
-f https://huggingface.co/datasets/andito/qwentts-cpp-python-wheels/tree/main/whl/cu130
# CUDA 12.4
pip install "qwentts-cpp-python==0.3.1+cu124" \
-f https://huggingface.co/datasets/andito/qwentts-cpp-python-wheels/tree/main/whl/cu124
# CPU-only fallback
pip install "qwentts-cpp-python==0.3.1+cpu" \
-f https://huggingface.co/datasets/andito/qwentts-cpp-python-wheels/tree/main/whl/cpu
pip install speech-to-speech
若要使用之前的 CUDA-graphs 实现,而不是 GGML,请传入 --qwen3_tts_backend torch。
可选组件
可选组件可通过 pip extras 安装:
pip install "speech-to-speech[kokoro]" # Kokoro-82M TTS on non-macOS
pip install "speech-to-speech[pocket]" # Pocket TTS
pip install "speech-to-speech[chattts]" # ChatTTS
pip install "speech-to-speech[omnivoice]" # OmniVoice TTS (CUDA, Intel XPU, or Apple Silicon)
pip install "speech-to-speech[faster-whisper]" # Faster Whisper STT
pip install "speech-to-speech[whisper-mlx]" # Lightning Whisper MLX STT on macOS
pip install "speech-to-speech[paraformer]" # Paraformer STT through FunASR
pip install "speech-to-speech[mlx-lm]" # mlx-vlm support for vision models on macOS
已弃用的实现(包括 MeloTTS)位于 archive/,并且已不再集成到 CLI 中。
关于 DeepFilterNet 的说明: DeepFilterNet 用于 VAD 中的可选音频增强,需要 numpy<2,与需要 numpy>=2 的 Pocket TTS 发生冲突。请仅在不使用 Pocket TTS 的环境中手动安装。
从源代码
git clone https://github.com/huggingface/speech-to-speech.git
cd speech-to-speech
uv sync
这将以可编辑模式安装该包,并使 speech-to-speech CLI 可用。
支持的组件
| 组件 | 后端 | 平台 | 安装 |
|---|---|---|---|
| VAD | Silero VAD v5 | 全部 | 内置 |
| STT | Parakeet TDT(默认) | 通过 nano-parakeet 支持 CUDA / CPU,通过 MLX 支持 Apple Silicon | 内置 |
| STT | Whisper 通过 Transformers | CUDA / CPU | 内置 |
| STT | Faster Whisper | CUDA / CPU | faster-whisper |
| STT | Lightning Whisper MLX | Apple Silicon | whisper-mlx |
| STT | MLX Audio Whisper | Apple Silicon | macOS 内置 |
| STT | Paraformer | CUDA / CPU | paraformer |
| STT | 兼容 OpenAI 的 /v1/audio/transcriptions 端点 |
本地或远程 HTTP 服务器 | 内置 |
| LLM | 兼容 OpenAI 的 API(responses-api、chat-completions) |
托管提供商或自托管服务器 | 内置 |
| LLM | Transformers | CUDA / CPU | 内置 |
| LLM | mlx-lm | Apple Silicon | macOS 内置 |
| TTS | Qwen3-TTS(默认) | Linux 上的 GGML / CUDA,macOS 上的 mlx-audio | 内置 |
| TTS | Kokoro-82M | CUDA / CPU,Apple Silicon | 非 macOS 使用 kokoro;macOS 内置 |
| TTS | Pocket TTS | CPU / CUDA | pocket |
| TTS | ChatTTS | CUDA / CPU | chattts |
| TTS | OmniVoice | CUDA / Intel XPU / Apple Silicon | omnivoice |
| TTS | MMS TTS | CUDA / CPU | 内置 |
使用 --stt、--llm_backend 和 --tts 选择实现。CLI 仅为所选后端构建配置;出于兼容性考虑,未激活后端的已知选项仍会被接受,但会触发警告并被忽略。JSON 配置中同样可能包含额外的未激活后端键,这些键会被忽略。运行 speech-to-speech serve -h 查看默认值,或在 -h 前传入选择器以查看其他组合的后端专属参数(例如,speech-to-speech serve --stt mlx-audio-whisper -h)。
若要使用 vLLM、OpenAI 托管的 Transcription API 或其他兼容服务器进行纯客户端语音识别,请参阅 兼容 OpenAI 的 STT。
命令
| 命令 | 行为 | 使用场景 |
|---|---|---|
serve |
基于 OpenAI Realtime WebSocket 和 WebRTC 运行管道服务器。 | 当你的应用或设备基于该 API 构建时。 |
talk --url <full-realtime-url> |
运行内置麦克风/扬声器客户端。 | 当你希望与一个现有 Realtime 服务器对话时。 |
local |
在进程内通过 loopback 组合 serve 和 talk。 |
当你希望用一条命令同时运行服务器并与其对话时。 |
serve 默认绑定到 127.0.0.1;如需暴露到网络,请显式传入 --host 0.0.0.0。local 始终绑定到 loopback,并通过 ws://127.0.0.1:<port>/v1/realtime 连接同一个内置客户端。
内置客户端可通过 talk --tool-module <module> 或 local --tool-module <module> 启用本地 Python 工具。模块约定、编程 API 以及一个 Serper 网络搜索示例见 Tool calling design。
从 --mode 迁移
--mode 已弃用,并将很快停止工作。在迁移期间,speech-to-speech --mode realtime 会运行 speech-to-speech serve,speech-to-speech --mode local 会运行 speech-to-speech local;两者都会打印警告。其他所有 mode 值均已移除,退出时会提示使用新命令。
Realtime 服务器
export OPENAI_API_KEY=...
speech-to-speech serve
这等价于:
speech-to-speech serve \
--thresh 0.6 \
--stt parakeet-tdt \
--llm_backend responses-api \
--tts qwen3 \
--qwen3_tts_model_name Qwen/Qwen3-TTS-12Hz-1.7B-CustomVoice \
--qwen3_tts_speaker Aiden \
--qwen3_tts_language auto \
--qwen3_tts_backend ggml \
--qwen3_tts_non_streaming_mode True \
--qwen3_tts_mlx_quantization 6bit \
--model_name gpt-5.6-terra \
--chat_size 30 \
--responses_api_stream \
--enable_live_transcription
默认模型为 gpt-5.6-terra,经由 OpenAI Responses API 调用,并将推理强度设为 none,以沿用原默认模型面向低延迟的推理行为。可使用 --model_name 覆盖模型、--responses_api_reasoning_effort 覆盖推理强度,并通过 --responses_api_base_url 指定其他兼容 OpenAI 的服务提供方或服务器。
本地 Mac
speech-to-speech local --mac-optimal-settings
可选使用特定 LLM:
speech-to-speech local \
--mac-optimal-settings \
--model_name mlx-community/Qwen3-4B-Instruct-2507-bf16
该设置:
- 对受支持的模型组件使用 MPS 默认配置。
- 将 STT 设置为 Parakeet TDT。
- 将 LLM 后端设置为 MLX LM。
- 将 TTS 设置为 Qwen3-TTS,默认使用
mlx-audio的6bitMLX 变体。
该预设仅提供这些默认值:显式指定的 --device、组件级设备参数(如 --qwen3_tts_device),以及 --stt、--llm_backend、--model_name 和 --tts 均优先生效。若希望对外提供服务端而不启动麦克风/扬声器客户端,请使用 serve 而非 local。
--tts pocket、--tts kokoro 和 --tts omnivoice 在 macOS 上同样可用。
要在本地比较 MLX 量化变体:
python scripts/benchmark_tts.py \
--handlers qwen3 \
--iterations 3 \
--qwen3_mlx_quantizations bf16 4bit 6bit 8bit
Docker
安装 NVIDIA Container Toolkit,然后:
docker compose up
该 Compose 文件会启动使用 Gemma 4 的 llama.cpp 服务和 Realtime 服务,并开放 8080 和 8765 端口。
Realtime API
Realtime 模式支持基于 WebSocket 和 WebRTC 的 OpenAI Realtime 协议,并提供实时转录与低延迟对话轮替。WebSocket 客户端连接地址为 /v1/realtime:
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:8765/v1",
websocket_base_url="ws://localhost:8765/v1",
api_key="not-needed",
)
with client.realtime.connect(model="local") as conn:
conn.send(
{
"type": "session.update",
"session": {
"type": "realtime",
"instructions": "You are a helpful assistant.",
"audio": {
"input": {
"turn_detection": {
"type": "server_vad",
"interrupt_response": True,
}
}
},
},
}
)
for event in conn:
print(event.type)
服务器实现了核心 Realtime 事件集:入站事件包括 input_audio_buffer.append、session.update、conversation.item.create、conversation.item.truncate、response.create 和 response.cancel;出站事件包括语音开始/停止、流式转写、音频增量、工具调用以及 response.done。CI 会通过 SDK 的标准 WebSocket 和 WebRTC 传输连接固定版本的 @openai/agents RealtimeSession 实例。这是一个经过测试的核心子集,并不宣称与完整的 OpenAI Realtime API 完全等价。事件矩阵、架构和设计细节位于 Realtime Engine README。
LLM 代理
启用 --enable_llm_proxy 后,实时服务器还会将所配置的远程 LLM 暴露为一个普通的 OpenAI 兼容端点,客户端即可使用工具和流式能力运行辅助任务(摘要、标题、后台智能体),与语音对话完全并发,且不会被新的语音打断:
POST /v1/chat/completions(当运行--llm_backend chat-completions时)POST /v1/responses(当运行--llm_backend responses-api时)
服务器本身不执行认证,也不进行限流。仅在可信网络中启用代理,或将服务器部署在负责访问控制的网关之后。s2s-endpoint 计算副本就是这样的网关:它仅向使用 HF token 创建会话的客户端开放这些路径,校验 API key 是否与该 token 匹配,并按用户应用速率限制。将标准 OpenAI SDK 指向你实际访问的主机即可;该服务器会忽略 API key(前置网关决定其应为何值):
from openai import OpenAI
llm = OpenAI(base_url="http://localhost:8765/v1", api_key="unused")
completion = llm.chat.completions.create(
model="anything", # ignored: the server forces its configured --model_name
messages=[{"role": "user", "content": "Summarize the conversation so far: ..."}],
)
请求均为无状态(每次需发送完整消息列表),由服务器使用其持有的密钥代理至所配置的上游,密钥不会暴露给客户端。model 字段始终会被服务器配置的 --model_name 覆盖。代理默认关闭,需要远程后端(chat-completions 或 responses-api),否则将返回 501 并说明原因。
LLM 后端
LLM 是流水线中计算量最大、延迟最高的组件。大模型的一次前向传播就可能决定端到端响应时间,因此根据硬件条件和延迟预算选择合适的后端非常重要。流水线支持:
- 本地推理:在 CUDA / CPU 上使用
transformers,在 Apple Silicon 上使用mlx-lm。 - 自托管服务:
responses-api和chat-completions可以指向本地 vLLM 或 llama.cpp 服务。 - 提供商 API:相同后端适用于 OpenAI、HF Inference Providers、OpenRouter 以及其他兼容 OpenAI 的提供商。
提供两种 API 后端,共享相同的 --responses_api_* 连接参数:
--llm_backend responses-api(默认)指向/v1/responses。--llm_backend chat-completions指向/v1/chat/completions。
直接音频输入(不使用 STT)
使用 --stt none --llm_backend chat-completions,可将每个已完成的 VAD 音频片段直接发送到支持音频输入的模型。使用 --llm_backend responses-api 时,不支持直接音频模式:某些模型可能通过 /v1/chat/completions 接受音频,而不支持 /v1/responses,包括 OpenAI 的 gpt-audio-1.5。
必须显式将 --model_name 设置为支持音频输入的模型:默认的 gpt-5.6-terra 接受文本和图像输入,但不接受音频。启用此模式前,请查阅提供商的模型文档和端点支持情况。对于 OpenAI,请参阅
GPT-5.6 Terra 模型卡片
和 音频输入指南。
speech-to-speech serve \
--stt none \
--llm_backend chat-completions \
--model_name "YOUR_AUDIO_CAPABLE_MODEL" \
--responses_api_base_url "https://provider.example/v1" \
--responses_api_api_key "$PROVIDER_API_KEY"
兼容 OpenAI 的服务端对输入音频的表示方式不同。对于内嵌 WAV base64,请使用
--responses_api_audio_content_type input_audio(默认值);对于 base64 data URL,请使用 --responses_api_audio_content_type audio_url。
以下示例将 Parakeet TDT 作为本地 STT、Qwen3-TTS 作为本地 TTS,并搭配不同的 LLM 后端。
Responses API 后端
适用于任何实现了 OpenAI Responses API 的提供商或服务器。将 --responses_api_base_url 指向相应端点,并相应设置 --model_name:
| 提供商 / 服务器 | --responses_api_base_url |
--responses_api_api_key |
|---|---|---|
| OpenAI | 省略,使用 OpenAI 默认值 | $OPENAI_API_KEY |
| HF Inference Providers | https://router.huggingface.co/v1 |
$HF_TOKEN |
| OpenRouter | https://openrouter.ai/api/v1 |
$OPENROUTER_API_KEY |
| vLLM | http://localhost:8000/v1 |
省略或任意字符串 |
| llama.cpp | http://127.0.0.1:8080/v1 |
空字符串 |
# OpenAI
speech-to-speech local \
--stt parakeet-tdt \
--llm_backend responses-api \
--tts qwen3 \
--qwen3_tts_mlx_quantization 6bit \
--model_name "gpt-4o-mini" \
--responses_api_api_key "$OPENAI_API_KEY" \
--responses_api_stream \
--enable_live_transcription
# HF Inference Providers: Qwen3.5-9B via Together
speech-to-speech local \
--stt parakeet-tdt \
--llm_backend responses-api \
--tts qwen3 \
--qwen3_tts_mlx_quantization 6bit \
--model_name "Qwen/Qwen3.5-9B:together" \
--responses_api_base_url "https://router.huggingface.co/v1" \
--responses_api_api_key "$HF_TOKEN" \
--responses_api_stream \
--enable_live_transcription
# HF Inference Providers: GPT-oss-20B via Groq
speech-to-speech serve \
--stt parakeet-tdt \
--llm_backend responses-api \
--tts qwen3 \
--qwen3_tts_mlx_quantization 6bit \
--model_name "openai/gpt-oss-20b:groq" \
--responses_api_base_url "https://router.huggingface.co/v1" \
--responses_api_api_key "$HF_TOKEN" \
--responses_api_stream \
--enable_live_transcription
Chat Completions 后端
配置与 responses-api 完全相同,复用相同的 --responses_api_* 连接参数,但调用的是 /v1/chat/completions,而非 /v1/responses。在以下情况下建议优先使用:
- 提供商在 Responses 路径下忽略
chat_template_kwargs.enable_thinking,需要通过reasoning_effort参数来抑制推理,或 - 服务器的 Responses 流式工具调用路径不可靠,而其 Chat Completions 工具调用流式输出稳定可靠。这对部分 vLLM 构建版本有帮助;参见 #312。
添加 --responses_api_reasoning_effort none,可在 chat-template 标志不生效的提供商中禁用推理:
# vLLM serving a Qwen model with tool calling
speech-to-speech serve \
--stt parakeet-tdt \
--llm_backend chat-completions \
--tts qwen3 \
--model_name "Qwen/Qwen3-4B-Instruct-2507" \
--responses_api_base_url "http://localhost:8000/v1" \
--responses_api_stream
# Gemma 4 31B via the HF router on Cerebras, with reasoning disabled for low voice latency
speech-to-speech serve \
--stt parakeet-tdt \
--llm_backend chat-completions \
--tts qwen3 \
--model_name "google/gemma-4-31B-it:cerebras" \
--responses_api_base_url "https://router.huggingface.co/v1" \
--responses_api_api_key "$HF_TOKEN" \
--responses_api_reasoning_effort none \
--responses_api_stream
完全本地
将 LLM 运行在独立的 llama.cpp 进程中,以实现操作成本最低的完全本地部署,如Reachy Mini 本地对话指南所示:
如需配置支持浏览器演示、Realtime 轮次修订和 barge-in 的完全本地 native-audio 方案,请参考已测试的Apple Silicon 版 Gemma 4 12B speech-to-speech 示例。
# Terminal 1: llama.cpp serving Gemma 4
llama-server -hf ggml-org/gemma-4-E4B-it-GGUF -np 2 -c 65536 -fa on --swa-full
# Terminal 2: speech-to-speech using that local LLM server
speech-to-speech serve \
--stt parakeet-tdt \
--llm_backend responses-api \
--tts qwen3 \
--model_name "ggml-org/gemma-4-E4B-it-GGUF" \
--responses_api_base_url "http://127.0.0.1:8080/v1" \
--responses_api_api_key "" \
--responses_api_stream \
--enable_live_transcription
如果你希望运行同一台服务器,并通过承载该服务器的机器与其对话,请使用 speech-to-speech local。在 Apple Silicon 上,可通过 --llm_backend mlx-lm 使用进程内本地后端;在 CUDA / CPU 上,可通过 --llm_backend transformers 使用进程内本地后端。
离线运行
安装所选组件的依赖项和模型资产到本地后,该流程即可在无需联网的情况下运行。断开连接前,请在联网状态下先完整启动一次目标配置,以便缓存所需的 STT、LLM、TTS、Silero VAD、NLTK 和 Smart Turn 资源。
若要最省心地完成全本地 LLM 配置,请按 Fully Local 中所述,在同一台机器上运行 llama.cpp。一旦 llama.cpp 和流程资源在本地可用,请在启动 speech-to-speech 时设置 HF_HUB_OFFLINE=1,以避免向 Hugging Face Hub 发起请求:
HF_HUB_OFFLINE=1 speech-to-speech serve \
--model_name "ggml-org/gemma-4-E4B-it-GGUF" \
--responses_api_base_url "http://127.0.0.1:8080/v1" \
--responses_api_api_key ""
若未设置本地 Base URL 覆盖,默认的 responses-api LLM 后端会调用远程服务。或者,
使用进程内本地后端,例如 transformers 或 mlx-lm。每个所选模型都必须已缓存,或
通过其后端支持的本地路径提供。
Smart Turn 使用独立的 ONNX 检查点。已缓存的检查点在 HF_HUB_OFFLINE=1 下可正常工作;如需显式、
不依赖缓存的配置,请传入 --smart_turn_model_path /path/to/smart-turn-v3.2-cpu.onnx。如果检查点不
可用,请传入 --no_smart_turn 以禁用 Smart Turn。
多语言支持
语言覆盖范围取决于你选择的 STT 和 TTS 后端,而不是流程本身:
| 组件 | 后端 | 语言 |
|---|---|---|
| STT | Parakeet TDT(默认) | 25 种欧洲语言 |
| STT | Whisper / Whisper MLX / Faster Whisper | 较广的多语言覆盖,具体取决于所选 Whisper 检查点 |
| STT | Paraformer | 取决于所选 FunASR 检查点;默认面向中文 |
| TTS | Qwen3-TTS(默认) | 多语言,默认使用 --qwen3_tts_language auto |
| TTS | Kokoro | 多种语言/音色映射,具体取决于后端可用性 |
| TTS | ChatTTS | 英语和中文 |
| TTS | MMS TTS | 通过 MMS 检查点提供较广的多语言覆盖 |
请确保所搭配的 STT、LLM 和 TTS 均能覆盖目标语言。两种使用方式:
- 单一语言:将
--language设置为目标语言代码。默认值为en。 - 语言切换:将
--language设置为auto。STT 会检测每段语音输入的语言,并将其传递给 LLM。还可以添加--enable_lang_prompt,以追加一条“Please reply to my message in ...”指令。该选项默认为False;大型 LLM 通常能从上下文推断语言,但显式指令可以帮助较小模型。
自动语言检测:
speech-to-speech serve \
--stt parakeet-tdt \
--language auto \
--llm_backend mlx-lm \
--model_name "mlx-community/Qwen3-4B-Instruct-2507-bf16"
单一非英语语言,本例中为中文:
speech-to-speech serve \
--stt whisper-mlx \
--stt_model_name large-v3 \
--language zh \
--llm_backend mlx-lm \
--model_name mlx-community/Qwen3-4B-Instruct-2507-bf16
Both commands also work with --mac-optimal-settings; explicit --stt flags override the defaults it sets. -> 这两个命令也都支持 --mac-optimal-settings;显式指定的 --stt 参数会覆盖它设置的默认值。
OmniVoice
OmniVoice provides voice cloning, voice design, and automatic voice selection across 600+ languages. Install its opt-in dependencies and provide a reference clip plus its transcript for voice cloning. This example uses CUDA on Linux or Windows; use --omnivoice_device mps on Apple Silicon or --omnivoice_device xpu with an Intel XPU-enabled PyTorch installation: -> ## OmniVoice
OmniVoice 提供语音克隆、语音设计以及跨 600 多种语言的自动音色选择。请安装其可选依赖项,并为语音克隆提供一个参考音频片段及其转录文本。本示例在 Linux 或 Windows 上使用 CUDA;在 Apple Silicon 上请使用 --omnivoice_device mps,或在支持 Intel XPU 的 PyTorch 安装环境中使用 --omnivoice_device xpu:
pip install "speech-to-speech[omnivoice]"
speech-to-speech serve \
--tts omnivoice \
--omnivoice_device cuda \
--omnivoice_ref_audio /path/to/reference.wav \
--omnivoice_ref_text "Transcript of the reference clip."
该处理器将 OmniVoice 已完成的 24 kHz float 输出转换为流水线的 16 kHz int16 数据块。OmniVoice 目前未通过 generate() 提供增量音频,因此只有整句合成完成后,首个数据块才可用。有关已保存的提示词、音色设计、设备、延迟以及所有后端参数,请参见 TTS 组件指南。
omnivoice 附加依赖支持 Linux、Windows 和 macOS。在非 macOS 平台上,OmniVoice 与内置 Qwen3 后端均通过 faster-qwen3-tts>=0.4.0 共用 Transformers 5,因此安装该附加依赖可保持默认 Qwen3 路径可用。Linux 默认使用 Qwen3 的 GGML 附加依赖;如果其 CUDA 12.8 / manylinux_2_39 原生 wheel 与你的主机不匹配,请参见 CUDA 说明。
Warning
OmniVoice 的代码采用 Apache-2.0,但其预训练权重采用 CC-BY-NC,不可用于商业用途。仅在获得授权和同意时使用声音克隆;请勿将其用于冒充、欺诈、诈骗或其他非法或不道德行为。
Pocket TTS
Kyutai Labs 的 Pocket TTS 提供带声音克隆的流式 TTS:
speech-to-speech serve \
--tts pocket \
--pocket_tts_voice jean \
--pocket_tts_device cpu
可用语音预设:alba、marius、javert、jean、fantine、cosette、eponine、azelma。自定义语音文件和 Hugging Face 路径也同样适用。
CLI 参考
流水线 CLI 参数的相关参考位于 arguments classes 以及 speech-to-speech serve -h 中。客户端参数可通过 speech-to-speech talk -h 列出。
模块级参数
参见 ModuleArguments。它允许设置:
- 统一的
--device,用于让所有组件在同一设备上运行 - macOS 模型/设备默认值(
--mac-optimal-settings) - STT 实现(
--stt) - LLM 后端(
--llm_backend:transformers、mlx-lm、responses-api或chat-completions) - TTS 实现(
--tts) - 日志级别
- 实时流水线池大小(
--num_pipelines)
VAD 参数
参见 VADHandlerArguments。主要选项:
--thresh:触发语音活动检测的阈值。--min_speech_ms:被识别为有效语音所需的最低语音活动持续时间。--min_speech_continuation_ms:在重开窗口内,用于延续可重开的软结束、未提交话轮时的持续迟滞阈值。默认且推荐的组合为--min_speech_ms 384 --min_speech_continuation_ms 192。--min_silence_ms:用于切分语音的静音间隔最短时长。默认值为 64 ms。--short_segment_merge_ms:可选合并窗口,用于拼接相邻且均短于--min_speech_ms的 VAD 片段。--speculative_reopen_ms:在软结束话轮后将响应提交延迟 800 ms,以便立即恢复的语音可以重新开启该话轮。--unanswered_reopen_ms:对尚未收到任何助手输出的软结束试探性话轮保持可重开时长的安全上限。启用 Smart Turn 时,该值会被限制为至少--smart_turn_max_wait_ms,从而确保一个话轮在整个宽限期内保持可重开。
Smart Turn 端点检测
Smart Turn v3.2 可基于当前轮次的内容与韵律,
验证 Silero 的语音结束判断。Silero 确认分段后,
STT/LLM 任务可先行推测执行。完整轮次会立即开始处理,并在
--speculative_reopen_ms(默认 800 ms)内正式提交输出。不完整轮次会等待
--smart_turn_incomplete_delay_ms(默认 600 ms)再启动 STT/LLM 任务,同时其输出仍受
--smart_turn_max_wait_ms(默认 2 秒)约束。如果在任一等待期间语音重新出现,则会以更新的修订版本重新打开当前轮次,重新发送已累积的音频,并在上一修订版本的处理结果到达用户之前将其丢弃。
基础包内置量化版 CPU 运行时,并默认启用 Smart Turn:
pip install speech-to-speech
speech-to-speech serve
首次使用时,将从 Hugging Face Hub 下载最新支持的 v3.2 CPU checkpoint。传入
--smart_turn_model_path /path/to/model.onnx 以使用本地模型,或使用 --no_smart_turn 禁用 Smart Turn。
Smart Turn 在服务器会话和随包提供的本地客户端中默认启用。
使用 --smart_turn_threshold 调整完成判定阈值(默认 0.5)。阈值越高,模糊的停顿越可能采用更长的推测式响应宽限期。
STT、LLM 与 TTS 参数
每个 STT、LLM 与 TTS 实现都提供 model_name、torch_dtype 和 device 参数。STT 和 TTS 参数使用处理程序前缀,例如 --stt_model_name 或 --qwen3_tts_device。LLM 模型选择与聊天设置通过未加前缀的标志在各后端间共享,例如 --model_name 和 --chat_size;后端专属标志在 responses-api 和 chat-completions 后端使用 responses_api_ 前缀,在本地后端使用 llm_ 前缀。
例如:
# Local transformers/mlx-lm backend
--model_name google/gemma-2b-it
# OpenAI-compatible backend
--llm_backend responses-api --model_name deepseek-chat --responses_api_base_url https://api.deepseek.com
生成参数
其他生成参数可以通过 handler 前缀加 _gen_ 来设置,例如 --stt_gen_max_new_tokens 128 或 --llm_gen_temperature 0.7。尚未暴露的参数可以添加到相应的 arguments 类中。
参与贡献
欢迎提交 Issues 和 PR。适合上手的入口是开放 issue。对于较大的改动,请先打开 issue 讨论方案。
本地开发:
uv sync
pytest
ruff check
星标历史
引用
如果你使用了该流程,请同时引用你所运行的组件模型。默认模型如下:
Silero VAD
@misc{SileroVAD,
author = {Silero Team},
title = {Silero VAD: pre-trained enterprise-grade Voice Activity Detector (VAD), Number Detector and Language Classifier},
year = {2021},
publisher = {GitHub},
journal = {GitHub repository},
howpublished = {\url{https://github.com/snakers4/silero-vad}},
email = {hello@silero.ai}
}
Parakeet TDT
@misc{parakeet-tdt,
author = {NVIDIA},
title = {Parakeet TDT 0.6B v3},
publisher = {Hugging Face},
howpublished = {\url{https://huggingface.co/nvidia/parakeet-tdt-0.6b-v3}}
}
Qwen3-TTS
@misc{qwen3-tts,
author = {Qwen Team},
title = {Qwen3-TTS},
publisher = {Hugging Face},
howpublished = {\url{https://huggingface.co/Qwen/Qwen3-TTS-12Hz-1.7B-CustomVoice}}
}
可选后端(如 Kokoro、Pocket TTS、ChatTTS、Whisper 变体、Paraformer 和 MMS)的引用条目,分别位于对应的 组件 README 中。
Introduction
语音对语音:一项致力于开源且模块化的 GPT4-o 的努力【此简介由AI生成】