当前位置: 首页 > news >正文

了解语音交互:从“若琪,今天杭州的天气”发生了什么?

本文是面向 Web 开发者所写,介绍关于“语音交互”的一篇科普性质的文章,希望借助这篇文章,让开发者了解到什么是语音交互,以及在 YodaOS 中的技术实现。

作为 Web 开发者,相信在面试时常会被问到“浏览器输入 URL 后发生了什么”这样的经典问题,这可以很好地帮助工程师理解整个 Web 的技术栈。因此,本文将从“若琪,今天杭州的天气”这一句话开始,尽量让大家了解到语音交互的技术全貌。

以下章节涉及到的知识点包括(可以先自行查阅之): 语音激活(VT) 语音识别(ASR) 语义理解(NLP) 语音合成(TTS) 技能(Skill)——语音交互时代的应用 如下是一次语音交互的流程:

从上图可以看出: 首先,用户(人类)通过智能设备上的麦克风获取音频信号数据(PCM),通过“语音激活”模块,它能正确地将带有激活词的数据转换成云端可以识别的音频数据(如 opus)。

接下来,由 VUI Client 会通过 WebSocket 上传音频数据,云端通过一系列算法最终将语音数据转换为两部分结果:

ASR:纯文本,表示这段音频数据中用户所说的话,比如“若琪今天的天气”。

NLP:JSON 格式的数据,NLP 也叫语义理解,通常会把每句话解析成两个重要的信息:

一部分叫意图(Intent),表示用户说这句话的目的,比如“今天的天气”,那我们可以获得这句话的意图是 query_weather,表示在查询天气;

另一部分是具体信息(Slots),一般在 JSON 中是一个对象,比如“今天的天气”会在 slots.date 中为 today,表示这句话询问的是“今天”的天气,类似也可以有像 slots.location 用于表示询问的是“哪儿”的天气;

ASR 和 NLP 会由 VUI Runtime 下发到具体的技能(Skill),每个技能通过解析 Intent 和 Slots 来做对应的处理,最终生成为一段文本,由 TTS 回复给用户。 以上其实就是一次语音交互的基本流程,接下来会按照不同的模块分别介绍。

语音激活流程

在说明这个流程之前,先来看看为什么需要它。当用户与一个智能设备交互时,由于媒介是语音(空气),所以不像传统的 GUI(PC、平板、手机)设备,它们拥有一个独自的媒介平台(如屏幕、按键等),所以交互目标是明确的。而生活中空气是共享的,这意味着在交互之前,首先要判断用户是不是想要跟你说话,比如你说“帮我开下灯”,可能是让你老婆去开灯,而不是若琪。

无论 Alexa、若琪、小爱同学,还是天猫精灵,首先需要给设备取一个悦耳的名字,这样设备才能知道你是否在跟他/她说话,这——便是语音激活模块要做的事儿。

然而要做好这么一件简单的事儿,可不容易。

首先我们先了解下什么是 PCM,维基百科上中文名称叫:脉冲编码调制。很难理解对吧?如果要把整个概念说清楚,可能需要涉及到很多声学和信号学的知识,这里就不拓展了。简单来说,你可以把它理解为,就是你说了一段话(语音),然后被麦克风记录成了二进制数据,这个原始数据就叫 PCM。

了解了 PCM 后,再来了解2个概念:

AEC,自音源消除。在智能音响上,通常都有麦克风和扬声器,麦克风在收音时,会把当前设备通过扬声器播放的声音也记录下来,因此 AEC 所做的就是从 PCM 数据中将设备本身播放的音频消除,减少干扰。 VT,激活算法模块。将 AEC 后的音频数据输入到 VT 算法/模型中,他会给出激活分数,最后通过分数判断是否激活。

在激活模块内部,从麦克风获取到语音数据后,会经过 AEC 处理,将扬声器的声音消除,接着会通过其他降噪算法去除一些额外的噪音,然后将最终处理过后的音频数据输入 VT,若模型判断是激活的话,就会把后面的(音频)数据通过 VUI Client 上传到云端 ASR,直到云端判断用户说完了并结束本次交互。

NLP 下发流程

前面讲到从云端会下发两种类型的数据:ASR 与 NLP,然而对于云端是如何生成这些数据并没有提及,这里我们先稍微讲解一些 NLP 的部分。

在 ASR 将音频数据转成文本后,会输入给 NLP 服务(云端),那么云端是怎么把一段简单的文本解析成本地想要的 JSON 格式呢?NLP 引入了领域(Domain)概念,比如“若琪,今天的天气”会被划分为天气领域,“我要开灯”是 IoT 领域,“我要听歌”则是音乐领域,类似的领域还有故事、时间、百科、导航和聊天等。

可以简单理解为领域是一个大的范围,表示用户想要跟设备交流的主题,而意图则是在这个主题下一个个需要设备帮助完成的任务。比如“今天的天气”,主题是天气,而意图则是问询。

有了“领域”的概念后,当我们获取到一串文本后,会经过预先训练好的模型以及预先定义好的规则和说法,就能判断出这段文本命中了什么领域和意图,然后再从文本中抽出相关的信息。最后将所有信息组合成一个完整的 JSON 下发至设备端。设备通过每条 NLP 命中领域或技能的不同,下发给对应的技能进行处理。

CloudApp

