LeRobot documentation

بث مجموعة بيانات التدريب

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

بث مجموعة بيانات التدريب

يتيح بثّ مجموعة البيانات أثناء التدريب لـlerobot-train استهلاك LeRobotDataset v3 دون الحاجة أولاً إلى تنزيل حمولة Parquet والفيديو الكاملة. فعّله من خلال المفتاح العام الموجود مسبقاً:

lerobot-train \
  --dataset.repo_id=OWNER/DATASET \
  --dataset.streaming=true \
  --policy.type=act \
  --output_dir=outputs/train/act_streaming

تستقل هذه الميزة عن --dataset.streaming_encoding=true. يتحكم streaming_encoding في كيفية كتابة مقاطع الفيديو أثناء التسجيل، بينما يتحكم dataset.streaming في كيفية قراءة مجموعة بيانات موجودة مسبقاً أثناء التدريب. لا تُستخدم مشفّرات التسجيل والتوسيع في مسار التدريب هذا.

كيف يتم قراءة دورة

يملك كل رتبة موزّعة مجموعة حتمية ومتوازنة من حيث الإطارات من الحلقات الكاملة. يمزج كل بركة تغطية دقيقة لكل عامل في DataLoader جزء العامل من تلك الحلقات مع زيارة كل إطار مختار مرة واحدة لكل حقبة تغطية. يتم جلب أعمدة Parquet ونطاقات البايتات المضغوطة من MP4 مسبقًا من نفس الجبهة القبولية الواعية بالبايتات. تُحل نوافذ التاريخ الزمني والمستقبل داخل الحلقة الكاملة، بما في ذلك أقنعة الحشو الحدودي نفسها كما في التحميل بنمط الخريطة.

تبقى السلوك الافتراضي بنمط الخريطة لـLeRobotDataset دون تغيير عند استخدام --dataset.streaming=false.

العمال، الشرائح والتزامن

يملك كل رتبة (rank) شريحة متوازنة الإطارات من الحلقات الكاملة. داخل الرتبة، يحدد --num_workers عدد عمليات عامل DataLoader، كما هو الحال مع مجموعات البيانات ذات نمط الخريطة. يملك كل عامل جزءًا منفصلًا ومتوازن الإطارات من حلقات الرتبة، مع حوض تغطية دقيقة خاص به، وحصته من ميزانية البايتات، ومجموعات خيوط خاصة به:

المرحلةالتزامنالإعداد
تقسيم الترتيبجزء واحد غير متداخل لكل حلقة كاملة لكل رتبةحجم العالم الموزّع
عمال DataLoaderجزء منفصل واحد من شريحة الرتبة لكل عامل--num_workers
جلب الحلقةصفوف Parquet ونطاقات بايت MP4، بالتوازيmax_num_shards، يُعيَّن من --num_workers
تجميع العينة وفك الترميزالنوافذ الزمنية وإطارات الفيديو، بالتوازي--dataset.streaming_decode_threads
خزانة عينات مرتبةعينات مُفكّكة محفوظة مسبقًا، بترتيب المخطط--dataset.streaming_decoded_queue_size

لماذا عدة عمّال. تجميع العينات وتسليم الدفعة ينفذانًا أكواد بايثون، وعملية واحدة تنفّذ كود بايثون على خيط واحد في كل مرة (بسبب قفل بايثون العالمي GIL). مع عامل واحد، تنتظر خيوط فك الترميز الخاصة برتبة معينة بعضها بعضًا، فتستخدم الرتبة نحو نواتين معالجتين فقط. كل عامل هو عملية مستقلة، لذا يجمع N من العمّال العينات ويفكّ ترميزها بالتوازي.

حجم المجموعة وتنوع الدفعة. يحدد streaming_episode_pool_size مجموعة كل عامل. إذا لم تقم بتعيينه، يمزج الرتبة 32 حلقة، ويحصل كل من العمال N على 32/N منها. كما أن كل عامل يسحب مسبقًا streaming_prefetch_episodes حلقة، وهو عملية Python مستقلة، لذا فإن استخدام عدد أكبر من العمال يستهلك ذاكرة أكثر: في مجموعة بيانات واحدة تحتوي على 3 كاميرات، استهلك 4 عمال حوالي 8 جيجابايت إجمالًا، مقابل حوالي 3 جيجابايت مع عامل واحد. يأخذ DataLoader كل دفعة من عامل واحد، لذا تمزج الدفعة حلقات من مجموعة عامل واحد. المجموعة الأكبر تمزج حلقات أكثر في كل دفعة، لكنها تستهلك ذاكرة أكثر وتجلب بيانات أكثر قبل العينة الأولى.

