03让 20 个人同时干,还得画得一样

编辑器做好了,一个人能顺利画出框。交给 20 个人,会冒出两个完全不同的失败: 大家互相打架,和大家各标各的。这一页讲这两层。

分片,不是合并 Ontology 规范的工程化

一、先冒出来的问题是打架

不是效率。甲和乙同时打开同一帧,各画了一半,谁的结果算数?

用过 Google Docs 的人很自然会想:能不能也做成多人同时编辑、实时同步?

不能,而且不是没做,是不该做
Google Docs 模型:一张文档,N 个人同时改  → 靠 OT / CRDT 合并冲突
标注平台模型:  N 个互不相交的工单,各改各的 → 冲突从设计上不存在

它把同步问题绕过去了,而不是解决了。这一点比任何同步算法都重要。

OT / CRDT 两种让多人实时编辑同一份文档的技术。 OT 是操作变换,CRDT 是无冲突复制数据类型。共同前提是那段内容不可分割, 所以只能靠算法去合并冲突。

二、为什么天然的分片单位是「一帧」

关键在于:文档可以切碎,一帧标注不可以。

文档一帧标注
最小单元段落、字符,可分割帧,标注对象之间强耦合
完整性局部属性,写到哪算哪帧级属性,"标全了没有"无法局部判定
两人同时改有意义,各写一段没有意义,而且有害

第二行是核心。设想甲标了左边 3 个物体、乙标了右边 4 个:

那么【没有任何人】能判断这一帧是不是标全了。

因为"漏没漏"是全帧性质:
  不能被两个人各自局部保证
  也不能靠"我负责的部分没问题"来推导

所以一帧必须独占。这不是性能取舍,是真值可用性的前提。

三、那后端到底在同步什么

拆开看,需要同步的只有四类,没有一类是协同编辑。

同步对象频率真正的技术需求
工单状态机分钟到小时级原子性,不是实时性
本体与类别极低,管理员改版本化,改了历史数据要不要迁移
进度与看板秒级,晚点无所谓无,派生数据
审核快照提交时一次不可变,提交即冻结

唯一需要原子性的地方,是领取任务的那一刻:

UPDATE task SET owner = :me, lease_until = now() + interval '2 hour'
 WHERE id = :fid AND owner IS NULL;
-- 影响行数 = 0 → 领取失败,刷新看板
是租约,不是锁

领取必须带期限。现实中一定会有人领了任务然后人跑了、电脑关了、离职了, 任务必须能自动回收。这是运营问题,不是技术炫技。

四、「一帧只有一个写者」买到了什么

把这条约束提炼一下就是 single writer。它的收益非常具体:每一帧有一条线性的版本链。

frame #1234
  v1   甲     标注        sourceId = -1
  v2   审核员  打回
  v3   甲     修正
  v4   审核员  通过        ← 当前有效

线性,所以"当前真值是哪个"这个问题永远有唯一答案。

反过来,如果允许并发写,版本历史就变成一张有向无环图,"哪个是真相" 从一个查询变成了一个合并或仲裁问题。你得引入 OT,还得先定义冲突时谁赢。

可追溯的来源

前面那张对比表里,标注平台的一行是持久化、可追溯。

可追溯这件事,本质上就是 single writer 的直接产物。

五、一个例外:冗余标注是 fork,不是共享写

有一种情况确实会让人并行处理同一帧:为了质检,平台把同一帧分给 2 到 3 个人各标一遍, 然后比对差异。这叫冗余标注。

        基线快照 v1(只读)
        ├── 甲 独立标 → a1
        ├── 乙 独立标 → a2
        └── 丙 独立标 → a3
                       ↓ 比对、仲裁
                       v2(融合结论)

它看起来像并发编辑,其实完全不是。三个人读的是同一份只读基线, 写的是三个互不相干的副本。编辑阶段完全没有冲突。

所以实时协同会摧毁这个质检手段

冗余标注的价值建立在两人互不知情之上。差异越大,越说明这里有问题。

而实时协同会让两人互相看见对方的框,不再是独立标注,差异就测不出来, 正好落进后面要讲的锚定偏差陷阱。

对标注来说,实时协同不是少做了一个功能,而是做了一个有害的功能。 独立性比协同性值钱。

什么时候才真需要 OT / CRDT

场景单元可分割吗需要实时协同吗
Google Docs❌ 一篇文档✅ 需要 OT / CRDT
Figma❌ 一块画布✅ 需要,几何合并更难
代码🟡 文件可分割🟡 用 Git,异步合并,不是实时
标注平台✅ 帧、层、类别都可分❌ 用不上,工单分片即可
判据

OT 和 CRDT 解决的是"不可分割的共享可变状态"。而标注数据天然可分割。 可分割,就不需要合并算法。

独占粒度可以调。细到层或类别级别,甲的 2D 框和乙的 3D 框能同时改, 并行度更高。但代价是"标全了没有"这个帧级属性被切碎了,得另找人为它负责。

六、所以并行真正的难点在哪

不在同步,在切分与负载均衡。

