高级 📋 6 个步骤 第 538 / 538 篇

用 Hugging Face speech-to-speech 搭本地零成本语音智能体

Hugging Face 开源的 speech-to-speech 把 VAD→STT→LLM→TTS 串成一条可本地运行的语音智能体流水线,对外暴露 OpenAI Realtime 兼容的 WebSocket,每个环节都能换模型。本教程带你一行命令起一个完全离线、零按量费的语音 Agent,并接上自己的大模型。

2026.10.16· 约 16 分钟阅读· 约 1534 字· 🎙️ speech-to-speech / 🤗 Hugging Face

想做一个能听、会想、开口说的语音智能体,但又不想被 OpenAI Realtime / ElevenLabs 按分钟计费?Hugging Face 开源的 speech-to-speech 把整条链路(VAD→STT→LLM→TTS)跑在你自己的机器上,对外暴露一个兼容 OpenAI Realtime 协议的 WebSocket——也就是说,你给 OpenAI Realtime 写的客户端,改个地址就能指向本地。本教程一行命令起一个完全离线、零按量费的语音 Agent。

💡 适用场景:做隐私敏感场景(本地数据不出机)、想摆脱语音按量费、要把语音 Agent 嵌进自己产品又不想绑死厂商的人。需要一台能跑本地模型的机器(有 GPU 更快,纯 CPU 能跑但回复慢)。

Step 1:先懂这条流水线长什么样

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 环境

2

需要 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 后端
🔑 平台差异:Apple Silicon Mac 用 MLX LM + mlx-audio(完全本地、最快上手);Linux/Windows + NVIDIA 用 Transformers + GGML 后端;无 GPU 的其他机器也能跑,但 LLM 回复会明显变慢。

Step 3:一行起本地语音助手

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:换成你自己的大模型

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 ""
🔑 关键点:LLM 槽位只认 OpenAI 兼容协议。你既能指向本地 llama.cpp / vLLM,也能指向 HF Inference Providers 或任意托管 OpenAI 兼容服务——只换 --responses_api_base_url 即可,其余环节不动。

Step 5:只起服务端,接你自己的客户端

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 改成上面的本地地址即可
🌐 兼容性红利:因为协议和 OpenAI Realtime 一致,官方文档提到 OpenAI Agents SDK、LiveKit Agents 等都能直接指向这个本地端点(传输层细节以官方 Realtime API 说明为准)。你已有的 Realtime 客户端几乎不用改。

Step 6:CUDA / 平台坑与离线运行

6

最后把环境收尾,避免装完跑不起来的常见坑。

# 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 也指向本地端点,整条链路断网可跑。
← 返回教程中心