رمز الخطأ: E1000

الفئة: وقت التجميع: HBM OOM

يشير هذا الخطأ إلى أنّ البرنامج يتطلّب ذاكرة عالية النطاق (HBM) أكثر من المتوفّر فعليًا على جهاز TPU.

في ما يلي أمثلة على رسائل الخطأ:

RESOURCE_EXHAUSTED: TPU TensorCore Hbm usage: 34.82G, SparseCore Hbm usage 174.10G, exceeding available bytes: 95.74G
RESOURCE_EXHAUSTED: XLA:TPU compile permanent error. Ran out of memory in memory space hbm. Used 49.34G of 32.00G hbm. Exceeded hbm capacity by 17.34G.

برامج XLA الخلفية: وحدة معالجة الموتّرات

نظرة عامة

تُجري XLA عمليات تحقّق للتأكّد من أنّ الحجم الإجمالي لجميع عمليات التخصيص الثابتة الضرورية يتناسب مع ذاكرة النطاق الترددي العالي (HBM) للجهاز.

يدير المترجم سعة ذاكرة النطاق الترددي العالي الثابتة في وحدة TPU لعدة أنواع من عمليات التخصيص:

  • مدخلات ومخرجات البرنامج: مجموعات التدريب وحالات المحسِّن وما إلى ذلك
  • البيانات المؤقتة لوحدة معالجة الموتّرات: الذاكرة الديناميكية المطلوبة لإجراء العمليات الحسابية الوسيطة (مثل عمليات التنشيط والتدرّجات وما إلى ذلك).
  • الرمز الثنائي المجمّع: رمز الآلة لكل من TensorCore (TC) وSparseCore (SC).
  • مساحة إضافية للنظام: مساحة محجوزة لوقت تشغيل XLA (مثل المخازن المؤقتة داخل الخلاصة في أجيال وحدات TPU القديمة)
  • الثوابت: يتم تخصيص القيم الثابتة المضمّنة في HLO IR على HBM.
  • التفاصيل الداخلية للمترجم البرمجي: عمليات التخصيص على مستوى البرنامج وعلى مستوى كل HLO (مثل معلومات التوجيه للعُقد في الشبكة).

يحدث هذا الخطأ عندما يتعذّر على برنامج التجميع XLA استيعاب جميع عمليات التخصيص المذكورة أعلاه في ذاكرة النطاق الترددي العالي (HBM) للجهاز.

تصحيح الأخطاء

حلِّل رسالة الخطأ والسجلات بعناية لتحديد فئة خطأ نفاد ذاكرة HBM أدناه التي تصف خطأك بأفضل شكل:


السيناريو 1 تحقيق التوازن بين استخدام "إدارة الأداء" و"إدارة المحتوى"

