هناك تطبيقان شائعان لخوارزمية ZeRO Redundancy Optimizer (Zero) في المجتمع، أحدهما من DeepSpeed ​​والآخر من PyTorch. يعرض Hugging Face Accelerate هذين الإطارين للمستخدمين النهائيين لتدريب/ضبط نماذجهم. تسلط هذه المدونة الضوء على الاختلافات بين كيفية عرض هذه الواجهات الخلفية من خلال برنامج Accelerate. لتمكين المستخدمين من التبديل بسلاسة بين هذه الواجهات الخلفية، قمنا بتوفير تغيير متعلق بالدقة ودليل مفاهيمي.

هل FSDP و DeepSpeed ​​قابلان للتبادل؟

لقد حاولنا مؤخرًا تشغيل مسار تدريب باستخدام DeepSpeed ​​وPyTorch FSDP. لاحظنا أن النتائج التي تم الحصول عليها اختلفت. كان النموذج المحدد هو قاعدة Mistral-7B وتم تحميله بنصف الدقة (bfloat16). في حين أن خسارة DeepSpeed ​​(الأزرق) قد تقاربت بشكل جيد، فإن خسارة FSDP (البرتقالي) لم تتناقص، كما هو موضح في الشكل 1.

لقد افترضنا أن معدل التعلم قد يحتاج إلى التوسع من خلال عدد وحدات معالجة الرسومات وقمنا بزيادة معدل التعلم بمقدار 4x نظرًا لأننا كنا نستخدم 4 وحدات معالجة رسوميات. ثم رأينا سلوك الخسارة التالي، كما هو موضح في الشكل 2.

الشكل 2

يبدو أن السلوك المطلوب قد تم تحقيقه من خلال زيادة معدل تعلم FSDP بعدد وحدات معالجة الرسومات! ومع ذلك، عندما جربنا معدل تعلم مختلف (1e-5) بدون القياس، لاحظنا خسارة مماثلة وخصائص معيارية متدرجة لكلا الإطارين، كما هو موضح في الشكل 3.

الشكل 3

مسائل الدقة

داخل DeepSpeed قاعدة التعليمات البرمجية، وتحديدا في تنفيذ
DeepSpeedZeroOptimizer_Stage3 (كما يوحي الاسم، ما الذي يتعامل مع تقسيم المُحسِّن للمرحلة الثالثة)، لاحظنا أن trainable_param_groups، تمر مجموعات المعلمات التي يتم التدريب عليها عبر ملف داخلي _setup_for_real_optimizer استدعاء دالة، الذي يستدعي دالة أخرى تسمى _create_fp32_partitions. كما fp32 في الاسم يوحي، DeepSpeed كان يقوم بالترقية داخليًا، ويحتفظ دائمًا بأوزانه الرئيسية fp32 حسب التصميم. ويعني هذا النقل إلى الدقة الكاملة أن المُحسِّن يمكن أن يتقارب بمعدلات تعلم لا يتقارب بها بدقة أقل. وكانت الملاحظات السابقة نتيجة لهذا الاختلاف في الدقة.

في FSDP، قبل توزيع معلمات النموذج والمحسن عبر وحدات معالجة الرسومات، يتم “تسويتها” أولاً إلى موتر أحادي البعد. يستخدم FSDP وDeepSpeed ​​طرقًا مختلفة dtypes لهذه المعلمات “المسطحة” التي لها تداعيات على مُحسّنات PyTorch. ويبين الجدول 1 العمليات الخاصة بكلا الإطارين؛ يشير العمود “المحلي” إلى العملية التي تحدث لكل وحدة معالجة رسومات، وبالتالي يتم استهلاك مقدار الذاكرة الناتجة عن البث التصاعدي بعدد وحدات معالجة الرسومات.

عملية محلي؟ نطاق تفاصيل
تحميل النموذج في (مثل AutoModel.from_pretrained(..., torch_dtype=torch_dtype))
التحضير، مثل إنشاء “المعلمات المسطحة” FSDP
السرعة العميقة
يستخدم torch_dtype
يتجاهل torch_dtype ويتم إنشاؤه في float32
تهيئة المُحسِّن FSDP
السرعة العميقة
يخلق المعلمات في torch_dtype
يخلق المعلمات في float32
خطوة التدريب (الأمام، الخلف، التخفيض) FSDP
السرعة العميقة
يتبع fsdp.MixedPrecision
يتبع deepspeed_config_file إعدادات الدقة المختلطة
محسن (ما قبل الخطوة) FSDP
السرعة العميقة
upcasting (إن وجدت) ل torch_dtype
رفع كل شيء ل float32
محسن (الخطوة الفعلية) FSDP
السرعة العميقة
يحدث في torch_dtype
يحدث في float32

الجدول 1: ملخص لكيفية تعامل FSDP وDeepSpeed ​​مع الدقة المختلطة

بعض النقاط الوجبات الجاهزة:

  • كما تمت الإشارة إلى 🤗 مشكلة التسريع، فإن القاعدة الأساسية عند تنفيذ الدقة المختلطة هي الاحتفاظ بالمعلمات القابلة للتدريب float32.
  • الرفع، كما هو الحال في DeepSpeed، قد يكون له تأثير ضئيل على استهلاك الذاكرة عند التقسيم على عدد كبير من وحدات معالجة الرسومات. ومع ذلك، عند استخدام DeepSpeed على عدد صغير من وحدات معالجة الرسومات، يمكن أن تكون الزيادة في استهلاك الذاكرة بمقدار الضعف كبيرة.
  • لا يفرض التنفيذ الأصلي لـ FSDP البث، مما يسمح للمستخدم بتشغيل مُحسِّنات PyTorch بدقة منخفضة. وهذا يوفر مرونة أكبر من البث الأصلي لـ DeepSpeed.

