多模态数据标注平台落地实施羽山数智方案

Label Studio / CVAT 双引擎 · 图像/文本/音频/视频/时序全类型 · 规模不限 · 可开发落地

1. 设计目标与规模弹性

        各模态样本量独立配置,架构按"亿级样本可扩展"设计——存储走对象存储横向扩容,算力走多 Worker/多 GPU 伸缩,任务按分片并行,任何量级只改资源不改进程。

规模维度

弹性机制

存储

MinIO 对象存储横向加盘/加节点,视频/音频/图像分桶隔离

算力

GPU Worker 按队列积压自动扩缩(云 GPU 按需)

任务

按帧区间/时间窗/段落分片,分片数随样本量线性增加

人工标注

标注员可多开引擎并发,任务分片分发

单点上限

不设业务上限,PostgreSQL 亿级行 + 分区表兜底

2. 技术栈(落地清单)

选型

版本参考

后端框架

Python 3.12 + FastAPI + SQLAlchemy 2 + Pydantic 2

FastAPI ≥0.110

队列调度

Celery 5 + Redis 7

任务分片与 Worker 伸缩

元数据库

PostgreSQL 16

亿级行分区表

对象存储

MinIO

S3 兼容,引擎直挂

标注引擎A

CVAT(视觉主引擎)

开源版 v2.x,容器化

标注引擎B

Label Studio(全类型)

v1.13+,S3 同步

视频模型

Ultralytics YOLO + BoxMOT(ByteTrack)

YOLOv8/v11

ASR

faster-whisper

small/medium/large 按需

LLM 标注

DeepSeek API / Ollama 本地

文本 NER/分类/关系

编排

Docker Compose 起步 → K8s 演进

Compose v2

3. 总体架构与代码目录

五层架构:接入层 → 核心服务 → 引擎层 → 自动标注管道 → 数据层。目录结构如下(FastAPI 单体 + 多 Worker):

annotation-platform/

├── docker-compose.yml              # 平台编排(PG/MinIO/Redis/API/Workers)

├── docker-compose.engines.yml      # CVAT + Label Studio 引擎编排

├── .env.example                    # 全部连接参数/密钥

├── backend/

│   ├── app/

│   │   ├── main.py                 # FastAPI 入口

│   │   ├── config.py               # pydantic-settings

│   │   ├── api/                    # 路由

│   │   │   ├── datasets.py  items.py  tasks.py

│   │   │   ├── annotations.py  jobs.py  export.py

│   │   ├── models/                 # SQLAlchemy 模型

│   │   ├── schemas/                # Pydantic schema

│   │   ├── adapters/               # 双引擎适配层(核心)

│   │   │   ├── base.py  uaf.py

│   │   │   ├── cvat.py  label_studio.py

│   │   ├── services/               # 业务逻辑

│   │   │   ├── import_service.py  task_service.py

│   │   │   └── prelabel_service.py export_service.py

│   │   └── core/                   # 队列/配置

│   ├── workers/                    # 五条模态管道(独立进程)

│   │   ├── video_pipe.py  image_pipe.py

│   │   ├── text_pipe.py  audio_pipe.py  ts_pipe.py

│   ├── ml/                         # 推理封装

│   │   ├── detector.py  tracker.py  asr.py  llm_client.py

│   └── requirements.txt

├── frontend/                       # 管理控制台(可复用羽山前端栈)

└── deploy/                         # 部署脚本/健康检查

4. 数据库设计(核心 DDL)

六张核心表:dataset / data_item / annotation_task / annotation / auto_job / user。标注结果存 UAF 结构(shape JSONB),按模态解释。

CREATE TABLE dataset (

  id BIGSERIAL PRIMARY KEY,

  name TEXT NOT NULL,

  type TEXT NOT NULL CHECK (type IN ('image','text','audio','video','time_series')),

  engine TEXT NOT NULL DEFAULT 'label_studio' CHECK (engine IN ('cvat','label_studio')),

  label_config TEXT,                -- LS 配置 / CVAT 标签定义

  status TEXT DEFAULT 'active',

  created_at TIMESTAMPTZ DEFAULT now());

 