إذا كان الخطأ يوضّح تفاصيل الاستخدام، مثلاً "استخدام ذاكرة النطاق الترددي العالي (HBM) في TensorCore: X، استخدام ذاكرة النطاق الترددي العالي (HBM) في SparseCore: Y"، يعني ذلك أنّ إجمالي استخدام TensorCore وSparseCore يتجاوز حد ذاكرة النطاق الترددي العالي (HBM). قارِن بين القيمتين لتحديد المشكلة:

  • الاستخدام المرتفع لـ SparseCore
    • تحسين استخدام حزمة HBM: يتناسب استهلاك ذاكرة حزمة HBM مع feature_width وmax_unique_nz_per_row وlogical_replica_count. يمكنك تقليل الحد الأقصى لاستخدام الحزمة من خلال ضبط العلامة --xla_sc_num_serialized_tables_to_optimize_hbm التي تسلسل معالجة الجداول. ويؤدي ذلك إلى تقليل التوازي.
    • التحقّق من مساحة التعبئة المستخدَمة: تعمل SparseCore على محاذاة جداول التضمين مع 32 بايت (8 أرقام عشرية). تتسبب الجداول التي تتضمّن ميزات ذات عروض صغيرة (مثل أقل من 8 أرقام عشرية) في زيادة كبيرة في مساحة التعبئة، ما يؤدي إلى إهدار ذاكرة النطاق الترددي العالي (HBM).
    • تقليل استخدام الذاكرة المؤقتة: تؤدي القيم المرتفعة لـ maximum_parallel_iterations إلى زيادة مقدار بيانات الإدخال التي يتم جلبها مسبقًا إلى الذاكرة المؤقتة HBM. يمكن أن يؤدي خفض هذه القيمة إلى توفير مساحة كبيرة من الذاكرة.
    • التحقّق من التقسيم: تأكَّد من تقسيم جداول التضمين بشكل صحيح على جميع الشرائح. اطّلِع على كيفية تحويل الحدود إلى جداول.
    • يمكنك الاطّلاع على SC: Performance and memory bottlenecks للحصول على المزيد من الأفكار.
  • الاستخدام العالي لـ TensorCore
  • متوازن
    • إذا لم يكن أي منهما مفرطًا بشكل فردي ولكن كان المجموع مرتفعًا جدًا، تكون قد وصلت إلى سعة الشريحة. عليك محاولة تقليل استخدام كلا المكوّنين. اتّبِع الاقتراحات في جميع الأقسام الثلاثة.

السيناريو 2. نفاد الذاكرة بسبب عمليات تخصيص كبيرة بشكل غير متوقّع

إذا ظهرت لك رسالة الخطأ "نفدَت الذاكرة في مساحة الذاكرة HBM" وكان هناك تخصيص واحد أو أكثر كبير بشكل غير متوقّع في السجلّات (أكثر من% 50 من حدّ HBM)، لا تكون المشكلة أبدًا متعلقة بسعة الأجهزة. ويكون عادةً خطأ في الإعداد. تحقَّق من تصنيف XLA (إذا كان متوفّرًا) لعمليات التخصيص الكبيرة للحصول على تلميحات بشأن رمز مصدر JAX.

  • إزالة عناصر تصحيح الأخطاء
    • يمكن أن يؤدي استخدام jax.debug.print() في عمليات التشغيل على نطاق واسع إلى إجبار برنامج التجميع على إنشاء المتّجه المتعدّد الأبعاد الكامل في ذاكرة النطاق الترددي العالي (HBM) لنقله إلى وحدة المعالجة المركزية (CPU)، ما يؤدي إلى إيقاف الدمج وزيادة الحد الأقصى لاستخدام الذاكرة. أزِل أي jax.debug.print() متبقّية.
  • إصلاح أشكال الشبكات المتداخلة أو التقسيم إلى أجزاء غير الفعّال
    • يمكن أن تؤدي أشكال الشبكات غير الصحيحة أو تعليقات توضيحية غير متوفرة لتقسيم إلى أجزاء إلى أن يستخدم برنامج التجميع الإعداد التلقائي للتكرار، ما يجبر برنامج التجميع على محاولة احتواء متّجهات متعدّدة الأبعاد كبيرة جدًا على شريحة واحدة.
    • تحقَّق من أشكال عمليات التخصيص الكبيرة وتأكَّد من أنّ عملية التقسيم محدّدة بشكلٍ صحيح ويتم نشرها من خلال XLA.

السيناريو 3. نفاد الذاكرة بسبب عمليات التخصيص المجمّعة

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

بعد تحديد بعض المساهمين الرئيسيين، اتّبِع الخطوات التالية لتحسين استهلاك الذاكرة.

السيناريو 3.أ: تعديل الإعداد

