Datasets documentation

الاستخدام مع JAX

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

الاستخدام مع JAX

هذا المستند مقدمة سريعة لاستخدام datasets مع JAX، مع تركيز خاص على كيفية استخراج كائنات jax.Array من مجموعات البيانات لدينا، وكيفية استخدامها لتدريب نماذج JAX.

يتطلب إعادة إنتاج الكود أعلاه تثبيت jax وjaxlib، لذا يرجى التأكد من تثبيتهما عبر الأمر pip install datasets[jax].

تنسيق مجموعة البيانات

بشكل افتراضي، تُرجع مجموعات البيانات كائنات بايثون العادية: أعداد صحيحة، وأعداد عشرية، ونصوص، وقوائم، وما إلى ذلك، وتبقى الكائنات النصية والثنائية دون تغيير، لأن JAX يدعم الأرقام فقط.

للحصول على مصفوفات JAX (مشابهة لـ numpy) بدلاً من ذلك، يمكنك تعيين صيغة مجموعة البيانات إلى jax:

>>> from datasets import Dataset
>>> data = [[1, 2], [3, 4]]
>>> ds = Dataset.from_dict({"data": data})
>>> ds = ds.with_format("jax")
>>> ds[0]
{'data': DeviceArray([1, 2], dtype=int32)}
>>> ds[:2]
{'data': DeviceArray([
    [1, 2],
    [3, 4]], dtype=int32)}

يُعدّ كائن Dataset غلافًا لجدول Arrow، مما يتيح قراءة سريعة من المصفوفات الموجودة في مجموعة البيانات إلى مصفوفات JAX.

لاحظ أن الإجراء نفسه تمامًا ينطبق على كائنات DatasetDict، بحيث عند تعيين صيغة DatasetDict إلى jax، سيتم تنسيق جميع Dataset الموجودة هناك كـ jax:

>>> from datasets import DatasetDict
>>> data = {"train": {"data": [[1, 2], [3, 4]]}, "test": {"data": [[5, 6], [7, 8]]}}
>>> dds = DatasetDict.from_dict(data)
>>> dds = dds.with_format("jax")
>>> dds["train"][:2]
{'data': DeviceArray([
    [1, 2],
    [3, 4]], dtype=int32)}

شيء آخر يجب أن تضعه في الاعتبار هو أن التنسيق لا يُطبَّق حتى تقوم فعليًا بالوصول إلى البيانات. لذا إذا كنت ترغب في الحصول على مصفوفة JAX من مجموعة بيانات، فستحتاج إلى الوصول إلى البيانات أولًا، وإلا فإن التنسيق سيبقى كما هو.

أخيرًا، لتحميل البيانات على الجهاز الذي تختاره، يمكنك تحديد معامل device، لكن لاحظ أن jaxlib.xla_extension.Device غير مدعوم لأنه غير قابل للتسلسل باستخدام pickle أو dill، لذا ستحتاج إلى استخدام معرّفه النصي بدلاً من ذلك:

>>> import jax
>>> from datasets import Dataset
>>> data = [[1, 2], [3, 4]]
>>> ds = Dataset.from_dict({"data": data})
>>> device = str(jax.devices()[0])  # Not casting to `str` before passing it to `with_format` will raise a `ValueError`
>>> ds = ds.with_format("jax", device=device)
>>> ds[0]
{'data': DeviceArray([1, 2], dtype=int32)}
>>> ds[0]["data"].device()
TFRT_CPU_0
>>> assert ds[0]["data"].device() == jax.devices()[0]
True

لاحظ أنه إذا لم يتم تقديم حجة device إلى with_format، فسيستخدم الجهاز الافتراضي وهو jax.devices()[0].

مصفوفات N الأبعاد

إذا كانت مجموعة بياناتك تتكون من مصفوفات ذات أبعاد N، فستلاحظ أنه افتراضياً تُعتبر المصفوفات ذات الشكل الثابت على أنها نفس الموتر:

>>> from datasets import Dataset
>>> data = [[[1, 2],[3, 4]], [[5, 6],[7, 8]]]  # fixed shape
>>> ds = Dataset.from_dict({"data": data})
>>> ds = ds.with_format("jax")
>>> ds[0]
{'data': Array([[1, 2],
        [3, 4]], dtype=int32)}
>>> from datasets import Dataset
>>> data = [[[1, 2],[3]], [[4, 5, 6],[7, 8]]]  # varying shape
>>> ds = Dataset.from_dict({"data": data})
>>> ds = ds.with_format("jax")
>>> ds[0]
{'data': [Array([1, 2], dtype=int32), Array([3], dtype=int32)]}

ومع ذلك، تتطلب هذه المنطق غالبًا مقارنات بطيئة للأشكال ونسخًا للبيانات. لتجنب ذلك، يجب عليك استخدام نوع الميزة Array بشكل صريح وتحديد شكل متجهاتك:

