想做一个能听、会想、开口说的语音智能体,但又不想被 OpenAI Realtime / ElevenLabs 按分钟计费?Hugging Face 开源的 speech-to-speech 把整条链路(VAD→STT→LLM→TTS)跑在你自己的机器上,对外暴露一个兼容 OpenAI Realtime 协议的 WebSocket——也就是说,你给 OpenAI Realtime 写的客户端,改个地址就能指向本地。本教程一行命令起一个完全离线、零按量费的语音 Agent。
Step 1:先懂这条流水线长什么样
它不是一个大黑盒,而是四个串起来、各自可换的环节,每个环节跑在独立线程、用队列衔接:
VAD(语音活动检测) → Silero VAD v5,判断什么时候开始/结束说话
STT(语音转文字) → Parakeet TDT,把你的话转成文本
LLM(语言模型) → 生成回复,流式输出文本与工具调用
TTS(文字转语音) → Qwen3-TTS,把回复合成为语音流回传
默认整体模型(会随版本演进,以官方 README 为准):
VAD Silero VAD v5
STT Parakeet TDT
LLM Qwen3.5-4B(Apple Silicon 走 MLX;其他走 Transformers / vLLM)
TTS Qwen3-TTS
对外接口:ws://localhost:8765/v1/realtime —— 与 OpenAI Realtime 协议兼容
模型版本会演进:默认 LLM 在不同文档里出现过 Qwen3.5-4B / Qwen3-TTS 等命名,具体默认值以你安装时的 pip install speech-to-speech 版本为准。每环都可经命令行参数替换,下文会演示。
Step 2:准备 Python 环境
需要 Python 3.10+(官方推荐 3.11)。用虚拟环境隔离依赖,避免污染系统。
# 1) 建虚拟环境并激活
python3 -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\Activate.ps1
# 2) 安装(默认已含标准实时链路所需全部组件)
pip install speech-to-speech
# 3) Ubuntu 还需要系统音频库
sudo apt-get install libportaudio2 libsndfile1
# macOS 无需额外系统依赖;Apple Silicon 会自动走 MLX 后端
Step 3:一行起本地语音助手
装好后一条命令就能边听边说。首次运行会下载模型,请联网等待几分钟;下完之后全部可离线。
# 启动「服务端 + 麦克风客户端」一体化进程
speech-to-speech local
# 它默认监听:ws://127.0.0.1:8765/v1/realtime
# 终端里直接说话 → 暂停 → 助手通过音箱回答
# Ctrl+C 停止
# 建议戴耳机,避免助手听到自己的声音造成回声
# 若不能戴耳机,加参数阻止播放时拾音:
speech-to-speech local --local_audio_block_mic_during_playback
回声陷阱:不用耳机、又不加 --local_audio_block_mic_during_playback 时,麦克风会录到音箱外放,导致助手"自己跟自己聊"。能戴耳机就戴耳机。
Step 4:换成你自己的大模型
默认 LLM 若不合你意,可用 llama.cpp 在本地起一个 OpenAI 兼容端点,再让 speech-to-speech 指向它。这样整条链彻底不依赖任何外部 API。
# 终端 A:用 llama.cpp 起本地 LLM(示例模型以实际可用为准)
llama-server -hf ggml-org/gemma-4-E4B-it-GGUF -np 2 -c 65536 -fa on --swa-full
# 终端 B:让语音流水线把 LLM 指向本地端点
speech-to-speech \
--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_base_url 即可,其余环节不动。Step 5:只起服务端,接你自己的客户端
如果你只想要一个语音后端、前端用自己的应用,用 serve 只起服务端,再用任意兼容 OpenAI Realtime 的客户端连。
# 只起服务端(不自动开麦克风客户端)
speech-to-speech serve
# → 监听 ws://127.0.0.1:8765/v1/realtime
# 用自带的音频客户端连:
speech-to-speech talk --url ws://127.0.0.1:8765/v1/realtime
# 或:你给 OpenAI Realtime 写的 Web/App 客户端,
# 把 endpoint 从 OpenAI 改成上面的本地地址即可
Step 6:CUDA / 平台坑与离线运行
最后把环境收尾,避免装完跑不起来的常见坑。
# 1) Qwen3-TTS 的 Linux 轮子默认面向 CUDA 12.8 + Ubuntu 24.04
# 你的 CUDA / glibc 更旧时,先装匹配的轮子再装主包:
pip install "qwentts-cpp-python==0.3.1+cu130" -f https://huggingface.co/datasets/andito/qwentts-cpp-python-wheels/tree/main/whl/cu130
# (cu124 / cpu 等变体同理,以 Hugging Face wheelhouse 当前可用为准)
pip install speech-to-speech
# 2) 离线运行:首次下载模型后,断网也能用
# 只要不指向外部 LLM 端点,整条链路不出本机
# 3) 想要网页仪表盘(可视化调参)可改用仓库方式:
# git clone https://github.com/huggingface/speech-to-speech.git
# cd speech-to-speech && uv sync && ./start_web_ui.sh
CUDA 轮子不匹配是头号报错源:报错多发生在 Linux 上 Qwen3-TTS 加载阶段。先确认本机 CUDA 主版本,再装对应 +cuXXX 轮子,不要硬装默认 12.8 轮子。纯 CPU 机器可用 cpu 轮子,但回复很慢,仅适合验证流程。
常见问题
| 现象 | 处理 |
|---|---|
| 启动后没声音 / 一直没反应 | 首次运行在下载模型,耐心等几分钟;确认麦克风/扬声器权限已授予终端或应用。 |
| 助手重复自己的话(回声) | 戴耳机,或加 --local_audio_block_mic_during_playback。 |
| Linux 上报 Qwen3-TTS 加载失败 | CUDA 轮子版本不对。按本机 CUDA 装 +cuXXX 匹配轮子后再装主包。 |
| 想接自己已有的 Realtime 客户端 | 把客户端 endpoint 从 OpenAI 改成 ws://127.0.0.1:8765/v1/realtime 即可,协议兼容。 |
| 能否完全离线 | 能。首次下载模型后,只要 LLM 也指向本地端点,整条链路断网可跑。 |