القيود. يبقى الميزانية بالبايت (streaming_byte_budget_gb) وحجم كاش مُفكّك الفيديو الصريح video_decoder_cache_size لكل رتبة: يحصل كل عامل على 1/N منها. يحتاج العامل إلى حلقة واحدة على الأقل، لذا يستخدم lerobot-train عدداً من العمال لا يتجاوز عدد الحلقات التي تملكها الرتبة. يحافظ --num_workers=0 على مجموعة البيانات في عملية التدريب. هناك، يطبّق خيط التدريب تحويلات الصور، لذا يعطي البذرة نفسها --seed نفس التحويلات.

ملفات MP4 المصاحبة والتشغيل الأول

يعتمد بث الفيديو على ملف فهرس MP4 جانبي. عند تهيئة مجموعة البيانات، يتحقق النظام أولاً من ذاكرة التخزين المؤقت المحلية المرتبطة بالإصدار، ثم يبحث عن ملف جانبي منشور صالح. إذا لم يتوفر أي منهما، يقوم LeRobot ببناء الملف الجانبي محلياً مع الاحتفاظ بقفل العملية، ثم تثبيته بشكل ذرّي. لا يستبدل البناء الفاشل أو المقطوع الملف الصالح السابق. تنتظر العمليات الأخرى التي تحتاج إلى نفس الملف الجانبي على القفل لمدة تصل إلى --dataset.streaming_sidecar_lock_timeout_s (30 دقيقة افتراضياً). قم بزيادة هذه القيمة لمجموعات البيانات الكبيرة التي تستغرق وقتاً أطول للفهرسة.

تُثبَّت قراءات حمولة Hub على التزامن (commit) الخاص بلقطة البيانات الوصفية. يتم فحص فهارس Bucket مقابل قائمة كائنات جديدة، بما في ذلك تجزئات المحتوى، بحيث يؤدي استبدال فيديو عند المسار نفسه إلى إبطال ملفه المصاحب (sidecar) حتى لو بقي حجم الملف دون تغيير. تضيف هذه القائمة عملاً عند بدء التشغيل، لكنها لا تقوم بتنزيل حمولات الفيديو. حافظ على البيانات الوصفية والحمولات دون تغيير أثناء التشغيل. تُعيد أنظمة الملفات البعيدة العامة التي تفتقر إلى هويات كائنات مستقرة بناء فهرسها عند كل فتح. تُعاد فهارس Bucket الموجودة التي تفتقر إلى بصمات الكائنات محلياً مرة واحدة؛ ويبقى نشر الملف المصاحب المحدَّث إجراءً صريحاً من جانب المُحافظ.

التدريب للقراءة فقط: فهو لا يرفع ملفًا مرافقًا ولا يعدّل مستودع مجموعة البيانات. على العنقود الذي يحتوي على ذاكرات تخزين مؤقت محلية للعقدة، قد يبني أول مهمة مرة واحدة لكل عقدة. يتجنّب ذلك التكرار استخدام ذاكرة تخزين مؤقت مشتركة لـ LeRobot.

تكتب عملية بناء المرافق (Sidecar) كل فهرس مصدر مكتمل في أرشيف مؤقت. وتحتفظ بعدد نتائج التحليل المُحدَّد كحد أقصى. وتعتمد ذاكرة المصفوفات على أكبر عدد من المصادر المتزامنة، بينما يستمر نمو بيانات الأرشيف الوصفية مع عدد المصادر. استخدم --workers لضبط التزامن أثناء التحليل عند تشغيل lerobot-build-mp4-sidecar. ويحافظ البناء الفاشل على المرافق السابق.

تحافظ أرشيفات NPZ المنشورة بمخطط الإصدار 3 على مصفوفات أعداد صحيحة قياسية من نوع int64. يقوم أول فتح بتحويل الأرشيف إلى فهرس للقراءة فقط، مرمّز في الذاكرة، تحت المسار $HF_LEROBOT_HOME/streaming-indexes. يستخدم الفهرس المشتق أصغر أنواع الأعداد الصحيحة الدقيقة. يخزّن مدة ثابتة، أو إزاحة تكوين، أو حجمًا، أو إزاحة بايت مرة واحدة فقط. تحافظ عروض المصفوفات للقراءة فقط على العدد المنطقي للعينات. تحافظ طوابع العرض الزمنية على قيم float64 دقيقة. تحافظ مصفوفات عينات المزامنة على التخزين الكثيف.

