在當今 人工智能技術迅猛發(fā)展的浪潮里, 大模型如雨后春筍般不斷涌現(xiàn),似乎已成為各個項目中不可或缺的關鍵要素。從 智能家居領域到智能辦公場景,從教育行業(yè)到娛樂產業(yè), AI的應用場景持續(xù)拓展延伸。而人工智能對話 機器人,更是一躍成為當下最為熱門的項目類型之一。眾多開發(fā)者競相涌入這一賽道,全力嘗試打造出令人稱奇的智能語音助手,期望能讓AI真正無縫融入人們的日常生活。就最新情況而言,小智(Xiaozhi - ESP32)無疑是當前極為成功的項目典范,在剛剛過去的農歷新年期間成為大眾熱議的焦點,網友們口口相傳,熱度居高不下。
將小智移植到 樹莓派5上,不僅能夠充分挖掘并發(fā)揮樹莓派5的硬件優(yōu)勢,還可流暢且高效地完成對話交互內容,為**智能體的開發(fā)工作夯實基礎,鋪平前行道路。本項目內容將詳細地從環(huán)境搭建開始,一步步深入到運行py - xiaozhi項目,進行全方位、手把手式的細致講解,尤其適合剛剛接觸樹莓派pi5的新手朋友。同時,在講解過程中還會分享這段時間探索項目時積累總結的寶貴經驗,助力大家更好地理解與實踐。
一、系統(tǒng)安裝
擇樹莓派?OS(64位) Bookworm系統(tǒng)(桌面版),選擇Bookworm是因為它支持PVE8,而Bullseye只支持PVE7選擇64位是因為很多特性只支持64位,兼容性更好,所以能64位就64位。這里我的TF卡的容量就是隨便找的,因為也不打算在TF卡上工作。因為現(xiàn)在 固態(tài)硬盤已經很便宜了一個普通25 6G的固態(tài)硬盤就一百元附近,跟TF的價格已經區(qū)別不明顯了,但是換來更高的速度更大的容量,所以我認為現(xiàn)在正確的打開方式都是加個固態(tài)硬盤,才是長久之計。 為了安裝固態(tài)硬盤,我們需要加一個固態(tài)硬盤的擴展板(樹莓派?M.2 HAT+),這個有樹莓派官方選擇和國內廠商的替代產品,性能上應該沒什么區(qū)別。?據(jù)說樹莓派原廠的也是我們國內代工的,所以大家可以放心使用。
因此在制作樹莓派系統(tǒng)的時候,一起給TF卡和固態(tài)硬盤的系統(tǒng)也給燒錄了,因為,還是需要用TF卡啟動系統(tǒng)后,進行簡單的設置,把啟動盤改為固態(tài)硬盤,后面就沒有TF卡什么事了,但是建議還是把這張TF卡保留著,當你的固態(tài)盤系統(tǒng)壞了,心態(tài)崩了的時候,它還可以救個場。
切換固態(tài)硬盤作啟動盤的操作步驟如下:
使用?SD?卡將你的樹莓派啟動到? Raspberry Pi OS。進入樹莓派配置工具在終端中,輸入?sudo raspi-config?命令來打開?Raspberry Pi?配置?CLI(命令行界面)更改啟動順序。
1、在 Raspberry Pi 配置工具中,導航到“Advanced Options”(高級選項)。
2、在“Advanced Options”下,選擇“Boot Order”(啟動順序)。
3、在“Boot Order”中,選擇“NVMe/USB boot”(NVMe/USB啟動)。
4、確認選擇并保存更改。
5、使用“Finish”或“Esc”鍵退出 Raspberry Pi 配置工具。
6、重啟樹莓派在終端中輸入 sudo reboot 命令來重新啟動你的樹莓派。(保險起見可以關機,把TF卡抽掉,重新開機)
開機時間大約10s,心情還是蠻好的。
file:///C:UsersADMINI~1AppDataLocalTempksohtml23896wps1.jpg

