# 本地调试指南 本文用于在本机启动 PostgreSQL 连接、中文 FunASR、Rust API 和微信小程序,并验证短录音、长录音及多课节汇总。 ## 1. 服务关系 ```text 微信小程序 -> Rust API(127.0.0.1:8080) -> PostgreSQL -> FunASR(127.0.0.1:10095) ``` 本地录音转写的核心是 FunASR,当前组合为: - Paraformer:中文语音识别。 - FSMN-VAD:检测并切分有效语音。 - CT-Transformer:恢复中文标点。 - PyTorch:CPU 推理运行时。 Rust API 负责音频保存、持久化任务队列、重试、课节状态和反馈汇总。小程序每 8 分钟自动切片,并每 3 秒无感刷新转写状态。 ## 2. 当前主机资源实测 测试主机为 Apple Silicon、10 核 CPU、16 GB 统一内存,配置为 CPU 单并发: | 项目 | 实测值 | | --- | --- | | FunASR 模型缓存 | 约 2.1 GB | | Python 虚拟环境 | 约 871 MB | | 模型加载后的物理内存 | 约 2.8 GB | | 进程历史内存峰值 | 约 4.9 GB | | 8 分钟、16 kHz、单声道、48 kbps MP3 | 约 44.8 秒完成 | | 推理期间 CPU | 约 90% 至 132%,即约 1 至 1.3 个 CPU 核 | 8 分钟数据使用重复的清晰中文样本测得,真实课堂中的噪声、停顿和说话人数会影响耗时和识别质量。 容量建议: - 当前单教师或低并发调试:不需要 GPU,当前 16 GB 主机足够。 - CPU 部署最低建议:4 vCPU、8 GB 内存;8 GB 可能发生交换,16 GB 更稳妥。 - 多教师并发:先保持单并发观察队列;若片段持续积压,再考虑增加 CPU 实例或 NVIDIA GPU。 - GPU 是可选优化,不是运行前提。CUDA 部署需要单独的 CUDA/PyTorch 镜像,当前 CPU 镜像不能只修改 `ASR_DEVICE=cuda`。 - GPU 部署建议从 8 GB 显存起步并用真实课堂录音压测。当前 Apple Silicon 配置没有使用 Apple GPU。 - `ASR_WORKER_CONCURRENCY` 和 `ASR_MAX_CONCURRENCY` 应保持一致;每提高一个并发都要重新观察内存和吞吐。 ## 3. 首次准备 在项目根目录执行: ```bash cd /Users/zhangheng/project/ai/miniprogram/teaching-feedback-assistant ``` 确认 `server/.env` 存在,并填写可访问的 `DATABASE_URL`。不存在时再复制示例,避免覆盖现有配置: ```bash test -f server/.env || cp server/.env.example server/.env ``` 本地 FunASR 默认配置如下,无需腾讯云密钥: ```env ASR_PROVIDER=local LOCAL_ASR_URL=http://127.0.0.1:10095 ASR_REQUEST_TIMEOUT_SECONDS=1800 ASR_WORKER_CONCURRENCY=1 ASR_JOB_LEASE_SECONDS=3600 ``` 首次准备 Python 环境: ```bash cd asr-service python3 -m venv .venv .venv/bin/python -m pip install --upgrade pip .venv/bin/python -m pip install -r requirements.txt cd .. ``` 模型首次启动会下载约 2.1 GB 到 `asr-service/.models`。`.venv` 和 `.models` 均已被 Git 和微信小程序打包忽略。 ## 4. 启动全部服务 ### 4.1 执行数据库迁移 每次拉取到新迁移后执行一次: ```bash cd server cargo run --bin migrate cd .. ``` 看到 `PostgreSQL migrations completed` 表示成功。 ### 4.2 启动 FunASR 终端一: ```bash cd asr-service MODELSCOPE_CACHE=.models .venv/bin/uvicorn app:app \ --host 127.0.0.1 \ --port 10095 \ --no-access-log ``` 另一个终端检查: ```bash curl http://127.0.0.1:10095/health ``` 预期结果: ```json {"status":"ok","model":"paraformer-zh","device":"cpu"} ``` 首次下载或缓存加载期间端口可能暂不可用,应等待模型完全加载。 Docker 方式可替代本机 Python: ```bash docker compose -f compose.asr.yml up --build -d docker compose -f compose.asr.yml logs -f funasr ``` ### 4.3 启动 Rust API 终端二: ```bash cd server cargo run ``` 检查完整链路: ```bash curl http://127.0.0.1:8080/health | jq . ``` 正常状态应包含: ```json { "status": "ok", "database_configured": true, "speech_configured": true, "speech_available": true, "speech_provider": "local-funasr" } ``` 接口文档: ### 4.4 启动微信开发者工具 终端三,在项目根目录执行: ```bash cli open \ --project /Users/zhangheng/project/ai/miniprogram/teaching-feedback-assistant \ --port 63097 \ --lang zh ``` 自动预览编译检查: ```bash cli auto-preview \ --project /Users/zhangheng/project/ai/miniprogram/teaching-feedback-assistant \ --port 63097 \ --lang zh \ --info-output /tmp/teaching-feedback-preview.json ``` 开发者工具模拟器默认访问 `http://127.0.0.1:8080`。进入小程序“我的”页面,应看到“服务、数据库和语音转录正常”。 ## 5. 录音测试流程 ### 短录音 1. 打开“反馈生成”。 2. 点击“语音录入”,录制 10 至 30 秒中文。 3. 点击“结束录音”。 4. 页面短暂显示“正在处理”。 5. 转写完成后文字应自动加入反馈内容。 短录音条件为不超过 60 秒,且转写文本未超过后端短文本限制。 ### 长录音 1. 录制超过 60 秒的中文。 2. 结束后等待状态变成“已就绪”。 3. 主按钮变为“生成反馈”。 4. 点击一次后,转写内容会汇总进反馈草稿。 ### 多课节汇总 1. 录制并结束第一节课。 2. 再次点击“语音录入”录制下一节。 3. 重复完成多节录音。 4. 所有课节就绪后点击一次“生成反馈”。 单节录音超过 8 分钟时,小程序会自动结束当前片段并立即开始下一片段,用户无需操作。 ## 6. 故障恢复测试 ### FunASR 未启动 停止 FunASR 后录音,Rust API 仍会保存音频,页面保持“正在处理”。重新启动 FunASR 后,后台队列会自动继续。 ### Rust 在推理中退出 任务使用租约避免多个工作线程重复处理。默认租约为 3600 秒。调试崩溃恢复时,可在 `server/.env` 临时设置: ```env ASR_JOB_LEASE_SECONDS=60 ``` 重新启动 Rust API 后,超出租约的任务会再次被领取。生产环境应使用足够覆盖最长片段推理时间的租约。 ### 转写失败 点击页面中的语音状态,可查看课节状态并重试失败片段。音频保存在 `server/data/audio`,转写失败不会立即删除原文件。 ## 7. 常见问题 ### `speech_configured=true` 但 `speech_available=false` - FunASR 尚未启动或模型仍在加载。 - `10095` 端口被占用。 - `LOCAL_ASR_URL` 配置错误。 检查: ```bash lsof -nP -iTCP:10095 -sTCP:LISTEN curl http://127.0.0.1:10095/health ``` ### `database_configured=false` 或数据接口返回 503 检查 `server/.env` 中的 `DATABASE_URL`,然后重新执行迁移并启动 API。 ### 微信模拟器无法连接 API ```bash lsof -nP -iTCP:8080 -sTCP:LISTEN curl http://127.0.0.1:8080/health ``` 再到小程序“我的”页面确认 API 地址为 `http://127.0.0.1:8080`。 ### 真机无法访问 `127.0.0.1` 真机中的 `127.0.0.1` 指手机自身。局域网调试时: 1. 将 `server/.env` 的 `HOST` 改为 `0.0.0.0`。 2. 确认手机和电脑连接同一网络。 3. 在“我的”页面将 API 地址改为 `http://<电脑局域网IP>:8080`。 4. 检查系统防火墙和微信开发者工具的域名校验设置。 正式环境必须使用微信允许的 HTTPS 合法域名。 ## 8. 代码检查 小程序: ```bash npm run typecheck ``` Rust: ```bash cd server cargo fmt --check cargo test cargo clippy --all-targets -- -D warnings ``` FunASR 服务: ```bash python3 -m py_compile asr-service/app.py asr-service/.venv/bin/python -m pip check ``` ## 9. 停止服务 前台运行时,在 FunASR 和 Rust API 各自终端按 `Ctrl+C`。 Docker 方式: ```bash docker compose -f compose.asr.yml down ``` 确认端口已经释放: ```bash lsof -nP -iTCP:8080 -sTCP:LISTEN lsof -nP -iTCP:10095 -sTCP:LISTEN ``` 正常停止服务不会删除 `asr-service/.models` 模型缓存。除非希望重新下载模型,否则不要删除该目录。