يستخدم الفهرس المشتق جيلًا منفصلًا للتخزين المؤقت. يحتفظ القارئون الأقدمون بتنسيق التخزين المؤقت الحالي لديهم. يمكن لأول فتح باستخدام القارئ الجديد تحويل الأرشيف مرة واحدة؛ وتعيد الفتح اللاحقة استخدامه. يستخدم التحويل قفل عملية واستبدالًا ذريًا. تعيد الرتب التي تتشارك التخزين المؤقت استخدام نفس الصفحات المدعومة بملفات. يبني كل رتبة السجلات فقط للملفات المصدرية المستخدمة في حلقاته. قد تتطلب أجيال التخزين المؤقت القديمة والجديدة مساحة قرص إضافية. يؤدي استبدال الملف المساعد إلى إنشاء جيل جديد غير قابل للتغيير دون إبطال القارئين النشطين.

لا يجعل هذا حجم جميع البيانات الوصفية ثابتًا: فبيانات الحلقات الوصفية وجداول الفواصل لا تزال تنمو مع حجم مجموعة البيانات، كما يمكن أن تلمس شُعب الترتيب المُبعثرة ملفات مصدر متداخلة. تُحتسب أيضًا الصفحات المُرسومة المقيمة في نظام التشغيل ضمن حجم الذاكرة المقيمة (RSS)؛ استخدم حجم المجموعة النسبي (PSS) عند قياس الذاكرة المشتركة بين الشُعب. تقطع عمليات قراءة Parquet مجموعات الصفوف باستخدام إحصاءات الحلقات ثم تُفلتر إلى الحلقة الكاملة. تبقى المجموعات التي لا تحتوي على إحصاءات مرشحة، لذا قد تتطلب الملفات التي لا تحتوي على حدود مفيدة قراءة مُتوقعة للملف بأكمله.

يمكن لصانعي مجموعات البيانات بناء ملف مرافق مسبقاً:

lerobot-build-mp4-sidecar \
  --repo-id=OWNER/DATASET \
  --revision=COMMIT_SHA \
  --data-root=hf://datasets/OWNER/DATASET@COMMIT_SHA \
  --output=/tmp/dataset-mp4-sidecar.npz

يكون النشر دائمًا صريحًا. أضف --push فقط بعد التحقق من ملف accompaniment الخاص بالبيانات الكاملة. لا يمكن نشر ملفات accompaniment الخاصة بالمجموعات الفرعية.

لمستودعات مجموعات البيانات، يُنشئ --push أو يُحدّث الفرع المخصص lerobot-sidecars. لا يتغير فرع/وسم مجموعة البيانات المصدرية. يبحث التدريب هناك عن فهرس مرتبط بارتكاب مصدر الفيديو المثبّت ويتحقق منه قبل الاستخدام. يتشارك الوسم وارتكابه المُحلَّلة نفس الفهرس المنشور؛ وتبقى الكاشات المحلية الموجودة والمفهرسة حسب المراجعة قابلة لإعادة الاستخدام. لا تزال الدلاء تنشر مباشرةً تحت meta/mp4-sidecars/. يتطلب النشر صلاحية كتابة للمستودع أو الدلو؛ بينما يحتاج التدريب فقط إلى صلاحية قراءة ولا ينشئ فرعًا أو يرفع ملفات أبدًا.

يحافظ مخطط Sidecar الإصدار 3 على توقيت تركيب MP4 وتعديلات تأخير المُشفِّر، بما في ذلك مقاطع الفيديو التي تحتوي على إطارات B. تُعاد بناء ملفات Sidecar الأقدم تلقائيًا في عنصر تخزين مؤقت منفصل مرتبط بمفتاح المراجعة؛ كما يجب إعادة بنائها قبل النشر الصريح. تتضمن مقاطع الفيديو المُعاد ترتيبها نهاية آخر مجموعة إطارات مفتاحية (GOP) في كل نطاق مسترجع، بحيث تبقى فهارس الإطارات المُفكَّكة متصلة. تُرفض خطوط زمنية تعديل MP4 المتكررة أو غير ذات المعدل الواحد، بدلاً من إرجاع إطارات غير محاذاة بشكل صحيح بصمت.

