- 人工智能
- 大模型
- 数据工程
- 数据清洗
- 数据增强
- 数据质检
【免费下载链接】data-juicer
Data processing for and with foundation models! 🍎 🍋 🌽 ➡️ ➡️🍸 🍹 🍷
Data-Juicer 提供了丰富的多模态数据处理算子(mapper),其中video_captioning_from_audio_mapper专门负责依据视频中的音频流、基于 Qwen-Audio 模型为视频自动生成描述性字幕(caption),适用于语音密集型视频(如人物讲话、课堂、会议、访谈类素材)的标注与数据增强。读完本文你将掌握该算子的内部处理链路、参数配置方法、输入数据格式要求、单元测试场景以及接入 Data-Juicer 配置文件的完整方式。
算子概览:类型、标签与定位
根据 video_captioning_from_audio_mapper.md 中的定义,该算子的元信息如下:
- 算子类型(Type):
mapper,即对样本做"一对多"改写映射——保留(或替换)原始样本,并追加一条带字幕的新样本。 - 标签(Tags):
gpu, hf, multimodal,表明它依赖 GPU 推理、使用 Hugging Face 模型仓库(hf)中的预训练权重,并且处理的是包含视频与音频的多模态数据。 - 功能定位:根据视频的音频流生成字幕。底层模型为阿里的Qwen-Audio多模态大模型,用于对音频内容进行理解与转述。
在源码 video_captioning_from_audio_mapper.py 中,算子通过@OPERATORS.register_module(NAME)注册到全局算子注册表(对应 registry.py 中的Registry.register_module),类名为VideoCaptioningFromAudioMapper,并声明了_accelerator = "cuda"与_batched_op = True两个类属性,表示它运行在 CUDA 设备上、且以批量(batched)方式处理样本,因而在批次内部还能做额外的并行优化。
内部工作原理与处理链路
从源码结构可以还原出该算子完整的数据流,主要分为五个阶段:
1. 模型与提示词初始化
构造函数__init__中完成三件关键事:
- 默认显存申请:
kwargs["memory"] = "30GB" if kwargs.get("memory", 0) == 0 else kwargs["memory"],即不显式传memory参数时默认按 30GB 显存规格向执行器申请资源。 - 依赖检查:通过
LazyLoader.check_packages校验transformers、transformers-stream-generator、einops、accelerate、tiktoken等包是否安装。 - 模型准备:调用 model_utils.py 中的
prepare_model(model_type="huggingface", pretrained_model_name_or_path="Qwen/Qwen-Audio", trust_remote_code=True)生成模型加载器,推理时再由get_model按设备(cuda:{rank})懒加载并缓存到全局MODEL_ZOO。
同时算子内置了一套用于引导 Qwen-Audio 输出的转录提示词:
<|startoftranscription|><|unknown|><|caption|><|unknown|><|notimestamps|><|wo_itn|>这段提示词要求模型输出纯字幕文本(caption)、不附带时间戳(notimestamps)、不做逆文本正则化(wo_itn),并用正则re.compile(r"<\|.*?\|>")在推理后剥离响应中残留的<|...|>标记。
2. 按 chunk 切分样本文本
样本的text字段以特殊 token<|dj_eoc|>(即SpecialTokens.eoc)分隔多个对话/内容块(chunk)。_process_single_sample按SpecialTokens.eoc切分文本,对每个非空 chunk 统计其中<video>特殊 token(SpecialTokens.video)的出现次数,从而得知该 chunk 内嵌了几段视频。
3. 提取音频并推理
对 chunk 内每个视频文件,调用 mm_utils.py 中的extract_audio_from_video(video, video + ".mp3", stream_indexes=[0]):
- 只提取第 0 号音频流(
stream_indexes=[0]),当前版本仅处理第一条音轨; - 输出为与视频同名的
.mp3文件(形如video_0.mp3),extract_audio_from_video目前只支持导出 mp3 格式; - 若视频没有有效音频流(返回的
valid_indexes为空),该视频被跳过,不生成字幕。
随后构造查询串<audio>{提取出的mp3路径}</audio>{提示词},经processor.process_audio(query)解析音频信息后,processor(query, return_tensors="pt", audio_info=audio_info)完成特征编码,在torch.no_grad()下调用model.generate(**inputs, audio_info=audio_info, use_cache=False)生成字幕(代码注释特别说明:较新的 transformers 需要use_cache=False,否则会报错),最后processor.decode还原文本。
4. 响应清理与失败兜底
生成的响应会依次做三类后处理:
- 移除响应中出现的音频路径占位符与
<audio>/</audio>标签; - 用正则删除所有
<|...|>内部标记; - 若清理后响应为空(生成失败),跳过该视频并删除临时 mp3。
成功后字幕被组织为<video> 字幕文本的形式追加到captioned_text_list,同时记录该视频到left_video_keys,并立即os.remove(extracted_audio_path)清理临时音频文件,避免磁盘占用。
5. 组装输出样本
所有 chunk 处理完后,字幕文本按<|dj_eoc|>重新拼接成captioned_sample[self.text_key],videos字段替换为实际生成成功的视频列表left_video_keys(生成失败、无音轨的视频会从新样本中移除),返回包含新样本的列表。
参数配置详解
原文档参数表给出的三个参数及其在源码中的真实语义如下:
| 参数名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
keep_original_sample | bool | True | 是否保留原始样本。为False时,最终数据集只保留带字幕的新样本,原始样本被移除;默认True,原始样本与字幕样本并存 |
args | - | '' | 透传给Mapper基类的额外位置参数 |
kwargs | - | '' | 透传给Mapper基类的额外关键字参数 |
keep_original_sample的实际行为体现在process_batched中:为True时原始样本先被加入结果列表,再追加生成的样本;为False时只保留生成样本。默认True意味着一条视频样本最终产出两条样本(原样本 + 字幕样本),这一点被单元测试反复验证(见下文)。
另外需要注意两点易被忽略的隐性参数行为:
memory:构造时若用户未指定memory,会被自动置为"30GB",用于向调度器声明该算子的显存需求;- 模型参数:
kwargs也会被保存为self.extra_args,可携带如use_cuda之类的运行时控制项。
在 config_all.yaml 中,该算子被登记为:
- video_captioning_from_audio_mapper: # caption a video according to its audio streams based on Qwen-Audio model即无需任何必填参数即可加入处理流程;需要调整行为时,典型写法为:
process: - video_captioning_from_audio_mapper: keep_original_sample: false输入数据格式要求
该算子对数据集 schema 有明确约定,遵循 Data-Juicer 多模态数据的特殊 token 规范(定义见 mm_utils.py 中的SpecialTokens类,可通过环境变量覆盖默认格式,默认video为<dj_video>、eoc为<|dj_eoc|>):
text字段:文本中通过SpecialTokens.video(默认<dj_video>)标记视频出现位置,多个内容块用SpecialTokens.eoc(默认<|dj_eoc|>)分隔;videos字段:与文本中<dj_video>标记一一对应的视频文件路径列表;- 缺失处理:若样本中不存在
videos字段或字段为空,_process_single_sample直接返回空列表,该样本不被改写。
例如一条合法的输入样本为:
{ "text": "<dj_video> 白色的小羊站在一旁讲话。旁边还有两只灰色猫咪。<|dj_eoc|>", "videos": ["/path/to/video1.mp4"] }处理后得到的两条样本中,新增样本的text会变为<dj_video> {Qwen-Audio生成的字幕}<|dj_eoc|>,且videos只保留音频提取成功的视频。
运行前提与依赖
该算子属于重型 GPU 算子,接入前需满足:
- 硬件:CUDA GPU(
_accelerator = "cuda"),默认按 30GB 显存申请资源; - 模型:首次运行会自动从 Hugging Face 下载
Qwen/Qwen-Audio权重(trust_remote_code=True),需保持网络可达; - Python 依赖:
transformers、transformers-stream-generator、einops、accelerate、tiktoken,以及音频提取所依赖的 PyAV(av,由extract_audio_from_video使用); - 音频格式:
extract_audio_from_video当前仅支持导出 mp3 音频文件。
此外,get_model在 Worker 进程中会通过setup_worker_threads(num_threads=1)限制线程数,防止num_proc > 1多进程并行时线程过度订阅;模型会按rank % cuda_device_count()分配到对应 GPU。
单元测试覆盖的行为契约
test_video_captioning_from_audio_mapper.py 用三个真实 mp4 样例(tests/ops/data下的video1.mp4、video2.mp4、video3.mp4)覆盖了五个核心场景,可作为该算子的行为契约:
- test_default_params:默认参数下,3 条样本处理后数据集变为 6 条(原样本 + 字幕样本),且每条样本中
<dj_video>数量与生成字幕数量相等; - test_with_eoc:文本以
<|dj_eoc|>结尾时行为与默认一致; - test_no_original_samples:
keep_original_sample=False时,3 条样本最终仍为 3 条,只保留字幕样本; - test_multi_chunk_samples:单个样本含多个 chunk、多个视频时,逐 chunk 处理仍保证视频数与字幕数一致;
- test_parallel:
num_proc=2多进程并行处理时结果与单进程一致。
测试还通过辅助方法_count_generated_caption_num校验"文本中每个<dj_video>标记都对应一条非空字幕"这一不变量,这直接对应源码中"生成失败即跳过并移除视频"的兜底逻辑。
与相关视频字幕算子的区分
Data-Juicer 的视频字幕家族(见 config_all.yaml)包括多个算子,选用时需按数据特点区分:
- video_captioning_from_audio_mapper(本文主角):只看音频流,适合人声/语音信息主导的视频;
- video_captioning_from_frames_mapper:基于抽帧做图像到文本生成,字幕来自多个帧的描述拼接;
- video_captioning_from_video_mapper:直接对视频整体生成字幕;
- video_captioning_from_summarizer_mapper:汇总视频/音频/帧等多种来源的字幕与标签后生成总结性字幕,可通过
vid_cap_from_vid_args、vid_cap_from_frm_args等参数组合底层算子; - video_captioning_from_human_tracks_mapper:需在
video_human_tracks_extraction_mapper之后使用,聚焦视频中单人像的字幕生成。
音频驱动方案的核心优势在于:对画面信息弱、但语音信息丰富的素材(讲话、旁白、访谈)而言,音频是比抽帧更直接、更完整的信息源。
使用注意事项
- 视频必须包含音轨,否则
valid_indexes为空、视频被静默跳过——对无声视频素材该算子不产生任何增益; - 临时 mp3 文件生成后即被删除,但若进程异常中断可能残留中间文件,建议保证目标目录可写;
- 生成字幕的质量依赖 Qwen-Audio 的识别能力,对多说话人、噪声、非普通话语音场景效果可能波动,建议配合下游质量过滤算子(如文本长度、语言分数过滤)使用;
- 默认
keep_original_sample=True会成倍扩大数据集,若仅需字幕样本用于替换式标注,应显式设置keep_original_sample: false。
总而言之,video_captioning_from_audio_mapper是一个"开箱即用"的音频→字幕映射算子:理解其基于SpecialTokens的样本格式、keep_original_sample的样本产出语义、以及音频提取与失败兜底的内部链路后,即可在 Data-Juicer 的process流程中通过一行 YAML 配置直接启用,为语音类视频数据高效生成高质量字幕标注。
- 人工智能
- 大模型
- 数据工程
- 数据清洗
- 数据增强
- 数据质检
【免费下载链接】data-juicer
Data processing for and with foundation models! 🍎 🍋 🌽 ➡️ ➡️🍸 🍹 🍷
相关推荐
Data-Juicer `video_audio_ASR_mapper` 算子全解析:基于 SenseVoiceSmall 的视频语音自动识别实战
Data Juicer video_audio_ASR_mapper 算子全解析:基于 SenseVoiceSmall 的视频语音自动识别实战 导读 video
人工智能大模型数据工程数据清洗数据增强数据质检Data-Juicer 的 video_motion_score_raft_filter:基于 RAFT 光流的视频运动得分过滤算子实战指南
Data Juicer 的 video_motion_score_raft_filter:基于 RAFT 光流的视频运动得分过滤算子实战指南 本文围绕 Data
人工智能大模型数据工程数据清洗数据增强数据质检data-juicer 视频字幕聚合生成算子 video_captioning_from_summarizer_mapper 深度解析
data juicer 视频字幕聚合生成算子 video_captioning_from_summarizer_mapper 深度解析 本文以 data jui
人工智能大模型数据工程数据清洗数据增强数据质检
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考