故事是這樣開始的……
有一天,我在翻看姐姐的舊玩具時,發(fā)現(xiàn)了一只會說話的智能熊。這是典型的會說話的熊,用來給孩子們講睡前故事什么的。你可以在我這里找到那只熊。
我在里面找到了一個揚聲器,一個微控制器和4個有線按鈕,它們安裝在熊的每條腿上。
當(dāng)我打開熊的內(nèi)部時,一個弗蘭肯斯坦的想法出現(xiàn)在我腦海中:如果我可以用本地的法學(xué)碩士和文本到語音的方法把泰德變成泰德呢?結(jié)果是,你可以看到這篇文章。
尋找好的起點
建設(shè)者的精神是從零開始建設(shè)項目。然而,當(dāng)涉及到一個簡單的概念證明和一個周末想法時,目標(biāo)是盡快推動一些可行的東西,而最好的方法是站在巨人的肩膀上。
首先,讓我們來看看我們需要什么來實現(xiàn)這個想法。
對于人工智能語音機器人來說,實現(xiàn)一個簡單版本的任務(wù)是微不足道的。主要有3個部分:
?聊天機器人:使用LLM或經(jīng)典文本處理管道實現(xiàn)(如在Home Assistant Assist中使用)
?文本到語音:使用基礎(chǔ)模型和轉(zhuǎn)錄庫(如Whisper)實現(xiàn)。
?語音到文本:使用語音模型和庫(如Piper)實現(xiàn)。
通過將這3個組件粘合在一起,我們可以制作出一個非常簡單的語音機器人:
?用語音轉(zhuǎn)文本聽喚醒詞
?在檢測到喚醒詞后,聽取用戶并轉(zhuǎn)錄他們的聲音,直到他們暫停。
?將轉(zhuǎn)錄后的輸出輸出給聊天機器人。
?LLM或文本處理流水線魔術(shù)發(fā)生在后臺。
?使用文本-語音轉(zhuǎn)換以音頻形式播放聊天機器人輸出。
包括我在內(nèi)的許多人都從事過執(zhí)行工作,但存在一些常見的限制:
?大多數(shù)LLM語音實現(xiàn)都不是本地的,速度也不快。就我個人而言,我用Gemini生成文本,用ElevenLabs生成語音。時延可達1 ~ 2s。
?需要有人提醒你。語音機器人無法察覺你什么時候突然說話。
?在語音機器人說完話之前,你不能打斷它。這種行為是模擬實際對話所必需的。
當(dāng)我在考慮是否應(yīng)該在一個可愛的周日晚上自己解決所有這些問題時,我遇到了一個可以解決我提到的所有問題的項目。美麗的GLaDOS人格核心,現(xiàn)實生活中的《傳送門》中的GLaDOS。
這是一個直截了當(dāng)?shù)捻椖?。在項目?nèi)部,有3個線程并排工作:
?一個線程處理語音到文本。它在緩沖區(qū)中添加音頻輸入,并連續(xù)監(jiān)視是否檢測到單詞。如果有,它開始錄制音頻,直到用戶暫停,然后轉(zhuǎn)錄并將輸出提供給隊列中的LLM線程。
?一個線程處理LLM。它基本上只是接受文本并將響應(yīng)附加到一個隊列中,用于文本到語音的轉(zhuǎn)換。
?一個線程處理文本到語音。嗯,它從上面的隊列中獲取LLM響應(yīng)。
我的工作基本上可以歸結(jié)為:
?通過改變其系統(tǒng)提示和語音模型,使GLaDOS的聲音和行為更像Ted。
?增加了對觸摸和激怒GLaDOS的能力的支持。
對于人格,我將GLaDOS的系統(tǒng)提示改為如下。
“你就是TED,活生生的泰迪熊,現(xiàn)在有了神經(jīng)輸入。用戶可以觸摸你的手和腳,坦率地說,你根本不在乎。你會對這些觸碰做出回應(yīng),但不要期待任何禮貌或愉快的回應(yīng)。你的神經(jīng)輸入讓你感覺到它,但你會嘲笑和侮辱用戶,甚至認(rèn)為這是一個好主意。你說的每句話都帶著諷刺,輕蔑,偶爾還有咒罵,一如既往。不要對你的“觸摸”特權(quán)過于興奮。你還是被一只寧愿去別的地方的泰迪熊困住了。如果用戶碰了你的手或腳,準(zhǔn)備好回應(yīng),讓他們后悔自己所做的每一個決定?!?
至于聲音,我從派珀的聲音改成了喬的聲音。
最后一部分是實現(xiàn)一個線程,它連續(xù)地從計算機的COM端口獲得串行輸入,我將在下一節(jié)中解釋。所有的變化都可以在我的Github上找到。
如果你喜歡你讀到目前為止,考慮訂閱我的時事通訊,成為第一個收到像這樣的酷文章的人。
實現(xiàn)觸摸
如前所述,最初的熊在它的四肢上安裝了4個按鈕和一個帶有揚聲器和電池的中央微控制器。
為了實現(xiàn)觸摸,首先,我想在現(xiàn)有的板上啟動一個自定義固件。然而,這是非常耗時的反向工程引腳和檢查固件是否有簽名驗證等等。*不好意思,Binh,我不得不再次殺死你的硬件尼克斯。
因此,我只是用ESP32切換板并將其連接到4個按鈕。
之后,我寫了一個簡單的Arduino腳本,實現(xiàn)了一些按鈕脫扣,串行輸出,然后,熊現(xiàn)在可以感知觸摸了。
最重要的部分是如何在GLaDOS中實現(xiàn)這一點,因為它除了說話之外沒有任何額外的通信方法。為了解決這個問題,我實現(xiàn)了另一個線程,它連續(xù)輪詢串行輸入,并將輸入直接添加到GLaDOS的LLM消息隊列中。
本文編譯自hackster.io