>>> from datasets import Dataset, Features, Array2D
>>> data = [[[1, 2],[3, 4]],[[5, 6],[7, 8]]]
>>> features = Features({"data": Array2D(shape=(2, 2), dtype='int32')})
>>> ds = Dataset.from_dict({"data": data}, features=features)
>>> ds = ds.with_format("jax")
>>> ds[0]
{'data': Array([[1, 2],
        [3, 4]], dtype=int32)}
>>> ds[:2]
{'data': Array([[[1, 2],
         [3, 4]],
 
        [[5, 6],
         [7, 8]]], dtype=int32)}

أنواع ميزات أخرى

يتم تحويل بيانات ClassLabel إلى مصفوفات بشكل صحيح:

>>> from datasets import Dataset, Features, ClassLabel
>>> labels = [0, 0, 1]
>>> features = Features({"label": ClassLabel(names=["negative", "positive"])})
>>> ds = Dataset.from_dict({"label": labels}, features=features)
>>> ds = ds.with_format("jax")
>>> ds[:3]
{'label': DeviceArray([0, 0, 1], dtype=int32)}

تبقى كائنات النص والثنائية دون تغيير، لأن JAX يدعم الأرقام فقط.

تُدعم أنواع الميزات Image وAudio أيضًا.

لاستخدام نوع الميزة Image، ستحتاج إلى تثبيت الإضافة vision عبر الأمر pip install datasets[vision].

>>> from datasets import Dataset, Features, Image
>>> images = ["path/to/image.png"] * 10
>>> features = Features({"image": Image()})
>>> ds = Dataset.from_dict({"image": images}, features=features)
>>> ds = ds.with_format("jax")
>>> ds[0]["image"].shape
(512, 512, 3)
>>> ds[0]
{'image': DeviceArray([[[ 255, 255, 255],
              [ 255, 255, 255],
              ...,
              [ 255, 255, 255],
              [ 255, 255, 255]]], dtype=uint8)}
>>> ds[:2]["image"].shape
(2, 512, 512, 3)
>>> ds[:2]
{'image': DeviceArray([[[[ 255, 255, 255],
              [ 255, 255, 255],
              ...,
              [ 255, 255, 255],
              [ 255, 255, 255]]]], dtype=uint8)}

لاستخدام نوع الميزة Audio، ستحتاج إلى تثبيت الإضافة audio عبر الأمر pip install datasets[audio].

>>> from datasets import Dataset, Features, Audio
>>> audio = ["path/to/audio.wav"] * 10
>>> features = Features({"audio": Audio()})
>>> ds = Dataset.from_dict({"audio": audio}, features=features)
>>> ds = ds.with_format("jax")
>>> ds[0]["audio"]["array"]
DeviceArray([-0.059021  , -0.03894043, -0.00735474, ...,  0.0133667 ,
              0.01809692,  0.00268555], dtype=float32)
>>> ds[0]["audio"]["sampling_rate"]
DeviceArray(44100, dtype=int32, weak_type=True)

تحميل البيانات

لا تملك JAX أي قدرات مدمجة لتحميل البيانات، لذا ستحتاج إلى استخدام مكتبة مثل PyTorch لتحميل بياناتك باستخدام DataLoader أو TensorFlow باستخدام tf.data.Dataset. مستشهدًا بـ وثائق JAX حول هذا الموضوع: «تركّز JAX بدقة على تحويلات البرامج وNumPy المدعوم بالمسرّعات، لذا لا نضمّن تحميل البيانات أو معالجتها في مكتبة JAX. هناك بالفعل الكثير من محمّلات البيانات الرائعة في الخارج، لذا دعونا نستخدمها بدلا من إعادة اختراع أي شيء. سنأخذ محمّل بيانات PyTorch، ونصنع غلافًا صغيرًا لجعله يعمل مع مصفوفات NumPy».

ولهذا السبب يكون تنسيق JAX في datasets مفيدًا للغاية، لأنه يتيح لك استخدام أي نموذج من HuggingFace Hub مع JAX، دون الحاجة إلى القلق بشأن جزء تحميل البيانات.

استخدام with_format('jax')

أسهل طريقة للحصول على مصفوفات JAX من مجموعة بيانات هي استخدام طريقة with_format('jax'). لنفترض أننا نريد تدريب شبكة عصبية على مجموعة بيانات MNIST المتوفرة في HuggingFace Hub على https://huggingface.co/datasets/ylecun/mnist.

>>> from datasets import load_dataset
>>> ds = load_dataset("ylecun/mnist")
>>> ds = ds.with_format("jax")
>>> ds["train"][0]
{'image': DeviceArray([[  0,   0,   0, ...],
                       [  0,   0,   0, ...],
                       ...,
                       [  0,   0,   0, ...],
                       [  0,   0,   0, ...]], dtype=uint8),
 'label': DeviceArray(5, dtype=int32)}

بمجرد ضبط التنسيق، يمكننا تغذية مجموعة البيانات إلى نموذج JAX على دفعات باستخدام طريقة Dataset.iter():

>>> for epoch in range(epochs):
...     for batch in ds["train"].iter(batch_size=32):
...         x, y = batch["image"], batch["label"]
...         ...
Update on GitHub