• 方案介紹
    • 一、系統(tǒng)安裝
    • 二、更換軟件源
    • 三、遠(yuǎn)程編程工具
    • 四、py-xiaozhi項(xiàng)目移植
    • 總結(jié):
  • 附件下載
  • 相關(guān)推薦
申請入駐 產(chǎn)業(yè)圖譜

樹莓派5智能對話系統(tǒng)移植

05/29 09:55
93
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

xiaozhi_final.zip

共1個文件

在當(dāng)今人工智能技術(shù)迅猛發(fā)展的浪潮里,大模型如雨后春筍般不斷涌現(xiàn),似乎已成為各個項(xiàng)目中不可或缺的關(guān)鍵要素。從智能家居領(lǐng)域到智能辦公場景,從教育行業(yè)到娛樂產(chǎn)業(yè),AI的應(yīng)用場景持續(xù)拓展延伸。而人工智能對話機(jī)器人,更是一躍成為當(dāng)下最為熱門的項(xiàng)目類型之一。眾多開發(fā)者競相涌入這一賽道,全力嘗試打造出令人稱奇的智能語音助手,期望能讓AI真正無縫融入人們的日常生活。就最新情況而言,小智(Xiaozhi - ESP32)無疑是當(dāng)前極為成功的項(xiàng)目典范,在剛剛過去的農(nóng)歷新年期間成為大眾熱議的焦點(diǎn),網(wǎng)友們口口相傳,熱度居高不下。
將小智移植到樹莓派5上,不僅能夠充分挖掘并發(fā)揮樹莓派5的硬件優(yōu)勢,還可流暢且高效地完成對話交互內(nèi)容,為**智能體的開發(fā)工作夯實(shí)基礎(chǔ),鋪平前行道路。本項(xiàng)目內(nèi)容將詳細(xì)地從環(huán)境搭建開始,一步步深入到運(yùn)行py - xiaozhi項(xiàng)目,進(jìn)行全方位、手把手式的細(xì)致講解,尤其適合剛剛接觸樹莓派pi5的新手朋友。同時,在講解過程中還會分享這段時間探索項(xiàng)目時積累總結(jié)的寶貴經(jīng)驗(yàn),助力大家更好地理解與實(shí)踐。

一、系統(tǒng)安裝

擇樹莓派?OS(64位) Bookworm系統(tǒng)(桌面版),選擇Bookworm是因?yàn)樗С諴VE8,而Bullseye只支持PVE7選擇64位是因?yàn)楹芏嗵匦灾恢С?4位,兼容性更好,所以能64位就64位。這里我的TF卡的容量就是隨便找的,因?yàn)橐膊淮蛩阍赥F卡上工作。因?yàn)楝F(xiàn)在固態(tài)硬盤已經(jīng)很便宜了一個普通256G的固態(tài)硬盤就一百元附近,跟TF的價(jià)格已經(jīng)區(qū)別不明顯了,但是換來更高的速度更大的容量,所以我認(rèn)為現(xiàn)在正確的打開方式都是加個固態(tài)硬盤,才是長久之計(jì)。 為了安裝固態(tài)硬盤,我們需要加一個固態(tài)硬盤的擴(kuò)展板(樹莓派?M.2 HAT+),這個有樹莓派官方選擇和國內(nèi)廠商的替代產(chǎn)品,性能上應(yīng)該沒什么區(qū)別。?據(jù)說樹莓派原廠的也是我們國內(nèi)代工的,所以大家可以放心使用。
因此在制作樹莓派系統(tǒng)的時候,一起給TF卡和固態(tài)硬盤的系統(tǒng)也給燒錄了,因?yàn)?,還是需要用TF卡啟動系統(tǒng)后,進(jìn)行簡單的設(shè)置,把啟動盤改為固態(tài)硬盤,后面就沒有TF卡什么事了,但是建議還是把這張TF卡保留著,當(dāng)你的固態(tài)盤系統(tǒng)壞了,心態(tài)崩了的時候,它還可以救個場。
切換固態(tài)硬盤作啟動盤的操作步驟如下:
使用?SD?卡將你的樹莓派啟動到?Raspberry Pi OS。進(jìn)入樹莓派配置工具在終端中,輸入?sudo raspi-config?命令來打開?Raspberry Pi?配置?CLI(命令行界面)更改啟動順序。
1、在 Raspberry Pi 配置工具中,導(dǎo)航到“Advanced Options”(高級選項(xiàng))。
2、在“Advanced Options”下,選擇“Boot Order”(啟動順序)。
3、在“Boot Order”中,選擇“NVMe/USB boot”(NVMe/USB啟動)。
4、確認(rèn)選擇并保存更改。
5、使用“Finish”或“Esc”鍵退出 Raspberry Pi 配置工具。
6、重啟樹莓派在終端中輸入 sudo reboot 命令來重新啟動你的樹莓派。(保險(xiǎn)起見可以關(guān)機(jī),把TF卡抽掉,重新開機(jī))
開機(jī)時間大約10s,心情還是蠻好的。
file:///C:UsersADMINI~1AppDataLocalTempksohtml23896wps1.jpg