الإعداد

القيم الافتراضية للإنتاج هي:

خيارافتراضيالمعنى
streaming_episode_pool_size32 / N لكلأقصى عدد من الحلقات المكتملة التي يمزجها كل عامل
streaming_sampling_strategyremainingوزن الإطارات المتبقلة أو round_robin المُختل
streaming_prefetch_episodes8الحلقات التي تم جلبها مسبقاً لكل مجموعة من عمال
streaming_byte_budget_gb8الحد الأقصى لبايتات MP4 المُصنَّعة لكل رتبة
streaming_decode_threads2عمال تجميع العينات المتوازية وفك ترميز الفيديو
streaming_decoded_queue_size8عينات مُفكّكة ومخزّنة مؤقتًا مسبقًا، بترتيب المخطط
video_decoder_cache_sizepool × كاميراتالحد الأقصى لعدد عناصر قائمة LRU في مُفكِّك الفيديو المفتوح لكل عامل
streaming_native_http_connectionsإلغاء تعيينالحد الأقصى لعدد اتصالات HTTP الأصلية لكل رتبة
streaming_native_http_subranges1المقاطع الفرعية المتزامنة لكل قراءة نطاق HTTP أصلية
streaming_sidecar_lock_timeout_s1800الثواني التي يجب الانتظارها لبناء sidecar آخر
max_num_shards (--num_workers)16الحلقات التي تم جلبها بالتوازي لكل عامل

جميع الخيارات باستثناء max_num_shards هي أعلام --dataset.*. أما max_num_shards فهو معامل لـStreamingLeRobotDataset؛ حيث يحدده lerobot-train من --num_workers (1 على الأقل).

للحصول على خلط أكثر توازناً بين الحلقات، اختر --dataset.streaming_sampling_strategy=round_robin. في كل جولة، يتم خلط الحلقات المقيمة حاليًا واختيار إطار واحد مخفوط من كل حلقة؛ والحلقات التي تُقبل أثناء جولة ما تنضم إلى الجولة التالية. تحافظ كلا الاستراتيجيتين على تغطية دقيقة لمرة واحدة لكل حقبة وعلى نفس حدود الموارد. لا تُعد أيٌّ منهما تبديلاً منتظمًا شاملًا: فأولوية الدوران تفضل الحلقات الأقصر في البادئات المحدودة وقد تزيد من تقلب فك التشفير وتقلل من الإنتاجية. يأتي الترتيب من --seed (الافتراضي 1000)، إلى جانب تهيئة السياسة ومولّدات العشوائية الأخرى المزروعة. تمنح البذور المختلفة ترتيبات مختلفة للحلقات والنقاط المرجعية، ويكرر نفس البذرة الترتيب. يستخدم --seed=null بذرة البث الثابتة 42. حافظ على نفس الاستراتيجية و--seed وإعدادات المجموعة عند استئناف نقطة التفتيش. تخزّن نقطة التفتيش البذرة، لذا يحافظ --resume العادي على الترتيب. نقطة التفتيش من تشغيل بدأ قبل وصول --seed إلى مجموعة بيانات البث استخدمت البذرة 42 لترتيبها: مرّر --seed=42 عند استئنافها للحفاظ على ذلك الترتيب.

يُحدَّد مجموعة الحلقات النشطة بحدّين: عدد الحلقات، والأحجام الدقيقة لمقاطع MP4 المصغّرة المُصنَّعة المُحسوبة من الملف المساعد. تفشل الحلقة التي يتجاوز حجمها ميزانية الرتبة الكاملة قبل أن يجلب التدريب حمولتها. تشمل الحجوزات عمليات الجلب المعلّقة، وعمليات الجلب المسبق المكتملة، والحلقات التي لا تزال قيد فك الترميز. عند امتلاء الميزانية، يتوقف الجلب المسبق التخميني، وتنتظر الموافقة على الاستبدال حتى تُطلق آخر عملية فك ترميز بايتاتها. يُبلّغ EpisodeByteCache.reserved_bytes عن هذه الحجوزات؛ بينما يُبلّغ resident_bytes عن جميع الحمولات المكتملة، حتى قبل طلب أول عيّنة منها.

