Datasets 文档

创建视频数据集

Hugging Face's logo
加入 Hugging Face 社区

并获得增强的文档体验

开始使用

创建视频数据集

本指南将向您展示如何使用 VideoFolder 和一些元数据来创建视频数据集。这是一个无需编写代码的解决方案,可快速创建包含数千个视频的视频数据集。

您可以通过要求用户先共享他们的联系信息来控制对数据集的访问。有关如何在 Hub 上启用此功能的更多信息,请参阅受保护的数据集指南。

VideoFolder

VideoFolder 是一种数据集构建器,旨在快速加载包含数千个视频的视频数据集,而无需您编写任何代码。

💡 请参阅 Split pattern hierarchy(切分模式层级),以进一步了解 VideoFolder 如何根据您的数据集仓库结构创建数据集切分(splits)。

VideoFolder 会根据目录名称自动推断数据集的类别标签。请将您的数据集存储在如下目录结构中:

folder/train/dog/golden_retriever.mp4
folder/train/dog/german_shepherd.mp4
folder/train/dog/chihuahua.mp4

folder/train/cat/maine_coon.mp4
folder/train/cat/bengal.mp4
folder/train/cat/birman.mp4

如果数据集符合 VideoFolder 结构,则可以直接使用 load_dataset() 进行加载

>>> from datasets import load_dataset

>>> dataset = load_dataset("path/to/folder")

这相当于在 load_dataset() 中手动传递 videofolder 并在 data_dir 中指定目录

>>> dataset = load_dataset("videofolder", data_dir="/path/to/folder")

您还可以使用 videofolder 来加载涉及多个切分的数据集。为此,您的数据集目录应具有以下结构:

folder/train/dog/golden_retriever.mp4
folder/train/cat/maine_coon.mp4
folder/test/dog/german_shepherd.mp4
folder/test/cat/bengal.mp4

如果所有视频文件都包含在单个目录中,或者它们不在相同的目录结构层级上,则不会自动添加 label 列。如果您需要该列,请显式设置 drop_labels=False

如果您想包含有关数据集的额外信息,例如文本标题或边界框,请将其添加为文件夹中的 metadata.csv 文件。这使您可以快速创建用于不同计算机视觉任务(如文本字幕或目标检测)的数据集。您也可以使用 JSONL 文件 metadata.jsonl 或 Parquet 文件 metadata.parquet

folder/train/metadata.csv
folder/train/0001.mp4
folder/train/0002.mp4
folder/train/0003.mp4

您的 metadata.csv 文件必须包含一个 file_name*_file_name 字段,用于将视频文件与其元数据相关联

file_name,additional_feature
0001.mp4,This is a first value of a text feature you added to your videos
0002.mp4,This is a second value of a text feature you added to your videos
0003.mp4,This is a third value of a text feature you added to your videos

或使用 metadata.jsonl

{"file_name": "0001.mp4", "additional_feature": "This is a first value of a text feature you added to your videos"}
{"file_name": "0002.mp4", "additional_feature": "This is a second value of a text feature you added to your videos"}
{"file_name": "0003.mp4", "additional_feature": "This is a third value of a text feature you added to your videos"}

此处 file_name 必须是与元数据文件相邻的视频文件名。更广泛地说,它必须是从包含元数据的目录到视频文件的相对路径。

您可以在数据集的每一行中指向多个视频,例如当您的输入和输出都是视频时

{"input_file_name": "0001.mp4", "output_file_name": "0001_output.mp4"}
{"input_file_name": "0002.mp4", "output_file_name": "0002_output.mp4"}
{"input_file_name": "0003.mp4", "output_file_name": "0003_output.mp4"}

您还可以定义视频列表。在这种情况下,您需要将该字段命名为 file_names*_file_names。示例如下:

{"videos_file_names": ["0001_left.mp4", "0001_right.mp4"], "label": "moving_up"}
{"videos_file_names": ["0002_left.mp4", "0002_right.mp4"], "label": "moving_down"}
{"videos_file_names": ["0003_left.mp4", "0003_right.mp4"], "label": "moving_right"}

视频字幕 (Video captioning)

视频字幕数据集包含描述视频的文本。一个 metadata.csv 的示例可能如下所示:

file_name,text
0001.mp4,This is a golden retriever playing with a ball
0002.mp4,A german shepherd
0003.mp4,One chihuahua

使用 VideoFolder 加载数据集,它将为视频字幕创建 text

>>> dataset = load_dataset("videofolder", data_dir="/path/to/folder", split="train")
>>> dataset[0]["text"]
"This is a golden retriever playing with a ball"

将数据集上传到 Hub

创建数据集后,您可以使用 huggingface_hub 等工具将其共享。请确保已安装 huggingface_hub 库并已登录您的 Hugging Face 账户(详见 使用 Python 上传教程)。

使用 huggingface_hub.HfApi.upload_folder 上传您的数据集

from huggingface_hub import HfApi
api = HfApi()

api.upload_folder(
    folder_path="/path/to/local/dataset",
    repo_id="username/my-cool-dataset",
    repo_type="dataset",
)

WebDataset

WebDataset 格式基于 TAR 归档文件,适用于大型视频数据集。事实上,您可以将视频分组在 TAR 归档中(例如,每个 TAR 归档包含 1GB 视频),并拥有数千个 TAR 归档

folder/train/00000.tar
folder/train/00001.tar
folder/train/00002.tar
...

