1
This commit is contained in:
+39
-14
@@ -62,34 +62,59 @@ GPU delegate 默认允许 FP16 计算(YOLO 类精度损失可忽略);如
|
||||
|
||||
## 模型热更新(多数据集模型)
|
||||
|
||||
模型与 APK 更新走**独立通道**:启动时拉取 `GET /api/v1/app/update` 随附的
|
||||
`models` 目录(公开接口,无需登录),与 `UpdateChecker` 的 APK 检查并行。
|
||||
模型与 APK 更新走**独立通道**:进入视野页时后台同步 `GET /api/v1/app/update`
|
||||
随附的 `models` 目录(公开接口,无需登录;不阻塞相机预览启动),与
|
||||
`UpdateChecker` 的 APK 检查并行。
|
||||
|
||||
- **目录条目**:`{datasetId, datasetName, variant, version, labels[], sizeBytes, sha256,
|
||||
downloadUrl, coverUrl}`——**双档位(2026-09-03)**:每数据集至多 2 条 = 高识别 s
|
||||
downloadUrl, coverUrl}`——**双档位(2026-09-03)**:每数据集至多 2 条 = 高精度 s
|
||||
(@1280 精度优先,默认)+ 高性能 n(@704 速度优先)各自的当前版本,条目带 `variant`
|
||||
(s/n);服务器未发布模型时不返回 `models` 字段,App 无模型可用,
|
||||
相机页仅预览不识别。
|
||||
- **下载入口**:相机页设置弹层「模型清单」按需下载/使用(封面缩略图 2 列网格,
|
||||
每数据集两档各占一格并带档位角标;未下载点击「使用」显示进度,完成自动激活;
|
||||
已激活再次点击取消;下载中可取消)。**档位切换**:弹层顶部「识别模式」分段控件
|
||||
(s 高识别 / n 高性能,默认 s)持久化本地,切换即热加载新档位已激活模型。
|
||||
**同一物种合并一张卡**,卡上双档行标注各自版本与状态(使用中绿色高亮);点
|
||||
「下载」一次性补下该动物高精度+高性能两个已训练文件——各档独立进度逐条展示、
|
||||
可取消(已下过的档不重复下),**目标档落地即自动启用、伴档备好**;目标档已
|
||||
启用显示「使用中」点击取消使用。弹层高度上限 70% 屏高(防盖满全屏无法关闭)。
|
||||
**档位(2026-09-03 修订)**:同一物种一次只运行一个档位——激活某档会自动停用
|
||||
同物种另一档,**不同物种可用不同档位并行识别**(如雉鸡用高性能、斑鸠用高精度)。
|
||||
弹层顶部「识别模式」分段控件(高性能 / 高精度,默认高精度,持久化本地;
|
||||
2026-09-03 高性能移到左位)是**目标档偏好**:不直接切换运行中的模型,
|
||||
只决定卡片按钮面向哪个档。卡片主按钮(2026-09-03 简化:不再出现「改用X」、
|
||||
不再显示当前运行档提示):目标档未下载 →「下载」(落地自动启用、伴档备好;
|
||||
同一动物另一档在使用时补下目标档后自动切换过去);已下载未启用 →「使用」
|
||||
点击即用(另一档在使用会被自动停用);启用中 →「使用中」点击取消使用。
|
||||
- **存储**:应用私有目录 `models/<datasetId>/<variant>/`(双档位 2026-09-03,
|
||||
原无 variant 目录与存量 s 档一致——s 档复用 `models/<datasetId>/` 同级读取,
|
||||
目录键 = 档位标识符),含 `model.tflite`、`labels.json`、`meta.json`
|
||||
(meta 记录 `{version, sha256}`)。版本与摘要都未变化时跳过下载;变化则下载到
|
||||
`.part` 临时文件、sha256 校验通过后原子 rename 替换,失败重试一次并保留旧模型,
|
||||
下次启动再试——检查记账按 `(datasetId, variant)` 独立。
|
||||
- **目录缓存(2026-09-03)**:最近一次成功拉取的模型目录落盘应用私有目录
|
||||
`catalog.json`;每次刷新先载入缓存、展示立即可用(弹层离线/弱网也有内容),
|
||||
网络成功后再以权威目录覆盖缓存。清理与自动更新只在网络拉取成功时执行:
|
||||
离线降级不清文件、不触发下载——升级后断网首启不会误删已下载模型。
|
||||
- **清理**:服务器下线的数据集下次同步时删除本地对应目录(两档都无条目时才删)。
|
||||
- **并行推理合并**:识别时加载**当前识别档位**下全部已激活模型(`DetectorWorker`
|
||||
isolate 内逐模型加载,单个失败不影响其他),同帧各模型独立推理后按类别分组做
|
||||
**跨模型 NMS**(同类别不同模型检出同一目标取高分去重,不同类别互不压制),
|
||||
结果叠加 `modelName`(数据集名+档位)标注来源。
|
||||
- **识别会话制(2026-09-03 修订)**:每次进入视野页即开始新识别会话——从
|
||||
**仅预览**开始、**不自动恢复上次使用的模型**(上次崩溃/坏模型不会在下一次打开时
|
||||
自动复现,用户总能进入模型清单调整;这也是打开即慢的根因消除项:进入页面不再
|
||||
读模型/重建推理器)。识别需在模型清单**手动启用**,启用状态只在本会话内生效
|
||||
(不跨会话持久化);已下载文件常驻本地,「使用」即点即用不重新下载。
|
||||
服务器新版本仅对**已下载文件**后台自动补齐,补齐不改变启用状态。
|
||||
- **并行推理合并**:识别时加载**本会话已启用**的全部模型(激活集即实际运行集,
|
||||
会话内每数据集至多一个档位;`DetectorWorker` isolate 内逐模型加载,单个失败
|
||||
不影响其他;worker 构建完成后原地挂到已启动的相机流,不重启相机),
|
||||
同帧各模型独立推理后做**跨模型 NMS**(所有模型的框统一按 IoU 去重取高分——
|
||||
异类别重叠也压制,实测多个模型会对同一目标检出不同类别),结果叠加 `modelName`
|
||||
(数据集名)标注来源。
|
||||
|
||||
实现:`lib/models/model_manager.dart`(下载/校验/持久化,`ModelManager`
|
||||
单例 + ChangeNotifier,条目身份含档位)、`lib/detection/detector_worker.dart`
|
||||
(多模型并行推理与 `mergeAcrossModels`)、`lib/camera/camera_screen.dart`
|
||||
(启动同步 + 设置弹层「识别模式」切换 + 诊断行展示模型列表)。
|
||||
实现:`lib/models/model_manager.dart`(下载/校验/清单/会话制单档激活收敛,
|
||||
`ModelManager` 单例 + ChangeNotifier,条目身份含档位)、
|
||||
`lib/detection/detector_worker.dart`(多模型并行推理与 `mergeAcrossModels`)、
|
||||
`lib/camera/camera_screen.dart`(会话重置从仅预览开始 + 先出预览后台同步 +
|
||||
设置弹层「识别模式」目标档切换 + 底部状态胶囊:识别延迟)、
|
||||
`lib/camera/model_catalog_section.dart`(清单网格:按数据集合并卡片、
|
||||
双档下载与「使用/使用中/下载」主按钮动作,2026-09-03 简化文案)。
|
||||
|
||||
- **模型输入是 NHWC**:训练导出的模型需做字节级手术(开头 TRANSPOSE→RESHAPE,
|
||||
输入 [1,320,320,3])再发布给 App,否则 iOS 报
|
||||
|
||||
Reference in New Issue
Block a user