هذا ميزانية لحِمل مضغوط، وليس حدًا لذاكرة العملية (RSS): فذاكرة العمل المؤقتة لجلب النطاق/التركيب، وحالة المُفكِّك، وجداول Parquet، والمُتجهات المُفكَّكة تتطلب ذاكرة إضافية. وللمفكِّك LRU وذاكرة المؤقتة للعينة المُفكَّكة حدود منفصلة. ابدأ بحوض أو ميزانية أصغر على الأجهزة ذات القيود الذاكرة:

lerobot-train \
  --dataset.repo_id=OWNER/DATASET \
  --dataset.streaming=true \
  --dataset.streaming_episode_pool_size=16 \
  --dataset.streaming_prefetch_episodes=4 \
  --dataset.streaming_byte_budget_gb=4 \
  --dataset.streaming_decode_threads=2 \
  --dataset.streaming_decoded_queue_size=8 \
  --num_workers=4 \
  --policy.type=act \
  --output_dir=outputs/train/act_streaming

للمجموعة الكاملة من البيانات المخزنة في حاوية تخزين HF، استخدم معرّف الحاوية ونوع المستودع، أو مرّر عنوان URI الخاص بالحاوية على النحو --dataset.root=hf://buckets/OWNER/BUCKET. يجب أن تكون البيانات الوصفية (meta/) وملفات Parquet وملفات الفيديو موجودة جميعها في جذر تلك الحاوية:

lerobot-train \
  --dataset.repo_id=OWNER/BUCKET \
  --dataset.repo_type=bucket \
  --dataset.streaming=true \
  --policy.type=act \
  --output_dir=outputs/train/act_bucket_streaming

تستخدم مجموعات بيانات Hub repo_type=dataset افتراضيًا. لمجموعة بيانات محلية كاملة، اضبط --dataset.root على مجلدها. يقوم التدريب بحل البيانات الوصفية والأحمال من نفس المصدر؛ لا حاجة إلى علم منفصل لموقع حمل البث.

استئناف هجرة البيانات وخلطها

استخدم قارئ البث السابق مخزن مؤقتًا مُحدَّد الحدّ لتبديل الصفوف. أما قارئ الحلقات فيمتلك ترتيبًا حتميًا لتغطية دقيقة مشتقًا من البذرة (seed) والعصر (epoch). يعيد استئناف نقطة التفتيش استعادة إزاحة العينة لكل رتبة باستخدام حجم الدفعة (batch) الخاص بنقطة التفتيش. عند وجود عدة عمّال، يستنتج كل عامل إزاحته الخاصة من هذه الإزاحة، لأن DataLoader يأخذ الدفعات من عمّاله بالتناوب. يؤدي تغيير حجم العالم الموزّع، أو حجم الدفعة، أو --num_workers إلى تغيير ملكية الدفعات أو حدودها. للمقارنات الدقيقة على مستوى العينة، استأنف بنفس حجم العالم، وحجم الدفعة، وعدد العمّال. حافظ على نفس مستوى التزامن الداخلي لجلب البيانات عند مقارنة الأداء.

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

استكشاف الأخطاء وإصلاحها

العرضما يجب فعله
يستغرق الدفعة الأولى وقتًا طويلاًتحقق من السجلات لبناء وحدة جانبية. أعد استخدام ذاكرة تخزين مؤقت مشتركة أو انشر صراحةً وحدة جانبية كاملة ومُتحقق منها.
تنتهي مهلة قفل المرافققد يكون هناك عملية أخرى ما تزال تقوم بفهرسة نفس المراجعة. تأكد من أنها تعمل بشكل سليم قبل إزالة قفل قديم.
لا يملك أي رتبة بياناتقلّل عدد الرتب بحيث تمتلك كل رتبة حلقة واحدة على الأقل من الحلقات المحددة.
تم تجاوز ميزانية البايتخفّض حجم مجموعة الحلقات، أو ارفع ميزانية البايت لكل رتبة، أو استخدم تخطيط حمولة بمجال حلقات أصغر.
لا يمكن للقراءات عن بُعد المصادقةاجعل رمز Hugging Face أو بيانات اعتماد fsspec متاحة لكل عامل. لا تضمّن العمليات الجانبية بيانات الاعتماد أبدًا.
مستويات إعادة التعبئة مرتفعةقارن زمن انتظار الدفعة عند p95/p99، وقلل من ازدحام الشبكة، وارفع قيمة الاستباق تدريجياً، وتحقق من تطابق المكوّن المساعد مع الإصدار.
Update on GitHub