摘要

2024年3月,我参与了某新能源车企“自动驾驶数据标注平台V3.0”的重构与研发工作,在项目中担任系统架构师,负责总体架构设计、服务拆分、核心组件选型和关键链路治理。该平台面向自动驾驶感知算法训练,主要处理摄像头图像、激光雷达点云、多传感器融合帧、轨迹片段和场景标签等数据,支撑数据导入、任务分发、人工标注、模型预标注、质检审核、数据集发布和训练回流等业务。旧平台采用单体架构,存在模块耦合高、任务调度慢、标注高峰期数据库压力大、模型预标注难以弹性扩展等问题。为此,我主导设计了基于 Spring Cloud 的微服务架构,将系统拆分为数据管理、任务调度、标注作业、质检审核、模型预标注、数据集管理和用户权限等核心服务,并引入 Redis、RocketMQ、分布式锁、对象存储和 Sentinel 等组件。系统上线后,日处理标注任务提升至原来的3倍,任务分发延迟降低到秒级,平台可用性达到99.9%,有效支撑了自动驾驶数据闭环。

正文

一、项目背景与问题分析

随着自动驾驶算法从规则驱动向数据驱动演进,训练数据的规模、质量和迭代效率直接影响感知模型效果。我参与的“自动驾驶数据标注平台V3.0”主要服务于公司L2+和L4测试项目,负责将路测车辆采集的图像、点云和多模态融合数据转化为可用于模型训练的高质量标注数据。平台需要支持2D框、3D框、车道线、可行驶区域、障碍物属性、时序轨迹和场景标签等多种标注类型。

原有系统采用 Java EE 单体架构,所有功能模块部署在一个应用中,数据库也集中在一套 MySQL 实例上。随着车队规模扩大和模型迭代频率提高,旧系统逐渐暴露出三个主要问题。

第一,业务模块耦合严重。数据导入、任务分发、标注作业、质检审核和数据集发布混在同一个工程中,某个标注类型的规则调整可能影响任务调度和审核流程,发布风险高,迭代周期长。

第二,高峰期性能瓶颈明显。大批量Clip数据入库或批量创建标注任务时,数据库连接池经常被打满,任务状态更新延迟明显。标注员集中登录后,任务领取、保存和提交接口响应变慢,影响作业效率。

第三,模型预标注能力难以扩展。平台需要调用目标检测、车道线检测、点云3D检测等模型进行预标注,但模型推理任务计算量大、耗时长,单体架构无法针对预标注任务独立扩容,也无法与人工标注链路解耦。

基于上述问题,我决定采用微服务架构对平台进行重构。设计目标是:一是按业务边界拆分服务,降低耦合;二是通过缓存、消息队列和异步任务提升吞吐量;三是通过弹性扩展支撑模型预标注;四是在任务流转、标注结果和数据集发布等关键环节保证一致性和可追溯性。

二、系统架构设计与模块划分

我基于领域驱动设计思想,将自动驾驶标注平台拆分为七类核心服务,并通过 Spring Cloud Gateway 提供统一入口,通过 Nacos 实现服务注册与配置管理,通过 OpenFeign 进行同步调用,通过 RocketMQ 实现异步解耦。

(1)数据管理服务。负责原始数据接入、Clip切分、传感器元数据解析、数据索引和对象存储地址管理。图像、点云和日志等大文件不直接存入数据库,而是存放在对象存储中,数据库只保存文件URI、时间戳、车辆编号、场景标签和版本信息。

(2)任务调度服务。负责标注任务创建、任务池管理、优先级调度、任务领取和状态流转。任务状态包括待预标注、待领取、标注中、待审核、审核退回、已完成和已发布。

(3)标注作业服务。负责标注员在线作业、结果保存、增量提交和草稿恢复。为了减少网络传输压力,前端只提交标注增量变更,服务端合并生成完整标注结果。

(4)质检审核服务。负责抽检、全检、复核和问题回退。系统支持按标注员、数据批次、场景类型和模型版本进行质量统计,形成可追溯的审核链路。

(5)模型预标注服务。负责调用2D检测、3D检测和车道线模型生成初始标注结果。该服务计算资源消耗高,因此独立部署在GPU节点上,并通过消息队列接收任务。

(6)数据集管理服务。负责训练集、验证集和测试集构建,支持按车辆、区域、时间、天气、场景类型和审核状态筛选数据,并生成数据集版本。

(7)用户权限服务。负责用户、角色、团队、项目权限和操作审计。平台采用 JWT 进行身份认证,并通过角色权限控制标注员、审核员、项目管理员和算法工程师的操作范围。

三、核心业务流程与关键技术实施

1. 数据导入:对象存储与异步解析

数据导入是平台的入口,也是旧系统最容易阻塞的环节。自动驾驶原始数据体积大,单个Clip可能包含多路摄像头图像、点云、定位和车身状态文件。如果同步解析全部文件后再返回,接口会长时间占用线程,影响系统稳定性。

我的解决方案是将数据导入拆分为“元数据入库”和“异步解析”两步。数据管理服务收到导入请求后,先校验文件清单和批次信息,将原始文件写入对象存储,并在 MySQL 中记录批次、车辆、时间、传感器类型和文件URI。随后向 RocketMQ 发送数据解析消息,由后台解析服务异步抽取关键帧、生成缩略图、建立索引并更新数据状态。

