引言
随着人工智能技术的广泛应用,各种专门为AI设计的硬件设备正迅速涌现。这些设备不仅提升了AI应用的性能,还将其带入更多生活和工作场景。
比如最先乘着大语言模型的东风,在互联网上火起来的rabbit R1硬件。其拥有一块触摸屏(官方设定为非触摸,听说可以修改系统设置变成可以识别触屏),以及上下推拉式的对话按钮,同时还配备了一个360度摄像头。我们在rabbit R1官网上可以查看到,其拥有一些很酷的小技能。如语音对话,物品识别,双向翻译,网络购物之类的。其在系统级别集成大语言模型的接口,将设备传感器获取的多模态数据(图像,语言,文字等等,甚至是按钮操作),在本地进行一些低算力的应用,如果需要高算力的应用支持则需要接入网络,借助服务器的算力识别。
另外最近各个公司都在积极推出结合自家大模型技术的ai硬件产品,比如智能戒指,智能鼠标之类的。其中最引入瞩目的便是字节跳动公司计划推出的ai眼镜、智能耳机产品,相关计算接入了自家的豆包大模型。处理一些语音对话,实时翻译之类的任务。通过在硬件上搭载的传感器,收集相关语音输入,把ai推理所需要的计算放在云端,云端处理完过后将处理结果返回。当然本地也可以执行一些算力低的推理任务,将一部分计算上传至云,此时如何将调度部分任务卸载至云的问题亟待解决。
另外就是一些将ai计算加速硬件,嵌入到产品中。比如npu加速,以及最近很火的ai pc名词。
为了支持大规模AI计算,硬件厂商推出了大量适合边缘设备和嵌入式应用的AI芯片。例如:
谷歌 Coral:基于 Edge TPU,专为边缘AI任务设计,支持低功耗运行和快速模型推理。英伟达 Jetson 系列:提供强大的GPU性能,用于边缘设备上的计算密集型AI任务。自家厂商推出的npu,适用于自家硬件平台,在一些特定任务上有高效加速作用。
此前在llama.cpp刚出来的时候,本人在树莓派4B上测试推理结果,一个7B参数的模型,推理速度大概是每20s一个token,速度完全不能够实用。现如今,各种场景下的应用ai模型发展的都十分迅速,技术更迭也很快,如今已经出现了很多易于配置,应用大模型的一套解决方案。比如dify,ollama之类的大模型应用框架。直接在应用中就可以拉取模型,处理输入输出。刚好感谢得捷电子以及电源网联合推出的diy活动,希望能通过这个机会体验一下ai应用,尝试将大模型更好地、方便地带入生活之中。
项目目标
计划是基于树莓派实现一个本地语言助手,数据保存本地保护隐私。
tip:但在实际开发过程中,觉得ollama的性能在树莓派上的表现实在还是不够,需要更换一些更快的推理引擎。
语音识别:通过 SenseVoice 模型将语音转化为文字,支持多种语言的语音输入。
自然语言理解与生成:通过调用 Ollama API 的 Qwen 模型生成智能对话,理解用户问题并给予自然语言的响应。
语音输出:通过 pyttsx3 将 Qwen 模型生成的文字回答转换为语音,返回给用户。
唤醒功能:实现按键和语音(通过 Snowboy)唤醒功能,允许用户通过不同方式启动语音助手。
项目材料
树莓派 5:主控板,负责运行所有逻辑。
USB 声卡 + 麦克风:用于高质量语音输入以及输出。树莓派是自带有i2s接口的,但是为了方便还是用的usb免驱的。
软件
操作系统:基于 ubuntu 24。
语音处理:ASR:使用 阿里推出的sensevoice模型,支持多国语言,拥有情感分析
TTS:基于 pyttsx3
LLM 推理:使用ollama大模型应用框架,进行本地语音模型推理
安装ollama推理框架
Ollama 是一个开源框架,专注于本地部署大型语言模型(LLM),让用户无需依赖云服务即可运行强大的 AI 应用。它通过容器化模型管理和轻量化的 API 接口,支持聊天交互、文本生成、模型定制等功能。
curl https://ollama.ai/install.sh | sh
ollama并不支持使用rapberrypi5的gpu处理,虽然自带的gpu很羸弱。树莓派5可以装配pcie扩展的ai加速 kit。
ollama pull tinyllama //拉取模型
ollama list //显示本地模型
ollama有一套很完整的大模型调用框架。
ollama有对话模式,以及可以调用api。但在我实际运行中,树莓派上本地调用api返回回答非常慢。
可以通过简单的 HTTP 请求调用 Ollama 提供的 API 生成文本。
import requests
# 定义请求的 URL 和头部信息
url = "https://api.ollama.com/v1/generate"
headers = {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
}
# 定义请求的 payload
payload = {
"model": "qwen", # 使用的模型名称,支持多个模型
"input": "Hello, how are you?", # 输入的对话或文本
}
# 发送请求
response = requests.post(url, json=payload, headers=headers)
# 输出结果
if response.status_code == 200:
data = response.json()
print("Response:", data['text']) # 返回的生成文本
else:
print(f"Error: {response.status_code}")
使用不同的模型
除了 qwen,Ollama 还支持其他模型。想使用不同的模型,只需在命令中指定模型名称:
ollama run <model_name> "<input_text>"
例如,如果您想使用 llama 模型进行文本生成,可以执行:
ollama run llama "What is the meaning of life?"
模型列表
可以列出 Ollama 支持的所有可用模型:
ollama models
此命令会列出当前可以使用的
安装阿里的sencevoice
SenseVoice 是一个语音基础模型,具有多种语音理解功能,包括自动语音识别 (ASR)、口语识别 (LID)、语音情感识别 (SER) 和音频事件检测 (AED)。
安装为python模块
git clone https://github.com/alibaba/FunASR.git && cd FunASR
pip3 install -e ./
tts可以使用pip 下的pyttsx3
唤醒进行录音
# 按键唤醒线程
def button_wakeup():
import keyboard
global wakeup_flag
while True:
if keyboard.read_key() == "enter":
with lock:
wakeup_flag = True
print("按键唤醒成功!")
# Snowboy 唤醒线程
def snowboy_wakeup(model_path="resources/snowboy.umdl"):
def detected_callback():
global wakeup_flag
with lock:
wakeup_flag = True
print("语音唤醒成功!")
detector = snowboydecoder.HotwordDetector(model_path, sensitivity=0.5)
print("正在监听语音唤醒...")
detector.start(detected_callback=detected_callback)
detector.terminate()
sencevoice语音转文字
# SenseVoice 音频转录函数
def recognize_speech_with_sensevoice(audio_data, language="auto"):
model_dir = "iic/SenseVoiceSmall"
model = AutoModel(
model=model_dir,
trust_remote_code=True,
remote_code="./model.py",
vad_model="fsmn-vad",
vad_kwargs={"max_single_segment_time": 30000},
device="cuda:0",
)
# 将录音传给模型进行转录
res = model.generate(
input=audio_data,
cache={},
language=language, # "zh", "en", "yue", "ja", "ko", "nospeech"
use_itn=True,
batch_size_s=60,
merge_vad=True,
merge_length_s=15,
)
text = rich_transcription_postprocess(res[0]["text"])
return text
调用ollama的api功能进行推理
# Ollama API 调用
def call_ollama(prompt, api_url="http://localhost:8000/api/generate"):
headers = {"Content-Type": "application/json"}
payload = {"prompt": prompt, "model": "qwen"}
try:
response = requests.post(api_url, json=payload)
if response.status_code == 200:
return response.json().get("text", "No response.")
else:
return f"Error: {response.status_code}"
except Exception as e:
return f"Exception occurred: {str(e)}"
这里的推理速度很奇怪,在ollama进入对话模式的时候,推理速度是很快的,但是调用api的时候推理十分慢。感觉应该是cpu占用问题,ollama的cpu占用较大,很影响效率。
录音功能
# 录音功能
def record_audio(duration=5, sample_rate=16000):
print("开始录音...")
audio = sd.rec(int(duration * sample_rate), samplerate=sample_rate, channels=1, dtype=np.int16)
sd.wait()
print("录音结束。")
return audio
调用tts语音
# 全局变量
wakeup_flag = False
lock = threading.Lock()
# 初始化语音合成
def speak(text):
engine = pyttsx3.init()
engine.setProperty('rate', 150) # 设置语速
engine.setProperty('voice', 'english') # 设置语音
engine.say(text)
engine.runAndWait()
语音本来是也想用阿里的cozyvoice模型的,但是看了一下好像对arm支持不是很好,并且自带了英伟达显卡的加速,如果不能用加速的话本地跑是非常非常慢的,对于想实时对话来说不太现实。可以考虑在服务器部署然后调用相关的api。
总结:
在本项目中,我开发了一个基于大语言模型(LLM)的语音助手系统,使用了Ollama API来处理文本生成任务,结合 SenseVoice 进行语音转录,最终使用 pyttsx3 进行语音合成,使用了按键或者是snowboy进行唤醒录音。
项目不足:推理速度较慢: 使用 Ollama API 进行大语言模型推理时,响应速度不尽如人意。虽然 OLLama 提供了便捷的接口,但由于网络延迟及模型本身推理的时间,导致响应速度较慢,尤其是在进行长文本生成时。
语音识别的准确性问题: 尽管 SenseVoice 支持多语言转录,但在嘈杂环境或发音不清晰时,识别效果仍存在一定局限性,尤其是在口音多样化的情况下。
改进方向:本地部署优化: 为了提升推理速度,考虑将 Ollama 或类似的大语言模型替换为其他支持大模型的推理引擎llama.cpp,这样可以提升响应速度。
由于在大模型应用做实践的比较少,ollama在算力高的平台是非常易用的,但是跑在树莓派5上性能就有点不尽人意。这也让我认识到,在项目初期制定方案的时候,应该参考网上已有的用例,看是否可行并且高效。在边缘设备上一般采用性能更好的使用c++推理的框架。