0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

来养一只羊驼宝宝吧?!快来Duo S上跑你的第一个生成式AI

算能开发者社区 2024-05-25 08:34 次阅读

OpenAI的创始成员Andrej Karpathy近日在一个周末内训练了一个微型LLaMA 2模型,并成功将其移植到C语言中。这个项目被他命名为Baby LLaMA 2,令人惊叹的是,推理代码仅有500行。

RISC-V挑战赛中,我们期望在一个轻量级的RISC-V开发板上把这个模型运行起来,所以就有了这个赛题:Baby LLaMA 2 on Duo 速度优化

7cd0e390-1a2e-11ef-bebc-92fbcf53809c.png

先看看效果:


赛题回顾

让 Baby LLaMA 2 运行在 Milk-V Duo 这样的小板子上是很有挑战的事情。本次竞赛旨在提升 Baby LLaMA 2 在 Milk-V Duo 平台上的性能,目标是实现更高的每秒 Token 处理速度。参赛者需要运用轻量级技术和编译器优化策略,结合麦克风语音输入或命令行输入提示词等多种方式,开发一个能够讲故事的机器人 Demo。该 Demo 应通过扬声器进行输出,并可借鉴小米米兔讲故事机器人的原型设计。

赛题地址:https://rvspoc.org/s2311/

实机教程与演示:让DuoS成为孩子的“故事王”

通过外接SPI显示屏、麦克风、音频输出设备,Duo团队实现了一个简易的场景Demo。(源码附在最后)

主要分为以下四个部分:

1、通过麦克风采集语音

2、经过语音转文字ASR模型实现语音实时转换

3、大模型实现“讲故事”实时交互

4、通过文字转语音TTS模型实现语音实时从扬声器播放“故事”

硬件连接方法:

需要设置和使用到的硬件主要有:duo s、SPI显示屏、麦克风、音频输出、按键、Wifi、UART串口、type-c(type-c这里只做供电使用,连接板子均通过串口实现)

7cf06e90-1a2e-11ef-bebc-92fbcf53809c.png

1、SPI显示屏连接

将SPI显示屏背面的引脚对应的接口和duo s板卡的引脚对应

duo s整体引脚图如下:

7d17f780-1a2e-11ef-bebc-92fbcf53809c.png

7d29e94a-1a2e-11ef-bebc-92fbcf53809c.png

SPI屏幕对应的引脚7d2e98f0-1a2e-11ef-bebc-92fbcf53809c.png

整体引脚对应连接图如下:

7d2e98f0-1a2e-11ef-bebc-92fbcf53809c.png

# 清屏cat /dev/zero > /dev/fb0# 花屏cat /dev/random > /dev/fb0

2、麦克风连接

使用USB声卡,注意麦克风和音频输出对应孔的正确连接

# 录音命令(Ctrl+C结束录音):arecord -f dat -c 1 -r 16000 XXXX.wav

3、音频输出连接

使用USB声卡,注意麦克风和扬声器输入孔的正确对应

# 播放录音:aplay XXXX.wav

4、按键连接

按键连接引脚如下:(只需要将引脚和duo s对应功能的引脚连接即可)7d7c129c-1a2e-11ef-bebc-92fbcf53809c.png

5、Wifi连接

这里通过一个一键运行脚本进行设置Wifi

vi wifi-duo-s.sh
# 执行i进入编辑模式,将以下内容写入########################################!/bin/bash# 提示用户输入WiFi的SSID和密码read -p "请输入WiFi的SSID: " ssidread -p "请输入WiFi的密码: " password# 编辑 /etc/wpa_supplicant.conf 文件cat < /etc/wpa_supplicant.confctrl_interface=/var/run/wpa_supplicantap_scan=1update_config=1
network={ ssid="$ssid" psk="$password" key_mgmt=WPA-PSK}EOF# 重启网络wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant.confecho "WiFi configuration completed."######################################## ESC退出编辑模式,:wq保存退出
# 执行shsh wifi-duo-s.sh

6、UART串口连接

将USB-TTL的引脚对应duo s的引脚,对应关系如下:

Milk-V duo s

<----->

USB-TTL 串口

GND(pin 6)

<----->

GND

TX(pin 8)

<----->

RX

RX(pin 10)

<----->

TX

duo s的对应引脚如下:

7d80f0aa-1a2e-11ef-bebc-92fbcf53809c.png

USB-TTL引脚如下:

7e71b260-1a2e-11ef-bebc-92fbcf53809c.jpg

注:关于麦克风和音频输出的其他相关设置命令(可选)

# 查看录音设备arecord -l# 查看播放设备aplay -l# 查看具体设备号的信息(假设设备号为3)amixer contents -c 3
# 麦克风音量设置(name根据具体而定,常规是这个)amixer -Dhw:0 cset name='ADC Capture Volume' 24# 扬声器播放音量设置(假设音量设置为24)# 两种方式:(假设设备号为3)amixer -Dhw:3 cset name='Speaker Playback Volume' 24amixer cset -c 3 numid=6 24

软件使用方法

1、连接WiFi

sh wifi.sh# 输入连接wifi的ssid和pwd

2、安装运行依赖包

pip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple some-package

3、运行故事机baby llama

python asr_chat-llama-baby.py# 在输出Wait for key press后,通过按键输入语音(按住即开始语音输入,松开即结束语音输入)

7e980528-1a2e-11ef-bebc-92fbcf53809c.png

注:baby llama源码如下

# -*- coding: UTF-8 -*-import http.clientimport urllib.parseimport jsonimport subprocessimport timeimport httpximport requests
subprocess.Popen(['chmod', '+x', 'stable_demo'])subprocess.Popen(['./stable_demo'])print('Asr chat tts begin....')appKey = 'P918jP30TLJNHi3Q'#'P918jP30TLJNHi3Q'#s9NZm8ozBKyX63vK' #'RxkHgzYYYYLIP4OD'token = '31b129713beb46b8b0db321a005ecb0d'
# Chat ConfigurationAPI_KEY = "ebb785194c713e7b419ca8742277d414.hCBC11QCZvC5N0YK"BASE_URL = "https://open.bigmodel.cn/api/paas/v4/chat/completions"history = [{"role": "system", "content": "您好!"}]# Aliyun# url = 'https://nls-gateway-cn-shanghai.aliyuncs.com/stream/v1/asr'host = 'nls-gateway-cn-shanghai.aliyuncs.com'
def record_on_gpio(pin): is_pressed = False audioFilepath = './output.wav' while True: try: with open('/sys/class/gpio/gpio{}/value'.format(pin), 'r') as gpio_file: value = gpio_file.read().strip() #print('get key value {}',value) if value == '1' and not is_pressed: # 按键按下时开始录音 recording_process = subprocess.Popen(['arecord', '-f', 'dat', '-c', '1', '-r', '16000', 'output.wav']) is_pressed = True print("Recording started.")
if value == '0' and is_pressed: subprocess.Popen(['killall', 'arecord']) recording_process.wait() # 等待录音进程结束 is_pressed = False print("Recording stopped.") return audioFilepath except Exception as e: print("Error:", e)
def process_chunk(chunk,response_accumulator): if chunk.strip() == "[DONE]": return True, None try: data = json.loads(chunk) # print('process_chunk data:', data) if 'choices' in data and data['choices']: for choice in data['choices']: if 'delta' in choice and 'content' in choice['delta'] and choice['delta']['content']: result = choice['delta']['content'] # print('process_chunk result:', result) response_accumulator.append(result) return False, result except Exception as e: print(f"处理数据块时出错: {e}") return False, None


def chat(query, history): history += [{"role": "user", "content": query}] data = { "model": "glm-4", "messages": history, "temperature": 0.3, "stream": True, }
headers = { "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json" }
response_accumulator = [] response = requests.post(BASE_URL, data=json.dumps(data), headers=headers, stream=True) send_to_lvgl(f"[CLEAR]{query}: ") try: for chunk in response.iter_lines(): if chunk: chunk_str = chunk.decode("utf-8") if chunk_str.startswith("data: "): chunk_str = chunk_str[len("data: "):]
done, result = process_chunk(chunk_str,response_accumulator) # print('result is', result)
chunk_str = "data: " + chunk_str # print("Get response:", chunk_str) if result: send_to_lvgl(result)
if done: tts_text = ''.join(response_accumulator) tts_to_play(tts_text)

except Exception as e: print(f"Error: {str(e)}")