二、更換軟件源

軟件源是指樹莓派系統(tǒng)軟件安裝的數(shù)據(jù)來源,默認(rèn)的源應(yīng)該是樹莓派官方的源,普通民眾也不是不能容,但是遇到稍大的下載項(xiàng)目就容易斷,因?yàn)?,?*的幸福生活,第一步建議更換軟件源:
樹莓派更改軟件源為清華源
1. 備份原有的 sources.list 文件
在開始之前,最好備份原有的 sources.list 文件,以防萬一需要恢復(fù)。
打開終端,執(zhí)行以下命令來備份原有的 sources.list 文件
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak
2. 編輯 sources.list 文件
接下來,我們需要編輯 /etc/apt/sources.list 文件,將其替換為清華大學(xué)的鏡像源地址。
使用文本編輯器打開 sources.list 文件,例如使用 nano:
sudo nano /etc/apt/sources.list
# 默認(rèn)注釋了源碼鏡像以提高 apt update 速度,如有需要可自行取消注釋
deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-updates main contrib non-free non-free-firmware
# 以下安全更新軟件源包含了官方源與鏡像站配置,如有需要可自行修改注釋切換
deb https://security.debian.org/debian-security bookworm-security main contrib non-free non-free-firmware
5 修改其他文件
/etc/apt/sources.list.d/raspi.list
sudo nano /etc/apt/sources.list.d/raspi.list
內(nèi)容修改為
deb https://mirrors.tuna.tsinghua.edu.cn/raspberrypi/ bookworm main
6.更新源
sudo apt update
sudo apt upgrade?
另外,值得注意下,上面的操作只是更換了系統(tǒng)軟件源,但是如果你要用python編程環(huán)境的話,還要替換pip源,因?yàn)閜ython的默認(rèn)源也在國外,在這里也一同把它替換掉,以免后顧之憂。
這將指定清華大學(xué) 的 PyPI 鏡像源作為默認(rèn)源。你也可以選擇其他鏡像源,如:
pip config set global.index-url https://mirrors.aliyun.com/pypi/simple
   -阿里云:`https://mirrors.aliyun.com/pypi/simple/`
   -中科大:`https://pypi.mirrors.ustc.edu.cn/simple/`   

三、遠(yuǎn)程編程工具

因?yàn)闃漭赏ǔ6疾皇怯脕懋?dāng)主力機(jī),配置都較為簡單可能沒有配置鼠標(biāo)、鍵盤顯示器,有時不是因?yàn)椴幌嗯洌皇钦加昧颂喙ぷ髋_面的地方,顯得很凌亂,一個不小心被女主人全扔了,所以“為了優(yōu)雅”,我們堅(jiān)持保持桌面整潔,采用遠(yuǎn)程操作的方式開展工作做好了,樹莓派還就只占用巴掌大的地方,與各方諸侯保持安全距離。
一般情況大家都會上工具iShell,Wave Terminal, MobaXterm,這些工具都很強(qiáng)大,建議大家去體驗(yàn)一下。MobaXterm是老牌軟件,穩(wěn)定功能強(qiáng)大,但也意味著沒有創(chuàng)新,iShell是國產(chǎn)新秀,高級要收費(fèi),帶AI問答。Wave Terminal?就更新潮了,也同樣白嫖AI.
file:///C:UsersADMINI~1AppDataLocalTempksohtml23896wps2.jpg
這里重點(diǎn)介紹使用?Visual Studio Code?的遠(yuǎn)程開發(fā)擴(kuò)展:
安裝?Remote - SSH?擴(kuò)展。
配置?SSH:
在?VS Code?中打開命令面板(Ctrl + Shift + P),然后選擇“Remote-SSH: Connect to Host”。
輸入樹莓派的?SSH?信息(如?pi@<樹莓派的IP地址>)。

