本文是面向 Web 開發者所寫,介紹關於「語音交互」的一篇科普性質的文章,但願藉助這篇文章,讓開發者瞭解到什麼是語音交互,以及在 YodaOS 中的技術實現。git
做爲 Web 開發者,相信在面試時常會被問到「瀏覽器輸入 URL 後發生了什麼」這樣的經典問題,這能夠很好地幫助工程師理解整個 Web 的技術棧。所以,本文將從「若琪,今天杭州的天氣」這一句話開始,儘可能讓你們瞭解到語音交互的技術全貌。github
如下章節涉及到的知識點包括(能夠先自行查閱之): 語音激活(VT) 語音識別(ASR) 語義理解(NLP) 語音合成(TTS) 技能(Skill)——語音交互時代的應用 以下是一次語音交互的流程:面試
從上圖能夠看出: 首先,用戶(人類)經過智能設備上的麥克風獲取音頻信號數據(PCM),經過「語音激活」模塊,它能正確地將帶有激活詞的數據轉換成雲端能夠識別的音頻數據(如 opus)。算法
接下來,由 VUI Client 會經過 WebSocket 上傳音頻數據,雲端經過一系列算法最終將語音數據轉換爲兩部分結果:瀏覽器
ASR:純文本,表示這段音頻數據中用戶所說的話,好比「若琪今天的天氣」。服務器
NLP:JSON 格式的數據,NLP 也叫語義理解,一般會把每句話解析成兩個重要的信息:編碼
一部分叫意圖(Intent),表示用戶說這句話的目的,好比「今天的天氣」,那咱們能夠得到這句話的意圖是 query_weather,表示在查詢天氣;cdn
另外一部分是具體信息(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…