Datasets documentation

動画データセットを作成する

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

動画データセットを作成する

このガイドでは、VideoFolderと一部のメタデータを使用して動画データセットを作成する方法を示します。これは、数千本の動画からなる動画データセットを素早く作成するためのノーコードソリューションです。

ユーザーが連絡先情報を共有することを条件に、データセットへのアクセスを制御できます。この機能をHubで有効にする方法の詳細については、Gated datasetsガイドを参照してください。

VideoFolder

VideoFolderは、コードを書かずに数千本の動画からなる動画データセットを素早く読み込むために設計されたデータセットビルダーです。

💡 VideoFolderがデータセットリポジトリの構造に基づいてデータセットの分割を作成する方法について詳しく知るには、Split pattern hierarchyをご覧ください。

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キャプショニングのデータセットには、動画の説明となるテキストが含まれます。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 アカウントにログインしていることを確認してください(詳細は Upload with Python tutorial を参照)。

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アーカイブにグループ化(例: 1つの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を読み込むと、ファイルの拡張子ごとに1列ずつ作成されます(ここでは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テーブルは、テキストやスカラー値だけでなく、画像、音声、動画などの大きなバイナリオブジェクト(blob)も、タブラーデータと並んでネイティブに保存できます。

Lanceには、Lanceデータセット内で大きなblobを保存・取得することを容易にするblob APIが提供されています。 以下の例では、より重い動画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などを使用)、メタデータと動画を単一の成果物としてまとめて保持したまま、データセットリポジトリとして共有できます。

Lance データセットは、データがディスク上にカラムナフォーマットで保存されるため、非常に大きなサイズ(テラバイト以上)までスケールできます。 Lance における大規模なブロブの保存と取得に関するベストプラクティスの最新情報については、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のドキュメントを参照してください。

Update on GitHub