file:///C:UsersADMINI~1AppDataLocalTempksohtml23896wps3.jpg
然后就可以想在本地一樣打開樹莓派上的文件夾和文件進(jìn)行編輯,也可以在vscode的終端上運(yùn)行樹莓派的命令,操控樹莓派。

四、py-xiaozhi項(xiàng)目移植

(1)獨(dú)立python環(huán)境

在python的世界,很多程序都可以共享支持庫,但是每個程序?qū)?yīng)庫的版本又可能存在細(xì)微的差別,也就細(xì)微的差別就會導(dǎo)致運(yùn)行失敗。所以為了保障每個程序都有個私密的環(huán)境,也不影響其他的程序運(yùn)行,良好的操作規(guī)范還是創(chuàng)建獨(dú)立的運(yùn)行環(huán)境。其中帶來的問題就是稍微的會多占用點(diǎn)存儲空間,鑒于前面我們已經(jīng)解決了硬盤空間的問題了,所以到這一步也不是什么問題了,為了減少后面的各種崩潰,或者限定崩潰的范圍也是值得的。
? ???良好操作規(guī)范:
   # 確保你安裝了虛擬環(huán)境工具
   sudo apt update
   sudo apt install python3-venv python3-pip
   # 創(chuàng)建一個新的虛擬環(huán)境
   python3 -m venv myenv
   # 激活虛擬環(huán)境
   source myenv/bin/activate
   # 在虛擬環(huán)境中安裝 requirements.txt 中的包
   pip install -r requirements.txt

 

激活虛擬環(huán)境后,所有的 `pip` 安裝都會在這個獨(dú)立的環(huán)境中進(jìn)行,不會影響系統(tǒng)的 Python。退出虛擬環(huán)境可以運(yùn)行 `deactivate`。

(2)音頻測試

小智是個智能對話系統(tǒng),可謂“國民女朋友”你值得擁有,因此,基本配置就是要有麥克風(fēng)和喇叭。Pi5上面原生是沒有這些設(shè)備的,看看是不是連個耳機(jī)孔都沒有呀。 為了優(yōu)雅起見,建議購買麥克喇叭一體套裝,如果沒有可以到會議室去“借”一個,就可以完美地解決這個問題了。
基本的測試我們需要讓Pi5能出聲和能聽到聲音,保障這些功能后才進(jìn)行下一步,不然后面有你受的。
從USB口插上麥克喇叭一體設(shè)備后,查看設(shè)備,如下所示,這里的card0就是我的設(shè)備,但是后來沒用這個,用了得力的音質(zhì)更好的產(chǎn)品。
(myenv) genvex@raspberrypi:~/py-xiaozhi $ aplay -l  # 查看可用設(shè)備
**** List of PLAYBACK Hardware Devices ****
card 0: YueMiUSB [YueMi_USB], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: vc4hdmi0 [vc4-hdmi-0], device 0: MAI PCM i2s-hifi-0 [MAI PCM i2s-hifi-0]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 2: vc4hdmi1 [vc4-hdmi-1], device 0: MAI PCM i2s-hifi-0 [MAI PCM i2s-hifi-0]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
設(shè)備狀態(tài)監(jiān)控
<BASH>
# 實(shí)時查看音頻電平alsamixer -c 0  # 控制USB聲卡
Available audio input devices:
Device Index    Device Name             Default Sample Rate (Hz)
0               YueMi_USB: USB Audio (hw:0,0)           44100.0
1               sysdefault              44100.0
5               spdif           44100.0
6               pulse           44100.0
7               speex           44100.0
8               upmix           44100.0
9               vdownmix                44100.0
11              default         44100.0?
這個設(shè)備的采樣頻率跟小智需要的采樣率不對呀,小智需要的是16000,這個問題后面看看有沒解決的方案。
在移植小智過程中,經(jīng)過上述一系列妥善的處理,pi5已經(jīng)已經(jīng)進(jìn)入了最佳狀態(tài),可以大刀闊斧地進(jìn)行工作了,其中Pyaudio?安裝問題,有些周折,以下線索提供參考。

(3)安裝?PortAudio?開發(fā)包:

在基于?Debian/Ubuntu?的系統(tǒng)(如樹莓派的?Raspbian)上,你需要安裝?`portaudio`?的開發(fā)包,使用以下命令:
sudo apt update
   sudo apt install portaudio19-dev
這會安裝?`portaudio`?庫的頭文件和其他開發(fā)文件。
2.安裝?`PyAudio`:
? ?安裝完?`portaudio`?開發(fā)包后,再次嘗試安裝?`PyAudio`:
  pip install pyaudio

 

