DJ-SORA 数据工程路线图解析:基于 Data-Juicer 的大规模高质量视频数据流水线
DJ-SORA 数据工程路线图解析:基于 Data-Juicer 的大规模高质量视频数据流水线
本文档系统梳理 Data-Juicer 项目中 DJ-SORA 数据工程路线图:如何依托 Data-Juicer 上百个多模态算子与工具,构建面向 SORA 类文本生成视频(text-to-video)大模型的大规模高质量多模态数据集。读者将掌握视频数据的并行加载与调度方案、时空维度基础算子、跨模态匹配与生成进阶算子、代表性数据集格式转换工具,以及"数据菜谱—数据集—模型训练"的协同开发闭环。
动机:SORA 式视频生成模型的数据挑战
DJ-SORA 项目成立的直接背景是:SORA 等前沿大模型的官方披露中仅简略提及使用 DALLE-3 生成高质量 caption,且模型输入数据具备变化的时长、分辨率和宽高比。要复现并超越这类能力,高质量、大规模、细粒度的多模态数据是决定性要素之一。
从文本生成视频模型的实际痛点出发,DJ-SORA 路线图明确了数据侧需要密集化的方向(DJ-SORA_ZH):
- 画面流畅性和一致性:部分生成的视频存在丢帧及静止状态,需要在数据中增强帧间连续性与运动信息;
- 文本理解能力与细粒度:生成结果与 prompt 匹配度较低,需要更强、更细粒度的图文(video-text)语义对齐数据;
- 视频时长过短:生成内容大多只有约 10 秒且场景画面不会发生大的改变,需要更长、更多样化的时序数据;
- 物理真实性问题:生成内容存在变形扭曲和物理规则违背,尤其在实体做出动作时,需要补充高动态、多场景、物理真实的数据。
DJ-SORA 的应对思路是:以 Data-Juicer 中上百个专用的视频、图像、音频、文本多模态处理算子(完整算子清单见 Operators.md)为基础,沉淀出一系列系统化、可复用的多模态数据菜谱(recipe),用于分析、清洗及生成大规模高质量多模态数据,最终形成开源社区可复用的数据集生态。
视频数据的高性能加载与处理底座
大规模视频处理的首要瓶颈是 I/O 与算力调度。DJ-SORA 路线图在该层面已经完成的工作包括:
| 能力 | 状态 | 说明 |
|---|---|---|
| lazy load with pyAV and ffmpeg | ✅ | 按需加载视频元信息与帧,避免全量解码 |
| 多模态数据路径签名 | ✅ | 对视频等资源文件进行路径签名,支撑缓存与指纹复用 |
| 单机多核并行 | ✅ | 算子级并行处理 |
| GPU 调用 | ✅ | 支持 CUDA 加速算子(如 OCR、美学评分) |
| Ray 多机分布式 | ✅ | 通过 Ray 横向扩展处理规模 |
| 基于阿里云 PAI-DLC 和 Slurm 的多机分布式 | ✅ | 适配云上与自建集群 |
| 分布式调度优化(OP-aware、自动化负载均衡) | ✅ | 已落地于 Aliyun PAI-DLC |
| 视频算子低精度加速支持 | ⏳ WIP(git tags: dj_op, dj_efficiency) |
|
| 现有视频算子的 SOTA 模型增强 | ⏳ WIP(git tags: dj_op, dj_sota_models) |
从源码实现看,这种"高性能"是落在算子基座层的:例如视频解码统一走 load_video(pyAV 容器级读取),统计计算与过滤分离为 compute_stats_single / process_single 两阶段(见 video_resolution_filter.py),并且大量视频算子通过 LOADED_VIDEOS、INTER_SAMPLED_FRAMES 等注册机制参与算子融合(op fusion),使得同一视频在一次加载后被多个算子共享,避免重复解码。
实操层面,仓库提供了基于 Ray 的视频处理示例配置 demo.yaml,核心骨架如下:
project_name: 'ray-demo'
executor_type: 'ray'
dataset_path: './demos/process_video_on_ray/data/demo-dataset.jsonl'
ray_address: 'auto' # 改为你的 Ray 集群地址,如 ray://<hostname>:<port>
export_path: './outputs/demo/demo-processed-ray-videos'
process:
- video_duration_filter:
min_duration: 20
max_duration: 100
- video_resolution_filter:
min_width: 200
max_width: 4096
min_height: 200
max_height: 4096
any_or_all: any
- video_split_by_duration_mapper:
split_duration: 10
min_last_split_duration: 0
keep_original_sample: true
- video_resize_aspect_ratio_mapper:
min_ratio: 1
max_ratio: 1.1
strategy: increase
- video_split_by_key_frame_mapper:
keep_original_sample: true
- ray_video_deduplicator:
redis_host: 'your_redis_host'
redis_port: your_redis_port
其中 ray_video_deduplicator 是可在多节点上运行的 MD5 精确匹配去重器,其 Redis 端口配置需注意与 Ray 默认端口(6379)错开。新版配置还支持 dataset.configs 的结构化写法,见 demo-new-config.yaml。
基础算子:视频时空维度的质量过滤与多样性增强
这一组算子聚焦视频的空间(分辨率/宽高比/画面内容)与时间(时长/运动/场景)维度,是清洗视频语料的"第一道工序"。
面向数据质量的 Filter 算子
| 算子 | 维度 | 作用 | 仓库源码 |
|---|---|---|---|
video_resolution_filter |
分辨率 | 过滤分辨率不在指定范围的视频 | video_resolution_filter.py |
video_aspect_ratio_filter |
宽高比 | 过滤宽高比(w/h)不在指定范围的视频 | video_aspect_ratio_filter.py |
video_duration_filter |
时间 | 过滤时长不在指定范围的视频 | video_duration_filter.py |
video_motion_score_filter |
连续性 | 计算光流,去除静态与极端动态视频 | video_motion_score_filter.py |
video_ocr_area_ratio_filter |
画面内容 | 移除文本区域占比过大的样本 | video_ocr_area_ratio_filter.py |
以 video_resolution_filter 为例,其参数与默认值为:min_width=1、max_width=sys.maxsize、min_height=1、max_height=sys.maxsize、any_or_all='any'。实现上通过 pyAV 读取视频首个视频流的 codec_context.width/height 得到统计量 video_width/video_height 并缓存;any_or_all 决定一个样本含多个视频时是"任一满足即保留"(any)还是"全部满足才保留"(all),非法取值会直接抛出 ValueError(见 video_resolution_filter.py)。
video_motion_score_filter 则使用 OpenCV 的 Farneback 稠密光流算法(cv2.calcOpticalFlowFarneback),以光流幅度的均值作为运动得分,其关键参数包括:
min_score=0.25/max_score:保留得分的上下界,默认用于去除静态视频;sampling_fps=2:光流计算的抽帧采样率;relative=False:设为True时将光流幅度按帧对角线长度归一化到 [0,1];size/max_size/divisible:计算前的帧缩放控制;if_output_optical_flow=False/optical_flow_key='video_optical_flow':可把光流结果(形状(num_frame, H, W, 2))输出到 meta 字段,供后续算子使用;any_or_all='any':多视频保留策略。
该算子被注册为 UNFORKABLE(见 video_motion_score_filter.py),提示其在分布式场景下不宜被 fork 复制(OpenCV 视频捕获句柄不可跨进程共享)。其测试用例见 test_video_motion_score_filter.py。
video_ocr_area_ratio_filter 使用 EasyOCR 检测文本,frame_sample_num=3 控制抽帧数量(1 取中间帧、2 取首尾帧、大于 2 时首尾之外均匀采样),languages_to_detect 默认 <a href="https://link.gitcode.com/i/901cec955e7f1d48cc1e87d3a75b154f" target="_blank">'ch_sim', 'en'],min_area_ratio=0 / max_area_ratio=1.0 界定文本占比范围(见 [video_ocr_area_ratio_filter.py)。它支持 CUDA 加速(_accelerator = "cuda"),检测结果同时覆盖水平矩形框与自由四边形区域,两者面积相加后除以整帧面积得到 OCR 占比。这对视频中出现大面积字幕、贴片文字的样本尤其有效。
面向数据多样性与数量的 Mapper 算子
| 算子 | 维度 | 作用 |
|---|---|---|
video_resize_resolution_mapper |
分辨率 | 将视频映射到指定分辨率范围 |
video_resize_aspect_ratio_mapper |
宽高比 | 将视频宽高比调整到指定范围 |
video_split_by_key_frame_mapper |
关键帧 | 基于关键帧切割视频 |
video_split_by_duration_mapper |
时间 | 按时长切割视频 |
video_split_by_scene_mapper |
场景 | 基于场景连续性切割视频 |
其中 video_split_by_scene_mapper 基于 PySceneDetect 实现,支持三种检测器:ContentDetector(默认)、ThresholdDetector、AdaptiveDetector,关键参数为 threshold=27.0、min_scene_len=15、show_progress=False,以及 save_dir(输出目录,可用环境变量 DJ_PRODUCED_DATA_DIR 指定)、save_field(新字段名,缺省覆盖原视频字段)、ffmpeg_extra_args(默认 -movflags frag_keyframe+empty_moov,便于流式播放)、output_format(path 或 bytes,见 video_split_by_scene_mapper.py)。
值得注意的细节:切割完成后,算子会用 re.sub 将样本文本中的视频特殊 token(<__dj__video>)按场景数量展开替换,从而让"文本 token 数 ↔ 视频片段数"保持一一对应(见 video_split_by_scene_mapper.py)。若某视频未检出任何场景(场景数 ≤1),则保持原视频不变。这类 Mapper 是"数据稠密化"的关键手段:一段长视频可被拆分为多个场景片段,每个片段配以独立的 caption,显著提升训练样本的密度与多样性。
进阶算子:细粒度模态间匹配与生成
基础算子解决"单模态质量",进阶算子则面向跨模态对齐与生成,这正是 SORA 类模型学好"文本 → spacetime token"条件映射所需的数据形态。
面向数据质量
video_frames_text_similarity_filter:在时空一致性维度过滤,计算关键/指定帧图像与文本的匹配分数,剔除"画面与 caption 对不上"的样本,从源头提升图文对齐质量。
面向数据多样性及数量
这一组 Mapper 通过不同粒度的模型组合,为视频生成多层次、多来源的文本描述:
| 算子 | 模型粒度 | 生成内容 |
|---|---|---|
video_tagging_from_frames_mapper |
轻量图生文模型 | 对密集帧生成空间概要标签 |
video_captioning_from_frames_mapper |
更重的图生文模型 | 用少量帧生成更详细的空间信息描述 |
video_tagging_from_audio_mapper |
音频分类/类别 | 引入 audio classification/category 等 meta 信息 |
video_captioning_from_audio_mapper |
音频生文 | 引入人声/对话、AudioCaption 环境与场景等全局信息 |
video_captioning_from_video_mapper |
视频生文模型 | 基于连续帧生成时序信息描述 |
video_captioning_from_summarizer_mapper |
纯文本大模型 | 对上述各类 caption 信息去噪、摘要,组合成最终 caption |
这套"标签(tag)→ 空间描述 → 时序描述 → 摘要融合"的分层生成链路,构成了一个可复用的视频 caption 数据菜谱,能系统性解决"生成结果与 prompt 匹配度低"的问题。上述算子均已集成在 config_all.yaml 的默认配置中(如 video_captioning_from_audio_mapper 基于 Qwen-Audio、video_captioning_from_frames_mapper 基于图生文模型、video_captioning_from_summarizer_mapper 负责多源文本摘要)。
交叉模态交织(WIP)
video_interleaved_mapper(开发中):在 ICL(上下文学习)、时间与跨模态维度增强,支持interleaved_modes:text_image_interleaved:按时序交叉放置同一视频的 caption 与 frames;text_audio_interleaved:按时序交叉放置同一视频的 ASR 文本与 frames;text_image_audio_interleaved:交替拼接上述两种交织模式。
这种交织格式与 Data-Juicer 的多模态中间格式一脉相承——即按文本块组织、以特殊 token 定位各模态资源(详见下文"数据集格式转换"一节),为视频理解/生成模型提供 ICL 友好的长序列样本。
进阶算子:视频内容质量、合规与隐私
已完成
-
video_deduplicator:比较 MD5 哈希值,在文件样本级别去重(文档级精确匹配);多节点版本为ray_video_deduplicator; -
video_aesthetic_filter:拆帧后进行美学度打分过滤,剔除构图与画质低下的片段; -
ffmpeg 命令兼容封装:
audio_ffmpeg_wrapped_mapper:包装 FFmpeg 音频滤镜;video_ffmpeg_wrapped_mapper:包装 FFmpeg 视频滤镜。
这两类算子让 Data-Juicer 直接复用成熟的 FFmpeg 滤镜生态,例如缩放、旋转、裁剪、降噪、加字幕等,无需另行实现原生算子。
视频内容合规与隐私保护(WIP,多数子项已完成)
- ✅ 马赛克(mosaic)
- ✅ 版权水印移除
- ✅ 人脸模糊(
video_face_blur_mapper已实现,见 config_all.yaml) - ✅ 黄暴恐内容过滤(
video_nsfw_filter已实现)
Beyond Interpolation:增强数据真实性与稠密性(TODO)
面向物理真实性问题,路线图规划了"超越插值"的增强方向:碰撞、光影、重力、3D、场景切换(phase transition)、景深等物理现象。具体形态包括:
- Filter 类算子:校验 caption 是否真实描述画面,给出描述的相关性得分/正确性得分;
- Mapper 类算子:增强视频数据中对物理现象的文本描述。
这是从"数据工程"走向"数据生成"的探索方向,旨在让模型从数据中习得物理规则,缓解实体动作时的变形扭曲。
DJ-SORA 数据菜谱与数据集
代表性数据的统一加载与转换
不同开源视频数据集格式差异极大。Data-Juicer 提出了一种基于文本的、交替式的中间多模态格式:一个多模态样本由若干文本块(chunk)组成,块与块之间以特殊 token <|__dj__eoc|> 分隔;文本块内以 <__dj__video>、<__dj__image> 等特殊 token 定位对应模态资源,资源文件路径按 token 出现顺序排列在一级字段列表中(格式说明与示例见 README_ZH.md)。
围绕该格式,tools/fmt_conversion/multimodal 提供了双向转换工具:
| 数据集 | 规模/形态 | 源格式→DJ | DJ→源格式 |
|---|---|---|---|
| Video-ChatGPT | 100K video-instruction 数据 {<question, answer, youtube_id>} |
video_chatgpt_to_dj.py |
dj_to_video_chatgpt.py |
| Youku-mPLUG-CN | 36TB video-caption 数据 {<caption, video_id>} |
youku_to_dj.py |
dj_to_youku.py |
| InternVid | 234M 数据样本 {<caption, youtube_id, start/end_time>} |
internvid_to_dj.py |
dj_to_internvid.py |
| MSR-VTT | 10K video-caption 数据 {<caption, video_id>} |
msrvtt_to_dj.py |
dj_to_msrvtt.py |
| ModelScope 数据集集成 | 平台级数据接入 | — | — |
| VideoInstruct-100K、Panda70M 等 | 持续扩充 | — | — |
以 InternVid 为例(见 internvid_to_dj.py),源格式字段为 YoutubeID、Start_timestamp、End_timestamp、Caption(以及 Aesthetic_Score、UMT_Score 等辅助评分);转换时(cut_videos=True)会按起止时间戳调用 cut_video_by_seconds 剪辑出对应片段,并生成 DJ 格式样本:
{
"videos": ["videos/qJrOyggIB-w-cut.mp4"],
"text": "<__dj__video> a screen shot of heroes of the storm with people in action <|__dj__eoc|>",
"Start_timestamp": "00:07:33.689",
"End_timestamp": "00:07:51.085",
"Aesthetic_Score": 4.29296875,
"UMT_Score": 0.4501953125
}
所有转换脚本均可用 python ... --help 查看完整参数。工具链还包含 absolute_path_to_relative_path.py,用于将处理后的绝对路径转为相对路径并把多源数据拷贝到统一目录,方便数据迁移与后续训练部署。
大规模高质量 DJ-SORA 数据集
- ✅ Data sandbox:基于 DJ-video 算子构建和优化多模态数据菜谱,算子与菜谱同期持续完善;
- ✅ 数据源持续扩充:open-datasets、youku、web 等;
- ⏳ 基于 DJ 菜谱规模化分析、清洗、生成高质量多模态数据集(WIP:多场景、高动态)。
DJ-SORA 数据验证与模型训练
数据质量最终要在模型训练与评测中得到验证,DJ-SORA 将"数据—模型"协同开发作为闭环:
- ✅ 探索并完善多模态数据和模型的协同开发,形成 benchmark 与 insights(对应论文见 DJ-SORA 文档中的 arXiv 链接);
- ⏳ 类 SORA 模型训练 pipeline 集成(WIP),已接入:
- EasyAnimate(AIGC 视频生成方案);
- T2V(文本生成视频方案);
- V-Bench(视频生成评测基准);
- ✅ (Model-Data sandbox) 在相对较小的模型和 DJ-SORA 数据集上,探索低开销、可迁移、有指导性的 data-model co-design 配置及检查点;
- ⏳ 更大规模、更多场景使用 DJ-SORA 数据训练类 SORA 模型(WIP):
- ✅ 已产出 Data-Juicer-T2V 模型及其 v2 版本,在 V-Bench 评测中取得 Top1 成绩(见 DJ-SORA_ZH)。
这一"小模型快速验证 → 数据菜谱迭代 → 大规模训练放大"的路径,正是 DJ-SORA 区别于一次性造数据的核心方法论:数据菜谱与模型训练共享同一套算子与中间格式,使数据生产过程的每个环节都可被验证、可被回溯。
总结
DJ-SORA 路线图呈现了一条完整的视频数据工程链路:高性能加载与调度底座 → 时空维度基础清洗 → 跨模态匹配与生成增强 → 内容合规与物理真实增强 → 统一格式的数据集转换与菜谱沉淀 → 模型训练验证闭环。其技术要点可以概括为:
- 底座先行:pyAV/ffmpeg 惰性加载、算子融合、单机多核 + GPU + Ray/PAI-DLC/Slurm 的分布式调度,解决大规模视频数据的高吞吐处理问题;
- 分层算子体系:Filter 保证质量下限(分辨率、宽高比、时长、运动、OCR、图文相似度),Mapper 负责多样性扩展(缩放、切割、跨模态 caption/tag 生成);
- 统一中间格式:基于文本块与特殊 token 的交替式多模态格式,使 Video-ChatGPT、InternVid、MSR-VTT、Youku-mPLUG 等数据集可双向无损转换;
- 数据-模型协同:通过 Model-Data sandbox 与 Data-Juicer-T2V 等实践,让数据菜谱的每一次调整都能在模型评测中得到反馈,最终沉淀为社区可复用的高质量多模态数据集与配套菜谱。
对于希望构建或优化自有视频数据的团队,可以直接复用仓库中的算子配置(config_all.yaml)、Ray 处理示例(demo.yaml)与格式转换工具(tools/fmt_conversion/multimodal),在 Data-Juicer 框架内快速搭建自己的"视频数据菜谱"。