为了防止重复导入,我在数据批次维度设计了幂等键,使用车辆编号、采集时间、Clip编号和文件哈希生成唯一标识。导入前先查询幂等表,若该批次已存在则直接返回,避免重复数据污染训练集。

2. 任务调度:Redis队列与分布式锁

任务调度是标注平台的核心。旧系统中,标注员领取任务时直接查询数据库并更新状态,高并发下容易出现同一任务被多人领取的问题。

为解决该问题,我设计了基于 Redis 的任务池。任务调度服务按项目、标注类型和优先级将任务写入不同队列,标注员领取任务时先从 Redis 队列弹出任务ID,再回写 MySQL 状态。对于关键状态变更,我使用 Redisson 分布式锁,以任务ID作为锁Key,确保同一任务在同一时刻只能被一个用户领取或提交。

同时,我设计了任务超时回收机制。若标注员领取任务后长时间未提交,系统会根据心跳和最后保存时间判断是否释放任务。释放前保存草稿,避免标注结果丢失。通过该机制,任务分发延迟从分钟级降低到秒级,重复领取问题基本消除。

3. 模型预标注:MQ异步解耦与GPU弹性扩展

模型预标注可以显著提升人工标注效率,但它属于计算密集型任务。如果同步调用模型服务,会拖慢任务创建链路,甚至影响普通标注功能。

我的设计是将预标注服务与主业务链路解耦。任务调度服务创建任务后,将“待预标注”消息发送到 RocketMQ。模型预标注服务作为消费者,从队列中获取任务,调用GPU推理服务生成初始标注结果,再写入标注结果库,并将任务状态改为“待领取”。

在资源层面,模型预标注服务独立部署在 Kubernetes GPU节点上,根据消息堆积量进行扩容。当任务量大时增加推理实例,低峰期缩容释放GPU资源。对于推理失败的任务,系统记录失败原因并进入重试队列;连续失败后标记为人工标注,避免任务长期阻塞。

4. 标注结果保存:版本控制与最终一致性

标注结果是训练数据的核心资产,必须保证可追溯、可回滚和可审核。旧系统只保存最终结果,无法定位每次修改来源,也无法分析审核退回原因。

我在标注作业服务中引入版本化设计。每次提交结果时,系统生成新的结果版本,记录操作人、时间、变更内容、任务状态和审核意见。草稿保存使用 Redis 缓存提高响应速度,正式提交后再落库到 MySQL,并将大字段结果写入对象存储。

考虑到标注结果保存、任务状态更新和审核消息通知涉及多个服务,我没有采用强一致分布式事务,而是采用本地事务加消息最终一致性。标注服务先在本地事务中保存结果和状态,再发送“任务已提交”消息。质检服务消费消息后创建审核任务。消费端通过任务ID和结果版本号做幂等检查,避免重复消费导致状态错乱。

5. 服务治理:熔断限流与监控告警

平台上线初期,模型预标注服务在大批量任务进入时曾出现响应变慢,导致任务调度服务线程堆积。为避免局部故障扩散,我引入 Sentinel 对核心接口进行限流、熔断和降级。

对于数据导入、任务领取、结果提交和模型预标注等接口,我分别设置QPS阈值、慢调用比例和异常比例。当模型服务超时或异常比例升高时,任务调度服务不再同步等待,而是将任务转为“待人工标注”或进入延迟重试队列。这样可以保证标注员核心作业链路不被模型服务拖垮。

同时,我建设了可观测体系,监控任务积压量、任务领取耗时、结果保存耗时、审核通过率、模型预标注成功率、Redis命中率、MQ堆积量和数据库慢SQL。出现异常时,系统通过告警通知值班人员及时处理。

四、实施效果与总结

该自动驾驶标注平台于2024年10月正式上线,支撑了图像、点云和多模态融合数据的规模化标注。系统上线后,平台日处理标注任务量提升至原来的3倍,任务领取和分发延迟由分钟级降低到秒级,模型预标注任务可根据MQ堆积量弹性扩展,平台整体可用性达到99.9%。

通过微服务架构改造,系统取得了三方面效果。第一,业务解耦明显。数据管理、任务调度、标注作业、质检审核和模型预标注可以独立开发、测试和发布,降低了变更风险。第二,性能和扩展性提升。高频任务领取走 Redis 队列,重计算预标注走 RocketMQ 异步链路,GPU服务可独立扩容。第三,数据质量更可控。标注结果版本化、审核链路可追溯、消费端幂等和质量统计机制,保证了训练数据的可靠性。

本项目实践表明,微服务架构适合用于自动驾驶标注平台这类业务流程复杂、吞吐压力明显、模块边界清晰的系统。但微服务不是简单拆分服务,而是要结合业务边界、数据一致性、异步解耦、服务治理和可观测体系进行整体设计。未来,我计划进一步引入工作流引擎和主动学习机制,使模型能够根据低置信度样本自动触发标注任务,进一步提升自动驾驶数据闭环效率。

更多推荐