(4)按鍵驅(qū)動

因?yàn)檫€沒完成?語音喚醒?發(fā)送消息邏輯?,通過按鍵簡單完成這個激活小智的對話過程,長按按鍵開始錄音,松開按鍵?自動發(fā)送語音信息,等待信息回復(fù)。?還是為了優(yōu)雅,我在pi5加了個seeed的多功能擴(kuò)展板,板載多個grove接口,grove接口是 業(yè)界大廠seeed和M5stack傳感器的通用接口,他們的傳感器以顏值著稱。這里我只是用了普通IO,還有i2c,uart這些端口也是引出的,以后要繼續(xù)折騰其他傳感器也非常便利。但是注意Pi5的IO驅(qū)動要使用gpiozero這個庫,pi4常用的rpi.gpio庫在pi5上就不好用了,在這個地方也是折騰了好久。因此,當(dāng)前這個移植是可以向下兼容的(pi4或者其他linux開發(fā)板是也是可以用的)。

file:///C:UsersADMINI~1AppDataLocalTempksohtml23896wps5.jpg
https://wiki.seeedstudio.com/Grove_Base_Hat_for_Raspberry_Pi_Zero/
這里我們使用IO16作為按鍵使用,可以根據(jù)自己的實(shí)際情況修改。

(5)py-xiaozhi移植精講

下面到了py-xiaozhi代碼分解的內(nèi)容,也是我們學(xué)以致用的重要內(nèi)容,我們不單純?yōu)榱税秧?xiàng)目跑起來,一些技術(shù)層面的知識可以讓我們跑得更快更遠(yuǎn)。
小智對話**系統(tǒng)的運(yùn)行架構(gòu)?
py-xiaozhi運(yùn)行時序圖
file:///C:UsersADMINI~1AppDataLocalTempksohtml23896wps6.jpg
# 主要組件交互關(guān)系
while running:
    1. GUI線程 --> 消息隊(duì)列 --> 更新**記錄
    2. MQTT線程 --> 接收云端指令 --> 控制音頻會話
    3. 音頻線程 --> UDP加密傳輸 --> 實(shí)現(xiàn)雙向語音
    4. 心跳線程 --> 維持連接 --> 處理會話超時

 

# 典型通信流程示例
def send_audio():
    while running:
        錄音 -> Opus編碼 -> AES加密 -> UDP發(fā)送
def on_mqtt_message():
    接收J(rèn)SON指令 -> 更新會話狀態(tài) -> 控制音頻線程

def on_space_key_press():
    global key_state, udp_socket, aes_opus_info, listen_state, conn_state
    if key_state == "press":
        return
    key_state = "press"
    # 判斷是否需要發(fā)送hello消息
    if conn_state is False or aes_opus_info['session_id'] is None:
        conn_state = True
        # 發(fā)送hello消息,建立udp連接
        hello_msg = {"type": "hello", "version": 3, "transport": "udp",
                     "audio_params": {"format": "opus", "sample_rate": 16000, "channels": 1, "frame_duration": 60}}
        push_mqtt_msg(hello_msg)
        print(f"send hello message: {hello_msg}")
    if tts_state == "start" or tts_state == "entence_start":
        # 在播放狀態(tài)下發(fā)送abort消息
        push_mqtt_msg({"type": "abort"})
        print(f"send abort message")
    if aes_opus_info['session_id'] is not None:
        # 發(fā)送start listen消息
        msg = {"session_id": aes_opus_info['session_id'], "type": "listen", "state": "start", "mode": "manual"}
        print(f"send start listen message: {msg}")
        push_mqtt_msg(msg)


def on_space_key_release():
    global aes_opus_info, key_state
    key_state = "release"
    # 發(fā)送stop listen消息
    if aes_opus_info['session_id'] is not None:
        msg = {"session_id": aes_opus_info['session_id'], "type": "listen", "state": "stop"}
        print(f"send stop listen message: {msg}")
        push_mqtt_msg(msg)


# def on_press(key):
#     if key == pynput_keyboard.Key.space:
#         on_space_key_press(None)


# def on_release(key):
#     if key == pynput_keyboard.Key.space:
#         on_space_key_release(None)
#     # Stop listener
#     if key == pynput_keyboard.Key.esc:
#         return False


