• 回复
  • 收藏
  • 点赞
  • 分享
  • 发新帖

【 DigiKey DIY原创大赛】基于树莓派5的llm本地语音助手系统

引言

随着人工智能技术的广泛应用,各种专门为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++推理的框架。

全部回复(0)
正序查看
倒序查看
现在还没有回复呢,说说你的想法