Datasets documentation

Carregar dados de vídeo

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v4.8.4).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Carregar dados de vídeo

O suporte a vídeo é experimental e está sujeito a alterações.

Os conjuntos de dados de vídeo possuem colunas do tipo Video, que contêm objetos torchcodec.

Para trabalhar com conjuntos de dados de vídeo, é necessário ter os pacotes torchcodec e ffmpeg instalados. Consulte o guia de instalação para aprender como instalá-los.

Ao carregar um conjunto de dados de vídeo e chamar a coluna de vídeo, os vídeos são decodificados como Vídeos torchcodec:

>>> from datasets import load_dataset, Video

>>> dataset = load_dataset("path/to/video/folder", split="train")
>>> dataset[0]["video"]
<torchcodec.decoders._video_decoder.VideoDecoder object at 0x14a61d5a0>

Acesse um conjunto de dados de vídeo usando primeiro o índice da linha e, em seguida, a coluna video - dataset[0]["video"] - para evitar a criação de todos os objetos de vídeo no conjunto de dados. Caso contrário, isso pode ser um processo lento e demorado se você tiver um conjunto de dados grande.

Para um guia sobre como carregar qualquer tipo de conjunto de dados, consulte o guia de carregamento geral.

Ler quadros

Acesse os quadros diretamente de um vídeo usando o VideoReader com next():

>>> video = dataset[0]["video"]
>>> first_frame = video.get_frame_at(0)
>>> first_frame.data.shape
(3, 240, 320)
>>> first_frame.pts_seconds  # timestamp
0.0

Para obter vários quadros de uma vez, você pode chamar .get_frames_in_range(start: int, stop: int, step: int). Isso retornará um lote de quadros. Esta é a maneira eficiente de obter uma longa lista de quadros. Consulte a documentação do torchcodec para ver mais funções para acessar os dados de forma eficiente:

>>> import torch
>>> frames = video.get_frames_in_range(0, 6, 1)
>>> frames.data.shape
torch.Size([5, 3, 240, 320])

Há também .get_frames_played_in_range(start_seconds: float, stop_seconds: float) para acessar todos os frames reproduzidos dentro de um determinado intervalo de tempo.

>>> frames = video.get_frames_played_in_range(.5, 1.2)
>>> frames.data.shape
torch.Size([42, 3, 240, 320])

Arquivos locais

Você pode carregar um conjunto de dados a partir do caminho do vídeo. Use a função cast_column() para aceitar uma coluna de caminhos de arquivos de vídeo e decodificá-la em um vídeo torchcodec com o recurso Video:

>>> from datasets import Dataset, Video

>>> dataset = Dataset.from_dict({"video": ["path/to/video_1", "path/to/video_2", ..., "path/to/video_n"]}).cast_column("video", Video())
>>> dataset[0]["video"]
<torchcodec.decoders._video_decoder.VideoDecoder object at 0x14a61e080>

Se você deseja apenas carregar o caminho subjacente do conjunto de dados de vídeo sem decodificar o objeto de vídeo, defina decode=False no recurso Video:

>>> dataset = dataset.cast_column("video", Video(decode=False))
>>> dataset[0]["video"]
{'bytes': None,
 'path': 'path/to/video/folder/video0.mp4'}

VideoFolder

Você também pode carregar um conjunto de dados com o construtor de conjuntos de dados VideoFolder, que não exige a criação de um dataloader personalizado. Isso torna o VideoFolder ideal para criar e carregar rapidamente conjuntos de dados de vídeo com vários milhares de vídeos para diferentes tarefas de visão. A estrutura do seu conjunto de dados de vídeo deve ser assim:

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

Se o conjunto de dados seguir a estrutura VideoFolder, você pode carregá-lo diretamente com load_dataset():

>>> from datasets import load_dataset

>>> dataset = load_dataset("username/dataset_name")
>>> # OR locally:
>>> dataset = load_dataset("/path/to/folder")

Para conjuntos de dados locais, isso é equivalente a passar videofolder manualmente em load_dataset() e o diretório em data_dir:

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

Em seguida, você pode acessar os vídeos como objetos torchcodec.decoders._video_decoder.VideoDecoder:

>>> dataset["train"][0]
{"video": <torchcodec.decoders._video_decoder.VideoDecoder object at 0x14a61e080>, "label": 0}

>>> dataset["train"][-1]
{"video": <torchcodec.decoders._video_decoder.VideoDecoder object at 0x14a61e090>, "label": 1}

Para ignorar as informações no arquivo de metadados, defina drop_metadata=True em load_dataset():

>>> from datasets import load_dataset