def run():
    global mqtt_info, mqttc
    # 獲取mqtt與版本信息
    get_ota_version()
    # 監(jiān)聽鍵盤按鍵,當(dāng)按下空格鍵時,發(fā)送listen消息
    # listener = pynput_keyboard.Listener(on_press=on_press, on_release=on_release)
    # listener.start()
    button = Button(16)
    button.when_pressed = on_space_key_press
    button.when_released = on_space_key_release
    # 創(chuàng)建客戶端實(shí)例
    mqttc = mqtt.Client(callback_api_version=mqtt.CallbackAPIVersion.VERSION2, client_id=mqtt_info['client_id'])
    mqttc.username_pw_set(username=mqtt_info['username'], password=mqtt_info['password'])
    mqttc.tls_set(ca_certs=None, certfile=None, keyfile=None, cert_reqs=mqtt.ssl.CERT_REQUIRED,
                  tls_version=mqtt.ssl.PROTOCOL_TLS, ciphers=None)
    mqttc.on_connect = on_connect
    mqttc.on_message = on_message
    mqttc.connect(host=mqtt_info['endpoint'], port=8883)
    mqttc.loop_forever()


if __name__ == "__main__":
    audio = pyaudio.PyAudio()
    run()
部分關(guān)鍵代碼

總結(jié):

人工智能已經(jīng)把人類帶向了一個前所未有的繁榮,樹莓派作以其優(yōu)越的性能,成為了承載人工智能運(yùn)行的實(shí)體,走進(jìn)平凡人家的最佳實(shí)踐。借助樹莓派,智能家居系統(tǒng)變得觸手可及。人們僅需通過簡單的語音指令,就能依托樹莓派搭載的人工智能程序,輕松操控家中的燈光、溫度與電器設(shè)備,讓生活變得更加便捷與舒適。在教育領(lǐng)域,樹莓派為學(xué)生們開啟了探索人工智能世界的大門。學(xué)生們可以利用它開展簡單的圖像識別、語音交互等實(shí)驗(yàn)項(xiàng)目,將抽象的人工智能理論知識轉(zhuǎn)化為生動有趣的實(shí)踐操作,極大地激發(fā)了他們對科技的熱愛與創(chuàng)新思維。在科研層面,樹莓派憑借其靈活的擴(kuò)展性,成為了眾多科研人員進(jìn)行小型人工智能實(shí)驗(yàn)的得力助手,幫助他們在有限的資源條件下,快速驗(yàn)證新的算法與模型,為人工智能技術(shù)的進(jìn)一步突破貢獻(xiàn)力量。隨著技術(shù)的不斷迭代升級,未來樹莓派有望在更多領(lǐng)域大放異彩,持續(xù)推動人工智能與日常生活深度融合,創(chuàng)造出更多令人驚喜的應(yīng)用場景 。
參考附件
?
  • xiaozhi_final.zip
    下載
DigiKey得捷

DigiKey得捷

DigiKey 總部位于美國明尼蘇達(dá)州錫夫里弗福爾斯市,是一家獲得原廠授權(quán)的全球性、全類目電子元器件和自動化產(chǎn)品分銷商。我們通過分銷來自 2,300 多家優(yōu)質(zhì)品牌制造商的 1,020 多萬種元器件獲得了強(qiáng)大的技術(shù)優(yōu)勢。DigiKey 還為工程師、設(shè)計(jì)師、開發(fā)者和采購專業(yè)人員提供豐富的數(shù)字解決方案、無障礙互動和工具支持,以幫助他們提升工作效率。在中國,客戶可以通過電子郵件、電話和客服獲得全方位技術(shù)支持。如需了解更多信息和獲取 DigiKey 廣泛的產(chǎn)品,請?jiān)L問 www.digikey.cn 并關(guān)注我們的微信、微博、騰訊視頻和 BiliBili 賬號。

DigiKey 總部位于美國明尼蘇達(dá)州錫夫里弗福爾斯市,是一家獲得原廠授權(quán)的全球性、全類目電子元器件和自動化產(chǎn)品分銷商。我們通過分銷來自 2,300 多家優(yōu)質(zhì)品牌制造商的 1,020 多萬種元器件獲得了強(qiáng)大的技術(shù)優(yōu)勢。DigiKey 還為工程師、設(shè)計(jì)師、開發(fā)者和采購專業(yè)人員提供豐富的數(shù)字解決方案、無障礙互動和工具支持,以幫助他們提升工作效率。在中國,客戶可以通過電子郵件、電話和客服獲得全方位技術(shù)支持。如需了解更多信息和獲取 DigiKey 廣泛的產(chǎn)品,請?jiān)L問 www.digikey.cn 并關(guān)注我們的微信、微博、騰訊視頻和 BiliBili 賬號。收起

查看更多

相關(guān)推薦