视频帧标签
更新时间:2026-09-14
简介
视频抽帧打标算子:按 all_keyframes 或 uniform 抽帧,逐帧过 RAM++(recognize-anything plus)打标,再按标签出现频次降序合并成一条视频级标签列表。
功能描述
- 抽帧语义:
all_keyframes只解关键帧(I 帧,PyAV 的skip_frame="NONKEY");uniform下frame_num=1取中间帧、=2取首尾帧、>2在时长内均匀取(含首尾) max_frames(默认 64)是显存兜底:抽出的帧超过上限时再按同一均匀规则抽稀,否则长视频关键帧过多会打爆显存- 打标按
batch_size分批,且整列的(行号, 帧)会先展平再统一分批,一个 batch 可以跨行,避免逐视频起停模型 - 帧级标签先在帧内去重(保序),再跨帧计频;因此最终频次等于「出现该标签的帧数」,同一帧内重复出现的标签不重复计数
- 视频级输出按频次降序、已去重(同频次保持首次出现顺序)
- 权重只从本地
<model_path>/<model_name>加载,文件缺失时__init__抛FileNotFoundError,不联网、不做运行时 pip 安装 - 兼容处理:RAM++ 的 BERT 代码从
transformers.modeling_utils导三个已迁走的函数,算子加载前会从transformers.pytorch_utils回填同名别名,不需要为它降级整个环境的 transformers - 解码走 PyAV 而不是 torchcodec:torchcodec 依赖 CUDA NPP 动态库(
libnppicc.so),镜像缺库时整个模块 import 就会失败 - 单行抽帧失败或某个 batch 推理失败只记日志,对应行返回空列表,不影响同批其它行
算子参数
输入
| 输入 | 含义 |
|---|---|
| video | 视频输入数组,内容类型由 video_src_type 决定(本地/BOS 路径 / Base64 字符串 / bytes) |
输出
| 输出 | 含义 |
|---|---|
| frame_tags | list<large_string>,视频级标签,按出现频次降序去重;输入为 null 或该行失败时为空列表 |
参数
| 参数名称 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| video_src_type | str | "video_url" | 输入形式:video_url / video_base64 / video_binary |
| model_path | str | "/opt/aihc/model" | 权重根目录 |
| model_name | str | "ram_plus_swin_large_14m.pth" | 相对 model_path 的 RAM++ 权重文件名 |
| frame_sampling_method | str | "all_keyframes" | 抽帧方式:all_keyframes / uniform |
| frame_num | int | 3 | uniform 模式抽帧数,必须为正 |
| input_size | int | 384 | 模型输入分辨率 |
| max_frames | int | 64 | 单视频抽帧上限,<= 0 表示不限 |
| batch_size | int | 8 | 打标微批大小,<= 1 时按 1 处理 |
| rank | int | 0 | 多卡场景 worker 序号,设备取 cuda:<rank % 可见卡数> |
注意事项
- 标签频次是帧内去重后的计频(等于「出现该标签的帧数」),同频次标签按首次出现顺序排列,因此同频次标签之间的先后不代表置信度差异。
all_keyframes抽出的帧数取决于视频的 GOP 结构,不可控;需要固定帧数就用uniform+frame_num。- backbone 固定为
swin_l(与默认权重匹配),换权重要确认结构一致;input_size需与权重训练分辨率匹配。 ram(recognize-anything)包是运行依赖,算子不会在运行时安装它,缺失时 import 直接失败。- 是否用 GPU 由
aihc_udf的num_gpus推导(基类按num_gpus > 0置use_gpu)。
调用示例
Python
1from __future__ import annotations
2
3import os
4
5import daft
6from daft import col
7
8from daft.aihc.common.udf import aihc_udf
9from daft.aihc.functions.video.video_tagging_from_frames import VideoTaggingFromFrames
10
11os.environ.setdefault("BOS_ENDPOINT", "http://bj.bcebos.com")
12os.environ.setdefault("BOS_REGION", "bj")
13
14if __name__ == "__main__":
15 if os.getenv("DAFT_RUNNER", "native") == "ray":
16 import ray
17 ray.init(dashboard_host="0.0.0.0", ignore_reinit_error=True)
18 daft.set_runner_ray()
19 daft.set_execution_config(actor_udf_ready_timeout=6000, min_cpu_per_task=0)
20
21ds = daft.from_pydict({"video": ["bos://your-bucket/sample.mp4"]})
22 ds = ds.with_column(
23 "frame_tags",
24 aihc_udf(
25 VideoTaggingFromFrames,
26 construct_args={
27 "video_src_type": "video_url",
28 "model_path": "/path/to/models",
29 "model_name": "ram_plus_swin_large_14m.pth",
30 "frame_sampling_method": "uniform",
31 "frame_num": 3,
32 "batch_size": 4,
33 },
34 num_cpus=1,
35 num_gpus=1,
36 concurrency=1,
37 batch_size=1,
38 )(col("video")),
39 )
40 ds.show()
评价此篇文章
