يمكن أن تحدث الأحداث الكارثية التي تتضمن NaN في بعض الأحيان أثناء برنامج TensorFlow ، مما يؤدي إلى شل عمليات التدريب النموذجية. غالبًا ما يكون السبب الجذري لمثل هذه الأحداث غامضًا ، خاصة بالنسبة للنماذج ذات الحجم غير التافه والتعقيد. لتسهيل تصحيح هذا النوع من أخطاء النموذج ، يوفر TensorBoard 2.3+ (مع TensorFlow 2.3+) لوحة معلومات متخصصة تسمى Debugger V2. نوضح هنا كيفية استخدام هذه الأداة من خلال العمل من خلال خطأ حقيقي يتضمن NaNs في شبكة عصبية مكتوبة في TensorFlow.
التقنيات الموضحة في هذا البرنامج التعليمي قابلة للتطبيق على أنواع أخرى من أنشطة التصحيح مثل فحص أشكال موتر وقت التشغيل في البرامج المعقدة. يركز هذا البرنامج التعليمي على NaNs نظرًا لتكرار حدوثها المرتفع نسبيًا.
مراقبة الخلل
الكود المصدري لبرنامج TF2 الذي سنقوم بتصحيحه متاح على GitHub . يتم أيضًا تجميع البرنامج النموذجي في حزمة tensorflow pip (الإصدار 2.3+) ويمكن استدعاؤه بواسطة:
python -m tensorflow.python.debug.examples.v2.debug_mnist_v2
ينشئ برنامج TF2 هذا تصورًا متعدد الطبقات (MLP) ويدربه على التعرف على صور MNIST . يستخدم هذا المثال عن قصد واجهة برمجة التطبيقات ذات المستوى المنخفض من TF2 لتحديد بنيات الطبقة المخصصة ، ووظيفة الخسارة ، وحلقة التدريب ، لأن احتمالية وجود أخطاء NaN تكون أعلى عندما نستخدم واجهة برمجة التطبيقات (API) الأكثر مرونة ولكنها أكثر عرضة للخطأ مما هي عليه عندما نستخدم الأسهل - للاستخدام ولكن أقل مرونة قليلاً من واجهات برمجة التطبيقات عالية المستوى مثل tf.keras .
يقوم البرنامج بطباعة دقة الاختبار بعد كل خطوة تدريبية. يمكننا أن نرى في وحدة التحكم أن دقة الاختبار تتعطل عند مستوى شبه فرصة (~ 0.1) بعد الخطوة الأولى. هذه بالتأكيد ليست الطريقة التي يُتوقع أن يتصرف بها تدريب النموذج: نتوقع أن تقترب الدقة تدريجيًا من 1.0 (100٪) مع زيادة الخطوة.
Accuracy at step 0: 0.216
Accuracy at step 1: 0.098
Accuracy at step 2: 0.098
Accuracy at step 3: 0.098
...
التخمين المتعلم هو أن سبب هذه المشكلة هو عدم الاستقرار العددي ، مثل NaN أو اللانهاية. ومع ذلك ، كيف يمكننا التأكد من أن هذا هو الحال بالفعل وكيف يمكننا العثور على عملية TensorFlow (المرجع) المسؤولة عن توليد عدم الاستقرار العددي؟ للإجابة على هذه الأسئلة ، دعنا نجهز برنامج عربات التي تجرها الدواب باستخدام Debugger V2.
تجهيز كود TensorFlow باستخدام المصحح V2
tf.debugging.experimental.enable_dump_debug_info() هي نقطة إدخال واجهة برمجة التطبيقات لـ Debugger V2. إنها أدوات برنامج TF2 بسطر واحد من التعليمات البرمجية. على سبيل المثال ، ستؤدي إضافة السطر التالي بالقرب من بداية البرنامج إلى كتابة معلومات التصحيح إلى دليل السجل (logdir) في / tmp / tfdbg2_logdir. تغطي معلومات التصحيح جوانب مختلفة من وقت تشغيل TensorFlow. في TF2 ، يتضمن السجل الكامل للتنفيذ الحثيث ، وبناء الرسم البياني الذي تقوم به دالة @ tf ، وتنفيذ الرسوم البيانية ، وقيم الموتر الناتجة عن أحداث التنفيذ ، بالإضافة إلى موقع الكود (تتبع مكدس Python) لتلك الأحداث . ثراء معلومات التصحيح تمكن المستخدمين من تضييق نطاق الأخطاء الغامضة.
tf.debugging.experimental.enable_dump_debug_info(
"/tmp/tfdbg2_logdir",
tensor_debug_mode="FULL_HEALTH",
circular_buffer_size=-1)
تتحكم الوسيطة tensor_debug_mode في المعلومات التي يستخرجها المصحح V2 من كل موتر متحمس أو داخل الرسم البياني. "FULL_HEALTH" هو الوضع الذي يلتقط المعلومات التالية حول كل موتر من النوع العائم (على سبيل المثال ، float32 الشائع و bfloat16 dtype الأقل شيوعًا):
- نوع D
- مرتبة
- العدد الإجمالي للعناصر
- تقسيم العناصر من النوع العائم إلى الفئات التالية: سالب منتهي (
-) ، صفر (0) ، محدود موجب (+) ، ما لا نهاية سالب (-) ، ما لا نهاية موجب (+∞-∞، وNaN.
يعد الوضع "FULL_HEALTH" مناسبًا لتصحيح الأخطاء التي تتضمن NaN واللانهاية. انظر أدناه للحصول على tensor_debug_mode s الأخرى المدعومة.
تتحكم الوسيطة circular_buffer_size في عدد أحداث الموتر التي يتم حفظها في logdir. يتم تعيينه افتراضيًا على 1000 ، مما يتسبب في حفظ آخر 1000 موتر فقط قبل نهاية برنامج TF2 المُجهز على القرص. يقلل هذا السلوك الافتراضي المصحح الحمل عن طريق التضحية باكمال بيانات التصحيح. إذا كان الكمال مفضلًا ، كما في هذه الحالة ، فيمكننا تعطيل المخزن المؤقت الدائري عن طريق ضبط الوسيطة على قيمة سالبة (على سبيل المثال ، -1 هنا).
يستدعي المثال enable_dump_debug_info() بتمرير إشارات سطر الأوامر إليه. لتشغيل برنامج TF2 الإشكالي مرة أخرى مع تمكين أدوات التصحيح هذه ، قم بما يلي:
python -m tensorflow.python.debug.examples.v2.debug_mnist_v2 \
--dump_dir /tmp/tfdbg2_logdir --dump_tensor_debug_mode FULL_HEALTH
بدء تشغيل المصحح V2 GUI في TensorBoard
يؤدي تشغيل البرنامج باستخدام أدوات مصحح الأخطاء إلى إنشاء logdir في / tmp / tfdbg2_logdir. يمكننا بدء TensorBoard وتوجيهه إلى logdir باستخدام:
tensorboard --logdir /tmp/tfdbg2_logdir
في مستعرض الويب ، انتقل إلى صفحة TensorBoard على http: // localhost: 6006. سيكون المكون الإضافي "Debugger V2" غير نشط بشكل افتراضي ، لذا حدده من قائمة "المكونات الإضافية غير النشطة" في أعلى اليمين. بمجرد تحديده ، يجب أن يبدو كما يلي:

استخدام المصحح V2 GUI للعثور على السبب الجذري لـ NaNs
تم تنظيم Debugger V2 GUI في TensorBoard إلى ستة أقسام:
- التنبيهات : يحتوي هذا القسم الموجود أعلى اليسار على قائمة بأحداث "التنبيه" التي اكتشفها مصحح الأخطاء في بيانات تصحيح الأخطاء من برنامج TensorFlow المُجهز. يشير كل تنبيه إلى حالة شاذة معينة تستدعي الانتباه. في حالتنا ، يسلط هذا القسم الضوء على أحداث 499 NaN / بلون وردي أحمر بارز. هذا يؤكد شكوكنا في أن النموذج يفشل في التعلم بسبب وجود NaNs و / أو اللانهايات في قيم موتره الداخلية. سوف نتعمق في هذه التنبيهات قريبًا.
- المخطط الزمني لتنفيذ Python : هذا هو النصف العلوي من القسم العلوي الأوسط. يقدم التاريخ الكامل للتنفيذ المتلهف للعمليات والرسوم البيانية. يتم تمييز كل مربع في الخط الزمني بالحرف الأولي من المرجع أو اسم الرسم البياني (على سبيل المثال ، "T" لـ "TensorSliceDataset" المرجع ، "m"
tf.function"النموذج"). يمكننا التنقل في هذا المخطط الزمني باستخدام أزرار التنقل وشريط التمرير أعلى الخط الزمني. - تنفيذ الرسم البياني : يقع هذا القسم في الزاوية العلوية اليمنى من واجهة المستخدم الرسومية ، وسيكون هذا القسم مركزيًا لمهمة تصحيح الأخطاء لدينا. يحتوي على تاريخ لجميع الموترات العائمة من النوع dtype المحسوبة داخل الرسوم البيانية (على سبيل المثال ، تم تجميعها بواسطة
@tf-functions). - بنية الرسم البياني (النصف السفلي من القسم العلوي الأوسط) ، وكود المصدر (القسم السفلي الأيسر) ، وتتبع المكدس (القسم السفلي الأيمن) فارغة في البداية. سيتم ملء محتوياتها عندما نتفاعل مع واجهة المستخدم الرسومية. ستلعب هذه الأقسام الثلاثة أيضًا أدوارًا مهمة في مهمة تصحيح الأخطاء.
بعد أن وجهنا أنفسنا إلى تنظيم واجهة المستخدم ، دعنا نتخذ الخطوات التالية لمعرفة سبب ظهور NaNs. أولاً ، انقر فوق تنبيه NaN / ∞ في قسم التنبيهات. يقوم هذا تلقائيًا بالتمرير إلى قائمة 600 موتر للرسم البياني في قسم تنفيذ الرسم البياني ويركز على # 88 ، وهو موتر يسمى Log:0 تم إنشاؤه بواسطة Log (اللوغاريتم الطبيعي) المرجع. يبرز اللون الوردي والأحمر البارز عنصر a-من بين 1000 عنصر من موتر 2D float32. هذا هو الموتر الأول في سجل وقت تشغيل برنامج TF2 الذي يحتوي على أي NaN أو ما لا نهاية: الموترات المحسوبة قبل أن لا تحتوي على NaN أو ∞ ؛ تحتوي العديد من الموترات (في الواقع ، معظم) المحسوبة بعد ذلك على NaNs. يمكننا تأكيد ذلك بالتمرير لأعلى ولأسفل في قائمة تنفيذ الرسم البياني. توفر هذه الملاحظة تلميحًا قويًا إلى أن Log op هو مصدر عدم الاستقرار العددي في برنامج TF2 هذا.

لماذا يقوم هذا Log بصق؟ تتطلب الإجابة على هذا السؤال فحص المدخلات في المرجع. يؤدي النقر فوق اسم الموتر ( Log:0 ) إلى عرض مرئي بسيط ولكنه غني بالمعلومات حول منطقة Log op في الرسم البياني TensorFlow الخاص به في قسم بنية الرسم البياني. لاحظ الاتجاه من أعلى إلى أسفل لتدفق المعلومات. يظهر المرجع نفسه بالخط العريض في المنتصف. فوقه مباشرة ، يمكننا أن نرى العنصر النائب الذي يوفر الإدخال الوحيد إلى مرجع Log . أين الموتر الذي تم إنشاؤه بواسطة هذا probs النائب في قائمة تنفيذ الرسم البياني؟ باستخدام لون الخلفية الأصفر كوسيلة مساعدة بصرية ، يمكننا أن نرى أن probs:0 موتر هو ثلاثة صفوف فوق Log:0 موتر ، أي في الصف 85.

نظرة أكثر تفصيلاً على الانهيار العددي للمسببات: يكشف موتر probs:0 في الصف 85 سبب قيام المستهلك بتسجيل Log:0 ينتج a-: من بين 1000 عنصر من probs:0 ، عنصر واحد له قيمة 0. The-هو نتيجة لحساب اللوغاريتم الطبيعي لـ 0! إذا تمكنا بطريقة ما من التأكد من أن Log يتعرض للمدخلات الإيجابية فقط ، فسنكون قادرين على منع حدوث NaN /. يمكن تحقيق ذلك عن طريق تطبيق القص (على سبيل المثال ، باستخدام tf.clip_by_value() ) على موتر probs العنصر النائب.
نحن نقترب من حل الخطأ ، لكن لم ننتهي تمامًا بعد. من أجل تطبيق الإصلاح ، نحتاج إلى معرفة مكان نشأة Log وإدخال العنصر النائب في كود مصدر Python. يوفر المصحح V2 دعمًا من الدرجة الأولى لتتبع عمليات الرسم البياني وأحداث التنفيذ إلى مصدرها. عندما نقرنا على Log:0 tensor في Graph Executions ، تمت تعبئة قسم Stack Trace بتتبع المكدس الأصلي لإنشاء Log العمليات. يعد تتبع المكدس كبيرًا إلى حد ما لأنه يتضمن العديد من الإطارات من الكود الداخلي لـ TensorFlow (على سبيل المثال ، gen_math_ops.py و dumping_callback.py) ، والتي يمكننا تجاهلها بأمان لمعظم مهام التصحيح. إطار الاهتمام هو سطر 216 من debug_mnist_v2.py (على سبيل المثال ، ملف Python الذي نحاول تصحيحه بالفعل). يؤدي النقر على "سطر 216" إلى إظهار عرض لسطر الشفرة المقابل في قسم شفرة المصدر.

يقودنا هذا أخيرًا إلى الكود المصدري الذي أنشأ مرجع Log الإشكالي من مدخلات probs الخاصة به. هذه هي وظيفة فقدان الانتروبيا الفئوية المخصصة لدينا والمزينة بوظيفة @tf.function ومن ثم يتم تحويلها إلى رسم بياني TensorFlow. تتوافق probs Placeholder op مع وسيطة الإدخال الأولى لوظيفة الخسارة. يتم إنشاء مرجع Log باستدعاء tf.math.log () API.
سيبدو إصلاح قص القيمة لهذا الخطأ كما يلي:
diff = -(labels *
tf.math.log(tf.clip_by_value(probs), 1e-6, 1.))
سوف يحل عدم الاستقرار العددي في برنامج TF2 هذا ويتسبب في تدريب MLP بنجاح. هناك طريقة أخرى محتملة لإصلاح عدم الاستقرار العددي وهي استخدام tf.keras.losses.CategoricalCrossentropy .
هذا يختتم رحلتنا من مراقبة خطأ نموذج TF2 إلى الخروج بتغيير رمز يعمل على إصلاح الخطأ ، بمساعدة أداة Debugger V2 ، التي توفر رؤية كاملة لسجل التنفيذ الشغوف والرسم البياني لبرنامج TF2 المُجهز ، بما في ذلك الملخصات العددية من قيم الموتر والارتباط بين العمليات والموتر ورمز المصدر الأصلي.
توافق الأجهزة لـ Debugger V2
يدعم المصحح V2 أجهزة التدريب السائدة بما في ذلك وحدة المعالجة المركزية ووحدة معالجة الرسومات. يتم أيضًا دعم التدريب على وحدات معالجة الرسومات المتعددة باستخدام tf.distributed.MirroredStrategy . لا يزال دعم TPU في مرحلة مبكرة ويتطلب الاتصال
tf.config.set_soft_device_placement(True)
قبل استدعاء enable_dump_debug_info() . قد يكون لها قيود أخرى على TPUs أيضًا. إذا واجهت مشاكل في استخدام Debugger V2 ، فالرجاء الإبلاغ عن الأخطاء على صفحة مشكلات GitHub .
توافق API لـ Debugger V2
يتم تنفيذ Debugger V2 على مستوى منخفض نسبيًا من مكدس برامج TensorFlow ، وبالتالي فهو متوافق مع tf.keras و tf.data وواجهات برمجة التطبيقات الأخرى المبنية على أعلى المستويات الدنيا لـ TensorFlow. المصحح V2 متوافق أيضًا مع الإصدارات السابقة مع TF1 ، على الرغم من أن المخطط الزمني للتنفيذ الحرصي سيكون فارغًا لسجلات تصحيح الأخطاء التي تم إنشاؤها بواسطة برامج TF1.
نصائح استخدام API
أحد الأسئلة المتداولة حول تصحيح الأخطاء API هذا هو المكان الذي يجب أن يقوم فيه المرء في كود TensorFlow بإدخال الاستدعاء إلى enable_dump_debug_info() . عادةً ، يجب استدعاء API في أقرب وقت ممكن في برنامج TF2 الخاص بك ، ويفضل أن يكون ذلك بعد خطوط استيراد Python وقبل بدء إنشاء الرسم البياني وتنفيذه. سيضمن ذلك التغطية الكاملة لجميع العمليات والرسوم البيانية التي تدعم نموذجك وتدريبه.
tensor_debug_modes المدعومة حاليًا هي: NO_TENSOR و CURT_HEALTH و CONCISE_HEALTH و FULL_HEALTH و SHAPE . وهي تختلف في مقدار المعلومات المستخرجة من كل موتر وأعباء الأداء للبرنامج الذي تم تصحيحه. يرجى الرجوع إلى قسم args من enable_dump_debug_info() .
عبء الأداء
تقدم واجهة برمجة التطبيقات (API) لتصحيح الأخطاء عبء الأداء إلى برنامج TensorFlow المُجهز. يختلف مقدار الحمل حسب tensor_debug_mode ونوع الجهاز وطبيعة برنامج TensorFlow المُجهز. كنقطة مرجعية ، في وحدة معالجة الرسومات ، يضيف وضع NO_TENSOR زيادة بنسبة 15٪ أثناء تدريب نموذج Transformer تحت حجم الدُفعة 64. النسبة المئوية لأوضاع tensor_debug_modes الأخرى أعلى: حوالي 50٪ لـ CURT_HEALTH و CONCISE_HEALTH و FULL_HEALTH و SHAPE أساليب. في وحدات المعالجة المركزية (CPU) ، يكون الحمل أقل قليلاً. على TPUs ، النفقات العامة أعلى حاليًا.
العلاقة مع واجهات برمجة تطبيقات تصحيح أخطاء TensorFlow الأخرى
لاحظ أن TensorFlow يقدم أدوات وواجهات برمجة تطبيقات أخرى لتصحيح الأخطاء. يمكنك تصفح واجهات برمجة التطبيقات هذه ضمن مساحة الاسم tf.debugging.* في صفحة مستندات API. من بين واجهات برمجة التطبيقات (API) الأكثر استخدامًا هو tf.print() . متى يجب استخدام Debugger V2 ومتى يجب tf.print() بدلاً من ذلك؟ tf.print() مناسب في حالة مكان
- نحن نعلم بالضبط ما هي الموترات التي يجب طباعتها ،
- نحن نعلم بالضبط مكان إدراج
tf.print()في الكود المصدري ، - عدد هذه الموترات ليس كبيرا جدا.
بالنسبة للحالات الأخرى (على سبيل المثال ، فحص العديد من قيم الموتر ، وفحص قيم الموتر الناتجة عن الكود الداخلي لـ TensorFlow ، والبحث عن أصل عدم الاستقرار العددي كما أوضحنا أعلاه) ، يوفر Debugger V2 طريقة أسرع لتصحيح الأخطاء. بالإضافة إلى ذلك ، يوفر Debugger V2 نهجًا موحدًا لفحص موترات الرسم البياني والمتحمسة. يوفر بالإضافة إلى ذلك معلومات حول بنية الرسم البياني ومواقع الكود ، والتي تتجاوز قدرة tf.print() .
واجهة برمجة تطبيقات أخرى يمكن استخدامها لتصحيح المشكلات التي تتضمن ∞ و NaN هي tf.debugging.enable_check_numerics() . على عكس enable_dump_debug_info() ، لا يقوم enable_check_numerics() بحفظ معلومات التصحيح على القرص. بدلاً من ذلك ، يقوم فقط بمراقبة ∞ و NaN أثناء وقت تشغيل TensorFlow والأخطاء في موقع رمز الأصل بمجرد أن يولد أي مرجع مثل هذه القيم الرقمية السيئة. يحتوي على أداء أقل مقارنةً بـ enable_dump_debug_info() ، لكنه لا يوفر تتبعًا كاملاً لمحفوظات تنفيذ البرنامج ولا يأتي بواجهة مستخدم رسومية مثل Debugger V2.
يمكن أن تحدث الأحداث الكارثية التي تتضمن NaN في بعض الأحيان أثناء برنامج TensorFlow ، مما يؤدي إلى شل عمليات التدريب النموذجية. غالبًا ما يكون السبب الجذري لمثل هذه الأحداث غامضًا ، خاصة بالنسبة للنماذج ذات الحجم غير التافه والتعقيد. لتسهيل تصحيح هذا النوع من أخطاء النموذج ، يوفر TensorBoard 2.3+ (مع TensorFlow 2.3+) لوحة معلومات متخصصة تسمى Debugger V2. نوضح هنا كيفية استخدام هذه الأداة من خلال العمل من خلال خطأ حقيقي يتضمن NaNs في شبكة عصبية مكتوبة في TensorFlow.
التقنيات الموضحة في هذا البرنامج التعليمي قابلة للتطبيق على أنواع أخرى من أنشطة التصحيح مثل فحص أشكال موتر وقت التشغيل في البرامج المعقدة. يركز هذا البرنامج التعليمي على NaNs نظرًا لتكرار حدوثها المرتفع نسبيًا.
مراقبة الخلل
الكود المصدري لبرنامج TF2 الذي سنقوم بتصحيحه متاح على GitHub . يتم أيضًا تجميع البرنامج النموذجي في حزمة tensorflow pip (الإصدار 2.3+) ويمكن استدعاؤه بواسطة:
python -m tensorflow.python.debug.examples.v2.debug_mnist_v2
ينشئ برنامج TF2 هذا تصورًا متعدد الطبقات (MLP) ويدربه على التعرف على صور MNIST . يستخدم هذا المثال عن قصد واجهة برمجة التطبيقات ذات المستوى المنخفض من TF2 لتحديد بنيات الطبقة المخصصة ، ووظيفة الخسارة ، وحلقة التدريب ، لأن احتمالية وجود أخطاء NaN تكون أعلى عندما نستخدم واجهة برمجة التطبيقات (API) الأكثر مرونة ولكنها أكثر عرضة للخطأ مما هي عليه عندما نستخدم الأسهل - للاستخدام ولكن أقل مرونة قليلاً من واجهات برمجة التطبيقات عالية المستوى مثل tf.keras .
يقوم البرنامج بطباعة دقة الاختبار بعد كل خطوة تدريبية. يمكننا أن نرى في وحدة التحكم أن دقة الاختبار تتعطل عند مستوى شبه فرصة (~ 0.1) بعد الخطوة الأولى. هذه بالتأكيد ليست الطريقة التي يُتوقع أن يتصرف بها تدريب النموذج: نتوقع أن تقترب الدقة تدريجيًا من 1.0 (100٪) مع زيادة الخطوة.
Accuracy at step 0: 0.216
Accuracy at step 1: 0.098
Accuracy at step 2: 0.098
Accuracy at step 3: 0.098
...
التخمين المتعلم هو أن سبب هذه المشكلة هو عدم الاستقرار العددي ، مثل NaN أو اللانهاية. ومع ذلك ، كيف يمكننا التأكد من أن هذا هو الحال بالفعل وكيف يمكننا العثور على عملية TensorFlow (المرجع) المسؤولة عن توليد عدم الاستقرار العددي؟ للإجابة على هذه الأسئلة ، دعنا نجهز برنامج عربات التي تجرها الدواب باستخدام Debugger V2.
تجهيز كود TensorFlow باستخدام المصحح V2
tf.debugging.experimental.enable_dump_debug_info() هي نقطة إدخال واجهة برمجة التطبيقات لـ Debugger V2. إنها أدوات برنامج TF2 بسطر واحد من التعليمات البرمجية. على سبيل المثال ، ستؤدي إضافة السطر التالي بالقرب من بداية البرنامج إلى كتابة معلومات التصحيح إلى دليل السجل (logdir) في / tmp / tfdbg2_logdir. تغطي معلومات التصحيح جوانب مختلفة من وقت تشغيل TensorFlow. في TF2 ، يتضمن السجل الكامل للتنفيذ الحثيث ، وبناء الرسم البياني الذي تقوم به دالة @ tf ، وتنفيذ الرسوم البيانية ، وقيم الموتر الناتجة عن أحداث التنفيذ ، بالإضافة إلى موقع الكود (تتبع مكدس Python) لتلك الأحداث . ثراء معلومات التصحيح تمكن المستخدمين من تضييق نطاق الأخطاء الغامضة.
tf.debugging.experimental.enable_dump_debug_info(
"/tmp/tfdbg2_logdir",
tensor_debug_mode="FULL_HEALTH",
circular_buffer_size=-1)
تتحكم الوسيطة tensor_debug_mode في المعلومات التي يستخرجها المصحح V2 من كل موتر متحمس أو داخل الرسم البياني. "FULL_HEALTH" هو الوضع الذي يلتقط المعلومات التالية حول كل موتر من النوع العائم (على سبيل المثال ، float32 الشائع و bfloat16 dtype الأقل شيوعًا):
- نوع D
- مرتبة
- العدد الإجمالي للعناصر
- تقسيم العناصر من النوع العائم إلى الفئات التالية: سالب منتهي (
-) ، صفر (0) ، محدود موجب (+) ، ما لا نهاية سالب (-) ، ما لا نهاية موجب (+∞-∞، وNaN.
يعد الوضع "FULL_HEALTH" مناسبًا لتصحيح الأخطاء التي تتضمن NaN واللانهاية. انظر أدناه للحصول على tensor_debug_mode s الأخرى المدعومة.
تتحكم الوسيطة circular_buffer_size في عدد أحداث الموتر التي يتم حفظها في logdir. يتم تعيينه افتراضيًا على 1000 ، مما يتسبب في حفظ آخر 1000 موتر فقط قبل نهاية برنامج TF2 المُجهز على القرص. يقلل هذا السلوك الافتراضي المصحح الحمل عن طريق التضحية باكمال بيانات التصحيح. إذا كان الكمال مفضلًا ، كما في هذه الحالة ، فيمكننا تعطيل المخزن المؤقت الدائري عن طريق ضبط الوسيطة على قيمة سالبة (على سبيل المثال ، -1 هنا).
يستدعي المثال enable_dump_debug_info() بتمرير إشارات سطر الأوامر إليه. لتشغيل برنامج TF2 الإشكالي مرة أخرى مع تمكين أدوات التصحيح هذه ، قم بما يلي:
python -m tensorflow.python.debug.examples.v2.debug_mnist_v2 \
--dump_dir /tmp/tfdbg2_logdir --dump_tensor_debug_mode FULL_HEALTH
بدء تشغيل المصحح V2 GUI في TensorBoard
يؤدي تشغيل البرنامج باستخدام أدوات مصحح الأخطاء إلى إنشاء logdir في / tmp / tfdbg2_logdir. يمكننا بدء TensorBoard وتوجيهه إلى logdir باستخدام:
tensorboard --logdir /tmp/tfdbg2_logdir
في مستعرض الويب ، انتقل إلى صفحة TensorBoard على http: // localhost: 6006. سيكون المكون الإضافي "Debugger V2" غير نشط بشكل افتراضي ، لذا حدده من قائمة "المكونات الإضافية غير النشطة" في أعلى اليمين. بمجرد تحديده ، يجب أن يبدو كما يلي:

استخدام المصحح V2 GUI للعثور على السبب الجذري لـ NaNs
تم تنظيم Debugger V2 GUI في TensorBoard إلى ستة أقسام:
- التنبيهات : يحتوي هذا القسم الموجود أعلى اليسار على قائمة بأحداث "التنبيه" التي اكتشفها مصحح الأخطاء في بيانات تصحيح الأخطاء من برنامج TensorFlow المُجهز. يشير كل تنبيه إلى حالة شاذة معينة تستدعي الانتباه. في حالتنا ، يسلط هذا القسم الضوء على أحداث 499 NaN / بلون وردي أحمر بارز. هذا يؤكد شكوكنا في أن النموذج يفشل في التعلم بسبب وجود NaNs و / أو اللانهايات في قيم موتره الداخلية. سوف نتعمق في هذه التنبيهات قريبًا.
- المخطط الزمني لتنفيذ Python : هذا هو النصف العلوي من القسم العلوي الأوسط. يقدم التاريخ الكامل للتنفيذ المتلهف للعمليات والرسوم البيانية. يتم تمييز كل مربع في الخط الزمني بالحرف الأولي من المرجع أو اسم الرسم البياني (على سبيل المثال ، "T" لـ "TensorSliceDataset" المرجع ، "m"
tf.function"النموذج"). يمكننا التنقل في هذا المخطط الزمني باستخدام أزرار التنقل وشريط التمرير أعلى الخط الزمني. - تنفيذ الرسم البياني : يقع هذا القسم في الزاوية العلوية اليمنى من واجهة المستخدم الرسومية ، وسيكون هذا القسم مركزيًا لمهمة تصحيح الأخطاء لدينا. يحتوي على تاريخ لجميع الموترات العائمة من النوع dtype المحسوبة داخل الرسوم البيانية (على سبيل المثال ، تم تجميعها بواسطة
@tf-functions). - بنية الرسم البياني (النصف السفلي من القسم العلوي الأوسط) ، وكود المصدر (القسم السفلي الأيسر) ، وتتبع المكدس (القسم السفلي الأيمن) فارغة في البداية. سيتم ملء محتوياتها عندما نتفاعل مع واجهة المستخدم الرسومية. ستلعب هذه الأقسام الثلاثة أيضًا أدوارًا مهمة في مهمة تصحيح الأخطاء.
بعد أن وجهنا أنفسنا إلى تنظيم واجهة المستخدم ، دعنا نتخذ الخطوات التالية لمعرفة سبب ظهور NaNs. أولاً ، انقر فوق تنبيه NaN / ∞ في قسم التنبيهات. يقوم هذا تلقائيًا بالتمرير إلى قائمة 600 موتر للرسم البياني في قسم تنفيذ الرسم البياني ويركز على # 88 ، وهو موتر يسمى Log:0 تم إنشاؤه بواسطة Log (اللوغاريتم الطبيعي) المرجع. يبرز اللون الوردي والأحمر البارز عنصر a-من بين 1000 عنصر من موتر 2D float32. هذا هو الموتر الأول في سجل وقت تشغيل برنامج TF2 الذي يحتوي على أي NaN أو ما لا نهاية: الموترات المحسوبة قبل أن لا تحتوي على NaN أو ∞ ؛ تحتوي العديد من الموترات (في الواقع ، معظم) المحسوبة بعد ذلك على NaNs. يمكننا تأكيد ذلك بالتمرير لأعلى ولأسفل في قائمة تنفيذ الرسم البياني. توفر هذه الملاحظة تلميحًا قويًا إلى أن Log op هو مصدر عدم الاستقرار العددي في برنامج TF2 هذا.

لماذا يقوم هذا Log بصق؟ تتطلب الإجابة على هذا السؤال فحص المدخلات في المرجع. يؤدي النقر فوق اسم الموتر ( Log:0 ) إلى عرض مرئي بسيط ولكنه غني بالمعلومات حول منطقة Log op في الرسم البياني TensorFlow الخاص به في قسم بنية الرسم البياني. لاحظ الاتجاه من أعلى إلى أسفل لتدفق المعلومات. يظهر المرجع نفسه بالخط العريض في المنتصف. فوقه مباشرة ، يمكننا أن نرى العنصر النائب الذي يوفر الإدخال الوحيد إلى مرجع Log . أين الموتر الذي تم إنشاؤه بواسطة هذا probs النائب في قائمة تنفيذ الرسم البياني؟ باستخدام لون الخلفية الأصفر كوسيلة مساعدة بصرية ، يمكننا أن نرى أن probs:0 موتر هو ثلاثة صفوف فوق Log:0 موتر ، أي في الصف 85.

نظرة أكثر تفصيلاً على الانهيار العددي للمسببات: يكشف موتر probs:0 في الصف 85 سبب قيام المستهلك بتسجيل Log:0 ينتج a-: من بين 1000 عنصر من probs:0 ، عنصر واحد له قيمة 0. The-هو نتيجة لحساب اللوغاريتم الطبيعي لـ 0! إذا تمكنا بطريقة ما من التأكد من أن Log يتعرض للمدخلات الإيجابية فقط ، فسنكون قادرين على منع حدوث NaN /. يمكن تحقيق ذلك عن طريق تطبيق القص (على سبيل المثال ، باستخدام tf.clip_by_value() ) على موتر probs العنصر النائب.
نحن نقترب من حل الخطأ ، لكن لم ننتهي تمامًا بعد. من أجل تطبيق الإصلاح ، نحتاج إلى معرفة مكان نشأة Log وإدخال العنصر النائب في كود مصدر Python. يوفر المصحح V2 دعمًا من الدرجة الأولى لتتبع عمليات الرسم البياني وأحداث التنفيذ إلى مصدرها. عندما نقرنا على Log:0 tensor في Graph Executions ، تمت تعبئة قسم Stack Trace بتتبع المكدس الأصلي لإنشاء Log العمليات. يعد تتبع المكدس كبيرًا إلى حد ما لأنه يتضمن العديد من الإطارات من الكود الداخلي لـ TensorFlow (على سبيل المثال ، gen_math_ops.py و dumping_callback.py) ، والتي يمكننا تجاهلها بأمان لمعظم مهام التصحيح. إطار الاهتمام هو سطر 216 من debug_mnist_v2.py (على سبيل المثال ، ملف Python الذي نحاول تصحيحه بالفعل). يؤدي النقر على "سطر 216" إلى إظهار عرض لسطر الشفرة المقابل في قسم شفرة المصدر.

يقودنا هذا أخيرًا إلى الكود المصدري الذي أنشأ مرجع Log الإشكالي من مدخلات probs الخاصة به. هذه هي وظيفة فقدان الانتروبيا الفئوية المخصصة لدينا والمزينة بوظيفة @tf.function ومن ثم يتم تحويلها إلى رسم بياني TensorFlow. تتوافق probs Placeholder op مع وسيطة الإدخال الأولى لوظيفة الخسارة. يتم إنشاء مرجع Log باستدعاء tf.math.log () API.
سيبدو إصلاح قص القيمة لهذا الخطأ كما يلي:
diff = -(labels *
tf.math.log(tf.clip_by_value(probs), 1e-6, 1.))
سوف يحل عدم الاستقرار العددي في برنامج TF2 هذا ويتسبب في تدريب MLP بنجاح. هناك طريقة أخرى محتملة لإصلاح عدم الاستقرار العددي وهي استخدام tf.keras.losses.CategoricalCrossentropy .
هذا يختتم رحلتنا من مراقبة خطأ نموذج TF2 إلى الخروج بتغيير رمز يعمل على إصلاح الخطأ ، بمساعدة أداة Debugger V2 ، التي توفر رؤية كاملة لسجل التنفيذ الشغوف والرسم البياني لبرنامج TF2 المُجهز ، بما في ذلك الملخصات العددية من قيم الموتر والارتباط بين العمليات والموتر ورمز المصدر الأصلي.
توافق الأجهزة لـ Debugger V2
يدعم المصحح V2 أجهزة التدريب السائدة بما في ذلك وحدة المعالجة المركزية ووحدة معالجة الرسومات. يتم أيضًا دعم التدريب على وحدات معالجة الرسومات المتعددة باستخدام tf.distributed.MirroredStrategy . لا يزال دعم TPU في مرحلة مبكرة ويتطلب الاتصال
tf.config.set_soft_device_placement(True)
قبل استدعاء enable_dump_debug_info() . قد يكون لها قيود أخرى على TPUs أيضًا. إذا واجهت مشاكل في استخدام Debugger V2 ، فالرجاء الإبلاغ عن الأخطاء على صفحة مشكلات GitHub .
توافق API لـ Debugger V2
يتم تنفيذ Debugger V2 على مستوى منخفض نسبيًا من مكدس برامج TensorFlow ، وبالتالي فهو متوافق مع tf.keras و tf.data وواجهات برمجة التطبيقات الأخرى المبنية على أعلى المستويات الدنيا لـ TensorFlow. المصحح V2 متوافق أيضًا مع الإصدارات السابقة مع TF1 ، على الرغم من أن المخطط الزمني للتنفيذ الحرصي سيكون فارغًا لسجلات تصحيح الأخطاء التي تم إنشاؤها بواسطة برامج TF1.
نصائح استخدام API
أحد الأسئلة المتداولة حول تصحيح الأخطاء API هذا هو المكان الذي يجب أن يقوم فيه المرء في كود TensorFlow بإدخال الاستدعاء إلى enable_dump_debug_info() . عادةً ، يجب استدعاء API في أقرب وقت ممكن في برنامج TF2 الخاص بك ، ويفضل أن يكون ذلك بعد خطوط استيراد Python وقبل بدء إنشاء الرسم البياني وتنفيذه. سيضمن ذلك التغطية الكاملة لجميع العمليات والرسوم البيانية التي تدعم نموذجك وتدريبه.
tensor_debug_modes المدعومة حاليًا هي: NO_TENSOR و CURT_HEALTH و CONCISE_HEALTH و FULL_HEALTH و SHAPE . وهي تختلف في مقدار المعلومات المستخرجة من كل موتر وأعباء الأداء للبرنامج الذي تم تصحيحه. يرجى الرجوع إلى قسم args من enable_dump_debug_info() .
حمل الأداء
تقدم واجهة برمجة التطبيقات (API) لتصحيح الأخطاء عبء الأداء إلى برنامج TensorFlow المُجهز. يختلف مقدار الحمل حسب tensor_debug_mode ونوع الجهاز وطبيعة برنامج TensorFlow المُجهز. كنقطة مرجعية ، في وحدة معالجة الرسومات ، يضيف وضع NO_TENSOR زيادة بنسبة 15٪ أثناء تدريب نموذج Transformer تحت حجم الدُفعة 64. النسبة المئوية لأوضاع tensor_debug_modes الأخرى أعلى: حوالي 50٪ لـ CURT_HEALTH و CONCISE_HEALTH و FULL_HEALTH و SHAPE أساليب. في وحدات المعالجة المركزية (CPU) ، يكون الحمل أقل قليلاً. على TPUs ، النفقات العامة أعلى حاليًا.
العلاقة مع واجهات برمجة تطبيقات تصحيح أخطاء TensorFlow الأخرى
لاحظ أن TensorFlow يقدم أدوات وواجهات برمجة تطبيقات أخرى لتصحيح الأخطاء. يمكنك تصفح واجهات برمجة التطبيقات هذه ضمن مساحة الاسم tf.debugging.* في صفحة مستندات API. من بين واجهات برمجة التطبيقات (API) الأكثر استخدامًا هو tf.print() . متى يجب استخدام Debugger V2 ومتى يجب tf.print() بدلاً من ذلك؟ tf.print() مناسب في حالة مكان
- نحن نعلم بالضبط ما هي الموترات التي يجب طباعتها ،
- نحن نعلم بالضبط مكان إدراج
tf.print()في الكود المصدري ، - عدد هذه الموترات ليس كبيرا جدا.
بالنسبة للحالات الأخرى (على سبيل المثال ، فحص العديد من قيم الموتر ، وفحص قيم الموتر الناتجة عن الكود الداخلي لـ TensorFlow ، والبحث عن أصل عدم الاستقرار العددي كما أوضحنا أعلاه) ، يوفر Debugger V2 طريقة أسرع لتصحيح الأخطاء. بالإضافة إلى ذلك ، يوفر Debugger V2 نهجًا موحدًا لفحص موترات الرسم البياني والمتحمسة. يوفر بالإضافة إلى ذلك معلومات حول بنية الرسم البياني ومواقع الكود ، والتي تتجاوز قدرة tf.print() .
واجهة برمجة تطبيقات أخرى يمكن استخدامها لتصحيح المشكلات التي تتضمن ∞ و NaN هي tf.debugging.enable_check_numerics() . على عكس enable_dump_debug_info() ، لا يقوم enable_check_numerics() بحفظ معلومات التصحيح على القرص. بدلاً من ذلك ، يقوم فقط بمراقبة ∞ و NaN أثناء وقت تشغيل TensorFlow والأخطاء في موقع رمز الأصل بمجرد أن يولد أي مرجع مثل هذه القيم الرقمية السيئة. يحتوي على أداء أقل مقارنةً بـ enable_dump_debug_info() ، لكنه لا يوفر تتبعًا كاملاً لمحفوظات تنفيذ البرنامج ولا يأتي بواجهة مستخدم رسومية مثل Debugger V2.