语音交互的输出相对比较单一,基本上是:TTS、音效以及多媒体音乐,因此这里有一个 VUI Rendering 的概念。

在 GUI 时代,渲染的输出是屏幕的可交互的控件、声音以及视频。而 VUI 就是 TTS、音效和多媒体音乐,相对于 GUI 来说,已经相当简单了。因此与 Web 一样,VUI 渲染也分为服务端渲染和本地渲染:

本地渲染:本地应用直接处理 NLP 数据,在本地执行业务逻辑,并最终播放 TTS、音效以及多媒体音乐。

服务端渲染:NLP 服务会将数据先发送到预先配置好的一台服务器,在服务器上执行业务逻辑,并分别将 TTS、音效和多媒体音乐转换为一条条指令(Directive),返回给 NLP 服务,最后设备端收到后,只需按照指令执行对应的操作即可。

一般把在服务端渲染的应用称作 CloudApp,其优点当然是实时更新,开发快捷简便,与 Web 的运行机制类似,缺点则是能力受限,拓展依赖于协议本身的能力(类似于浏览器沙箱)。

技能生命周期

无论是本地还是云端,技能跟我们所熟知的页面一样具有其生命周期,VUI Runtime 会对其进行管理。在 YodaOS 中,每个技能可以由两种方式启动:

用户通过语音 NLP 下发命令并启动。

用户通过设备按键触发启动。

每个技能在启动后,就会处于技能栈栈顶,表示当前技能正在运行,此时可以控制设备的输出内容(TTS、音效与多媒体)。与此同时,若之前有技能已经在运行,则会将之前的技能销毁或暂停,这取决于他是即时(CUT)还是场景(SCENE)技能:

CUT:用于单次会话的技能,因此有新的技能命中时,会毫不犹豫地结束(销毁)该技能。

SCENE:用于长时间需要交互的技能,如音乐播放、游戏或有声故事。若新请求的技能是 CUT,会先暂停上一个技能,待 CUT 结束后恢复;若新请求的技能是 SCENE,则会替换掉之前的技能。

总结

其实一次语音交互远不止上文所提到的这些流程,这里也仅仅希望抛砖引玉,以及给对于语音交互感兴趣的工程师分享出我们在做 YodaOS 的一些心得,最后欢迎大家关注我们的 VUI Runtime:github.com/yodaos-proj…

相关文章:

  • 阿里云SLB出现502 Bad Gateway 错误排查解决方法
  • bat(DOS)常用命令详解
  • 力扣(LeetCode)357
  • 来,膜拜下android roadmap,强大的执行力
  • JS · \r\n被转义导致出错
  • [译] 每天一段 Spring 5 官方文档(5.1.4.RELEASE)—— Spring Framework Overview 10
  • P3398 仓鼠找sugar (一道LCA的裸题)
  • 创建一个 Django 项目
  • GitHub如何下载clone指定的tag
  • 技术面试感觉什么都会,面试官一问回答不上来怎么办?
  • 性能测试总结(二)---测试流程篇(转载)
  • servlet,javabean,客户端跳转和服务端跳转。
  • 启动从Windows Server 2016发布的应用程序时,黑屏在应用程序可见之前出现几秒钟...
  • 如何自己制作iconfont
  • URL与URI的不同
  • [译] React v16.8: 含有Hooks的版本
  • 【刷算法】求1+2+3+...+n
  • 【跃迁之路】【733天】程序员高效学习方法论探索系列(实验阶段490-2019.2.23)...
  • ES6之路之模块详解
  • miaov-React 最佳入门
  • Object.assign方法不能实现深复制
  • Selenium实战教程系列(二)---元素定位
  • Spring技术内幕笔记(2):Spring MVC 与 Web
  • Vue 动态创建 component
  • 道格拉斯-普克 抽稀算法 附javascript实现
  • 分布式任务队列Celery
  • 深入 Nginx 之配置篇
  • 使用iElevator.js模拟segmentfault的文章标题导航
  • 首页查询功能的一次实现过程
  • 详解NodeJs流之一
  • 一起来学SpringBoot | 第十篇:使用Spring Cache集成Redis
  • Android开发者必备:推荐一款助力开发的开源APP
  • (02)Hive SQL编译成MapReduce任务的过程
  • (175)FPGA门控时钟技术
  • (C++20) consteval立即函数
  • (echarts)echarts使用时重新加载数据之前的数据存留在图上的问题
  • (pt可视化)利用torch的make_grid进行张量可视化
  • (二)学习JVM —— 垃圾回收机制
  • (附源码)springboot高校宿舍交电费系统 毕业设计031552
  • (附源码)ssm户外用品商城 毕业设计 112346
  • (论文阅读32/100)Flowing convnets for human pose estimation in videos
  • (使用vite搭建vue3项目(vite + vue3 + vue router + pinia + element plus))
  • (四)七种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • .libPaths()设置包加载目录
  • .net core 客户端缓存、服务器端响应缓存、服务器内存缓存
  • .NET Windows:删除文件夹后立即判断,有可能依然存在
  • .NET大文件上传知识整理
  • [ C++ ] STL---string类的模拟实现
  • []指针
  • [2018-01-08] Python强化周的第一天
  • [20190113]四校联考
  • [Android]通过PhoneLookup读取所有电话号码
  • [AX]AX2012 SSRS报表Drill through action
  • [C++]模板与STL简介
  • [CF]Codeforces Round #551 (Div. 2)