AIoT应用开发:搞定语音对话机器人=ASR+LLM+TTS

最近新入手了一台 arm 开发板,希望打造一款有温度、有情怀的陪伴式 AI 对话机器人。

大体实现思路如下:

前几篇,在板子上把LLM 大脑耳朵嘴巴装上了:

对应到设备上:

  • 耳朵 == 麦克风;
  • 大脑 == 大语言模型;
  • 嘴巴 == 扬声器;

今日分享,带大家实操:如何把三者串联起来,实现实时语音对话。

有小伙伴问:没有 arm 开发板怎么办?准备一台 Android 手机就行。

友情提醒:本文实操,请确保已在手机端准备好 Linux 环境,具体参考教程:如何在手机端部署大模型?

1. 语音识别-ASR

原打算在板子上部署语音识别模型,发现小模型效果不太好,而大模型的耗时不能忍。

故先采用云端接口跑通流程,这里选用 siliconflow 提供的免费接口。

给大家贴下调用代码:

def asr_sensevoice(file_path="output/test.mp3"):
    url = "https://api.siliconflow.cn/v1/audio/transcriptions"
    headers = {
        "accept": "application/json",
        "Authorization": "Bearer xxx"
    }
    files = {
        "file": open(file_path, "rb"),  # The key "file" should match the expected parameter name on the server
        "model": (None, "iic/SenseVoiceSmall")  # "None" is used because model is just a string, not a file
    }
    response = requests.post(url, files=files, headers=headers)
    data = response.json()
    return data["text"]

2. 智能问答-LLM

如何在手机端部署大模型?中,我们本地部署了qwen2:0.5b并接入了OneAPI,直接调用即可。

3. 语音合成-TTS

之前和大家过几款最近爆火的 TTS 项目:

EdgeTTS 使用最为简单,先接进来:

def tts_edge(text='', filename='data/audios/tts.wav'):
    communicate = edge_tts.Communicate(text=text,
        voice="zh-CN-XiaoxiaoNeural", # zh-HK-HiuGaaiNeural
        rate='+0%',
        volume= '+0%',
        pitch= '+0Hz')
    communicate.save_sync(filename)

4. 整体实现

最后,我们把 ASR + LLM + TTS 串联起来,关键流程如下:

  • 基于AIoT应用开发:给板子装上’耳朵’,实现音频录制中实现的逻辑,一旦有音频文件保存到本地,即触发对话功能;
  • 语音识别:如果识别结果开头包含关键词kwords,才会触发 LLM;
  • 智能问答:LLM 基于语音识别结果,做出文字答复;
  • 语音合成:TTS 结果保存到本地;
  • 音频播放:把保存在本地的 TTS 结果,通过蓝牙音箱播放。

贴一下完整代码:

import android
droid = android.Android()
def asr_llm_tts(filename='xx.wav', llm_list=['qwen-0.5b'], tts_path='/sdcard/audios', kwords='小爱'):
    asr_text = asr_sensevoice(filename)
    logging.info(f"ASR 识别结果:{asr_text}")
    if asr_text.startswith(kwords):
        messages = [
                {'role': 'system', 'content': sys_base_prompt},
                {'role': 'user', 'content': asr_text}
            ]
        result = unillm(llm_list, messages)
        logging.info(f"LLM 结果:{result}")
        filename = f'{tts_path}/{datetime.now().strftime("%Y%m%d_%H%M%S")}.wav'
        tts_edge(result, filename=filename)
        if os.path.exists(filename):
            tag = os.path.basename(filename).split('.')[0]
            # 查看是否有音频播放
            play_list = droid.mediaPlayList().result
            for item in play_list:
                res = droid.mediaPlayInfo(item)
                isplaying = res.result['isplaying']
                if not isplaying:
                    droid.mediaPlayClose(item)
            # 开始播放音频
            res = droid.mediaPlay(filename, tag, True)
            # 打印播放信息
            logging.info(droid.mediaPlayInfo(tag).result)
        else:
            logging.error("TTS 失败。")

值得注意的是:asr_llm_tts() 函数耗时较长,会阻塞主线程,导致无法及时从音频流中读取数据,引起下面的错误。