CREATE TABLE data_item (

  id BIGSERIAL PRIMARY KEY,

  dataset_id BIGINT REFERENCES dataset(id) ON DELETE CASCADE,

  storage_key TEXT NOT NULL,        -- MinIO 对象键

  meta JSONB,                       -- duration/fps/sample_rate/width/height

  status TEXT DEFAULT 'imported',

  created_at TIMESTAMPTZ DEFAULT now());

 

CREATE TABLE annotation_task (

  id BIGSERIAL PRIMARY KEY,

  dataset_id BIGINT REFERENCES dataset(id),

  engine_type TEXT NOT NULL,        -- cvat | label_studio

  engine_task_id TEXT,              -- 引擎侧任务ID

  split JSONB,                      -- 帧区间/时间窗/段落范围

  assignee_id BIGINT,

  status TEXT DEFAULT 'pending',

  created_at TIMESTAMPTZ DEFAULT now());

 

CREATE TABLE annotation (

  id BIGSERIAL PRIMARY KEY,

  item_id BIGINT REFERENCES data_item(id) ON DELETE CASCADE,

  label TEXT NOT NULL,

  shape JSONB,                      -- bbox/polygon/track/span/wave_range

  source TEXT DEFAULT 'human' CHECK (source IN ('auto','human')),

  model_version TEXT,

  confidence REAL,

  reviewed BOOLEAN DEFAULT FALSE,

  created_by BIGINT,

  created_at TIMESTAMPTZ DEFAULT now());

 

CREATE TABLE auto_job (

  id BIGSERIAL PRIMARY KEY,

  dataset_id BIGINT REFERENCES dataset(id),

  pipe_type TEXT NOT NULL,          -- video/image/text/audio/ts

  params JSONB,                     -- fps/batch/模型名

  model_version TEXT,

  status TEXT DEFAULT 'pending',

  stats JSONB,                      -- 处理帧数/耗时/检出数

  created_at TIMESTAMPTZ DEFAULT now());

亿级扩展:data_item 与 annotation 按 dataset_id 分区(PARTITION BY RANGE/HASH),annotation 按 item_id 建索引 + shape 走 GIN 索引支撑按标签检索。

5. API 设计(核心端点)

POST   /api/datasets                      # 创建数据集(指定type+engine)

GET    /api/datasets                      # 数据集列表

POST   /api/datasets/{id}/import          # 批量导入(分片/离线硬盘)

GET    /api/datasets/{id}/stats           # 统计(样本/标注/进度)

POST   /api/datasets/{id}/prelabel        # 触发自动标注作业

POST   /api/datasets/{id}/tasks           # 创建人工标注任务(自动分片)

GET    /api/tasks/{id}/open               # 302跳转引擎标注页

GET    /api/tasks/{id}/sync               # 从引擎拉取最新标注→UAF

POST   /api/annotations                   # 保存/更新标注(UAF)

GET    /api/export?fmt=coco|yolo|ls_json # 按需导出训练格式

POST   /api/jobs/{id}/retry               # 失败作业重试

GET    /api/engines/status                # CVAT/LS 健康检查

6. 双引擎集成方案(落地细节)

引擎

数据接入

预标注回填

标注拉回

CVAT

S3 云存储挂载(直连 MinIO 桶),不复制数据

API 上传 shapes.xml + 帧索引;或用内置 auto-annotation 服务

任务完成回调/轮询 → 下载标注 → 转 UAF

Label Studio

LS S3 同步 + 任务 JSON 导入

Prediction API 导入预标注(带 confidence)

GET 任务标注 → 转 UAF

关键实现要点:① CVAT 用 Cloud Storage 特性挂 MinIO,避免 3.4TB 级拷贝;② LS 预标注走 predictions(可区分 auto/human 且可回滚);③ 平台侧定时轮询引擎任务状态 + Webhook 回调,增量拉取标注写入 annotation 表。

7. 自动标注管道(工程化)

模态

Worker 流程

模型

视频

FFmpeg归一化→抽帧2fps→检测→ByteTrack→传播→UAF回填

