Datasets documentation
تحميل بيانات الفيديو
تحميل بيانات الفيديو
دعم الفيديو تجريبي وقد يخضع للتغيير.
تحتوي مجموعات بيانات الفيديو على أعمدة من نوع Video، والتي تحتوي على كائنات torchcodec.
للتعامل مع مجموعات بيانات الفيديو، يجب أن تكون حزم
torchcodecوffmpegمثبّتة. اطّلع على دليل التثبيت لمعرفة كيفية تثبيتها.
عند تحميل مجموعة بيانات فيديو واستدعاء عمود الفيديو، يتم فك ترميز مقاطع الفيديو كفيديوهات 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>استخدم فهرس الصف أولاً ثم عمود
videoللوصول إلى مجموعة بيانات الفيديو -dataset[0]["video"]- لتجنب إنشاء جميع كائنات الفيديو في مجموعة البيانات. وإلا، فقد يكون هذا الأمر بطيئاً ومستهلكاً للوقت إذا كانت لديك مجموعة بيانات كبيرة.
للاطلاع على دليل حول كيفية تحميل أي نوع من مجموعات البيانات، راجع دليل التحميل العام.
قراءة الإطارات
الوصول إلى الإطارات مباشرةً من فيديو باستخدام VideoReader عبر 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للحصول على عدة إطارات دفعة واحدة، يمكنك استدعاء .get_frames_in_range(start: int, stop: int, step: int). سيعيد هذا الأمر دفعة من الإطارات.
هذه هي الطريقة الفعّالة للحصول على قائمة طويلة من الإطارات، راجع وثائق torchcodec للاطلاع على المزيد من الدوال للوصول إلى البيانات بكفاءة:
>>> import torch
>>> frames = video.get_frames_in_range(0, 6, 1)
>>> frames.data.shape
torch.Size([5, 3, 240, 320])يوجد أيضاً .get_frames_played_in_range(start_seconds: float, stop_seconds: float) للوصول إلى جميع الإطارات التي تم تشغيلها ضمن نطاق زمني معين.
>>> frames = video.get_frames_played_in_range(.5, 1.2)
>>> frames.data.shape
torch.Size([42, 3, 240, 320])الملفات المحلية
يمكنك تحميل مجموعة بيانات من مسار الفيديو. استخدم دالة cast_column() لقبول عمود من مسارات ملفات الفيديو، وفكّ تشفيره إلى فيديو torchcodec باستخدام ميزة 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>إذا كنت ترغب فقط في تحميل المسار الأساسي لمجموعة بيانات الفيديو دون فك ترميز كائن الفيديو، فاضبط decode=False في ميزة Video:
>>> dataset = dataset.cast_column("video", Video(decode=False))
>>> dataset[0]["video"]
{'bytes': None,
'path': 'path/to/video/folder/video0.mp4'}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("username/dataset_name")
>>> # OR locally:
>>> dataset = load_dataset("/path/to/folder")بالنسبة إلى مجموعات البيانات المحلية، يعادل هذا تمرير videofolder يدويًا في load_dataset() والمجلد في data_dir:
>>> dataset = load_dataset("videofolder", data_dir="/path/to/folder")ثم يمكنك الوصول إلى مقاطع الفيديو ككائنات من نوع 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}لتجاهل المعلومات في ملف البيانات الوصفية، اضبط drop_metadata=True في load_dataset():
>>> from datasets import load_dataset
>>> dataset = load_dataset("username/dataset_with_metadata", drop_metadata=True)إذا لم يكن لديك ملف بيانات وصفية، يستنتج VideoFolder تلقائيًا اسم التسمية من اسم المجلد.
إذا كنت ترغب في إسقاط التسميات المُنشأة تلقائيًا، اضبط drop_labels=True.
في هذه الحالة، لن يحتوي مجموعة بياناتك إلا على عمود فيديو:
>>> from datasets import load_dataset
>>> dataset = load_dataset("username/dataset_without_metadata", drop_labels=True)وأخيرًا، يتيح لك الحجة filters تحميل مجموعة فرعية فقط من مجموعة البيانات، بناءً على شرط يتعلق بالتسمية أو البيانات الوصفية. وهذا مفيد بشكل خاص إذا كانت البيانات الوصفية بصيغة Parquet، لأن هذه الصيغة تتيح التصفية السريعة. كما يُنصح باستخدام هذه الحجة مع streaming=True، لأن مجموعة البيانات تُحمَّل بالكامل قبل التصفية افتراضيًا.
>>> filters = [("label", "=", 0)]
>>> dataset = load_dataset("username/dataset_name", streaming=True, filters=filters)لمزيد من المعلومات حول إنشاء مجموعة بيانات
VideoFolderخاصة بك، راجع دليل إنشاء مجموعة بيانات فيديو.
WebDataset
يعتمد تنسيق WebDataset على مجلد من أرشيفات TAR وهو مناسب لمجموعات بيانات الفيديو الكبيرة.
ونظرًا لحجمها، يتم تحميل WebDatasets بشكل عام في وضع البث (باستخدام streaming=True).
يمكنك تحميل WebDataset على النحو التالي:
>>> from datasets import load_dataset
>>> dataset = load_dataset("webdataset", data_dir="/path/to/folder", streaming=True)Lance
Lance هو تنسيق جداول مفتوح المصدر متعدد الوسائط. يمكن لجداول Lance تخزين النصوص والقيم القياسية بشكل أصلي، بل وتخزين الكائنات الثنائية الكبيرة (blobs) مثل الصور والصوت والفيديو إلى جانب بياناتك الجدولية. داخل جدول Lance، تُخزَّن الكائنات الثنائية الكبيرة مثل مقاطع الفيديو على شكل بايتات مع إزاحات (انظر دليل blobs لمزيد من التفاصيل)، مما يسهّل مسح البيانات الوصفية وتصفيتها دون تحميل كائنات الفيديو الثقيلة، ثم جلب كائنات الفيديو المحددة التي تحتاجها عند الطلب فقط.
كما أن Lance هو تنسيق أعمدي، يمكنك إسقاط وفلترة أعمدة البيانات الوصفية التي تهتم بها فقط (دون جلب ملفات الفيديو الكبيرة)، ثم استرجاع مجموعة صغيرة من الصفوف (بما في ذلك الفيديو) عندما تكون مستعدًا. وهذا يحافظ على بياناتك الوصفية وفيديوهاتك في مكان واحد، دون الحاجة إلى مخزن ملفات منفصل أو فهرس خارجي.
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())في هذا المثال، يُخزَّن الفيديو بشكل أصلي (بصفتها بايتات مشفّرة) في جدول Lance، لذا يمكنك كتابته مباشرةً في ملف mp4 على نظام الملفات المحلي لديك دون أي خطوة تحويل إضافية.
لمزيد من التفاصيل حول العمل مع مجموعات بيانات Lance، راجع توثيق Lance.
فك ترميز الفيديو
بشكل افتراضي، يتم فك ترميز مقاطع الفيديو بشكل تسلسلي كـ VideoDecoders من torchcodec عند تكرار مجموعة البيانات.
فإنه يفك ترميز بيانات الوصف (metadata) للمقاطع الفيديو بشكل تسلسلي، ولا يقرأ إطارات الفيديو حتى تقوم بالوصول إليها.
ومع ذلك، من الممكن تسريع مجموعة البيانات بشكل كبير باستخدام فك الترميز متعدد الخيوط:
>>> 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 !
... ...يمكنك تفعيل تعدد الخيوط باستخدام num_threads. وهذا مفيد بشكل خاص لتسريع بث البيانات عن بُعد.
ومع ذلك، قد يكون أبطأ من num_threads=0 للبيانات المحلية على الأقراص سريعة.
إذا لم تكن مهتمًا بالفيديوهات المُفكَّكة كـ VideoDecoders في torchcodec، وأردت الوصول إلى المسار/البايتات بدلاً من ذلك، يمكنك تعطيل فك الترميز:
>>> dataset = dataset.decode(False)ملاحظة: IterableDataset.decode() متاح حاليًا فقط لمجموعات البيانات التي يتم بثها.
Update on GitHub