speech-to-speech 怎么配置 --stt none 直接音频输入模式跳过 STT?
【免费下载链接】speech-to-speechBuild voice agents with open-source models项目地址: https://gitcode.com/GitHub_Trending/sp/speech-to-speech
speech-to-speech 的默认流水线是 VAD → STT → LLM → TTS,用户语音要先经过 Parakeet TDT 这类本地 STT 模型转成文字,才交给 LLM。如果你的 LLM 本身就接受音频输入(例如支持原生音频的 Gemma 4 12B),就可以跳过 STT 这一环:配置--stt none --llm_backend chat-completions后,每一段完成的 VAD 音频直接发给音频模型。下面先给出这个模式的硬性限制,再以 Apple Silicon 上「llama.cpp + Gemma 4 12B」的全本地测试示例为主路径,走完配置、启动和验证;接远程 OpenAI 兼容服务作为可选分支。
这个模式的两条硬性限制
在动任何配置之前,先确认你的 LLM 端点满足以下条件(来自 README.md 的 "Direct Audio Input (No STT)" 一节和 module_arguments.py 中--stt的帮助文本):
--stt none只与--llm_backend chat-completions搭配。直接音频模式在--llm_backend responses-api下不受支持:一个模型可能通过/v1/chat/completions接受音频,却并不实现/v1/responses(OpenAI 的gpt-audio-1.5就是这种例子)。- 必须显式用
--model_name指定一个接受音频输入的模型。默认的gpt-5.6-terra只接受文本和图片输入,不接受音频。启用该模式前,核对服务商的模型文档和端点支持情况。
另外,音频在请求里的表示格式由--responses_api_audio_content_type控制(定义见 responses_api_language_model_arguments.py):
input_audio(默认):WAV 以 base64 直接内嵌;audio_url:以 base64 data URL 发送。
不同 OpenAI 兼容服务端只接受其中一种,选错会报内容类型错误。
准备全本地环境(Apple Silicon 主路径)
examples/gemma4-12b-macos/README.md 是仓库中唯一完整跑通--stt none的端到端示例,流程如下:
microphone -> browser demo -> Realtime server -> VAD -> Gemma 4 12B (native audio) speakers <- audio deltas <- Qwen3-TTS <- assistant response该示例的前置条件:
- 一台 Apple Silicon Mac。Q4 模型约 7.2 GB,建议 24 GB 或更多统一内存,给 Qwen3-TTS 留余量。
- 一个带 Gemma 4 Unified 多模态支持的较新 llama.cpp 构建。
- 一个包含 PR #298 的源码检出(即 speech-to-speech 仓库本身)。
uv、Homebrew 和一个现代浏览器。
安装或升级 llama.cpp:
brew install llama.cpp brew upgrade llama.cpp llama-server --version如果构建过旧,现象是语言模型能加载、但多模态 projector 报unknown projector type: gemma4uv,此时升级 llama.cpp。
在仓库根目录安装 speech-to-speech 环境:
uv sync首次运行会下载 Gemma GGUF、它的多模态 projector 以及本地 MLX 版 Qwen3-TTS 模型。
终端 1:启动音频输入 LLM
llama-server \ -hf ggml-org/gemma-4-12B-it-GGUF:Q4_0 \ -c 16384 \ -np 1 \ -fa on \ --host 127.0.0.1 \ --port 8080-hf会同时下载并加载 Q4 模型和它的多模态 projector。启动 speech-to-speech 之前,等 llama.cpp 打印出这两行:
loaded multimodal model listening on http://127.0.0.1:8080它关于「audio input 是 experimental」的警告来自 llama.cpp,属于预期现象。
终端 2:用 --stt none 启动 speech-to-speech 服务
uv run speech-to-speech serve \ --stt none \ --llm_backend chat-completions \ --tts qwen3 \ --model_name "ggml-org/gemma-4-12B-it-GGUF" \ --responses_api_base_url "http://127.0.0.1:8080/v1" \ --responses_api_api_key "" \ --responses_api_audio_content_type input_audio \ --responses_api_stream \ --qwen3_tts_mlx_quantization 6bit \ --min_silence_ms 300逐条说明影响本模式的关键参数:
--stt none:跳过 STT,把捕获到的 WAV 直接转发给 Gemma。--llm_backend chat-completions:走 llama.cpp 的/v1/chat/completions端点,这是能接受原生音频的端点。--model_name "ggml-org/gemma-4-12B-it-GGUF":必须显式指定音频输入模型。--responses_api_audio_content_type input_audio:当前 llama.cpp 构建支持的 payload 形状。--responses_api_api_key "":本地 llama.cpp 端点用空字符串(见 README 的 Responses API 后端表格)。--tts qwen3+--qwen3_tts_mlx_quantization 6bit:本地语音输出;在 Apple Silicon 上 Qwen3-TTS 默认走mlx-audio后端。--min_silence_ms 300:避免把词与词之间的极短停顿当成结束回合,同时保持端点检测灵敏。serve:带推测性回合修订、响应取消和标准 Realtime 事件生命周期运行 API。
等服务器开始监听ws://127.0.0.1:8765/v1/realtime后,再启动客户端。
连接客户端并验证
最简单的验证方式是仓库自带的无头麦克风/扬声器客户端:
uv run speech-to-speech talk \ --url ws://127.0.0.1:8765/v1/realtime正常说话、停顿以结束回合。判定链路是否打通的两个信号:
- 服务端日志出现
Audio input completed记录行(包含音频时长秒数、turn 编号与修订号),说明该段 VAD 音频已经越过 STT 阶段、进入 LLM 阶段。实现见 audio_input_notifier.py,它把完成的 VAD 音频直接桥接到 LLM 阶段。 - 稍后从扬声器听到 Qwen3-TTS 合成的助手回复。
要测试打断(barge-in)和回合修订,用浏览器 demo 更直观。在终端 3 运行:
SPEECH_TO_SPEECH_URL="ws://localhost:8765/v1/realtime" \ STARTUP_GREETING="" \ uv run --with-requirements demo/requirements.txt \ uvicorn --app-dir demo server:app --port 7860打开http://localhost:7860,点击 orb 并允许麦克风访问,正常说话、停顿结束回合。测试 barge-in 时请戴耳机,避免 TTS 播放回流进麦克风。STARTUP_GREETING置空可以让测试聚焦在第一轮语音上。用Ctrl-C停止 demo 与服务端。
可选分支:指向远程 OpenAI 兼容服务
如果音频输入模型不在本机,README 给出的通用命令只需要替换服务地址和模型名(下面代码块中的三处占位符必须替换为真实值):
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"YOUR_AUDIO_CAPABLE_MODEL:替换为你服务商接受的音频输入模型名;https://provider.example/v1:替换为该服务商的 OpenAI 兼容 base URL;$PROVIDER_API_KEY:你的服务商 API key。
这条路径对应的安装方式见 README Quickstart:pip install speech-to-speech(Python 3.10+),命令前不需要uv run。
遇到问题时按现象排查
以下条目全部来自 macOS 示例的 Troubleshooting 一节:
| 现象 | 处理 |
|---|---|
unknown projector type: gemma4uv | 升级 llama.cpp,然后确认llama-server --version已变化 |
unsupported content[].type | 保持--responses_api_audio_content_type input_audio;audio_url不被测试过的 llama.cpp 端点接受 |
| 没有麦克风输入 | 在浏览器中允许麦克风;若之前被拒绝,到 System Settings → Privacy & Security → Microphone 打开后刷新页面 |
| UI 连不上 | 确认 speech-to-speech 服务监听在8765端口,且 demo 使用了上面确切的SPEECH_TO_SPEECH_URL |
| WebRTC 返回 501 | 保持 demo 默认的 WebSocket 传输,或先安装webrtcextra |
| 助手听到自己 | 戴耳机;测试 barge-in 时不要传--block_mic_during_playback,该选项会在无头客户端播放期间刻意暂停麦克风捕获 |
| 回合结束得太早 | 把--min_silence_ms提到500或700;数值每提高多少,端点检测延迟就增加多少 |
| 内存紧张 | 停掉其他本地模型;保持-np 1;若 6-bit TTS 模型余量不足,改用--qwen3_tts_mlx_quantization 4bit |
边界与限制
--stt none模式下没有 STT 阶段,--enable_live_transcription的帮助文本写明它只对 parakeet-tdt 生效,因此该模式下不会有实时转写显示。- VAD 与 Smart Turn 端点检测仍然照常工作,
--min_silence_ms等参数依旧影响回合切分;--stt none改变的只是音频段之后的去向,而不是端点检测本身。 - 该模式对
--llm_backend responses-api明确不受支持,换回 responses-api 之前,把--model_name换回文本输入模型并恢复默认 STT(如parakeet-tdt)即可回到标准流水线。
【免费下载链接】speech-to-speechBuild voice agents with open-source models项目地址: https://gitcode.com/GitHub_Trending/sp/speech-to-speech
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考