p = pyaudio.PyAudio()
stream = p.open()
data = stream.read(chunk)
  File "/home/aidlux/.local/lib/python3.8/site-packages/pyaudio/__init__.py", line 570, in read
    return pa.read_stream(self._stream, num_frames,
OSError: [Errno -9981] Input overflowed

这是因为 stream.read(chunk) 需要定期被调用,以清空音频输入缓冲区,如果这个调用被延迟,缓冲区就会溢出。

为了解决这个问题,有两种方法:

  • 异步处理:将 asr_llm_tts() 放在一个异步任务中执行,这样主线程可以继续处理音频流,而不会因为等待异步任务完成而阻塞。

  • 多线程处理:创建一个新的线程来处理 asr_llm_tts(),这样就不会干扰主线程的音频流处理。

import threading
threading.Thread(target=asr_llm_tts, args=(filename,)).start()

5. 效果展示

给大家展示一段日志信息:

程序正在运行,按 Ctrl+C 停止...
开始录音...
ASR 识别结果:
低音量持续,停止录音。
录音已保存为 data/audios/20240917_094434.wav
ASR 识别结果:小爱小爱,夸夸我。
LLM 结果:你好!初次见面,很高兴认识你。你的问题我可以帮忙回答。你最近的生活和工作状态如何?遇到什么问题了吗?我会尽力帮助你。
{'loaded': True, 'duration': 13344, 'looping': False, 'isplaying': True, 'tag': '20240917_094440', 'position': 0, 'url': '/sdcard/audios/20240917_094440.wav'}

最后播报的音频结果:体验地址

写在最后

至此,我们已经给开发板装上了:大脑 + 耳朵 + 嘴巴,并实现了实时语音对话,一个 AI 机器人的雏形总算捏出来了。

如果对你有帮助,欢迎点赞收藏备用。

下篇,我们将继续接入 AI 视觉能力,实现更多有意思的创意,敬请期待!


为方便大家交流,新建了一个 AI 交流群,欢迎对AIoTAI工具AI自媒体等感兴趣的小伙伴加入。

最近打造的微信机器人小爱(AI)也在群里,公众号后台「联系我」,拉你进群,交个朋友。


猴哥的文章一直秉承分享干货 真诚利他的原则,最近陆续有几篇分享免费资源的文章被优快云下架,申诉无效,也懒得费口舌了,欢迎大家关注下方公众号,同步更新中。

### 关于Hi3816与ASR的关系或兼容性 Hi3816 是华为海思推出的一款高性能视频处理芯片,主要应用于安防监控领域。它具备强大的图像信号处理能力和编码能力,能够支持高清视频的实时采集、处理和传输[^1]。 #### ASR 技术概述 自动语音识别(Automatic Speech Recognition, ASR)是一种将人类语音转换为文本的技术。尽管 Hi3816 主要专注于视频处理,但在某些应用场景下,可能需要结合音频处理功能来实现更全面的数据分析。例如,在智能监控系统中,除了视觉信息外,还可能需要通过声音检测异常事件或记录对话内容[^2]。 #### Hi3816 和 ASR 的潜在关系 虽然 Hi3816 并未专门设计用于语音处理,但它可以通过与其他模块协作完成复杂的多媒体任务。具体来说: - **硬件扩展**:Hi3816 可能通过外部接口连接专用的语音处理单元或者 FPGA 加速卡,从而间接支持 ASR 功能。 - **软件集成**:在嵌入式 Linux 环境下运行的应用程序可以调用第三方库(如 Kaldi 或 DeepSpeech),利用 CPU 资源执行轻量级的语音转文字操作[^3]。 以下是基于 Hi3816 架构的一个简单示例代码片段展示如何设置编译选项以适应不同类型的负载需求: ```cpp // 配置强制链接不可见函数至目标二进制文件 if (build_enable == "true") { ldflags += [ "-Wl,--whole-archive" ]; // 添加必要的静态库路径 foreach(force_link_lib, bin_file.force_link_libs) { ldflags += [ "-l${force_link_lib}" ]; } // 特定 BSP 库关联 ldflags += [ "-lbsp${bsp_target_name}" ]; ldflags += [ "-Wl,--no-whole-archive" ]; } ``` 此代码段展示了如何调整构建脚本中的 `ldflags` 参数以便更好地控制最终可执行文件的行为特性,这对于确保复杂项目内的各个组件间无缝交互至关重要。 ### 使用场景探讨 对于 Hi3816 来说,其典型应用集中在以下几个方面,并且这些场合也可能涉及一定程度上的 ASR 支持: 1. **智能家居设备** – 结合摄像头捕捉画面的同时监听特定关键词触发报警机制; 2. **工业自动化生产线监测** – 实现对机械设备运转噪音模式变化敏感度提升进而预测维护周期; 3. **公共安全防护体系增强版解决方案**– 不仅依靠影像资料判断是否存在危险行为还能依据背景音效辅助决策制定过程更加精准可靠; 综上所述,尽管 Hi3816 自身并不直接提供完整的 ASR 解决方案,但凭借灵活的设计理念以及丰富的生态系统资源完全可以满足大多数实际工程项目的多样化诉求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值