Edge AI 本地推理:WhisperCPP 离线语音 + 毫米波雷达检测
云端 AI 好用但有个致命问题——你的语音数据被上传到服务器。家里装了 WhisperCPP 本地推理,所有语音识别在本地完成,数据不出门。配合毫米波雷达做人体检测, privacy-first 的智能家居终于有了完整方案。
为什么需要 Edge AI
| 方案 | 延迟 | 隐私 | 成本 | 稳定性 |
|---|---|---|---|---|
| 云端 API(OpenAI Whisper) | 2-5 秒 | ❌ 数据上传 | 月费 $0.006/分钟 | 依赖网络 |
| Edge AI(WhisperCPP) | 0.5-1 秒 | ✅ 本地处理 | 一次性硬件成本 | 离线可用 |
| 传统语音识别(离线规则) | < 0.1 秒 | ✅ | 低 | 准确率有限 |
我的判断:语音识别类场景(指令控制、跌倒语音呼救)必须本地化。云端 API 适合非敏感场景(天气查询、闲聊)。
WhisperCPP 本地部署
Docker 方案(推荐)
# ~/whisper/docker-compose.yml
services:
whispercpp:
image: ggerganov/whisper.cpp:latest
restart: unless-stopped
ports:
- "8080:8080" # REST API 端口
volumes:
- ./models:/models # 模型文件
- ./audio:/audio # 输入音频
- ./results:/results # 转写结果
environment:
- WHISPER_MODEL=base # tiny/base/small/large
- WHISPER_LANG=zh # 语言:zh/en/ja
- WHISPER_DEVICE=cpu # cpu/gpu(Pi 只能用 cpu)
- WHISPER_BEAM_SIZE=3 # 束搜索宽度,越大越准越慢
command: >
./server
--model /models/base.bin
--language zh
--convert
# 下载模型(base 约 150MB,small 约 460MB)
mkdir -p ~/whisper/models
cd ~/whisper/models
wget https://huggingface.co/ggerganov/whisper.cpp/resolve/main/base.bin
wget https://huggingface.co/ggerganov/whisper.cpp/resolve/main/base.en.bin
# 启动
cd ~/whisper && docker compose up -d
# 测试
curl -X POST http://localhost:8080/v1/transcriptions \
-F "[email protected]" \
-F "language=zh" \
-F "model=base"
模型选择
| 模型 | 大小 | CPU 耗时(1 分钟音频) | 中文准确率 | 推荐场景 |
|---|---|---|---|---|
| tiny | 39MB | ~3 秒 | 65% | 简单关键词检测 |
| base | 150MB | ~10 秒 | 85% | 日常语音指令(首选) |
| small | 460MB | ~30 秒 | 90% | 复杂指令、长对话 |
| medium | 1.5GB | ~80 秒 | 93% | 会议转录(不推荐家用) |
| large | 3GB | ~150 秒 | 95% | 专业转录 |
我的判断:家用语音指令控制选 base 模型,准确率和速度平衡最好。tiny 够用但错字多,small 以上对 Pi 4 压力太大。
毫米波雷达接入
硬件选型
| 型号 | 价格 | 检测距离 | 特点 | 推荐指数 |
|---|---|---|---|---|
| LTCC-RD02PD | ¥45 | 4-8 米 | 运动 + 存在检测,UART 输出 | ⭐⭐⭐⭐⭐ |
| LD2410 | ¥60 | 6 米 | 有 RSSI 强度,可测速 | ⭐⭐⭐⭐ |
| RD02 | ¥35 | 4 米 | 最便宜,基础款 | ⭐⭐⭐ |
| HM3301 | ¥80 | 10 米 | 远距离,工业级 | ⭐⭐⭐ |
推荐:老人跌倒检测选 LD2410(有 RSSI,能区分移动和静止);普通存在检测选 LTCC-RD02PD(便宜够用)。
ESPHome 固件
# rd02pd-sensor.yaml
esphome:
name: living-room-radar
platformio_options:
lib_deps:
- bblanchon/[email protected]
esp32:
board: esp32-c6-devkitc-1
framework:
type: arduino
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
ota:
password: !secret ota_password
# 毫米波雷达 UART(TX→GPIO6, RX→GPIO7)
uart:
tx_pin: GPIO6
rx_pin: GPIO7
baud_rate: 115200
parity: NONE
stop_bits: 1
# 自定义解析 LTCC-RD02PD 协议
binary_sensor:
- platform: gpio
name: "Living Room Motion"
pin:
number: GPIO8
mode:
input: true
pullup: true
device_class: motion
filters:
- delayed_on: 100ms
- delayed_off: 3s
# 通过 UART 解析雷达数据(存在/移动状态)
sensor:
- platform: custom
lambda: |-
auto radar = new LtccRadarSensor();
App.register_component(radar);
return {radar->motion_detection, radar->presence_detection};
sensors:
- name: "Motion Level"
unit_of_measurement: "%"
accuracy_decimals: 0
- name: "Presence Level"
unit_of_measurement: "%"
accuracy_decimals: 0
# 自定义组件(解析 LTCC-RD02PD 串口协议)
custom_component:
- lambda: |
class LtccRadarSensor : public Component, public Sensor {
public:
void setup() override {
// 初始化 UART
Serial2.begin(115200, SERIAL_8N1, GPIO6, GPIO7);
}
void loop() override {
if (Serial2.available() >= 8) {
uint8_t buf[8];
Serial2.readBytes(buf, 8);
// 协议解析:0xAA 0x55 + 状态字节 + 数据 + 校验
if (buf[0] == 0xAA && buf[1] == 0x55) {
motion_ = (buf[2] & 0x01) ? 100 : 0;
presence_ = (buf[2] & 0x02) ? 100 : 0;
// 发布传感器值
motion_sensor_->publish_state(motion_);
presence_sensor_->publish_state(presence_);
}
}
}
private:
float motion_ = 0;
float presence_ = 0;
Sensor* motion_sensor_ = nullptr;
Sensor* presence_sensor_ = nullptr;
};
HA 集成
雷达数据通过 ESPHome integration 自动出现在 HA 里:
- binary_sensor.living_room_motion — 运动检测(on/off)
- sensor.living_room_motion_level — 运动强度(0-100%)
- sensor.living_room_presence_level — 存在强度(0-100%)
实际应用场景
场景一:离线语音指令控制
# 语音指令识别后触发自动化
alias: "语音控制灯光"
triggers:
- trigger: event
event_type: whisper_transcription
event_data:
text: "打开客厅灯"
conditions: []
actions:
- action: light.turn_on
target:
entity_id: light.living_room
# WhisperCPP 监听麦克风,检测到语音后发布 event
# 用 pulseaudio 或 alsa 捕获音频
arecord -f S16_LE -r 16000 -d 3 /tmp/audio.wav
curl -X POST http://localhost:8080/v1/transcriptions \
-F "file=@/tmp/audio.wav" \
-F "language=zh" | jq .text
注意:HA 原生没有 Whisper 集成,需要用 Node-RED 或自定义 Python 脚本做桥接。
场景二:老人跌倒检测联动
# 毫米波雷达 + 语音双重确认
alias: "跌倒检测紧急响应"
triggers:
- trigger: state
entity_id: binary_sensor.living_room_motion
to: "off"
for: "00:00:05" # 5 秒内无运动
conditions:
- condition: template
value_template: >
{{ is_state('sensor.living_room_presence_level', '100')
and is_state('binary_sensor.living_room_motion', 'off') }}
actions:
# 1. 语音询问
- action: tts.speak
target:
entity_id: media_player.living_room
data:
message: "检测到您可能跌倒,需要帮助吗?"
# 2. 等待 10 秒
- delay: "00:00:10"
# 3. 无回应则通知
- condition: state
entity_id: binary_sensor.living_room_motion
state: "off"
actions:
- action: notify.mobile_app
data:
message: "🚨 客厅疑似跌倒,请立即确认!"
title: "紧急警报"
data:
priority: high
场景三:夜间智能夜灯
# 毫米波雷达检测静止存在,比 PIR 更适合夜间
alias: "夜间毫米波夜灯"
triggers:
- trigger: state
entity_id: sensor.living_room_presence_level
above: 50
conditions:
- condition: time
after: "21:00:00"
before: "06:00:00"
- condition: state
entity_id: light.living_room
state: "off"
actions:
- action: light.turn_on
target:
entity_id: light.hallway_night_light
data:
brightness_pct: 10 # 极低亮度,不打扰
为什么用雷达不用 PIR:PIR 检测不到静止人体(呼吸幅度太小),老人睡着后 PIR 会判定"无人"关灯。雷达检测的是微动(胸腔起伏),静止也能检测到。
3 个真实翻车案例
案例一:WhisperCPP 识别中文效果差
现象:base 模型英文识别准确率 90%,中文只有 60%。
根因:下载的模型是 base.en(英文专用),中文需要 base 模型(多语言)。
# 错误:下了英文模型
wget https://huggingface.co/ggerganov/whisper.cpp/resolve/main/base.en.bin
# 正确:下多语言模型
wget https://huggingface.co/ggerganov/whisper.cpp/resolve/main/base.bin
修复:
# 设置 WHISPER_MODEL=base(不是 base.en)
# 在请求时指定 language=zh
curl -X POST http://localhost:8080/v1/transcriptions \
-F "[email protected]" \
-F "language=zh" \
-F "model=base"
案例二:毫米波雷达误触发
现象:雷达频繁报"有人",但其实屋里没人。
根因:雷达安装角度太低(< 15°),地面反射造成误检。
修复: 1. 调整安装高度:建议 2.0-2.5 米 2. 调整检测角度:向下 15-30°,不要水平或向上 3. 调低灵敏度:通过 UART 发送 AT 命令降低检测阈值
案例三:WhisperCPP 内存溢出
现象:Pi 4 上跑 base 模型,转写时 OOM(Out of Memory)崩溃。
根因:默认模型加载到 RAM,Pi 4 4GB 内存被其他进程占用后剩余不足。
# 检查内存
free -h
# 剩余 < 500MB 时会 OOM
# 解决方案 1:用 tiny 模型(39MB,足够关键词检测)
WHISPER_MODEL=tiny
# 解决方案 2:加 swap
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
# 解决方案 3:换 x86 小主机(8GB+ RAM)
我的判断:Pi 4 4GB 跑 base 模型勉强够,但建议加 swap。如果跑 small 以上模型,换 x86 小主机更稳。
总结
Edge AI 本地推理的核心价值是隐私 + 离线可用。WhisperCPP 让语音识别不再依赖云端,毫米波雷达让存在检测不再侵犯隐私。两者结合,家庭 AI 才能真正"本地化"。
我的判断:现在入手 Edge AI 的时机已经成熟——WhisperCPP 在 Pi 4 上能跑 base 模型,LTCC-RD02PD 只要 ¥45。预算有限先装雷达(¥45),再逐步加语音识别(免费 Docker 镜像)。不要一开始就追求完整方案,分阶段上线风险更低。
延伸阅读
- Matter 1.4 + Thread 智能家居协议:边缘路由搭建实战
- ESPHome DIY 智能设备:ESP32-C6/H2 开发入门
- AI Agent 智能家居自动化:Blueprint AI 2.0