难点做法
负载不均,有人分到全是难帧拉模式动态领取,而不是推模式
专挑简单的做计件加难度权重,或者固定批次下发
领了不做,做一半跑了租约到期自动回收
有帧压根没人标状态机加完整性校验,提交时要求必填项齐

七、第二种失败:大家标得不一样

工作流解决了打架。接下来的失败不是没人标,而是大家标得不一样。

这一层被称作标注质量的头号杀手。这个说法值得展开,因为不展开会觉得夸张。

为什么类别定义不一致这么致命

把三类错误放一起对比就看明白了:

错误类型看得见吗后果
框画歪了✅ 看得见审核能抓
漏标一个物体🟡 难,但可对比有机制,冗余标注或抽样
卡车的定义不一致❌ 完全看不见模型学到两种定义的混合,在边界上必然出错

第三行是关键。两个人对"什么算卡车"的理解不同,各自都觉得自己标得完全正确。 没有报错,没有告警,画面上看起来都正常。分歧是静默的。

这不是抽象的担忧,它天天在发生:

"卡车"包不包括皮卡?
  带挂车的牵引车,算一个还是算两个?
  停在路边卸货的货车,是卡车还是静止物?
  被树挡住一半的卡车,遮挡多少才标?

"行人"包不包括骑车的人、坐轮椅的人、交警?
  远处只有 2 px 高的人,标不标的阈值定在哪?

每一行都是真实存在的争议。20 个标注员乘上每行一种理解,就是 20 种定义混进同一批数据。

更麻烦的是它不可事后修复:

标完 5 万帧 → 才发现"卡车"的定义有问题
  → 这 5 万帧全部可疑
  → 而且挑不出哪些有问题(错误是定义级的,不是画错的)
  → 只能重标

八、Ontology 是什么

先澄清一个容易困惑的点:Ontology 既是通用概念,也是一个模块名。

Ontology(本体)   通用概念,来自哲学和知识表示,比任何平台都早几十年
Ontology Center    某个平台给"实现这个概念的那个模块"起的名字

通用定义是(Gruber, 1993):对某个领域里概念及其相互关系的显式、形式化描述。

它不是一张词表
概念 + 层级 + 关系 + 约束

一个平铺的类别列表不是 ontology,那只是个标签集合。差别就在后面三项。

它在平台里具体长什么样

以 Xtreme1 为例,配置入口在数据集下面的 Ontology,内容分两大类。

① Class:区域级标注

一个 Class = 一个类别 + 绑定的标注工具
                   (2D 框、多边形、折线、3D 框……)

这是它比类别表强的地方:类别和工具绑死。

车         →  3D 框工具
车道线     →  折线工具
可行驶区域 →  多边形工具

选错工具的可能性从设计上就是零

② Classification:数据级标注

官方举的例子是"城市、住宅区、园区"这样的三级层级。它的语义和 Class 完全不同:

回答的问题作用范围
Class图里有哪些东西框、多边形、折线,区域级
Classification这段数据是什么场景整张图、整帧点云,数据级

Classification 其实就是数据治理的技术化。后面讲的长尾挖掘、按场景切分、配比策略, 在这里就是靠它落地的。

九、它的本质:把规范从人的责任变成系统的责任

这一条最值得带走
没有 Ontology:规范写在 PDF 里 → 靠人记住 → 靠培训 → 靠审核事后抓
有 Ontology:  规范写进数据库 → 系统不给选 → 从源头消除

传统做法是写一份标注规范、培训标注员、靠审核员抓。 Ontology 把它变成了系统强制的约束:类别只能从下拉选,属性只能是枚举值, 必填项不填就提交不了。

这是把"规范"这个概念工程化了,从文档约定升级到系统强制。

更准确的说法:让不规范无法被表达

事后检查:结果不规范 → 检测出来 → 打回重标   已经错了
事前约束:输入时就没有"不规范"这个选项        错不了
最好的类比是类型系统
单元测试、审核员   ≈  运行时检查   跑起来才发现
Ontology           ≈  类型系统     编译期就拦掉

类型系统不"检测"类型错误,它让类型错误根本编译不过。Ontology 对标注是同一件事。 所以"保持规范"这个说法可以换成"不允许偏离"。

但它有硬边界:管得住形式,管不住判断

管得住,语法层管不住,语义层
类别只能从列表里选这一帧里到底有几个卡车
属性只能是枚举值被挡住一半的卡车该不该标
类别和工具绑死这个框画得准不准
必填项不填提交不了标出来的东西是不是真值

右边这一列只能靠别的手段解决:规范文档、培训、冗余标注、审核抽样。 所以 Ontology 消除了一整类静默错误,但没消除全部。

十、这一页带走什么

两层的失败不一样,解法也不一样。

并行的问题是"打架",解法是分片:让人人独占一帧,冲突从设计上就不存在。 它买到的是线性的版本链,也就是可追溯。

一致性的问题是"各标各的",解法是把规范写进系统:让不规范的输入根本表达不出来。 它买到的是从源头消除一整类静默错误,代价是它只管得住形式。

← 上一页:为什么画一个框会很难 ·  下一页:让人别从零画 →
京ICP备19013239号