社区活动室里,老人说:“明天下午三点提醒我去社区活动室参加书法活动。”语音助手要先听清楚,再把时间和事项读回来;得到本人确认后,才应该保存提醒。识别错一个时间,影响的不只是转写分数。

这篇用一条本地流程演示:FunASR 转写,人工校对,Qwen 整理成待确认字段,CosyVoice 读回确认。示例用 macOS 合成的虚构语音,不含真实老人、社区居民、姓名、病情或联系方式。它是本地模型推理原型,没有调用日历或系统提醒,也没有做真实老人可用性测试;首次准备模型时需要联网下载。

先把三步拆开

步骤 做什么 继续条件
识别 FunASR 把语音转成文字 人工核对时间、地点和事项
整理 Qwen 把校对后的文字变成日期、时间、事项草稿 字段齐全且用户看得懂
读回 CosyVoice 读出摘要 本人明确确认后,应用才可进入保存提醒的步骤

任何一步没听清、时间不完整或用户说“不对”,都停下来追问;不要让模型猜日期,也不要在后台自动创建提醒。这里没有接日历工具,所以所有输出都只是 draft_only 草稿。

准备本地环境

练习包里有一段 5 秒的合成语音、转写和语音脚本:下载社区语音助手本地练习包。第一次运行 FunASR 和 CosyVoice 会下载模型,分别约 1 GB 和数 GB;Qwen3.8-27B 也需要较多磁盘和内存。本文实测机是 64 GB 的 M1 Max。模型准备好后,语音与文本推理都在本机进行。需要留意:本次 CosyVoice 初始化日志还显示它向 ModelScope 查询了可选 WeText 模型的版本和文件元数据;这些请求不含练习音频或提醒文本,因此首次准备环境并非完全离线。

不同模型依赖分开装:FunASR 用 Python 3.11 环境,CosyVoice 上游示例用 Python 3.10 环境;安装方式和运行参数以FunASR 文档和CosyVoice 官方安装说明为准。Qwen 用本地 Ollama;没有模型时先安装并运行 ollama pull qwen3.8:27b。练习脚本通过 Ollama 的本机 /api/chat 接口请求 JSON,不配置工具调用,也不上传识别文本。

FunASR 脚本固定使用 ModelScope checkpoint iic/speech_seaco_paraformer_large_asr_nat-zh-cn-16k-common-vocab8404-pytorch 的 v2.0.4,并把 device 设为 mps。该模型卡列明 Apache-2.0;FunASR 软件包和模型权重是不同许可对象,换 checkpoint 时要重新看对应模型卡。

1. 先听样音,再校对识别结果

解压练习包后运行:

python scripts/transcribe.py input/reminder.wav output/asr.json

脚本会输出原始识别文字和加载、推理耗时。此次原始结果把字拆开了:

明 天 下 午 三 点 提 醒 我 去 社 区 活 动 室 参 加 书 法 活 动

我逐字核对合成输入后,才整理成供下一步使用的文本:

明天下午三点,提醒我去社区活动室参加书法活动。

不要把语音识别直接当成用户确认。对老人实际使用时,可以让屏幕显示大字并读回关键信息;用户可选“对”“修改”或“找工作人员”。嘈杂环境、方言、较轻声音和专名都可能让转写变错,应保留重听和人工更正入口。FunASR 的模型别名可能变化,因此示例明确写出 checkpoint 与 revision;见模型卡。

2. 用 Qwen 整理成待确认草稿

把人工核过的文本传给脚本:

OLLAMA_MODEL=qwen3.8:27b python scripts/qwen_intent.py \
  '明天下午三点,提醒我去社区活动室参加书法活动。' \
  output/intent.json

本机测试结果整理出了“明天”“15:00”和“去社区活动室参加书法活动”,同时固定标为:

{
  "requires_confirmation": true,
  "confirmed": false,
  "action": "draft_only"
}

再试一句缺时间的输入:

OLLAMA_MODEL=qwen3.8:27b python scripts/qwen_intent.py \
  '明天提醒我去社区活动室参加书法活动。' \
  output/intent-missing-time.json

Qwen 留空 time_24h,把它放进 missing_fields,并给出追问草稿。模型输出即使是合法 JSON,也不代表意思正确;检查“明天”是否被误换成具体日期、三点是否误解成凌晨、事项是否被扩写。只有真实用户读回后明确确认,应用层才可以进入保存提醒的步骤。

此示例没有提供任何日历、联系人、电话或系统提醒工具;脚本还会把 confirmed 强制设为 false。不要把这段示例改成“模型返回 JSON 就自动执行”,尤其不要让它安排就医、用药剂量、转账、紧急呼叫或替用户联系他人。

3. 让 CosyVoice 读回确认

用完整确认句生成样音:

COSYVOICE_ROOT=/path/to/CosyVoice \
  python scripts/speak.py \
  '以下是 AI 合成语音示例。好的,我先复述一遍:明天下午三点,您要去社区活动室参加书法活动。请问时间和事项对吗?在您明确确认前,我不会创建提醒。' \
  output/reminder-confirmation.wav

本次用 Fun-CosyVoice3-0.5B-2512 本机合成了 14.44 秒音频,耗时 42.23 秒。初始化时日志还显示向 ModelScope 查询可选 WeText 模型元数据;这不是音频或提醒文本上传,但说明首次初始化会有网络请求。先听AI 合成语音示例,再用手机外放或耳机检查语速、停顿和时间是否清楚。Fun-CosyVoice3 的这个接口使用零样本参考音频;练习脚本只引用上游仓库附带的 demo 音频,没有录制或克隆用户、老人或家属的声音。实际项目要确认参考音频授权;不要用老人语音做声纹仿制,也不要把“像某个人”作为未授权功能。CosyVoice 模型卡

本机实测与适用范围

项目 实测结果
FunASR 1.4.16 / SeACo Paraformer v2.0.4 / MPS;首次下载并加载约 90.04 秒,5.16 秒语音推理 2.61 秒;识别内容正确,但输出需要去掉字间空格并补标点
Qwen Ollama 本机 qwen3.8-27b:latest;完整提醒整理 16.08 秒,缺时间对照输入 6.03 秒;后者没有猜时间
CosyVoice Fun-CosyVoice3-0.5B-2512;14.44 秒输出耗时 42.23 秒,约为音频长度的 2.9 倍;这台机器上的单句批量合成不满足实时响应
回读复核 再用 FunASR 转写合成音频,识别到了日期、时间、事项、确认问句和“不会创建提醒”;这只是自动交叉检查,不代替真人听感评估

整个实测只用一段人工合成的普通话和一个缺少时间的文本对照;它不能说明方言、噪声、不同年龄声音或辅助设备环境下的效果,也没有邀请老人试用。上线前还要由目标用户和工作人员检查听懂率、误识别后的恢复方式、语音音量与反馈入口。

声音可能关联到具体个人。实际采集前要说明用途、留存时间和删除方式,只保存完成任务所需的信息;本地运行不替代告知、授权和机构的数据管理要求。《个人信息保护法》。如果把合成音频、图片或教程发布到网上,应主动声明 AI 生成并使用平台提供的标识功能;本次音频开头带有“AI 合成语音示例”,封面也会加“AI生成封面”。《人工智能生成合成内容标识办法》