def send_to_lvgl(text): pipe_name = '/tmp/query_pipe' try: with open(pipe_name, 'w') as pipe: pipe.write(text) pipe.flush() except Exception as e: print(f"LVGL send error: {e}")

def process(request, token, audioFile) : # 读取音频 print('process {} {}'.format(request, audioFile)) with open(audioFile, mode = 'rb') as f: audioContent = f.read()
host = 'nls-gateway-cn-shanghai.aliyuncs.com'
# 设置HTTPS请求头部 httpHeaders = { 'X-NLS-Token': token, 'Content-type': 'application/octet-stream', 'Content-Length': len(audioContent) }
conn = http.client.HTTPSConnection(host)
conn.request(method='POST', url=request, body=audioContent, headers=httpHeaders)
response = conn.getresponse() print('Response status and response reason:') print(response.status ,response.reason)
try: body = json.loads(response.read()) text = body['result'] print('Recognized Text:', text) story = makeLLAMAStory(text) print('[makeLLAMAStory] return {}'.format(story)) #send_to_lvgl(story) tts_to_play(story) #chat_response = chat(text, history) #print('Chat Response:', chat_response) except ValueError: print('The response is not json format string')
conn.close()
def makeLLAMAStory(text): print('[makeLLAMAStory] {}'.format(text)) recording_process = subprocess.Popen(['./runq-fast-gcc', 'stories15M_q80.bin', '-t', '0.8', '-n', '256', '-i', text], stdout=subprocess.PIPE, stderr=subprocess.PIPE) return_value, stderr = recording_process.communicate() return return_value.decode('utf-8')
def oneloop(): print('Wait for key press') audioFilepath = record_on_gpio(499)
#print('Wait for first audio') format = 'pcm' sampleRate = 16000 enablePunctuationPrediction = True enableInverseTextNormalization = True enableVoiceDetection = False
# 设置RESTful请求参数 asrurl = f'https://{host}/stream/v1/asr' request = asrurl + '?appkey=' + appKey request = request + '&format=' + format request = request + '&sample_rate=' + str(sampleRate)
if enablePunctuationPrediction : request = request + '&enable_punctuation_prediction=' + 'true'
if enableInverseTextNormalization : request = request + '&enable_inverse_text_normalization=' + 'true'
if enableVoiceDetection : request = request + '&enable_voice_detection=' + 'true'
print('Request: ' + request)
process(request, token, audioFilepath)
def tts_to_play(text, file_path='response.wav'): ttsurl = f'https://{host}/stream/v1/tts' text_encoded = urllib.parse.quote_plus(text) tts_request = f"{ttsurl}?appkey={appKey}&token={token}&text={text_encoded}&format=wav&sample_rate=16000"
conn = http.client.HTTPSConnection(host) conn.request('GET', tts_request) response = conn.getresponse() body = response.read() if response.status == 200 and response.getheader('Content-Type') == 'audio/mpeg': with open(file_path, 'wb') as f: f.write(body) print('TTS audio saved successfully') subprocess.Popen(['aplay', file_path]) else: print('TTS request failed:', body) conn.close()

while True: try: oneloop() except Exception as e: print(e)

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • C语言
    +关注

    关注

    180

    文章

    7573

    浏览量

    133591
  • AI
    AI
    +关注

    关注

    87

    文章

    28698

    浏览量

    265959
  • 模型
    +关注

    关注

    1

    文章

    3023

    浏览量

    48285