>>> dataset = load_dataset("username/dataset_with_metadata", drop_metadata=True)

Se você não tiver um arquivo de metadados, o VideoFolder infere automaticamente o nome do rótulo a partir do nome do diretório. Se você quiser descartar os rótulos criados automaticamente, defina drop_labels=True. Nesse caso, seu conjunto de dados conterá apenas uma coluna de vídeo:

>>> from datasets import load_dataset

>>> dataset = load_dataset("username/dataset_without_metadata", drop_labels=True)

Por fim, o argumento filters permite carregar apenas um subconjunto do conjunto de dados, com base em uma condição sobre o rótulo ou os metadados. Isso é especialmente útil se os metadados estiverem em formato Parquet, pois esse formato permite filtragem rápida. Também é recomendado usar este argumento com streaming=True, porque, por padrão, o conjunto de dados é totalmente baixado antes da filtragem.

>>> filters = [("label", "=", 0)]
>>> dataset = load_dataset("username/dataset_name", streaming=True, filters=filters)

Para mais informações sobre a criação do seu próprio conjunto de dados VideoFolder, consulte o guia Criar um conjunto de dados de vídeo.

WebDataset

O formato WebDataset é baseado em uma pasta de arquivos TAR e é adequado para grandes conjuntos de dados de vídeo. Devido ao seu tamanho, os WebDatasets geralmente são carregados em modo de streaming (usando streaming=True).

Você pode carregar um WebDataset da seguinte forma:

>>> from datasets import load_dataset

>>> dataset = load_dataset("webdataset", data_dir="/path/to/folder", streaming=True)

Lance

Lance é um formato de tabela de lakehouse multimodal aberto. As tabelas Lance podem armazenar nativamente não apenas texto e valores escalares, mas também objetos binários grandes (blobs), como imagens, áudio e vídeo, junto com seus dados tabulares. Dentro de uma tabela Lance, blobs grandes, como vídeos, são armazenados como bytes com offsets (veja o guia de blobs para mais detalhes), o que facilita varrer e filtrar metadados sem carregar blobs de vídeo mais pesados e, em seguida, buscar apenas os blobs de vídeo específicos de que você precisa sob demanda.

Além disso, como o Lance é um formato colunar, você pode projetar e filtrar apenas as colunas de metadados que lhe interessam (sem buscar os grandes arquivos de vídeo) e, em seguida, recuperar um pequeno subconjunto de linhas (incluindo o vídeo) quando estiver pronto. Isso mantém seus metadados e vídeos em um único local, sem a necessidade de um armazenamento de arquivos separado ou de um índice externo.

import lance

ds = lance.dataset("hf://datasets/lance-format/openvid-lance/data/train.lance")

# 1. Browse metadata without loading video blobs.
metadata = ds.scanner(
    columns=["caption", "aesthetic_score"],
    filter="aesthetic_score >= 4.5",
    limit=2,
).to_table().to_pylist()

# 2. Fetch a single video blob by row index.
selected_index = 0
blob_file = ds.take_blobs("video_blob", ids=[selected_index])[0]
with open("video_0.mp4", "wb") as f:
    f.write(blob_file.read())

Neste exemplo, o vídeo é armazenado nativamente (como seus bytes codificados) na tabela Lance, então você pode gravá-lo diretamente em um arquivo mp4 no seu sistema de arquivos local, sem nenhuma etapa extra de conversão.

Para mais detalhes sobre o trabalho com conjuntos de dados Lance, consulte a documentação do Lance.

Decodificação de vídeo

Por padrão, os vídeos são decodificados sequencialmente como VideoDecoders do torchcodec ao iterar sobre um conjunto de dados. Ele decodifica sequencialmente os metadados dos vídeos e não lê os quadros do vídeo até que você os acesse.

No entanto, é possível acelerar significativamente o conjunto de dados usando decodificação multithreaded:

>>> import os
>>> num_threads = num_threads = min(32, (os.cpu_count() or 1) + 4)
>>> dataset = dataset.decode(num_threads=num_threads)
>>> for example in dataset:  # up to 20 times faster !
...     ...

Você pode habilitar a multithreading usando num_threads. Isso é especialmente útil para acelerar o streaming de dados remotos. No entanto, pode ser mais lento que num_threads=0 para dados locais em discos rápidos.

Se você não se interessa pelos vídeos decodificados como VideoDecoders do torchcodec e deseja acessar o caminho/bytes em vez disso, você pode desabilitar a decodificação:

>>> dataset = dataset.decode(False)

Observação: IterableDataset.decode() está disponível apenas para datasets em streaming no momento.

Update on GitHub