# 功能说明
AIUI的离线识别是为了提高常见命令词的识别速度,提升体验效果加入的。
AIUI在没有离线识别的情况下,对例如上一首,下一首,暂停播放这些音乐控制命令,都会将音频上传到AIUI云端,云端在处理后将听写和语义的结果再下发到客户端。
AIUI开启离线命令词识别功能后,会在音频送到AIUI云端的同时送到本地的离线识别引擎进行识别。
# 感性认识
离线功能的核心是编写的离线命令词语法。先举个例子,感性的认识一下
#BNF+IAT 1.0 UTF-8;
!grammar main;
!slot <sleep>;
!start <sleep>;
<sleep>:你去睡觉吧!id(2001)|你去休息吧!id(2001)|睡觉去吧!id(2001)
当如上的离线语法构建启用后,你在说‘你去睡觉吧’,‘你去休息吧,‘睡觉去吧’中任何一句后,离线引擎都会识别成功返回对应项的信息结果给你(返回结果在下文中有示例)。
离线命令词并不会返回听写或者语义的结果,它是把音频与编写的离线语法中的规则做匹配,返回离线语法中对应匹配项的信息。
# 开启方法
① 云端模式:
"speech":{
"intent_engine_type":"cloud"
}
AIUI的默认模式,不开启离线功能,全部使用云端语义和听写功能。
② 本地模式:
"speech":{
"intent_engine_type":"local"
}
AIUI完全离线,只使用本地的离线命令词功能。 在此模式下AIUI功能非常受限,只能完成简单命令词的识别。
③ 混合模式:
"speech":{
"intent_engine_type":"mixed"
}
混合模式下,音频会同时送到本地离线引擎和云端解析。 结果选择策略是哪个先返回有效结果,就采用哪个。
另外需要注意aiui.cfg中要包含如下配置项
// 离线语法识别参数
"asr":{
"threshold":"50",
"res_type":"assets",
"res_path":"asr/common.jet"
}
# 使用步骤
# 离线命令语法编写
离线命令语法是使用巴科斯范式(BNF)描述语音识别的语法。语法文件包括HEADER和BODY。
!grammar main;
!slot <sleep>;
!start <sleep>;
<sleep>:你去睡觉吧!id(2001)|你去休息吧!id(2001)|睡觉去吧!id(2001)
语法编写的具体文档可以参考讯飞云平台上识别语法分享–在线语法和离线语法编写指南 (opens new window)。 章节附录也有AIUIProdutDemo使用离线语法示例。
# 构建离线语法
在AIUI中定义了CMD_BUILD_GRAMMAR
命令构建语法。
SDK使用:
AIUIMessage buildGrammar = new AIUIMessage(AIUIConstant.CMD_BUILD_GRAMMAR,
0, 0, grammar_str, null); //grammar_str为编写的离线语法
mAIUIAgent.sendMessage(buildGrammar);
串口:
//构造如下json,放入主控消息类型中发送给AIUI。
{
"type": "aiui_msg",
"content": {
"msg_type": 16, //CMD_BUILD_GRAMMAR 重置AIUI唤醒状态
"arg1": 0,
"arg2": 0,
"params": "grammar_str" //grammar_str为编写的离线语法
}
}
每次调用命令构建的语法都会覆盖先前对应的GrammerID的离线语法。
该命令是有返回的,所以通过EVENT_CMD_RETURN事件的arg2参数可以判断构建结果。
构建使用离线语法中的错误码参考AIUI错误码。
# 离线语法槽更新
在离线语法中有槽的定义(具体定义可以参考上面提到的语法文档),主要作用就是在语法构建生效后,可以动态更新当前生效的语法中的部分内容。
定义了一个打电话的离线语法
!slot contact
!start <call>
<call>:打电话给<contact>
<contact>:张三|李四
已经通过AIUI构建了语法,并且使用了。假如当前通讯录有新联系人添加,那我们也要更新离线语法中(slot)槽contact的内容:
{
"name": "contact", //槽名称
"content":"张三\n李四\n王二\n" //词表内容
}
使用命令CMD_UPDATE_LOCAL_LEXICON(17),将params设置为上面的json,发送给AIUI即可。
SDK或者串口的具体使用方式可以参考上面构建语法时的操作。
# 结果解析
通过解析结果params下的sub字段,判断结果属于哪种类型,离线命令词识别结果sub字段为asr
。
离线命令识别结果(asr)举例如下:
"result": {
"sid": "",
"intent": {
"ws": [{
"slot": "<sleep>",
"cw": [{
"w": "你去睡觉吧",
"id": 2001,
"sc": 54
}]
}],
"rc": 0
}
},
"info": {
"data": [{
"params": {
"sub": "asr"
}
}]
}
主要解析intent中ws下的字段,根据先前编写的离线语法文件,很容易理解代表的字段。
id的字段跟语法中声明的对应,id的声明方法参考上面提到的语法文档。
# 注意事项
# 离线命令识别与线上语义结合
AIUI在纯离线模式下,功能很受限。如果需要使用离线命令的话,推荐使用混合模式,提高常见命令短语的识别速度,提升体验。
离线命令词的功能会比线上识别要弱一点,所以可能存在说法在离线命令词没有识别结果,在云端听写会正确听写结果。 如果在云端没有配置对应的语义,本次结果就会拒识。所以混合模式下,在本地定义离线命令语法的同时在云端说法也有对应的语义,这样会减少拒识的情况,提升体验。
# 附录
# AIUIProductDemo默认使用的离线语法文件
#BNF+IAT 1.0 UTF-8;
!grammar main;
!slot <music>;
!slot <sleep>;
!slot <smarthome>;
!slot <devices>;
!start <operation>;
<operation>:<music>|<sleep>|<smarthome>;
<music>:上一首!id(1001)
|下一首!id(1002)|换一首!id(1002)
|暂停播放!id(1003)|暂停!id(1003)
|继续!id(1004)|继续播放!id(1004)
|大点声!id(1005)|大点儿声!id(1005)|增大音量!id(1005)|再大点声!id(1005)|听不清!id(1005)
|小点声!id(1006)|小点儿声!id(1006)|降低音量!id(1006)|再小点声!id(1006)|太吵了!id(1006);
<sleep>:你去睡觉吧!id(2001)|你去休息吧!id(2001)|睡觉去吧!id(2001)
|休息去吧!id(2001)|不是跟你说话!id(2001)|不是在跟你说话!id(2001)
|没跟你说话!id(2001)|没和你说话!id(2001)|跪安吧!id(2001);
<smarthome>:打开台灯!id(3001)
|打开电灯!id(3001)|把灯打开!id(3001)|把电灯打开!id(3001)|把台灯打开!id(3001)|开灯!id(3001)
|关灯把电灯关了!id(3002)|关闭台灯!id(3002)|关灯!id(3002)|把电灯关了!id(3002)|把电灯关闭!id(3002)|把灯关了!id(3002)
|打开空调!id(3003)|把空调打开!id(3003)|屋里有点冷!id(3003)|屋里有点儿冷!id(3003)|屋里有点热!id(3003)|屋里有点儿热!id(3003)
|关闭空调!id(3004)|空调关闭!id(3004)|把空调关闭!id(3004)|把空调关了!id(3004)
|打开加湿器!id(3005)|把加湿器打开!id(3005)|屋里有点干!id(3005)|屋里有点儿干!id(3005)
|关闭加湿器!id(3006)|把加湿器关闭!id(3006)
|打开电风扇!id(3007)|把电风扇打开!id(3007)
|关闭电风扇!id(3008)|把电风扇关闭!id(3008)|把电风扇关了!id(3008);