收藏 人收藏

    评论

    相关推荐

    人手AI是如何诞生的?

    2023年是AI大语言模型爆发的年,以OpenAI推出的GPT大模型为起始,整个行业开始从“推理式AI”向“生成
    的头像 发表于 07-23 10:33 90次阅读

    中国生成AI专利申请量全球第一

    在科技日新月异的今天,生成人工智能(Generative AI)作为新兴技术的璀璨明珠,正以前所未有的速度改变着我们的世界。当地时间7月3日,世界知识产权组织(WIPO)发布的《生成
    的头像 发表于 07-04 14:49 455次阅读

    生成AI的基本原理和应用领域

    生成人工智能(Generative Artificial Intelligence,简称Generative AI)是种利用机器学习算法和深度学习技术,通过模拟人类的创造性思维过程
    的头像 发表于 07-04 11:50 393次阅读

    原来这才是【生成AI】!!

    随着ChatGPT、文心言等AI产品的火爆,生成AI已经成为了大家茶余饭后热议的话题。可是,为什么要在
    的头像 发表于 06-05 08:04 290次阅读
    原来这才是【<b class='flag-5'>生成</b><b class='flag-5'>式</b><b class='flag-5'>AI</b>】!!

    生成 AI 进入模型驱动时代

    随着ChatGPT和大型语言模型(LLM)呈现爆炸增长,生成人工智能(GenerativeAI)成为近来的大热词。由此引发了场争论:
    的头像 发表于 04-13 08:12 354次阅读
    <b class='flag-5'>生成</b><b class='flag-5'>式</b> <b class='flag-5'>AI</b> 进入模型驱动时代

    NVIDIA即将推出项新的生成AI专业认证

    NVIDIA 即将推出项新的生成 AI 专业认证,助力开发者在这重要领域证明自身技术实力。
    的头像 发表于 03-14 09:43 452次阅读

    世界上第一个石墨烯半导体的“石墨烯”究竟是什么?

    有媒体报道称有研究团队创造了世界上第一个由石墨烯制成的功能半导体(Functional Graphene Semiconductor)。
    的头像 发表于 01-23 11:26 869次阅读

    什么是AI PC、AI手机?AI PC和AI手机出现的来龙去脉

    相信大家现在每天经常可以在报章媒体看到“AI PC”、“AI 手机” 这两?特别是财经新闻,这几个月时不时就可以看见哪
    的头像 发表于 01-18 10:43 1412次阅读

    新火种AI|三星打响“AI手机”第一枪,2024会是AI终端元年吗?

    作者:文子   编辑:小迪 AI手机,距离取代传统手机不远了。 三星新年第一炸,AI手机重磅来袭 2024年才刚刚开始,手机行业就迎来第一个王炸。 作为常年盘踞销量全球前三的品牌,三星
    的头像 发表于 01-06 09:59 491次阅读
    新火种<b class='flag-5'>AI</b>|三星打响“<b class='flag-5'>AI</b>手机”<b class='flag-5'>第一</b>枪,2024会是<b class='flag-5'>AI</b>终端元年吗?

    生成AI技术的应用前景

    生成 AI(人工智能)与我们熟知的 AI 有何不同?这篇文章将为我们探究竟!
    的头像 发表于 11-29 12:20 1093次阅读

    中伟视界:AI分析盒子——ai算法中通过什么方法做到对象报警次,为每个对象生成ID

    AI算法实现对象报警次并生成ID的方法包括利用目标对象的特征信息进行识别和跟踪,以及利用时间戳等信息来排除重复报警。这些方法可确保准
    的头像 发表于 11-25 17:18 318次阅读

    朝夕光年A-SOUL的“”如何秒变“智

    会,展示数实融合“芯”成果 英特尔中国正式发布2022-2023企业社会责任报告 英特尔展示创新智能座舱解决方案,拥抱软件定义汽车新时代 原文标题:朝夕光年A-SOUL的“”如何秒变“智” 文章出处:【微信公众号:英特尔中
    的头像 发表于 11-17 20:00 470次阅读
    朝夕光年A-SOUL的“<b class='flag-5'>羊</b><b class='flag-5'>驼</b>”如何秒变“智<b class='flag-5'>驼</b>”

    利用 NVIDIA Jetson 实现生成 AI

    交互速率运行的 Llama-2-70B 模型。 图 1. 领先的生成 AI 模型在  Jetson AGX Orin 的推理性能 如要在 Jetson
    的头像 发表于 11-07 21:25 747次阅读
    利用 NVIDIA Jetson 实现<b class='flag-5'>生成</b><b class='flag-5'>式</b> <b class='flag-5'>AI</b>

    投票选出喜欢的生成 AI 贺卡!

    NVIDIA NGC Stable Diffusion XL  是款根据用户提供的文本内容巧妙生成相应图像作品的模型。在刚刚过去的假期,我们开展了中秋贺卡生成活动 , 聚焦于生成
    的头像 发表于 10-09 19:50 322次阅读

    MC9S12XEG128MAA 串口接受里面偶尔会出现第一个字节是次回复的数据中任意一个字节

    MC9S12XEG128MAA 串口接受里面偶尔会出现第一个字节是次回复的数据中任意一个字节 在回复完时初始化了数组,没有在发送中启用接
    发表于 09-18 10:50