مواءمة DeepSpeed ​​وFSDP في 🤗 التسريع

لمحاذاة DeepSpeed ​​وFSDP بشكل أفضل في 🤗 التسريع، يمكننا إجراء البث تلقائيًا لـ FSDP عند تمكين الدقة المختلطة. لقد أنشأنا طلب سحب بهذا التغيير الذي تم تضمينه في الإصدار 0.30.0.

الشكل 4

نتيجة هذا العلاقات العامة هي السماح لـ FSDP بالعمل في وضعين:

  • وضع “مختلط الدقة” مثل نظير DeepSpeed
  • وضع الدقة المنخفضة لسيناريوهات الذاكرة المقيدة، كما هو موضح في الشكل 4.

تم تلخيص وضعي FSDP الجديدين في الجدول 2 ومقارنتهما مع DeepSpeed.

نطاق تحميل النموذج (torch_dtype) الدقة المختلطة التحضير (محلي) تمرين محسن (محلي)
FSDP (مقيد بالذاكرة) bf16 الافتراضي (لا شيء) bf16 bf16 bf16
FSDP (وضع الدقة المختلط) bf16 bf16 fp32 bf16 fp32
السرعة العميقة bf16 bf16 fp32 bf16 fp32

الجدول 2: ملخص لوضعي FSDP الجديدين ومقارناتهما مع DeepSpeed

نتائج الإنتاجية

نحن نستخدم نموذج IBM Granite 7B (الذي يتبع بنية Meta Llama2) لمقارنات الإنتاجية. نقوم بمقارنة استخدام نموذج Flops (MFU) ومقاييس الرموز المميزة/الثانية/وحدة معالجة الرسومات ونعرضها لـ FSDP (التقسيم الكامل) وDeepSpeed ​​(Zero3).

استخدمنا أربع وحدات معالجة رسوميات A100 كما كان من قبل مع المعلمات الفائقة التالية:

  • حجم الدفعة 8
  • تم تحميل النموذج torch.bfloat16
  • الدقة المختلطة هي نفس dtype.

يوضح الجدول 3 أنه من المتوقع أن يعمل كل من FSDP وDeepSpeed ​​بشكل مماثل.

نعتزم المتابعة من خلال مقارنة شاملة للإنتاجية وأساليب لتحسين الإنتاجية (على سبيل المثال، الأقنعة رباعية الأبعاد مع التعبئة، وtorch.compile، وفحص التنشيط الانتقائي) حيث أصبحت تقنيات المحاذاة واسعة النطاق مثل InstructLab وGLAN شائعة.

نطاق الرموز / ثانية / الجهاز وقت الخطوة (ق) استخدام النموذج المتخبط (MFU)
FSDP (الوضع المحاذي) 3158.7 10.4 0.41
السرعة العميقة 3094.5 10.6 0.40

الجدول 3: مقارنات إنتاجية الملعب بين FSDP وDeepSpeed ​​على أربع وحدات معالجة رسوميات A100.

إغلاق الأفكار

لقد قدمنا ​​دليلاً مفاهيميًا جديدًا لمساعدة المستخدمين على الانتقال بين الإطارين. يساعد الدليل المستخدمين على الإجابة على أسئلة مثل:

  • كيف نحقق استراتيجيات المشاركة المكافئة؟
  • كيف نقوم بتحميل النموذج بكفاءة؟
  • كيف تتم إدارة الجلب المسبق للوزن في FSDP وDeepSpeed؟
  • ما هو المعادل لتغليف FSDP في DeepSpeed؟

نحن نفكر في طرق مختلفة لتكوين هذه الأطر في 🤗 تسريع،

🤗 تسريع يجعلها تقريبا تافه للتبديل بين FSDP وDeepSpeed، مع كون معظمها عبارة عن تغيير في ملف التكوين Accelerate (راجع دليل المفهوم الجديد للحصول على إرشادات حول هذا).

إلى جانب تغيير التكوين، هناك بعض الاعتبارات الأخرى (الموضحة أيضًا في الدليل) وهي الاختلافات في كيفية التعامل مع نقاط التفتيش، وما إلى ذلك.

يمكن إعادة إنتاج جميع التجارب في هذه المدونة باستخدام الكود الأصلي 🤗 تسريع المشكلة.

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

شكر وتقدير

هذا جهد شارك فيه عدة فرق عبر مؤسسات متعددة للالتقاء معًا. بدأ الأمر في IBM Research، وبالتحديد ألدو باريجا، الذي اكتشف المشكلة، وفابيان ليم، الذي حدد فجوات الدقة وأصلح هذه المشكلة. لقد كان زاك مولر وستاس بيكمان استثنائيين في تقديم التعليقات والإصلاحات لتسريعها. كان Less Wright من فريق PyTorch في Meta مفيدًا جدًا في الإجابة على الأسئلة المتعلقة بمعلمات FSDP. أخيرًا، نود أيضًا أن نشكر فريق DeepSpeed ​​لتقديم تعليقاته على هذه المدونة.

شاركها.
اترك تعليقاً