Datasets documentation
Charger des données vidéo
Charger des données vidéo
La prise en charge de la vidéo est expérimentale et peut évoluer.
Les jeux de données vidéo ont des colonnes de type Video, qui contiennent des objets torchcodec.
Pour travailler avec des jeux de données vidéo, vous devez avoir installé les paquets
torchcodecetffmpeg. Consultez le guide d'installation pour apprendre comment les installer.
Lorsque vous chargez un jeu de données vidéo et appelez la colonne vidéo, les vidéos sont décodées en tant que torchcodec Videos :
>>> 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>Accédez à un jeu de données vidéo en utilisant d'abord l'index de la ligne, puis la colonne
video-dataset[0]["video"]- afin d'éviter de créer tous les objets vidéo du jeu de données. Sinon, cela peut être un processus lent et chronophage si vous disposez d'un jeu de données volumineux.
Pour un guide sur la façon de charger n'importe quel type de jeu de données, consultez le guide de chargement général.
Lire les images
Accédez directement aux images d’une vidéo à l’aide de VideoReader en utilisant 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.0Pour obtenir plusieurs images à la fois, vous pouvez appeler .get_frames_in_range(start: int, stop: int, step: int). Cela renverra un lot d'images.
C'est la méthode efficace pour obtenir une longue liste d'images. Consultez la documentation de torchcodec pour découvrir d'autres fonctions permettant d'accéder efficacement aux données :
>>> import torch
>>> frames = video.get_frames_in_range(0, 6, 1)
>>> frames.data.shape
torch.Size([5, 3, 240, 320])Il existe également .get_frames_played_in_range(start_seconds: float, stop_seconds: float) pour accéder à toutes les images diffusées dans une certaine plage de temps.
>>> frames = video.get_frames_played_in_range(.5, 1.2)
>>> frames.data.shape
torch.Size([42, 3, 240, 320])Fichiers locaux
Vous pouvez charger un jeu de données à partir du chemin d'accès à la vidéo. Utilisez la fonction cast_column() pour accepter une colonne de chemins d'accès aux fichiers vidéo, et décodez-la en vidéo torchcodec avec la fonctionnalité 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>Si vous souhaitez uniquement charger le chemin sous-jacent du jeu de données vidéo sans décoder l’objet vidéo, définissez decode=False dans la fonctionnalité Video :
>>> dataset = dataset.cast_column("video", Video(decode=False))
>>> dataset[0]["video"]
{'bytes': None,
'path': 'path/to/video/folder/video0.mp4'}VideoFolder
Vous pouvez également charger un jeu de données avec le constructeur de jeu de données VideoFolder, qui ne nécessite pas d'écrire un chargeur de données personnalisé. Cela rend VideoFolder idéal pour créer et charger rapidement des jeux de données vidéo contenant plusieurs milliers de vidéos pour différentes tâches de vision. La structure de votre jeu de données vidéo doit ressembler à ceci :
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.mp4Si le jeu de données suit la structure VideoFolder, vous pouvez le charger directement avec load_dataset() :
>>> from datasets import load_dataset
>>> dataset = load_dataset("username/dataset_name")
>>> # OR locally:
>>> dataset = load_dataset("/path/to/folder")Pour les jeux de données locaux, cela équivaut à passer manuellement videofolder dans load_dataset() et le répertoire dans data_dir :
>>> dataset = load_dataset("videofolder", data_dir="/path/to/folder")Vous pouvez ensuite accéder aux vidéos en tant qu'objets 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}Pour ignorer les informations du fichier de métadonnées, définissez drop_metadata=True dans load_dataset() :
>>> from datasets import load_dataset
>>> dataset = load_dataset("username/dataset_with_metadata", drop_metadata=True)Si vous n’avez pas de fichier de métadonnées, VideoFolder infère automatiquement le nom de l’étiquette à partir du nom du répertoire.
Si vous souhaitez supprimer les étiquettes créées automatiquement, définissez drop_labels=True.
Dans ce cas, votre jeu de données ne contiendra qu’une colonne vidéo :
>>> from datasets import load_dataset
>>> dataset = load_dataset("username/dataset_without_metadata", drop_labels=True)Enfin, l'argument filters permet de charger uniquement un sous-ensemble du jeu de données, en fonction d'une condition sur l'étiquette ou les métadonnées. C'est particulièrement utile si les métadonnées sont au format Parquet, car ce format permet un filtrage rapide. Il est également recommandé d'utiliser cet argument avec streaming=True, car par défaut le jeu de données est entièrement téléchargé avant le filtrage.
>>> filters = [("label", "=", 0)]
>>> dataset = load_dataset("username/dataset_name", streaming=True, filters=filters)Pour plus d'informations sur la création de votre propre jeu de données
VideoFolder, consultez le guide Créer un jeu de données vidéo.
WebDataset
Le format WebDataset est basé sur un dossier d’archives TAR et convient aux grands jeux de données vidéo.
En raison de leur taille, les WebDatasets sont généralement chargés en mode streaming (en utilisant streaming=True).
Vous pouvez charger un WebDataset de cette manière :
>>> from datasets import load_dataset
>>> dataset = load_dataset("webdataset", data_dir="/path/to/folder", streaming=True)Lance
Lance est un format de table de lakehouse multimodal ouvert. Les tables Lance peuvent stocker nativement non seulement du texte et des valeurs scalaires, mais aussi de grands objets binaires (blobs) tels que des images, de l’audio et de la vidéo, aux côtés de vos données tabulaires. À l’intérieur d’une table Lance, les gros blobs comme les vidéos sont stockés sous forme d’octets avec des décalages (voir le guide des blobs pour plus de détails), ce qui facilite le balayage et le filtrage des métadonnées sans charger les blobs vidéo plus lourds, puis permet de récupérer uniquement les blobs vidéo spécifiques dont vous avez besoin à la demande.
De plus, comme Lance est un format en colonnes, vous pouvez projeter et filtrer uniquement les colonnes de métadonnées qui vous intéressent (sans récupérer de grands fichiers vidéo), puis extraire un petit sous-ensemble de lignes (y compris la vidéo) lorsque vous êtes prêt. Cela permet de conserver vos métadonnées et vos vidéos au même endroit, sans avoir besoin d'un stockage de fichiers séparé ni d'un index externe.
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())Dans cet exemple, la vidéo est stockée de manière native (sous forme de ses octets encodés) dans la table Lance, ce qui vous permet de l'écrire directement dans un fichier mp4 sur votre système de fichiers local, sans aucune étape de conversion supplémentaire.
Pour plus de détails sur le travail avec les jeux de données Lance, consultez la documentation Lance.
Décodage vidéo
Par défaut, les vidéos sont décodées séquentiellement en tant que VideoDecoders de torchcodec lorsque vous itérez sur un jeu de données.
Il décode séquentiellement les métadonnées des vidéos et ne lit les images de la vidéo que lorsque vous y accédez.
Cependant, il est possible d'accélérer considérablement le jeu de données en utilisant un décodage multithreadé :
>>> 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 !
... ...Vous pouvez activer le multithreading à l'aide de num_threads. Cela est particulièrement utile pour accélérer le streaming de données distantes.
Cependant, cela peut être plus lent que num_threads=0 pour des données locales sur des disques rapides.
Si vous n’êtes pas intéressé par les vidéos décodées en tant que VideoDecoders torchcodec et souhaitez plutôt accéder au chemin/aux octets, vous pouvez désactiver le décodage :
>>> dataset = dataset.decode(False)Remarque : IterableDataset.decode() n'est actuellement disponible que pour les jeux de données en flux.
Update on GitHub