在归档文件中,每个示例由共享相同前缀的文件组成

e39871fd9fd74f55.mp4
e39871fd9fd74f55.json
f18b91585c4d3f3e.mp4
f18b91585c4d3f3e.json
ede6e66b2fb59aab.mp4
ede6e66b2fb59aab.json
ed600d57fcee4f94.mp4
ed600d57fcee4f94.json
...

您可以使用 JSON 或文本文件来存储视频的标签/字幕/特征。

有关 WebDataset 格式和 Python 库的更多详情,请查阅 WebDataset 文档

加载您的 WebDataset,它将根据文件后缀创建相应的列(此处为 “mp4” 和 “json”)

>>> from datasets import load_dataset

>>> dataset = load_dataset("webdataset", data_dir="/path/to/folder", split="train")
>>> dataset[0]["json"]
{"bbox": [[302.0, 109.0, 73.0, 52.0]], "categories": [0]}

Lance

Lance 是一种开放的多模态湖仓表格式。Lance 表不仅可以原生存储文本和标量值,还可以将图像、音频和视频等大型二进制对象 (blobs) 与您的表格数据一起存储。

Lance 提供了一个 blob API,方便在 Lance 数据集中存储和检索大型 blob。以下示例展示了如何在不加载较重的视频 blob 的情况下高效浏览元数据,然后按需获取相关的视频 blob。

这是一个存储视频的 Lance 表的代表性视图(video_blob 列使用了 Lance 的 blob 编码)

+------------------------------------------+-----------------+-----+------------------------------------------+
| caption                                  | aesthetic_score | ... | video_blob                               |
+------------------------------------------+-----------------+-----+------------------------------------------+
| "a breathtaking view of a mounta..."     | 5.2401          | ... | {position: 0, size: 4873879}             |
| "a captivating view of the sun, b..."    | 5.2401          | ... | {position: 4873920, size: 3370571}       |
+------------------------------------------+-----------------+-----+------------------------------------------+

从原始视频文件写入 Lance 数据集

从磁盘上的原始视频文件及其相关元数据(例如,字幕和分数)开始,您可以将一个自包含的 Lance 数据集写入本地 *.lance 目录(Lance 数据集是磁盘上的一个目录,通常以 .lance 后缀命名)

import lance
import pyarrow as pa

import urllib.request

schema = pa.schema(
    [
        pa.field("caption", pa.utf8()),
        pa.field("aesthetic_score", pa.float64()),
        pa.field(
            "video_blob",
            pa.large_binary(),
            metadata={"lance-encoding:blob": "true"},
        ),
    ]
)

# Provide video files alongside metadata
rows = [
    {
        "video_path": "/path/to/videos/0001.mp4",
        "caption": "a breathtaking view of a mountainous landscape ...",
        "aesthetic_score": 5.240138053894043,
    },
    {
        "video_path": "0002.mp4",
        "caption": "a captivating view of the sun, bathed in hues ...",
        "aesthetic_score": 5.240137100219727,
    },
]

video_bytes = []
for r in rows:
    with open(r["video_path"], "rb") as f:
        video_bytes.append(f.read())

table = pa.table(
    {
        "caption": [r["caption"] for r in rows],
        "aesthetic_score": [r["aesthetic_score"] for r in rows],
        "video_blob": video_bytes,
    },
    schema=schema,
)

ds = lance.write_dataset(
    table,
    "./videos.lance",
    schema=schema,
    mode="create",
)

这将您的元数据和视频字节共同存储在 videos.lance/ 中,因此您可以移动/复制单个目录,而无需保持独立的 *.mp4 文件同步。

这是一个存储视频的 Lance 表的代表性视图(video_blob 列包含在 Lance 数据集中以 blob 形式原生存储的数据)

+------------------------------------------+-----------------+-----+------------------------------------------+
| caption                                  | aesthetic_score | ... | video_blob                               |
+------------------------------------------+-----------------+-----+------------------------------------------+
| "a breathtaking view of a mounta..."     | 5.2401          | ... | {position: 0, size: 4873879}             |
| "a captivating view of the sun, b..."    | 5.2401          | ... | {position: 4873920, size: 3370571}       |
+------------------------------------------+-----------------+-----+------------------------------------------+

您可以将生成的 videos.lance/ 目录上传到 Hub(例如使用 huggingface_hub.HfApi.upload_folder),并将其作为数据集仓库共享,将元数据和视频作为单个工件(artifact)保存在一起。

由于数据在磁盘上以列式格式存储,Lance 数据集可以扩展到非常大的规模(太字节 TB 及以上)。有关在 Lance 中存储和检索大型 blob 的最佳实践最新信息,请参阅 blob API 指南。

在写入大型数据集时,通常最好将每个单独的 *.lance 文件的大小限制在最多几个 GB。只需通过迭代器收集数据,并在写入数据集时指定 max_bytes_per_file 参数即可

MAX_BYTES_PER_FILE = 5 * 1024 * 1024 * 1024  # ~5 GB per file

# Write as Lance dataset with file size limits for each *.lance file
ds = lance.write_dataset(
    table,
    "./videos.lance",
    schema=schema,
    mode="create",
    max_bytes_per_file=MAX_BYTES_PER_FILE,
)

有关使用 Lance 数据集的更多详细信息,请参阅 Lance 文档

在 GitHub 上更新

© . This site is unofficial and not affiliated with Hugging Face, Inc.