1. 项目背景与核心目标
最近在折腾Longan Pi 3H开发板时,突然想到一个有趣的应用场景——给ChatGPT增加视觉和语音交互能力。这个想法源于日常使用AI助手的痛点:纯文本交互缺乏真实感,而市面上的智能音箱又不够开放。于是决定用这块性能不错的开发板,搭建一个能看会说的小型AI终端。
核心目标很明确:
- 视觉能力:通过摄像头让AI"看到"周围环境
- 语音交互:实现TTS(文本转语音)和语音输入
- 轻量服务:用FastAPI搭建高效的本地API服务
- 硬件适配:充分利用Longan Pi 3H的硬件特性
2. 硬件准备与环境配置
2.1 Longan Pi 3H开发板特性
这块板子有几个亮点特别适合本项目:
- 双核Cortex-A7主控,主频1.2GHz
- 内置128MB DDR2内存
- 支持Linux系统
- 丰富的接口:USB、GPIO、I2C等
- 低功耗设计(实测满载约2W)
提示:虽然性能比不上树莓派4,但胜在性价比高,跑轻量服务完全够用
2.2 外设选型与连接
视觉部分我选了常见的USB摄像头(罗技C270),语音交互用了USB麦克风+3.5mm音箱的组合。具体连接方式:
摄像头 → USB接口 麦克风 → USB声卡 音箱 → 3.5mm音频口安装系统时遇到个小坑:官方镜像默认没启用音频设备。解决方法是在/boot/config.txt中添加:
dtparam=audio=on audio_pwm_mode=23. FastAPI服务搭建实战
3.1 基础环境准备
先创建Python虚拟环境(强烈建议):
python -m venv venv source venv/bin/activate pip install --upgrade pip安装核心依赖:
pip install fastapi uvicorn python-multipart3.2 最小可用API实现
创建main.py作为入口文件:
from fastapi import FastAPI, UploadFile, File from fastapi.responses import StreamingResponse import io app = FastAPI() @app.post("/vision") async def process_image(file: UploadFile = File(...)): image_data = await file.read() # 这里添加图像处理逻辑 return {"message": "Image processed"} @app.get("/tts") async def text_to_speech(text: str): # 这里添加TTS逻辑 audio_stream = io.BytesIO() return StreamingResponse(audio_stream, media_type="audio/wav")启动服务:
uvicorn main:app --host 0.0.0.0 --port 80003.3 性能优化技巧
开发板上资源有限,这几个优化很关键:
- 使用
--workers 1避免内存溢出 - 添加
--limit-concurrency 10限制并发 - 启用HTTP压缩:
from fastapi.middleware.gzip import GZipMiddleware app.add_middleware(GZipMiddleware)
实测优化后QPS从15提升到28,内存占用降低40%。
4. TTS模块实现详解
4.1 方案选型对比
测试了几种TTS方案在开发板上的表现:
| 方案 | 延迟(s) | 内存占用(MB) | 语音质量 |
|---|---|---|---|
| pyttsx3 | 0.3 | 50 | 一般 |
| gTTS | 2.1 | 70 | 较好 |
| Piper (本地) | 1.2 | 120 | 优秀 |
| Edge-TTS | 1.8 | 90 | 优秀 |
最终选择Piper,虽然内存占用高但支持离线使用,且中文发音自然。
4.2 Piper TTS集成实战
安装Piper:
sudo apt install espeak-ng pip install piper-tts下载中文语音模型(约200MB):
wget https://huggingface.co/rhasspy/piper-tts/resolve/main/zh/zh_CN/lessac/medium/zh_CN-lessac-medium.onnx代码实现:
from piper import PiperVoice voice = PiperVoice.load("zh_CN-lessac-medium.onnx") def generate_speech(text): with io.BytesIO() as audio_stream: voice.synthesize(text, audio_stream) audio_stream.seek(0) return audio_stream.read()4.3 音频播放优化
直接使用pygame播放会有延迟,改用更底层的pyaudio:
import pyaudio p = pyaudio.PyAudio() stream = p.open(format=pyaudio.paInt16, channels=1, rate=22050, output=True) def play_audio(audio_data): stream.write(audio_data)实测延迟从1.2s降到0.4s,效果显著。
5. 视觉处理模块设计
5.1 图像采集方案
使用OpenCV捕获摄像头画面:
import cv2 camera = cv2.VideoCapture(0) def capture_frame(): ret, frame = camera.read() if ret: return cv2.imencode('.jpg', frame)[1].tobytes() return None5.2 图像处理流水线
设计了一个轻量处理流程:
- 尺寸缩放(640x480 → 320x240)
- 色彩空间转换(BGR → RGB)
- 归一化(0-255 → 0-1)
- 模型推理
- 结果可视化
关键优化点:
- 使用多线程处理,避免阻塞主循环
- 开启硬件加速(
cv2.UMat) - 合理设置JPEG压缩质量(70是个平衡点)
6. 系统集成与联调
6.1 API端点设计
最终API路由表:
POST /api/vision - 上传图像处理 GET /api/tts - 文本转语音 POST /api/chat - 对话接口 GET /api/status - 系统状态6.2 流式交互实现
为了实现更自然的对话体验,采用了SSE(Server-Sent Events):
from fastapi import Request from fastapi.responses import StreamingResponse @app.get("/stream") async def chat_stream(request: Request): async def event_generator(): while True: if await request.is_disconnected(): break # 获取对话结果 yield f"data: {response}\n\n" return StreamingResponse( event_generator(), media_type="text/event-stream" )6.3 性能压测数据
使用locust进行压力测试(并发10用户):
| 接口 | 平均响应时间(ms) | 错误率 |
|---|---|---|
| /api/vision | 320 | 0% |
| /api/tts | 420 | 0% |
| /api/chat | 580 | 2% |
7. 实际应用中的坑与解决方案
7.1 内存泄漏排查
运行一段时间后出现OOM,通过mprof工具定位到问题:
mprof run python main.py mprof plot发现是Piper的语音模型没有正确释放。修复方案:
class TTSEngine: def __init__(self): self._voice = None @property def voice(self): if self._voice is None: self._voice = PiperVoice.load(MODEL_PATH) return self._voice def cleanup(self): if self._voice: del self._voice self._voice = None7.2 音频卡顿问题
症状:长时间运行后TTS播放出现卡顿 根因:ALSA音频缓冲区积累 解决方案:定期重置音频设备
def reset_audio(): stream.stop_stream() stream.close() p.terminate() # 重新初始化 init_audio()7.3 温度控制
连续运行2小时后开发板温度达到68℃,添加散热措施:
- 粘贴散热片
- 增加小风扇(GPIO控制)
- 实现温度监控:
import psutil def get_cpu_temp(): with open("/sys/class/thermal/thermal_zone0/temp") as f: return int(f.read()) / 1000 if get_cpu_temp() > 60: # 触发降频或告警8. 项目优化方向
经过实际使用,发现几个值得改进的点:
- 语音唤醒:添加关键词唤醒功能,降低持续监听功耗
- 边缘计算:将部分AI推理放到开发板本地执行
- 多模态交互:结合视觉和语音上下文理解意图
- 低功耗优化:深度睡眠模式+事件驱动唤醒
具体到代码层面,下一步准备:
- 用Cython重写性能关键路径
- 实现模型量化(FP32 → INT8)
- 添加WebSocket支持实时视频流
这个项目最让我惊喜的是Longan Pi 3H的潜力——虽然资源有限,但通过合理优化完全可以跑通完整的AI交互流程。特别是在TTS本地化这个环节,Piper的表现超出预期,中文发音几乎听不出机械感。