2026.06.03征图日记28(终于摸到核心了?)
今天上午一直在熟悉webai-lite的代码。一边在改mentor留下的bug,一边在问Ai整个项目的逻辑结构
经过昨天的忙碌之后,我决定每天上午写代码,改bug,下午就开始标注,最多也就200张或者到下午5点,两者满足其一就不标了,剩下的时间可以看看八股或者刷刷算法。这样也不至于忙得工作日志都忘了写~~
骏哥让我把那个推理客户端从git上拉下来,然后说是我的win电脑上没有显卡,要帮我找一台工控机来运行推理客户端。我去兄弟!终于还是让我摸到这一层了吗?接下来我就可以了解到底是如何部署服务的,具体如何推理的,如何训练的,一些细节等等~
我发现写代码的时候时间过得真快,一下子一上午就过去了,感觉也没干什么。干标注的时候就觉得时间很漫长~
下午骏哥让我自己先cmake一下,不懂的问他,我直接一个cmake之后报错,没有Qt环境?安装好对应vs 2019 的Qt环境之后,cmake .. 又报错?没有安装cuda环境?我看了一下工控机上的cuda版本是12.9,我直接跑到英伟达官网安装一手。把CUDAToolkit套件放在指定目录(直接放在E盘根下了,不要学我~)。之后总算cmake过了,之后就是执行 cmake --build . --config Release 把各种环境变量(QT的环境变量、cuda的环境变量)都配置好,之后生成了一个Release目录,下面有一个WebAIClient.exe的文件,点击之后还缺少动态库?执行 windeployqt.exe WebAIClient.exe 添加Qt的动态库之后再次点击有报错?缺少FSAI_Core_ProccessV22.dll?这个东西是在webai2.0-dev下的3rdParty目录下的,现在考虑如何把这个目录下的所有东西都搬过去。或者尝试直接在工控机上运行看能不能行~。OK不行,之前都是问豆包,这次问一下cc看有什么办法吧~
字集(hot100 回溯)
1 | class Solution { |
静姐说晚上杨总在公司会所请大家吃小龙虾,这岂有不去的道理?
我chovy,又说没位置了让我下次,你给我通知好的啊!(没事正好减脂,去吃了小龙虾就没时间做有氧了)
今日工作内容
- 优化webai-lite标注界面体验
- 配置推理客户端环境
- 蓝膜标注83张
下阶段计划
- 梳理推理客户端代码结构
- 将推理客户端在工控机上跑起来
- 继续标注
btw:
完成两个关联特性:
- 多 mask 独立对象架构——从单全局 canvas 改为 MaskObjectManager 管理多个独立 canvas 层,mask 与矢量对象在 model.objects[] 中同级,支持选中高亮(调暗+轮廓)、独立编辑删除、undo 像素恢复。
- 统一缺陷编辑模型——多边形和矩形工具不再创建矢量对象,改为光栅化填充到 mask canvas 层,所有缺陷统一为 mask。旧数据加载时自动光栅化。同步沉淀 editor-architecture.md 和 editor-canvas-guide.md spec。
修复标注界面多个问题:
- 统一缺陷编辑模型——polygon/rectangle 光栅化为 mask,三种工具=三种画笔;
- 选中才能编辑——createNew 替代 classId 分组,擦除未选中无操作;
- 跨图片 mask 残留——切图时 clearAll;
- 保存丢失同 classId mask——prepareMaskData 按 id 匹配;
- 选中交互优化——点击空白取消、mask 模式下 click 切换选中、classId 双向同步防循环;
- 画笔尺寸跨图持久化——状态提升到页面级;
- bbox 选中框替代轮廓追踪。同步更新 editor-architecture.md 和 editor-canvas-guide.md spec。
修复切图时幽灵缺陷的根因:
- useCanvas 第一个 useEffect 在异步图片加载期间闭包捕获了旧的 initialObjects,加载完成后用旧数据 clearAll 清掉了第二个 useEffect 已恢复的正确 mask。
- 修复方案:第一个 useEffect 只负责 canvas 创建和图片加载,所有对象同步完全交给第二个 useEffect(依赖 initialObjects + ready)。
WebAI Lite 项目架构分析总结
日期: 2026-06-03
会话主题: 全面了解 WebAI Lite 项目架构
会话路线图
1. 入口点:converter 包
- 问题: converter 目录下的包是干什么的
- 答案: LSF JSON → 训练掩码(PNG class index)转换器
- 关键点: 只支持旧的 LSF 格式,不支持当前 CVAT 格式
2. 探索临时目录
- 问题: api 目录下的 _tmp* 是干什么的
- 答案: 测试临时目录(COCO 导出测试、Device Manager 输出测试)
3. 工作区结构
- 问题: _workspace 里面的目录是干什么的
- 答案: 用户工作区根目录
current/images/- 用户上传图片current/annotations/- vector 标注 JSONcurrent/masks/- mask PNG(训练用)current/jobs/- 任务队列current/models_parameter/- 模型参数覆盖current/flows_parameter/- 推理流程覆盖
4. 后端包结构
- 问题: webai_lite_api 里面的东西
- 答案: FastAPI 单进程服务
- 入口层: main.py, config.py, errors.py
- 路由层: routes/(health, workspace, annotations, artifacts, catalog, jobs, train, infer)
- 服务层: services/(paths, workspace, job_center, catalog, cvat_coco_export, cvat_mask_decode)
- 设备管理: device_manager/(可选,与 webai2.0 协议对齐)
5. 推理数据流
- 问题: 推理客户端是如何读到图片的
- 答案: 两种模式
- 本机模式: 直接读取文件系统
{workspace_root}/current/images/{stem}.{ext} - device_manager 模式: 打包成 COCO zip 通过 TCP 发送
- 本机模式: 直接读取文件系统
6. 网络访问方式
- 问题: 直接文件系统访问是通过网络读取吗
- 答案: 不是,客户端和服务端在同一台机器,直接读取本地磁盘
7. converter 包的局限性
- 问题: converter 支持画笔和多边形数据吗
- 答案: 不支持,只支持 LSF 格式(百分比坐标)
- 当前 CVAT 格式由 cvat_mask_decode.py 和 cvat_coco_export.py 处理
8. 标注数据处理
- 问题: cvat_coco_export.py 和 cvat_mask_decode.py 的作用
- 答案:
- cvat_mask_decode.py: 解码器,RLE → numpy 数组
- cvat_coco_export.py: 导出器,生成 COCO 格式 zip
- converter: 转换器,生成 masks/*.png(旧方案)
9. COCO 格式
- 问题: COCO 是什么
- 答案: Common Objects in Context,计算机视觉领域标准数据集格式
- 统一格式:检测、分割、关键点都支持
- 工具链丰富:pycocotools、Datumaro
- 评估标准:mAP、IoU 等指标计算
10. 打包流程
- 问题: 标注完成后会打包成 COCO zip 吗
- 答案: 是的,提交训练/推理任务时自动打包
- code.zip: 训练代码包
- config.zip: 配置参数
- sample.zip: COCO 数据集(图片+标注)
- res_dir: 输出目录
11. 任务配置
- 问题: device_manager_enabled 在哪里修改
- 答案: 在 .env 文件或系统环境变量中修改
WEBAI_LITE_DEVICE_MANAGER_ENABLED=trueWEBAI_LITE_DEVICE_SUBMIT_BRIDGE_ENABLED=true
12. 训练流程
- 问题: 提交训练后的流程
- 答案:
- 创建 jobs/*.json(status=submitted)
- 触发 schedule_disk_job_bridge()
- 打包 COCO zip
- 发送给设备或本机执行
13. 通信协议
- 问题: HTTP 和 TCP 如何管理
- 答案: 两种协议并行
- HTTP (8001): 状态查询、控制命令
- TCP (8002): 心跳、大文件传输
14. 自定义 TCP 协议
- 问题: 如何自定义 TCP 协议格式
- 答案:
- 固定长度字段: Command(16B), TaskID(36B), ModelType(32B)
- 变长字段: 先读长度前缀,再读内容
- 大文件: 分块传输(1MB/块)
15. 粘包和队头阻塞
- 问题: 如何解决粘包和队头阻塞
- 答案:
- 粘包: 固定长度 + 长度前缀
- 队头阻塞: 每设备独立连接 + 事件锁
16. 数据块大小
- 问题: 为什么数据块是 1MB
- 答案: 平衡点
- 系统调用: 适中
- 内存占用: 适中
- 事件循环: drain() 频率合理
- 磁盘 I/O: 对齐 4KB 块
核心架构图
1 | ┌─────────────────────────────────────────────────────────────┐ |
数据流总结
标注流程
1 | 用户画笔/多边形 → 前端生成 CVAT 格式 → PUT /api/annotations/{id} |
训练流程
1 | 提交训练 → jobs/*.json (submitted) |
推理流程
1 | 提交推理 → jobs/*.json (submitted) |
关键设计决策
1. 为什么用 CVAT 格式而不是 COCO 格式?
- CVAT 格式适合编辑(支持撤销/重做)
- COCO 格式适合训练(标准化)
- 导出时动态转换
2. 为什么用自定义 TCP 而不是 HTTP?
- 大文件传输效率更高
- 心跳机制更轻量
- 双向通信更灵活
3. 为什么每设备独立连接?
- 避免队头阻塞
- 任务串行化(同一设备)
- 任务并行化(不同设备)
4. 为什么用 1MB 数据块?
- 系统调用次数适中
- 内存占用适中
- asyncio 事件循环友好
- 磁盘 I/O 对齐
待解决问题
- 上传新图片时原图消失:
_clear_workspace_content()会清空所有数据 - macOS ._ 文件*:
shutil.copy2会生成 AppleDouble 文件 - converter 包过时: 只支持 LSF 格式,不支持当前 CVAT 格式