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 создаёт разбиения датасета на основе структуры вашего репозитория с данными.

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")

Это эквивалентно ручной передаче videofolder в load_dataset() и указанию каталога в 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"}

Описание видео

Наборы данных для описания видео содержат текст, описывающий видео. Пример 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 (например, 1 ГБ видео на один архив TAR) и иметь тысячи архивов 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 — это открытый формат таблиц для мультимодальных lakehouse-хранилищ. Таблицы Lance могут нативно хранить не только текст и скалярные значения, но и крупные бинарные объекты (blobs), такие как изображения, аудио и видео, наряду с табличными данными.

Lance предоставляет blob API, который упрощает хранение и извлечение крупных blob-объектов в наборах данных Lance. В следующем примере показано, как эффективно просматривать метаданные без загрузки более тяжёлых видео-blob, а затем получать нужные видео-blob по запросу.

Ниже приведён пример того, как может выглядеть таблица Lance, хранящая видео (колонка video_blob использует blob-кодирование Lance):

+------------------------------------------+-----------------+-----+------------------------------------------+
| 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 масштабируются до очень больших размеров (терабайты и более), поскольку данные хранятся на диске в столбчатом формате. См. руководство по API для blob для получения актуальной информации о лучших практиках хранения и извлечения больших blob в Lance.

При записи больших наборов данных обычно рекомендуется ограничивать размер каждого отдельного файла *.lance несколькими гигабайтами. Просто соберите данные через итератор и укажите параметр 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