二、更換軟件源
軟件源是指樹莓派系統(tǒng)軟件安裝的數(shù)據(jù)來源,默認的源應該是樹莓派官方的源,普通民眾也不是不能容,但是遇到稍大的下載項目就容易斷,因為,為**的幸福生活,第一步建議更換軟件源:
樹莓派更改軟件源為清華源
1. 備份原有的 sources.list 文件
在開始之前,最好備份原有的 sources.list 文件,以防萬一需要恢復。
打開終端,執(zhí)行以下命令來備份原有的 sources.list 文件
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak
2. 編輯 sources.list 文件
接下來,我們需要編輯 /etc/apt/sources.list 文件,將其替換為清華大學的鏡像源地址。
使用文本編輯器打開 sources.list 文件,例如使用 nano:
sudo nano /etc/apt/sources.list
# 默認注釋了源碼鏡像以提高 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
內容修改為
deb https://mirrors.tuna.tsinghua.edu.cn/raspberrypi/ bookworm main
6.更新源
sudo apt update
sudo apt upgrade?
另外,值得注意下,上面的操作只是更換了系統(tǒng)軟件源,但是如果你要用python編程環(huán)境的話,還要替換pip源,因為python的默認源也在國外,在這里也一同把它替換掉,以免后顧之憂。
這將指定清華大學 的 PyPI 鏡像源作為默認源。你也可以選擇其他鏡像源,如:
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/`
三、遠程編程工具
因為樹莓派通常都不是用來當主力機,配置都較為簡單可能沒有配置鼠標、鍵盤 顯示器,有時不是因為不相配,只是占用了太多工作臺面的地方,顯得很凌亂,一個不小心被女主人全扔了,所以“為了優(yōu)雅”,我們堅持保持桌面整潔,采用遠程操作的方式開展工作做好了,樹莓派還就只占用巴掌大的地方,與各方諸侯保持安全距離。
一般情況大家都會上工具iShell,Wave Terminal, MobaXterm,這些工具都很強大,建議大家去體驗一下。MobaXterm是老牌軟件,穩(wěn)定功能強大,但也意味著沒有創(chuàng)新,iShell是國產新秀,高級要收費,帶AI問答。Wave Terminal?就更新潮了,也同樣白嫖AI.
file:///C:UsersADMINI~1AppDataLocalTempksohtml23896wps2.jpg
這里重點介紹使用?Visual Studio Code?的遠程開發(fā)擴展:
安裝?Remote - SSH?擴展。
配置?SSH:
在?VS Code?中打開命令面板(Ctrl + Shift + P),然后選擇“Remote-SSH: Connect to Host”。
輸入樹莓派的?SSH?信息(如?pi@<樹莓派的IP地址>)。


file:///C:UsersADMINI~1AppDataLocalTempksohtml23896wps3.jpg
然后就可以想在本地一樣打開樹莓派上的文件夾和文件進行編輯,也可以在vscode的終端上運行樹莓派的命令,操控樹莓派。
四、py-xiaozhi項目移植
(1)獨立python環(huán)境
在python的世界,很多程序都可以共享支持庫,但是每個程序對應庫的版本又可能存在細微的差別,也就細微的差別就會導致運行失敗。所以為了保障每個程序都有個私密的環(huán)境,也不影響其他的程序運行,良好的操作規(guī)范還是創(chuàng)建獨立的運行環(huán)境。其中帶來的問題就是稍微的會多占用點存儲空間,鑒于前面我們已經解決了硬盤空間的問題了,所以到這一步也不是什么問題了,為了減少后面的各種崩潰,或者限定崩潰的范圍也是值得的。
? ???良好操作規(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` 安裝都會在這個獨立的環(huán)境中進行,不會影響系統(tǒng)的 Python。退出虛擬環(huán)境可以運行 `deactivate`。
(2)音頻測試
小智是個智能對話系統(tǒng),可謂“國民女朋友”你值得擁有,因此,基本配置就是要有 麥克風和喇叭。Pi5上面原生是沒有這些設備的,看看是不是連個耳機孔都沒有呀。 為了優(yōu)雅起見,建議購買麥克喇叭一體套裝,如果沒有可以到會議室去“借”一個,就可以完美地解決這個問題了。
基本的測試我們需要讓Pi5能出聲和能聽到聲音,保障這些功能后才進行下一步,不然后面有你受的。
從USB口插上麥克喇叭一體設備后,查看設備,如下所示,這里的card0就是我的設備,但是后來沒用這個,用了得力的音質更好的產品。
(myenv) genvex@raspberrypi:~/py-xiaozhi $ aplay -l # 查看可用設備
**** 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
設備狀態(tài)監(jiān)控
<BASH>
# 實時查看音頻電平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?
這個設備的 采樣頻率跟小智需要的采樣率不對呀,小智需要的是16000,這個問題后面看看有沒解決的方案。
在移植小智過程中,經過上述一系列妥善的處理,pi5已經已經進入了最佳狀態(tài),可以大刀闊斧地進行工作了,其中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`:
(4)按鍵驅動
因為還沒完成?語音喚醒?發(fā)送消息邏輯?,通過按鍵簡單完成這個激活小智的對話過程,長按按鍵開始錄音,松開按鍵?自動發(fā)送語音信息,等待信息回復。?還是為了優(yōu)雅,我在pi5加了個seeed的多功能擴展板,板載多個grove接口,grove接口是 業(yè)界大廠seeed和M5stack 傳感器的通用接口,他們的傳感器以顏值著稱。這里我只是用了普通IO,還有i2c,uart這些端口也是引出的,以后要繼續(xù)折騰其他傳感器也非常便利。但是注意Pi5的IO驅動要使用gpiozero這個庫,pi4常用的rpi.gpio庫在pi5上就不好用了,在這個地方也是折騰了好久。因此,當前這個移植是可以向下兼容的(pi4或者其他linux 開發(fā)板是也是可以用的)。

file:///C:UsersADMINI~1AppDataLocalTempksohtml23896wps5.jpg
https://wiki.seeedstudio.com/Grove_Base_Hat_for_Raspberry_Pi_Zero/
這里我們使用IO16作為按鍵使用,可以根據(jù)自己的實際情況修改。
(5)py-xiaozhi移植精講
下面到了py-xiaozhi代碼分解的內容,也是我們學以致用的重要內容,我們不單純?yōu)榱税秧椖颗芷饋?,一些技術層面的知識可以讓我們跑得更快更遠。


file:///C:UsersADMINI~1AppDataLocalTempksohtml23896wps6.jpg
# 主要組件交互關系
while running:
1. GUI線程 --> 消息隊列 --> 更新**記錄
2. MQTT線程 --> 接收云端指令 --> 控制音頻會話
3. 音頻線程 --> UDP加密傳輸 --> 實現(xiàn)雙向語音
4. 心跳線程 --> 維持連接 --> 處理會話超時
# 典型通信流程示例
def send_audio():
while running:
錄音 -> Opus編碼 -> AES加密 -> UDP發(fā)送
def on_mqtt_message():
接收JSON指令 -> 更新會話狀態(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)聽鍵盤按鍵,當按下空格鍵時,發(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)建客戶端實例
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()
部分關鍵代碼
總結:
人工智能已經把人類帶向了一個前所未有的繁榮,樹莓派作以其優(yōu)越的性能,成為了承載人工智能運行的實體,走進平凡人家的最佳實踐。借助樹莓派,智能家居系統(tǒng)變得觸手可及。人們僅需通過簡單的語音指令,就能依托樹莓派搭載的人工智能程序,輕松操控家中的燈光、溫度與電器設備,讓生活變得更加便捷與舒適。在教育領域,樹莓派為學生們開啟了探索人工智能世界的大門。學生們可以利用它開展簡單的 圖像識別、語音交互等實驗項目,將抽象的人工智能理論知識轉化為生動有趣的實踐操作,極大地激發(fā)了他們對科技的熱愛與創(chuàng)新思維。在科研層面,樹莓派憑借其靈活的擴展性,成為了眾多科研人員進行小型人工智能實驗的得力助手,幫助他們在有限的資源條件下,快速驗證新的算法與模型,為人工智能技術的進一步突破貢獻力量。隨著技術的不斷迭代升級,未來樹莓派有望在更多領域大放異彩,持續(xù)推動人工智能與日常生活深度融合,創(chuàng)造出更多令人驚喜的應用場景 。
參考附件
?
|