本文是面向 Web 開發(fā)者所寫,介紹關(guān)于“語(yǔ)音交互”的一篇科普性質(zhì)的文章勉抓,希望借助這篇文章贾漏,讓開發(fā)者了解到什么是語(yǔ)音交互,以及在 YodaOS 中的技術(shù)實(shí)現(xiàn)藕筋。
作為 Web 開發(fā)者纵散,相信在面試時(shí)常會(huì)被問到“瀏覽器輸入 URL 后發(fā)生了什么”這樣的經(jīng)典問題,這可以很好地幫助工程師理解整個(gè) Web 的技術(shù)棧隐圾。因此伍掀,本文將從“若琪,今天杭州的天氣”這一句話開始暇藏,盡量讓大家了解到語(yǔ)音交互的技術(shù)全貌蜜笤。
以下章節(jié)涉及到的知識(shí)點(diǎn)包括(可以先自行查閱之):
語(yǔ)音激活(VT)
語(yǔ)音識(shí)別(ASR)
語(yǔ)義理解(NLP)
語(yǔ)音合成(TTS)
技能(Skill)——語(yǔ)音交互時(shí)代的應(yīng)用
如下是一次語(yǔ)音交互的流程:
從上圖可以看出:
首先,用戶(人類)通過智能設(shè)備上的麥克風(fēng)獲取音頻信號(hào)數(shù)據(jù)(PCM)盐碱,通過“語(yǔ)音激活”模塊把兔,它能正確地將帶有激活詞的數(shù)據(jù)轉(zhuǎn)換成云端可以識(shí)別的音頻數(shù)據(jù)(如 opus)。
接下來(lái)瓮顽,由 VUI Client 會(huì)通過 WebSocket 上傳音頻數(shù)據(jù)县好,云端通過一系列算法最終將語(yǔ)音數(shù)據(jù)轉(zhuǎn)換為兩部分結(jié)果:
ASR:純文本,表示這段音頻數(shù)據(jù)中用戶所說的話暖混,比如“若琪今天的天氣”缕贡。
NLP:JSON 格式的數(shù)據(jù),NLP 也叫語(yǔ)義理解拣播,通常會(huì)把每句話解析成兩個(gè)重要的信息:
一部分叫意圖(Intent)善绎,表示用戶說這句話的目的,比如“今天的天氣”诫尽,那我們可以獲得這句話的意圖是 query_weather禀酱,表示在查詢天氣;
另一部分是具體信息(Slots)牧嫉,一般在 JSON 中是一個(gè)對(duì)象剂跟,比如“今天的天氣”會(huì)在 slots.date 中為 today减途,表示這句話詢問的是“今天”的天氣,類似也可以有像 slots.location 用于表示詢問的是“哪兒”的天氣曹洽;
ASR 和 NLP 會(huì)由 VUI Runtime 下發(fā)到具體的技能(Skill)鳍置,每個(gè)技能通過解析 Intent 和 Slots 來(lái)做對(duì)應(yīng)的處理,最終生成為一段文本送淆,由 TTS 回復(fù)給用戶税产。
以上其實(shí)就是一次語(yǔ)音交互的基本流程,接下來(lái)會(huì)按照不同的模塊分別介紹偷崩。
語(yǔ)音激活流程
在說明這個(gè)流程之前辟拷,先來(lái)看看為什么需要它。當(dāng)用戶與一個(gè)智能設(shè)備交互時(shí)阐斜,由于媒介是語(yǔ)音(空氣)衫冻,所以不像傳統(tǒng)的 GUI(PC、平板谒出、手機(jī))設(shè)備隅俘,它們擁有一個(gè)獨(dú)自的媒介平臺(tái)(如屏幕、按鍵等)笤喳,所以交互目標(biāo)是明確的为居。而生活中空氣是共享的,這意味著在交互之前杀狡,首先要判斷用戶是不是想要跟你說話颜骤,比如你說“幫我開下燈”,可能是讓你老婆去開燈捣卤,而不是若琪忍抽。
無(wú)論 Alexa、若琪董朝、小愛同學(xué)鸠项,還是天貓精靈,首先需要給設(shè)備取一個(gè)悅耳的名字子姜,這樣設(shè)備才能知道你是否在跟他/她說話祟绊,這——便是語(yǔ)音激活模塊要做的事兒。
然而要做好這么一件簡(jiǎn)單的事兒哥捕,可不容易牧抽。
首先我們先了解下什么是 PCM,維基百科上中文名稱叫:脈沖編碼調(diào)制遥赚。很難理解對(duì)吧扬舒?如果要把整個(gè)概念說清楚,可能需要涉及到很多聲學(xué)和信號(hào)學(xué)的知識(shí)凫佛,這里就不拓展了讲坎。簡(jiǎn)單來(lái)說孕惜,你可以把它理解為,就是你說了一段話(語(yǔ)音)晨炕,然后被麥克風(fēng)記錄成了二進(jìn)制數(shù)據(jù)衫画,這個(gè)原始數(shù)據(jù)就叫 PCM。
了解了 PCM 后瓮栗,再來(lái)了解2個(gè)概念:
AEC削罩,自音源消除。在智能音響上费奸,通常都有麥克風(fēng)和揚(yáng)聲器弥激,麥克風(fēng)在收音時(shí),會(huì)把當(dāng)前設(shè)備通過揚(yáng)聲器播放的聲音也記錄下來(lái)货邓,因此 AEC 所做的就是從 PCM 數(shù)據(jù)中將設(shè)備本身播放的音頻消除秆撮,減少干擾四濒。
VT换况,激活算法模塊。將 AEC 后的音頻數(shù)據(jù)輸入到 VT 算法/模型中,他會(huì)給出激活分?jǐn)?shù),最后通過分?jǐn)?shù)判斷是否激活坏快。
在激活模塊內(nèi)部罗捎,從麥克風(fēng)獲取到語(yǔ)音數(shù)據(jù)后,會(huì)經(jīng)過 AEC 處理缝呕,將揚(yáng)聲器的聲音消除,接著會(huì)通過其他降噪算法去除一些額外的噪音,然后將最終處理過后的音頻數(shù)據(jù)輸入 VT鲜滩,若模型判斷是激活的話,就會(huì)把后面的(音頻)數(shù)據(jù)通過 VUI Client 上傳到云端 ASR节值,直到云端判斷用戶說完了并結(jié)束本次交互徙硅。
NLP 下發(fā)流程
前面講到從云端會(huì)下發(fā)兩種類型的數(shù)據(jù):ASR 與 NLP,然而對(duì)于云端是如何生成這些數(shù)據(jù)并沒有提及搞疗,這里我們先稍微講解一些 NLP 的部分嗓蘑。
在 ASR 將音頻數(shù)據(jù)轉(zhuǎn)成文本后,會(huì)輸入給 NLP 服務(wù)(云端)匿乃,那么云端是怎么把一段簡(jiǎn)單的文本解析成本地想要的 JSON 格式呢桩皿?NLP 引入了領(lǐng)域(Domain)概念,比如“若琪幢炸,今天的天氣”會(huì)被劃分為天氣領(lǐng)域泄隔,“我要開燈”是 IoT 領(lǐng)域,“我要聽歌”則是音樂領(lǐng)域宛徊,類似的領(lǐng)域還有故事梅尤、時(shí)間柜思、百科、導(dǎo)航和聊天等巷燥。
可以簡(jiǎn)單理解為領(lǐng)域是一個(gè)大的范圍赡盘,表示用戶想要跟設(shè)備交流的主題,而意圖則是在這個(gè)主題下一個(gè)個(gè)需要設(shè)備幫助完成的任務(wù)缰揪。比如“今天的天氣”陨享,主題是天氣,而意圖則是問詢钝腺。
有了“領(lǐng)域”的概念后抛姑,當(dāng)我們獲取到一串文本后,會(huì)經(jīng)過預(yù)先訓(xùn)練好的模型以及預(yù)先定義好的規(guī)則和說法艳狐,就能判斷出這段文本命中了什么領(lǐng)域和意圖定硝,然后再?gòu)奈谋局谐槌鱿嚓P(guān)的信息。最后將所有信息組合成一個(gè)完整的 JSON 下發(fā)至設(shè)備端毫目。設(shè)備通過每條 NLP 命中領(lǐng)域或技能的不同蔬啡,下發(fā)給對(duì)應(yīng)的技能進(jìn)行處理。
CloudApp
語(yǔ)音交互的輸出相對(duì)比較單一镀虐,基本上是:TTS箱蟆、音效以及多媒體音樂,因此這里有一個(gè) VUI Rendering 的概念刮便。
在 GUI 時(shí)代空猜,渲染的輸出是屏幕的可交互的控件、聲音以及視頻恨旱。而 VUI 就是 TTS辈毯、音效和多媒體音樂,相對(duì)于 GUI 來(lái)說搜贤,已經(jīng)相當(dāng)簡(jiǎn)單了谆沃。因此與 Web 一樣,VUI 渲染也分為服務(wù)端渲染和本地渲染:
本地渲染:本地應(yīng)用直接處理 NLP 數(shù)據(jù)入客,在本地執(zhí)行業(yè)務(wù)邏輯管毙,并最終播放 TTS、音效以及多媒體音樂桌硫。
服務(wù)端渲染:NLP 服務(wù)會(huì)將數(shù)據(jù)先發(fā)送到預(yù)先配置好的一臺(tái)服務(wù)器夭咬,在服務(wù)器上執(zhí)行業(yè)務(wù)邏輯,并分別將 TTS铆隘、音效和多媒體音樂轉(zhuǎn)換為一條條指令(Directive)卓舵,返回給 NLP 服務(wù),最后設(shè)備端收到后膀钠,只需按照指令執(zhí)行對(duì)應(yīng)的操作即可掏湾。
一般把在服務(wù)端渲染的應(yīng)用稱作 CloudApp裹虫,其優(yōu)點(diǎn)當(dāng)然是實(shí)時(shí)更新,開發(fā)快捷簡(jiǎn)便融击,與 Web 的運(yùn)行機(jī)制類似筑公,缺點(diǎn)則是能力受限,拓展依賴于協(xié)議本身的能力(類似于瀏覽器沙箱)尊浪。
技能生命周期
無(wú)論是本地還是云端匣屡,技能跟我們所熟知的頁(yè)面一樣具有其生命周期,VUI Runtime 會(huì)對(duì)其進(jìn)行管理拇涤。在 YodaOS 中捣作,每個(gè)技能可以由兩種方式啟動(dòng):
用戶通過語(yǔ)音 NLP 下發(fā)命令并啟動(dòng)。
用戶通過設(shè)備按鍵觸發(fā)啟動(dòng)鹅士。
每個(gè)技能在啟動(dòng)后券躁,就會(huì)處于技能棧棧頂,表示當(dāng)前技能正在運(yùn)行掉盅,此時(shí)可以控制設(shè)備的輸出內(nèi)容(TTS也拜、音效與多媒體)。與此同時(shí)怔接,若之前有技能已經(jīng)在運(yùn)行搪泳,則會(huì)將之前的技能銷毀或暫停稀轨,這取決于他是即時(shí)(CUT)還是場(chǎng)景(SCENE)技能:
CUT:用于單次會(huì)話的技能扼脐,因此有新的技能命中時(shí),會(huì)毫不猶豫地結(jié)束(銷毀)該技能奋刽。
SCENE:用于長(zhǎng)時(shí)間需要交互的技能瓦侮,如音樂播放、游戲或有聲故事佣谐。若新請(qǐng)求的技能是 CUT肚吏,會(huì)先暫停上一個(gè)技能,待 CUT 結(jié)束后恢復(fù)狭魂;若新請(qǐng)求的技能是 SCENE罚攀,則會(huì)替換掉之前的技能。
總結(jié)
其實(shí)一次語(yǔ)音交互遠(yuǎn)不止上文所提到的這些流程雌澄,這里也僅僅希望拋磚引玉斋泄,以及給對(duì)于語(yǔ)音交互感興趣的工程師分享出我們?cè)谧?YodaOS 的一些心得,最后歡迎大家關(guān)注我們的 VUI Runtime:https://github.com/yodaos-project/yodart镐牺。