يمكنك غالبًا حلّ أخطاء نفاد الذاكرة من خلال تعديل إعدادات الضبط التالية:

  • تقليل حجم الدُفعة: تتناسب الذاكرة اللازمة للتنشيطات الوسيطة والتدرّجات بشكل مباشر مع حجم الدُفعة. يمكن أن يساعد تقليل حجم الدفعة في كثير من الأحيان في تقليل استخدام الذاكرة.
  • توفير مخازن مؤقتة للإدخال: عند استخدام jax.jit، حدِّد donate_argnums لمعلمات النموذج. يتيح ذلك لـ XLA الكتابة فوق ذاكرة الإدخال باستخدام الإخراج.
  • تفعيل الدقة المختلطة (bfloat16): استخدِم bfloat16 أو التكميم (int8 وما إلى ذلك) لأكبر موترات في البرنامج إذا كانت بنية النموذج ومتطلبات الجودة تسمح بذلك. يُرجى العِلم أنّ هذا التغيير يمكن أن يؤثر في سلوك النموذج، لذا يجب التفكير مليًا قبل إجرائه.

السيناريو 3.B تحسين البنية والتقسيم

إذا لم تكن تغييرات الإعداد كافية، قد يكون تصميم النموذج كبيرًا جدًا بالنسبة إلى إعدادات الأجهزة الحالية.

  • استخدام أجيال أحدث من وحدات TPU: توفّر وحدات TPU الأحدث بشكل عام المزيد من ذاكرة النطاق الترددي العالي (HBM) لكل شريحة، لذا ننصحك بالانتقال إلى أجيال أحدث من وحدات TPU إذا كانت متاحة.
  • التشغيل على بنية شرائح أكبر: إذا كانت أوزان النموذج كبيرة جدًا بالنسبة إلى البنية الحالية، يمكنك محاولة تقسيمها على المزيد من الشرائح.
  • استخدام تقنيات تقسيم متقدّمة:
    • استكشِف المزيد من الأساليب المتقدّمة لتوازي البيانات أو المتّجه متعدّد الأبعاد أو مسار التعلّم.
    • حدِّد تلميحات التقسيم للقيم والنتائج الوسيطة.
  • استخدام ميزة "نقل البيانات إلى المضيف" في JAX: تتيح تقنيات نقل البيانات إلى المضيف للمستخدم نقل الموترات الكبيرة إلى ذاكرة وحدة المعالجة المركزية للمضيف (مثل نقل بيانات التنشيط ونقل بيانات المحسِّن).

السيناريو 3.C التحقّق من الحشو والمحاذاة في الموتر

تُعدّ أشكال الموتر غير الفعّالة سببًا شائعًا وغير ملحوظ لأخطاء نفاد الذاكرة على وحدات TPU. للحصول على أفضل أداء على وحدات معالجة الموتّرات، تعمل وسادات XLA على توسيع أبعاد الموتّرات، وعادةً ما يكون ذلك بمضاعفات 128 لأصغر بُعد و8 للبعد الثاني الأصغر. يؤثر هذا الحشو في كل من مصفوفات الإدخال والموترات الوسيطة (البيانات المؤقتة في HLO)، ما قد يؤدي إلى زيادة كبيرة في استخدام الذاكرة، خاصةً مع أحجام الأبعاد الصغيرة. راجِع تنسيقات المصفوفات.

  • تدقيق أشكال المخازن المؤقتة الكبيرة: (على TPU v5 مع التنسيقات التلقائية)
    • عند تمرير مؤشر الماوس فوق مخزن مؤقت في أداة عرض الذاكرة في Xprof، تظهر بطاقة تفاصيل المخزن المؤقت التي تحتوي على تفاصيل المخزن المؤقت، بما في ذلك معلومات المساحة المتروكة.
    • مثال: قد يتمّ إضافة مساحة فارغة إلى شكل (129, 1024) ليصبح (256, 1024)، ما يؤدّي إلى إهدار ما يقارب% 50 من الذاكرة.
    • تصحيح: لا يتطلّب شكل (128, 1024) أي مساحة متروكة ويؤدي إلى عدم إهدار أي مساحة من الذاكرة.
  • محاذاة الأبعاد: تأكَّد من أنّ جميع أبعاد الموتر الكبيرة (حجم الدفعة، وبُعد التضمين، والحجم المخفي) هي مضاعفات للعدد 128. يُرجى العِلم أنّ هذا التغيير يمكن أن يؤثّر في سلوك النموذج، ويجب أخذه في الاعتبار بعناية.

