110 lines
4.1 KiB
Markdown
110 lines
4.1 KiB
Markdown
# Owner 语音桌宠
|
||
|
||
这是一个 Python 语音桌宠运行程序。当前第一版先提供无 GUI 的真实实时语音循环:
|
||
|
||
`小杰小杰` 唤醒 -> 麦克风录音 -> VAD 切分 -> ASR 转文字 -> 携带本次进程内临时历史调用 LLM -> TTS 生成语音 -> 本机扬声器播放 -> 回到待机继续监听。
|
||
|
||
## 当前能力
|
||
|
||
- `owner_voice_pet run-live`:真实常驻语音循环。
|
||
- `owner_voice_pet run-live --once`:只跑一轮,便于验收。
|
||
- `.env` 直接读取配置,不要求导出 shell 环境变量。
|
||
- 唤醒词检测使用本地 `sherpa-onnx` KWS 模型,不走云端 ASR。
|
||
- `OWNER_SPEECH_PROVIDER=cloud|local`:选择云端语音模型或本地语音模型。
|
||
- 默认云端语音模型:`mimo-v2.5-asr`、`mimo-v2.5-tts`。
|
||
- 本地设备:`sounddevice` 读取麦克风,扬声器或 `afplay` 播放。
|
||
- 本地模型:`models/` 存放 `sherpa-onnx` VAD/STT 模型,目录不提交 Git。
|
||
- 临时上下文:同一次 `run-live` 进程内携带最近 user/assistant 历史,退出即清空。
|
||
|
||
## 首次准备
|
||
|
||
```bash
|
||
python3.11 -m venv .venv
|
||
.venv/bin/python -m pip install --upgrade pip
|
||
.venv/bin/python -m pip install -e '.[speech]'
|
||
cp .env.example .env
|
||
```
|
||
|
||
然后编辑 `.env`,填写本地密钥和模型配置。当前默认示例:
|
||
|
||
```dotenv
|
||
OWNER_LLM_BASE_URL=https://token-plan-cn.xiaomimimo.com/v1
|
||
OWNER_LLM_API_KEY=
|
||
OWNER_LLM_MODEL=mimo-v2.5
|
||
OWNER_LLM_API_STYLE=chat_completions
|
||
OWNER_WAKE_PROVIDER=local_kws
|
||
OWNER_WAKE_KEYWORDS_FILE=
|
||
OWNER_WAKE_KWS_THRESHOLD=0.25
|
||
OWNER_WAKE_KWS_SCORE=1.0
|
||
OWNER_SPEECH_PROVIDER=cloud
|
||
OWNER_ASR_MODEL=mimo-v2.5-asr
|
||
OWNER_TTS_MODEL=mimo-v2.5-tts
|
||
OWNER_TTS_VOICE=mimo_default
|
||
```
|
||
|
||
`OWNER_WAKE_PROVIDER=local_kws` 表示唤醒词“小杰小杰”由本地模型检测。`OWNER_SPEECH_PROVIDER=cloud` 只影响唤醒后的正式问题 ASR/TTS:它会把 VAD 切出来的用户问题片段发送到云端 ASR,不会上传连续麦克风流,也不会用云端判断唤醒。改成 `local` 时使用项目 `models/` 下的本地语音模型路径。
|
||
|
||
## 本地模型
|
||
|
||
即使默认走云端 ASR/TTS,也必须准备本地唤醒模型;同一脚本会下载 wake、VAD、STT 模型,便于切换到 `OWNER_SPEECH_PROVIDER=local`:
|
||
|
||
```bash
|
||
python3.11 scripts/download_speech_models.py --dir models
|
||
.venv/bin/python -m owner_voice_pet model-check --models-dir models
|
||
```
|
||
|
||
`models/` 已在 `.gitignore` 中,不会提交大模型文件。
|
||
|
||
本地唤醒关键词文件位于 `models/wake/keywords.txt`。如果真人唤醒不灵敏,可以先把 `.env` 中 `OWNER_WAKE_KWS_THRESHOLD` 调低,例如 `0.15`,再重新运行。
|
||
|
||
## 设备检查
|
||
|
||
```bash
|
||
.venv/bin/python -m owner_voice_pet device-check
|
||
```
|
||
|
||
输出里 `ok=true` 表示已检测到可用麦克风和扬声器。
|
||
|
||
## 运行
|
||
|
||
单轮验收:
|
||
|
||
```bash
|
||
.venv/bin/python -m owner_voice_pet run-live --once
|
||
```
|
||
|
||
常驻重复对话:
|
||
|
||
```bash
|
||
.venv/bin/python -m owner_voice_pet run-live
|
||
```
|
||
|
||
运行后终端会显示待机、唤醒命中、录音中、转写中、转写结果、思考中、播放中、恢复待机等状态。说“小杰小杰”等待唤醒命中后再提问;听到回复后可以再次说“小杰小杰”继续下一轮。本次进程内会携带临时历史,程序退出后不保存。
|
||
|
||
## 验证
|
||
|
||
```bash
|
||
.venv/bin/python -m compileall src tests scripts
|
||
.venv/bin/python -m unittest discover -s tests
|
||
.venv/bin/python -m owner_voice_pet acceptance
|
||
.venv/bin/python -m owner_voice_pet validate-assets
|
||
.venv/bin/python -m owner_voice_pet security-check
|
||
.venv/bin/python -m owner_voice_pet model-check --models-dir models
|
||
.venv/bin/python -m owner_voice_pet device-check
|
||
openspec validate --all --strict
|
||
```
|
||
|
||
LLM smoke:
|
||
|
||
```bash
|
||
.venv/bin/python -m owner_voice_pet llm-smoke --no-stream --message '用一句中文回复:小杰在线。'
|
||
```
|
||
|
||
## 安全约束
|
||
|
||
- API key 只写入本地 `.env`,`.env` 不提交 Git。
|
||
- `models/`、`.venv/` 和临时音频文件不提交 Git。
|
||
- 默认不持久化麦克风原始音频。
|
||
- 云端 ASR 只接收 VAD 切分后的语音片段。
|
||
- `security-check` 会扫描已跟踪文本文件中的 `sk-...` 和 `tp-...` 形式密钥。
|