1. 项目背景:当老台灯遇上AI语音控制
上周收拾书房时,那盏陪伴我五年的小米台灯突然不亮了。拆开底座才发现是电源模块老化,修好之后突然萌生个想法:这盏灯只有物理按键和基础APP控制,能不能让它听懂人话?比如我说"开灯读书模式",它就自动调至4000K色温和80%亮度?
经过七天折腾,终于用小米Miot协议+向量引擎搭建了一套本地化语音控制系统。现在对着手机说"我要睡觉了",台灯就会在10秒内渐暗熄灭;说"加班模式"则切换至5000K冷白光。整个过程完全本地运行,不需要云端服务,响应速度在300ms以内。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术方案选型与核心组件
2.1 小米设备控制方案对比
先测试了三种控制小米智能设备的方案:
- 官方云API:需要企业资质申请,个人开发者无法使用
- MIoT协议:通过模拟米家APP通信,需抓包获取设备token
- HomeAssistant插件:功能完整但依赖第三方服务
最终选择MIoT协议,因其具备:
- 本地局域网控制(无需外网)
- 支持非标设备(老款台灯不在官方API列表)
- Python库成熟(python-miio)
关键代码片段:
python复制from miio import Device
device = Device(ip="192.168.1.100", token="b7c4a8e3d9f...")
device.send("set_properties", [{"did": "brightness", "value": 50}])
2.2 语音识别引擎选择
测试了四种语音转文本方案:
| 方案 | 离线支持 | 中文准确率 | 延迟 | 内存占用 |
|---|---|---|---|---|
| 百度语音API | ❌ | 92% | 800ms | 低 |
| Mozilla DeepSpeech | ✅ | 78% | 1.2s | 2GB |
| Vosk | ✅ | 85% | 600ms | 500MB |
| Whisper.cpp | ✅ | 89% | 400ms | 1GB |
选择Whisper.cpp的原因:
- 本地运行保障隐私
- 支持中英文混合识别("开灯"和"turn on"都能理解)
- 量化模型后仅占用300MB内存
2.3 语义理解关键:向量引擎
传统关键词匹配(如"开灯"触发on)的局限:
- 无法理解"屋里好暗"等同义表达
- 不支持组合指令("调亮一点并且变暖色")
解决方案是用向量引擎构建语义理解层:
- 使用all-MiniLM-L6-v2模型将文本转为384维向量
- 预先计算常见指令的向量并存储:
json复制{ "command": "sleep_mode", "vector": [0.12, -0.05, ..., 0.33], "action": {"brightness": 20, "color_temp": 2700} } - 实时计算语音输入的向量,通过余弦相似度匹配最接近的指令
3. 系统架构与数据流
3.1 整体工作流程
code复制[麦克风] → [Whisper语音转文本] → [向量相似度计算] → [MIoT指令转换] → [台灯]
↑ ↑
[本地模型] [预存指令向量库]
3.2 核心模块实现
3.2.1 语音采集与处理
使用PyAudio实现实时音频流采集,关键参数:
- 采样率:16000Hz
- 帧大小:1024 samples
- 静音检测阈值:-45dBFS
python复制def record_audio():
stream = p.open(format=pyaudio.paInt16,
channels=1,
rate=16000,
input=True,
frames_per_buffer=1024)
while True:
data = stream.read(1024)
if is_speech(data): # VAD检测
process_audio(data)
3.2.2 指令向量化处理
用SentenceTransformer加载本地模型:
python复制model = SentenceTransformer('all-MiniLM-L6-v2',
device='cpu',
cache_folder='./models')
def text_to_vector(text):
return model.encode(text)
3.2.3 指令匹配逻辑
采用FAISS进行高效向量搜索:
python复制import faiss
index = faiss.IndexFlatIP(384) # 内积搜索
index.add(predefined_vectors) # 添加预存指令
def find_command(input_vec):
D, I = index.search(input_vec, k=1)
if D[0][0] > 0.7: # 相似度阈值
return commands[I[0][0]]
return None
4. 实际效果与性能优化
4.1 典型场景测试
| 语音输入 | 识别文本 | 执行动作 | 响应时间 |
|---|---|---|---|
| "太黑了看不清" | 太黑了看不清 | 亮度70% + 色温4000K | 320ms |
| "我要睡了" | 我要睡了 | 10秒渐暗至关闭 | 290ms |
| "调成暖色不要太亮" | 调成暖色不要太亮 | 色温2700K + 亮度30% | 380ms |
4.2 性能优化技巧
-
模型量化:
- 将Whisper模型从FP32转为INT8,速度提升2倍
- 使用
ctransformers加载量化模型:python复制from ctransformers import AutoModelForCausalLM model = AutoModelForCausalLM.from_pretrained("whisper-small-int8")
-
向量缓存:
- 对重复指令缓存向量结果
- 设置5秒过期时间避免内存泄漏
-
设备通信优化:
- 维持长连接代替频繁握手
- 错误重试机制(3次/指令)
5. 常见问题与解决方案
5.1 设备Token获取方法
- 安卓手机安装"米家"APP
- 使用Packet Capture抓包
- 过滤
miot协议请求 - 从请求头提取
token字段
注意:部分新款设备采用动态token,需定期更新
5.2 中文语音识别不准
- 在Whisper训练数据中加入中文家居场景语料
- 添加自定义词汇表:
python复制processor.tokenizer.add_tokens(["色温", "亮度"])
5.3 向量匹配错误
- 调整相似度阈值(建议0.65-0.75)
- 添加否定样本(如"不要开灯")
- 引入上下文记忆(上一条指令加权)
6. 扩展应用场景
这套方案可复用于:
- 传统家电改造:空调+红外模块实现语音控温
- 多设备联动:说"观影模式"自动关灯+开投影
- 无障碍辅助:为视障人士提供语音控制家电能力
最近正在尝试接入人体传感器,实现"人离开自动关灯"的增强功能。经过实测,在树莓派4B上整套系统内存占用稳定在1.2GB左右,完全可以作为常驻服务运行。