YOLOv8m/v11 + BoxMOT

图像

批量检测/分割→UAF

YOLO

音频

切段→ASR→时间戳对齐→事件分类

faster-whisper

文本

批量 LLM 调用(NER/分类)→置信度过滤

DeepSeek API/Ollama

时序

滑窗模式识别/异常检测→区间标注

轻量模型/规则

工程要点:每个管道 = 独立 Celery task,参数化(fps/模型/batch);处理进度与统计写入 auto_job.stats;失败自动重试 + 断点续跑(按 data_item 幂等);低置信度结果标记 review_required,质检优先派发。

8. 任务调度与伸缩

五条模态队列隔离(video/image/text/audio/ts),Worker 按类型消费:GPU 队列(video/image/audio)挂 4090 节点,CPU 队列(text/ts)挂普通节点;云 GPU 按队列积压自动扩缩;文本管道可纯走 LLM API 零本地卡。人工任务分片:视频按帧区间(默认 60s/片)、音频按时段、文本按段落、时序按时间窗。

9. 部署方案

# docker-compose.yml 服务清单

services:

  postgres:   image: postgres:16        # 元数据

  minio:      image: minio/minio        # 对象存储(视频/音频/图像/文本/时序桶)

  redis:      image: redis:7            # 队列

  api:        build: ./backend          # FastAPI

  worker-video: build: ./backend        # GPU: YOLO+ByteTrack

  worker-audio: build: ./backend        # GPU: faster-whisper

  worker-text:  build: ./backend        # CPU: LLM 客户端

  worker-ts:    build: ./backend        # CPU: 时序

  # docker-compose.engines.yml:

  cvat:  cvat/server + cvat/worker      # 视觉引擎

  label-studio: heartsignal/label-studio  # 全类型引擎

部署步骤:① 起引擎编排(CVAT/LS 初始化账号);② 起平台编排;③ 平台侧配置引擎地址/密钥(.env);④ 健康检查全绿后导入数据。生产建议:Compose → K8s,GPU 用 nodeSelector 固定,MinIO 用独立盘 RAID。

10. 开发里程碑(8 周)

里程碑

周期

交付物

M1 骨架

2周

Compose 起 LS+CVAT+MinIO+PG+Redis;数据导入;图像/文本人工标注可用

M2 视频管道

2周

抽帧+YOLO+ByteTrack;预标注回填 CVAT;任务分片

M3 音频+文本管道

2周

faster-whisper ASR 管道;DeepSeek 文本预标注

M4 时序+质检

1周

时序管道;模态质检规则;多格式导出(COCO/YOLO/LS)

M5 闭环+伸缩

1周

难例回流主动学习;多 Worker/多 GPU 伸缩;Webhook 同步

11. 成本弹性公式

存储 = 样本数 × 单样本大小 × 副本数        # 视频3min480p≈34MB/条

视频算力 = 样本数 × 时长s × fps ÷ 300fps       # 4090单卡

音频算力 = 总时长h ÷ (20×并行度)               # faster-whisper small

文本成本 = 篇数 × tokens/篇 × DeepSeek单价     # 通常数元~数十元

GPU按需 = 用多少付多少,队列积压触发扩容

无固定 10 万基线:样本量只是公式输入,架构层不设上限。

羽山数智,致力于成为企业数据智能的实践者。

📌关于羽山数据

面向企业数智化转型需求,羽山数据通过数据产品、智能体应用、场景化 Demo、PoC 验证与 FDE 项目制交付,帮助客户把数据真正转化为可分析、可执行、可审计、可落地的业务能力。在 AI 编程工具应用领域,羽山强调“人机协同”的工程实践:AI 负责加速可标准化部分,人负责架构判断、代码审查和质量把控,确保 AI 提升的是团队真实的交付能力,而不只是代码提交量。

● 商务合作:孟经理

● Email:mengfanhui@yushanshuju.com

● 公司官网:www.usendata.com/

● 地址:上海市虹口区飞虹路 118 号

© 2026 羽山数据 | 转载请注明出处

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值