Files
Docs/DevLogs/Day18.md
2025-12-31 16:18:28 +08:00

248 lines
6.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Day 18 - 性能优化与数据流匹配
**日期**: 2025-12-22
**主题**: 服务器性能优化、客户端与服务器数据流匹配、户外网络适配
---
## 今日概述
基于之前的诊断报告,对 AvaotaF1 客户端和 OpenAIglasses_for_Navigation 服务器进行了全面的性能优化,重点解决:
1. 画面卡顿/延迟问题
2. 盲道导航语音延迟
3. 客户端与服务器音频包大小不匹配
4. 户外手机热点网络适配
---
## 一、服务器性能优化
### 1.1 YOLO 推理优化
| 优化项 | 修改内容 | 文件 |
|--------|---------|------|
| **FP16 半精度** | 启用 `half=True` 加速推理 | `workflow_blindpath.py` |
| **动态输入分辨率** | 支持通过环境变量配置 `AIGLASS_YOLO_IMGSZ` | `workflow_blindpath.py` |
| **模型层融合** | 添加 `yolo_seg_model.fuse()` | `app_main.py` |
| **多次 CUDA 预热** | 启动时预热 3 次确保 kernel 编译 | `app_main.py` |
```python
# workflow_blindpath.py - 推理优化
imgsz = int(os.getenv("AIGLASS_YOLO_IMGSZ", "480"))
use_half = os.getenv("AIGLASS_YOLO_HALF", "1") == "1"
results = self.yolo_model.predict(image, imgsz=imgsz, half=use_half, ...)
```
### 1.2 障碍物检测优化
同样为 `obstacle_detector_client.py` 添加了 FP16 和可配置分辨率:
```python
imgsz = int(os.getenv("AIGLASS_OBS_IMGSZ", "480"))
use_half = os.getenv("AIGLASS_OBS_HALF", "1") == "1"
```
### 1.3 线程池增大
```python
# app_main.py
frame_processing_executor = ThreadPoolExecutor(max_workers=3) # 从2增加到3
```
### 1.4 检测间隔调整
| 参数 | 之前 | 之后 |
|------|------|------|
| 盲道检测间隔 | 8 帧 | 10 帧 |
| 障碍物检测间隔 | 15 帧 | 18 帧 |
| 全局播报冷却 | 1.2s | 0.8s |
---
## 二、语音延迟优化
### 2.1 客户端 TTS 预缓冲
```cpp
// main.cpp - 降低预缓冲
const size_t PRE_BUFFER_FRAMES = 8000; // 2秒 → 0.5秒
const size_t MIN_PLAY_FRAMES = 1600; // 0.3秒 → 0.1秒
```
### 2.2 服务器语音冷却
```python
# audio_player.py
_voice_cooldown = 1.5 # 从3秒降低到1.5秒
```
---
## 三、音频包大小统一
### 问题发现
| 端 | 之前 | 问题 |
|----|------|------|
| 客户端 | 30ms (480 samples, 960 bytes) | - |
| 服务器 | 期望 20ms (320 samples, 640 bytes) | ❌ 不匹配 |
### 修复方案
统一使用 **20ms** 音频包(更规范,符合 WebRTC/VoIP 标准):
**客户端修改**
```cpp
// audio_capture.cpp
snd_pcm_uframes_t period_size = 320; // 480 → 320
// main.cpp
int16_t buffer[320]; // 480 → 320
snd_pcm_sframes_t frames_read = mic.read(buffer, 320);
```
**服务器修改**
```python
# app_main.py
CHUNK_MS = 20 # 保持20ms
SILENCE_CHUNK = bytes(BYTES_CHUNK) # 重命名
```
---
## 四、户外网络适配
### 问题背景
室外使用 4G 手机热点带宽波动大1-5 Mbps需要优化相机流配置。
### 配置方案对比
| 模式 | 帧率 | 质量 | 带宽 | 适用场景 |
|------|------|------|------|---------|
| 高性能 | 10fps | Q35 | ~400 KB/s | WiFi/5G |
| **户外稳定** ⭐ | 8fps | Q45 | ~200 KB/s | 4G 热点 |
| 极限省流 | 5fps | Q50 | ~100 KB/s | 弱网络 |
### 最终配置
```cpp
// camera.cpp - 户外稳定模式
#define DEFAULT_FPS 8 // 平衡流畅与带宽
#define DEFAULT_QUALITY 45 // 适度压缩节省带宽
```
---
## 五、.env 配置优化
为 RTX 3090 服务器创建了优化配置:
```bash
# GPU 配置
CUDA_VISIBLE_DEVICES=0
AIGLASS_DEVICE=cuda:0
# YOLO 推理
AIGLASS_YOLO_IMGSZ=640 # RTX 3090 用全分辨率
AIGLASS_YOLO_HALF=1 # 启用 FP16
AIGLASS_BLINDPATH_INTERVAL=6
# 障碍物检测
AIGLASS_OBS_IMGSZ=640
AIGLASS_OBS_INTERVAL=10
AIGLASS_OBS_HALF=1
# GPU 并发
AIGLASS_GPU_SLOTS=3
AIGLASS_AMP=bf16 # RTX 30 系列支持 BF16
```
---
## 六、代码清理
- 删除 `app_main.py` 中重复的 `import torch`L17 和 L29
---
## 七、修改文件汇总
### 客户端 (AvaotaF1)
| 文件 | 修改内容 |
|------|---------|
| `main.cpp` | TTS 预缓冲降低、音频包 320 samples |
| `audio/audio_capture.cpp` | ALSA period_size 320 |
| `camera/camera.cpp` | 户外模式 8fps/Q45 |
### 服务器 (OpenAIglasses_for_Navigation)
| 文件 | 修改内容 |
|------|---------|
| `app_main.py` | CHUNK_MS=20、删除重复import、模型融合预热 |
| `workflow_blindpath.py` | FP16、动态分辨率、间隔调整、冷却降低 |
| `obstacle_detector_client.py` | FP16、动态分辨率 |
| `audio_player.py` | 语音冷却 3s→1.5s |
| `.env` | RTX 3090 优化配置 |
| `.env.performance` | 性能调优模板 |
---
## 八、预期效果
### 在 RTX 3090 上
| 指标 | 优化前 (GTX 1060) | 优化后 (RTX 3090) |
|------|------------------|------------------|
| YOLO 推理 | ~100ms | ~15-25ms |
| 帧处理总时间 | ~150ms | ~40-60ms |
| 导航语音延迟 | ~3-4s | ~1-2s |
| 可支持帧率 | ~7 fps | ~20+ fps |
---
## 九、部署步骤
### 客户端(需重新编译)
```bash
cd AvaotaF1/avaota_app_demo/src
make clean && make
# 部署 avaota_client 到开发板
```
### 服务器端
```bash
cd OpenAIglasses_for_Navigation
source venv/bin/activate
python app_main.py
```
---
## 十、待验证
- [ ] RTX 3090 服务器实际推理速度
- [ ] 户外 4G 热点网络稳定性
- [ ] 盲道导航语音播报是否正常
- [ ] 音频 20ms 包大小对 ASR 识别率的影响
---
## 十一、深夜紧急修复 (Late Night Hotfixes)
### 11.1 传输瓶颈优化
- **问题**:多客户端(浏览器+Recorder连接时WebSocket 串行发送导致服务器卡顿。
- **修复**:在 `app_main.py` 中引入 `asyncio.gather` 实现并行广播,消除阻塞。
### 11.2 运行时崩溃修复
- **问题**`app_main.py` 缺少部分常量 (`MODEL`) 和导入 (`register_stream_route`, `broadcast_pcm16_realtime`)。
- **修复**:补全了缺失的代码,解决启动和运行时的 `NameError`
### 11.3 GPU 配置加载修复
- **问题**:虽然创建了 `.env`,但 `app_main.py` 代码中未调用 `load_dotenv()`,导致配置未生效(模型仍跑在 CPU
- **修复**:添加 `load_dotenv()` 调用,确保 `CUDA_VISIBLE_DEVICES` 生效,彻底解决画面假死问题。