256 lines
11 KiB
Plaintext
256 lines
11 KiB
Plaintext
1. ## 🎯 当前使用的ASR模型
|
||
### 模型名称:SenseVoice (RKNN版本)
|
||
### 模型架构:
|
||
- 编码器 : sense-voice-encoder.rknn - RKNN格式的神经网络模型
|
||
- 嵌入层 : embedding.npy - 词嵌入矩阵
|
||
- 分词器 : chn_jpn_yue_eng_ko_spectok.bpe.model - BPE分词模型
|
||
### 模型特点:
|
||
1. 多语言支持 - 支持中文、日文、粤语、英文、韩文
|
||
2. RKNN加速 - 针对RK3588等Rockchip芯片优化
|
||
3. ITN支持 - 启用了逆文本归一化(Inverse Text Normalization),提高数字/日期识别准确性
|
||
|
||
2. ## TTS模型信息
|
||
### 模型名称
|
||
Sherpa-ONNX VITS - 中文版本(sherpa-onnx-vits-zh-ll)
|
||
|
||
### 模型文件
|
||
位于 app/src/main/assets/tts_model/sherpa-onnx-vits-zh-ll/ 目录:
|
||
|
||
- model.onnx - ONNX格式的声学模型
|
||
- tokens.txt - 音素/字符映射表
|
||
- lexicon.txt - 发音词典
|
||
- phone.fst - 音素转换规则
|
||
- date.fst - 日期归一化规则
|
||
- number.fst - 数字归一化规则
|
||
- new_heteronym.fst - 多音字处理规则
|
||
|
||
3. ## VAD模型信息
|
||
### 模型名称
|
||
Silero VAD (Voice Activity Detection)
|
||
|
||
### 模型文件
|
||
- 文件路径: assets/vad_model/silero_vad.onnx
|
||
- 格式:ONNX格式
|
||
|
||
4. 模型部署对比
|
||
模型 类型 格式 RKNN加速 推理设备 配置
|
||
ASR SenseVoice .rknn ✅ 是 NPU RKNN Runtime
|
||
VAD Silero VAD .onnx ❌ 否 CPU provider="cpu"
|
||
TTS Sherpa-ONNX VITS .onnx ❌ 否 CPU ONNX Runtime
|
||
|
||
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
||
│ AudioProcessor │────▶│ VadManager │────▶│ ASR Queue │
|
||
│ (录音+增益) │ │ (语音活动检测) │ │ (Channel队列) │
|
||
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
||
│
|
||
┌─────────────────────────┘
|
||
▼
|
||
┌─────────────────┐
|
||
│ runAsrWorker │
|
||
│ (协程工作器) │
|
||
└─────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────┐
|
||
│ SenseVoice │
|
||
│ (RKNN推理) │
|
||
└─────────────────┘
|
||
|
||
5. live2d, Haru的动作
|
||
由于没有官方文档,基于Live2D模型的常见设计模式,我建议以下映射:
|
||
|
||
### 🎭 开心类情绪
|
||
- haru_g_m22 眯眼微笑
|
||
- haru_g_m21 跳动微笑
|
||
- haru_g_m18 手收背后微笑
|
||
- haru_g_m09 微微鞠躬
|
||
- haru_g_m08 深深鞠躬
|
||
|
||
|
||
### 😢 伤心类情绪
|
||
- haru_g_m25 - 扁嘴
|
||
- haru_g_m24 - 低头斜看地板,收手到背后
|
||
- haru_g_m05 扁嘴,张开双手
|
||
- haru_g_m16 双手捧腮,思考
|
||
|
||
### 😠 愤怒类情绪
|
||
- haru_g_m11 双手交叉,摇头,扁嘴
|
||
- haru_g_m04 双手交叉,点头
|
||
- haru_g_m03 双手交叉,点头
|
||
|
||
### 😌 平和类情绪
|
||
- haru_g_m15 双手交叉在胸前
|
||
- haru_g_m07 举起左手
|
||
- haru_g_m06 举起右手
|
||
- haru_g_m02 双手放到背后
|
||
- haru_g_m01 点头
|
||
|
||
|
||
### 😲 惊讶类情绪
|
||
- haru_g_m26 - 后退一步(适合:惊讶、吃惊)
|
||
- haru_g_m12 摆手,摇头
|
||
|
||
### 😕 困惑类情绪
|
||
- haru_g_m14 身体前倾,皱眉
|
||
- haru_g_m13 身体前倾,双手分开
|
||
|
||
### 害羞
|
||
- haru_g_m19 脸红微笑
|
||
|
||
|
||
### 担心
|
||
- haru_g_m20 手指点腮,思考,皱眉
|
||
|
||
### ❤️ 关心类情绪
|
||
- haru_g_m17 靠近侧脸
|
||
|
||
6. 其实可以抄一下讯飞的超脑平台的功能:
|
||
https://aiui-doc.xf-yun.com/project-2/doc-397/
|
||
|
||
7. 人脸检测使用的是RKNN zoo里的 retinaface模型,转成了rknn格式,并且使用了wider_face的数据集(验证集)进行了校准,下载地址:
|
||
https://www.modelscope.cn/datasets/shaoxuan/WIDER_FACE/files
|
||
|
||
8. 人脸识别模型是insightface的r18模型,转成了rknn格式,并且使用了 lfw 的数据集进行了校准,下载地址:
|
||
https://tianchi.aliyun.com/dataset/93864
|
||
|
||
9. 本地LLM,用的是 rkllm 模型,由于内存限制,只能用较小的模型,如 Qwen3-0.6B-rk3588-w8a8.rkllm。
|
||
|
||
10. 数字人交互设计说明书(优化版)
|
||
核心原则
|
||
* 尊重用户:给用户足够的反应时间,不抢话,不催促。
|
||
* 主动但不打扰:用户沉默时适度引导,但不强行交互;数字人拥有独立的内心活动,即便无人交互也保持“生命感”。
|
||
* 个性化:记住每个用户的偏好、名字、对话历史,并据此调整问候和回应。
|
||
* 动作同步:Live2D人物的表情与动作与当前状态、情绪、内心活动相匹配。
|
||
* 持续内心活动:数字人即使在没有用户时也会进行“回忆”或“思考”,并通过文字展现,用户可随时打断并询问想法。
|
||
|
||
状态定义
|
||
[空闲状态]:无人,数字人无内心活动(省电模式)。
|
||
[回忆状态]:无人,数字人正在根据记忆产生内心想法,通过表情表现。
|
||
[问候状态]:检测到用户,主动打招呼。
|
||
[等待回复状态]:问候后或对话间隙,等待用户回复。
|
||
[对话状态]:正在与用户交流,根据情绪调整动作。
|
||
[主动引导状态]:用户沉默但仍在画面中,数字人主动开启新话题。
|
||
[告别状态]:用户离开画面,数字人告别。
|
||
[空闲状态]
|
||
动作 : haru_g_idle (待机动作)
|
||
↓
|
||
检测到人脸 → 等待1秒(让人脸稳定)
|
||
↓
|
||
[问候状态]
|
||
动作 :
|
||
- 认识用户: haru_g_m22 (高兴动作)
|
||
- 不认识: haru_g_m01(中性动作)
|
||
AI问候(根据是否认识,节日,时间等因素个性化)
|
||
启动20秒计时器
|
||
↓
|
||
[等待回复状态]
|
||
动作 : haru_g_m17
|
||
↓
|
||
├─ 如果用户按下了麦克风按钮 → 进入[对话状态]
|
||
│ 动作 :根据对话情绪动态调整
|
||
│ - 开心: haru_g_m22 / haru_g_m21 / haru_g_m18 / haru_g_m09 / haru_g_m08
|
||
│ - 悲伤: haru_g_m25 / haru_g_m24 / haru_g_m05 / haru_g_m16
|
||
│ - 惊讶: haru_g_m26 / haru_g_m12
|
||
│ - 愤怒: haru_g_m04 / haru_g_m11 / haru_g_m04
|
||
│ - 平静: haru_g_m15 / haru_g_m07 / haru_g_m06 / haru_g_m02 / haru_g_m01
|
||
│ AI根据内容回应,持续直到用户说“再见”
|
||
│ ↓
|
||
│ (用户离开)→ 进入[告别状态]
|
||
│
|
||
└─ 如果20秒内无回复
|
||
↓
|
||
检查用户是否还在画面
|
||
↓
|
||
├─ 如果还在 → [主动引导状态]
|
||
│ 动作 : haru_g_m15 / haru_g_m07 (中性动作)
|
||
│ AI开启轻松话题(如“我出一道数学题考考你吧?1+6等于多少?”)
|
||
│ 等待10秒
|
||
│ ↓
|
||
│ ├─ 回复 → 进入[对话状态]
|
||
│ └─ 没回复 → 换话题,如,我们上完厕所应该干什么呀?最多重复3次
|
||
│ 动作 : haru_g_m22 / haru_g_m18
|
||
│ (重复尝试)→ 再次等待10秒
|
||
│ (3次后仍无回复)→ 回到[等待回复状态]
|
||
│
|
||
└─ 如果已离开 → [告别状态]
|
||
动作 : haru_g_idle (告别后待机)
|
||
↓
|
||
3秒后 → 回到[空闲状态]
|
||
|
||
[空闲状态] (长时间无人)
|
||
↓
|
||
如果持续30秒无人 → 进入[回忆状态]
|
||
动作 : haru_g_m15
|
||
回顾之前的聊天记录,生成想法,不发声,把想法显示在屏幕上
|
||
↓
|
||
如果检测到人脸 → 立即中断回忆,进入[问候状态]
|
||
|
||
|
||
[回忆状态] 被用户询问“你在想什么?”
|
||
↓
|
||
AI说出最近的想法(如“我刚才在想,上次你说你喜欢蓝色...”)
|
||
↓
|
||
进入[问候状态]或直接进入[对话状态](根据用户后续反应)
|
||
|
||
[告别状态] (用户离开后)
|
||
动作 : 简短告别,用语音,→ 等待3秒 → 回到[空闲状态]
|
||
|
||
11. ## 用户类型区分
|
||
1. guest 用户 :
|
||
|
||
- 默认用户ID,当没有检测到人脸时使用
|
||
- 在 Live2DChatActivity.kt 中初始化为 private var activeUserId: String = "guest"
|
||
- 表示未通过人脸识别的临时用户
|
||
2. face_ 用户 :
|
||
|
||
- 通过人脸识别生成的用户ID,格式为 face_<数字>
|
||
- 在 FaceDetectionPipeline.kt 中生成: lastFaceIdentityId = match.matchedId?.let { "face_$it" }
|
||
- 表示通过人脸识别的正式用户
|
||
## 转换逻辑
|
||
当系统检测到人脸时,会触发以下流程:
|
||
|
||
1. 人脸检测 : FaceDetectionPipeline 检测到人脸
|
||
2. 身份识别 : FaceRecognizer 尝试识别用户身份
|
||
3. ID生成 :如果是新用户,生成新的 face_<数字> ID
|
||
4. 回调更新 :通过 onPresenceChanged 回调将 faceIdentityId 传递给 Live2DChatActivity
|
||
5. ID切换 : Live2DChatActivity 中的 interactionController.onFacePresenceChanged 会调用 handler.onRememberUser(faceIdentityId, recognized)
|
||
6. 更新活跃用户 : onRememberUser 方法会将 activeUserId 更新为 faceIdentityId
|
||
因此,当检测到人脸时, guest 用户会自动切换为 face_ 用户。
|
||
|
||
face_profiles 和 user_memory 表之间的关联是通过 ID转换 实现的,没有专门的关联表:
|
||
|
||
## 关联机制
|
||
1. ID转换规则 :
|
||
- face_profiles 表中的 id 字段(数字)→ 转换为 face_<id> 格式
|
||
- 例如: id=1 → face_1
|
||
- 这个转换在 FaceDetectionPipeline.kt 中实现: lastFaceIdentityId = match.matchedId?.let { "face_$it" }
|
||
2. 关联流程 :
|
||
- 系统检测到人脸后,从 face_profiles 表中查找匹配的记录,获取 id
|
||
- 将 id 转换为 face_<id> 格式的用户ID
|
||
- 这个用户ID被用作 user_memory 表中的 userId 字段
|
||
- 通过这个 userId ,两个表就建立了关联
|
||
|
||
12. 使用 adb shell 直接操作sqlite数据库
|
||
1. 进入设备 shell
|
||
adb shell
|
||
2. 找到应用数据库
|
||
# 进入应用数据目录
|
||
run-as com.digitalperson
|
||
|
||
# 进入数据库目录
|
||
cd databases
|
||
|
||
# 查看数据库文件
|
||
ls -la
|
||
3. 使用 sqlite3 命令查看数据库
|
||
bash
|
||
# 打开数据库
|
||
sqlite3 your_database.db # digital_human.db face_feature.db
|
||
|
||
# 在 sqlite3 提示符下执行命令:
|
||
.tables # 查看所有表
|
||
.schema table_name # 查看表结构
|
||
SELECT * FROM table_name; # 查询数据
|
||
.headers on # 显示列名
|
||
.mode column # 列模式显示
|
||
.quit # 退出 |