
昨天蹲客厅拆新买的灯带时突然想起来,之前下在硬盘里的Qwen2-0.5B量化版一直没顾上玩,不如拿它对接下门口的ESP32灯控板,省得每次开灯还要喊云音箱跳公网,反应慢就算了,还总偷听说话。
先把本地模型跑起来不报错
我这边没自己折腾原生模型加载,之前试过自己倒腾transformers装依赖,版本不兼容的问题搞到头疼,直接用Ollama封装好的版本最省事,官网下安装包点下一步就行,全平台都支持。装完打开终端直接拉模型:
ollama run qwen2:0.5b-instruct-q4_0
等拉完模型,终端里能直接对话就说明跑通了。这个我还没细测不同量化等级的资源占用,反正我那台用了快6年的笔记本跑起来没卡顿,用来做指令识别完全够用。
别一上来就拉7B、14B的大模型,就做个简单的开关指令识别,大模型不仅占硬盘空间,响应还慢,喊完开灯光等半天,体验特别脱节。
写个短脚本做指令转发
模型跑通之后,写个很短的Python脚本就行,作用是把用户输入丢给模型,识别到开关指令就给局域网里的ESP32发UDP包,代码直接照着改IP就能用:
import requests
import socket
# 本地Ollama的默认接口地址
OLLAMA_API = "http://localhost:11434/api/generate"
# 改成你自己ESP32的局域网IP和监听端口
ESP32_ADDR = ("192.168.31.88", 8266)
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
while True:
user_input = input("说指令:")
prompt = f"用户输入是{user_input},如果是开灯相关请求就只返回ON,关灯就只返回OFF,其他无关内容都返回NONE,不要加任何额外解释、标点、语气词"
resp = requests.post(OLLAMA_API, json={
"model": "qwen2:0.5b-instruct-q4_0",
"prompt": prompt,
"stream": False
})
res = resp.json()["response"].strip()
if res in ["ON", "OFF"]:
sock.sendto(res.encode(), ESP32_ADDR)
print(f"已发送指令:{res}")
else:
print("没识别到有效开关指令")
这里要注意,提示词一定要约束死输出格式,别让模型自由发挥,我最开始没加严格约束,模型回我“好的呀,这就为您打开灯光~”,ESP32收到这串带语气的字符根本识别不了。
- 所有设备一定要连同一个局域网的主网段,别把跑模型的电脑连访客WiFi,ESP32连主WiFi,UDP包跨网段根本发不过去,我昨天在这卡了快四十分钟才反应过来
- ESP32端不用写复杂逻辑,直接打开Arduino IDE里的UDP接收示例,改下WiFi账号密码、对应引脚的电平控制逻辑就行,总共也就二十行不到的代码
- 要是想加语音输入,直接装SpeechRecognition库调用本地麦克风就行,代码加起来也就不到十行,我这边麦克风驱动还没调顺,等跑通了再补记录
反正这一套跑下来完全不碰公网,响应也跟手,比之前用的云智能音箱踏实多了。
评论一下?