السيناريو 3.D: ضبط الذاكرة الرئيسية التي تؤثر في علامات XLA

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

السيناريو 3.E: تمرير إعادة إنشاء Tune XLA/إنشاء نقاط توقّف يدويًا

إذا كان النموذج على وشك أن يتناسب مع الذاكرة، يمكنك استخدام أداة التزيين jax.checkpoint مع jax.grad للتحكّم يدويًا في الوسائط التي يتم حفظها في التمرير الأمامي مقابل إعادة احتسابها في التمرير الخلفي، ما يؤدي إلى استبدال دورات الحوسبة بذاكرة النطاق الترددي العالي (HBM).

بدلاً من ذلك، يمكنك فرض استخدام الخيار XLA::Rematerialization لتحديد أولويات توفير الذاكرة، وقد يؤدي ذلك إلى إبطاء عمليات التجميع:

علم الوصف التأثير / المفاضلة
--xla_tpu_max_hbm_size_mib يضبط هذا الخيار يدويًا الحد الأقصى لحجم HBM الذي تستخدمه عملية Rematerialization. يفرض على المترجم العمل بجهد أكبر لتضمين البرنامج في حد أصغر من ذاكرة النطاق الترددي العالي الفعلية.
--xla_tpu_rematerialization_algo=PEAK_PRIORITY تركيز الجهود على نقاط ذروة استخدام الذاكرة يمكن أن تكون أكثر فعالية في تقليل استخدام الذاكرة بشكل كبير مقارنةً بالخوارزمية التلقائية.
--xla_tpu_rematerialization_max_block_size_limit=32 تتحكّم هذه السمة في الحد الأقصى لعدد التعليمات في أحد الأقسام التي يمكن إعادة إنشائها في الوقت نفسه. تؤدي زيادة هذا الحد إلى توفير الذاكرة على حساب زيادة وقت التجميع بشكل كبير.
--xla_tpu_rematerialization_block_effort_factor=10.0 تحدّد هذه السمة مقدار الجهد (وقت الترجمة البرمجية) المبذول للبحث عن كتل لإعادة إنشائها. تسمح القيم الأعلى بإجراء بحث أكثر شمولاً عن توفير الذاكرة على حساب زيادة أوقات التجميع.
--xla_tpu_pre_fusion_remat=true تتيح هذه السمة تنفيذ عملية Rematerialization إضافية قبل عملية الدمج. يمكن العثور على المزيد من توفير الذاكرة، ولكن يزيد من أوقات التجميع وقد يؤثر في الثبات العددي.

يُرجى العِلم أنّ إجراء تغييرات على علامات XLA يجب أن يكون إجراءً أخيرًا، لأنّه يمكن أن يؤثر سلبًا في الأداء.

السيناريو 3.F استخدام أدوات إنشاء الملفات الشخصية المتقدّمة

تقدّم تصحيح أخطاء نفاد الذاكرة باستخدام XProf برنامجًا تعليميًا حول استخدام عارض الذاكرة XProf لتصوّر طريقة عرض برنامج التجميع لاستخدام الذاكرة العالية النطاق الترددي.

تتيح لك هذه الأداة الاطّلاع على الحد الأقصى لمقدار تخصيص الذاكرة وعمر المخزن المؤقت، وهو أمر بالغ الأهمية لفهم ما يستهلك ذاكرة النطاق الترددي العالي عند بلوغ الحد الأقصى للاستخدام. للاطّلاع على إعدادات إنشاء الملفات الشخصية العامة، راجِع بدء استخدام Xprof وإنشاء الملفات الشخصية في TensorBoard.