كيفية إصلاح "خطأ وقت التشغيل: خطأ CUDA: تم تشغيل التأكيد من جانب الجهاز"

نشرت: 2025-10-14

إذا كنت تعمل مع نماذج التعلم العميق في PyTorch، فمن المحتمل أنك عثرت على رسالة خطأ محيرة مثل:

 RuntimeError: CUDA error: device-side assert triggered

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

ماذا يعني هذا الخطأ في الواقع؟

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

تشمل الأسباب الشائعة ما يلي:

  • أخطاء الفهرسة (على سبيل المثال، محاولة استخدام فهرس فئة غير موجود)
  • أشكال موتر غير صالحة
  • استخدام غير صحيح لوظيفة الخسارة
  • البيانات التي تكسر التوقعات (مثل الموترات الفارغة)

لحسن الحظ، باستخدام النهج الصحيح، يمكنك تعقب هذه المشكلة وحلها - دعنا نتعرف على كيفية القيام بذلك.

عملية خطوة بخطوة للتشخيص والإصلاح

1.قم بتشغيل النموذج الخاص بك على وحدة المعالجة المركزية

الخطوة التشخيصية الأولى هي تعطيل CUDA وتشغيل كل شيء على وحدة المعالجة المركزية. في كثير من الأحيان، عند تشغيل PyTorch على وحدة المعالجة المركزية، فإنه يوفر رسائل خطأ أكثر وضوحًا لأن التأكيدات من جانب الجهاز يتم طرحها الآن كاستثناءات Python مع سياق كامل.

للتبديل إلى وضع وحدة المعالجة المركزية، قم بتعديل التعليمات البرمجية الخاصة بك كما يلي:

 device = torch.device("cpu") model.to(device)

إذا فشل التأكيد، فيجب أن تحصل الآن على تتبع مكدس أكثر إفادة.

2. تحقق من تسمياتك المستهدفة

أحد الأسباب الأكثر شيوعًا لهذا الخطأ هو تسميات الفئات غير الصحيحة - خاصة عند استخدام nn.CrossEntropyLoss . تتوقع دالة الخسارة هذه أن يتضمن الموتر المستهدف مؤشرات الفئة بين 0 و num_classes - 1 . لذا، إذا كان النموذج الخاص بك يُخرج 10 فئات، فيجب أن تكون الأهداف أعدادًا صحيحة من 0 إلى 9.

خطأ شائع:

 # Target contains 10 instead of 0–9 range target = torch.tensor([10])

إذا كانت هذه المؤشرات خارج الحدود، فسوف تواجه تأكيدًا على وحدة معالجة الرسومات. للتحقق من صحة ذلك، استخدم:

 assert target.max().item() < num_classes

إذا كنت تقوم بتصنيف الصور، فتأكد أيضًا من أن شكل هدفك مناسب. بالنسبة لـ CrossEntropyLoss ، يجب أن يكون بالشكل [batch_size] ، وليس مشفرًا بشكل ساخن!

 # Incorrect (for CrossEntropyLoss) target = torch.tensor([[0, 0, 1], [1, 0, 0]]) # Correct target = torch.tensor([2, 0])

3. افحص DataLoader بحثًا عن الأخطاء

في بعض الأحيان يأتي الخطأ من مجموعة البيانات أو DataLoader، خاصة عند استخدامه في التدريب المجمع. إذا كانت بعض التسميات تالفة أو غير متناسقة، فقد يؤدي ذلك إلى تعطل النموذج الخاص بك على وحدة معالجة الرسومات.

تحقق مرة أخرى من مجموعة البيانات الخاصة بك مثل هذا:

 for i, (x, y) in enumerate(loader): assert y.dtype == torch.long assert y.max().item() < num_classes assert x.shape[0] == y.shape[0]

يعد هذا مفيدًا بشكل خاص إذا تم إنشاء مجموعة البيانات الخاصة بك من ملف CSV أو منطق معالجة مخصص قد يقدم تسميات غير صالحة بصمت.

مطور استبطاني، فحص التعليمات البرمجية، الكمبيوتر المحمول، تصحيح الأخطاء

المزالق الشائعة الأخرى

4. أحجام الدفعات غير متطابقة

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

 # torchvision models usually expect [N, 3, 224, 224] assert inputs.shape[1:] == (3, 224, 224)

وهذا مهم بشكل خاص عند استخدام DataLoader مع drop_last=False — قد تكون الدفعة الأخيرة أصغر اعتمادًا على حجم مجموعة البيانات الخاصة بك. يجب أن يتعامل نموذجك أو عملياتك مثل BatchNorm بشكل صحيح أو يتحقق بشكل صريح من وجود دفعات أصغر.

5. الموترات العرضية على الأجهزة المختلفة

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

تحقق دائمًا من خلال:

 assert inputs.device == model.device

نصيحة متقدمة: تمكين الإبلاغ الكامل عن الأخطاء

إذا لم يساعد التشغيل على وحدة المعالجة المركزية (CPU)، أو كنت تعمل في إعداد مختلط لوحدة المعالجة المركزية/وحدة معالجة الرسومات (CPU) ولا تزال لا تحصل على أخطاء مفيدة - فحاول الإعداد:

 CUDA_LAUNCH_BLOCKING=1 python my_script.py

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

في بايثون فقط، دون تعديل الصدفة:

 import os os.environ["CUDA_LAUNCH_BLOCKING"] = "1"

الآن يجب أن يقدم وقت التشغيل معلومات أكثر تحديدًا حول مكان حدوث تأكيد CUDA.

الإصلاح بالمثال

دعونا نلقي نظرة على مثال عملي. لنفترض أنك تقوم ببناء نموذج لتصنيف الأرقام على MNIST وحدد طبقة النموذج النهائية الخاصة بك على النحو التالي:

 self.fc = nn.Linear(128, 10)

في حلقة التدريب، لديك:

 criterion = nn.CrossEntropyLoss() output = model(images) # Output shape: [batch_size, 10] loss = criterion(output, labels)

لكن التسميات الخاصة بك هي مثل:

 labels = torch.tensor([[0], [1], [2]])

هذا الشكل غير صحيح. يتوقع CrossEntropyLoss التسميات كمتجه أحادي الأبعاد لمؤشرات الفئة:

 labels = torch.tensor([0, 1, 2])

إصلاح هذا الشكل وحده يمكن أن يحل المشكلة.

نموذج pytorch، وظيفة الخسارة، خطأ GPU، الإصلاح

ملخص: قائمة مرجعية لإصلاح الخطأ

قبل أن تبدأي في سحب شعرك، اتبعي القائمة التالية:

  1. قم بالتبديل إلى وضع وحدة المعالجة المركزيةوحاول مرة أخرى - قد تكون رسالة الخطأ أكثر وصفًا.
  2. التحقق من تسميات الفصل:تأكد من أنها ضمن النطاق الصالح والتنسيق الصحيح.
  3. افحص البيانات الواردة من DataLoader— قم بالتكرار عبر الدُفعات وتحقق من وجود حالات شاذة.
  4. التأكد من أشكال وأبعاد الموتر المناسبة، خاصة بالنسبة للمخرجات والأهداف.
  5. استخدم CUDA_LAUNCH_BLOCKING=1للحصول على تتبع تفصيلي ومتزامن من CUDA.

خاتمة

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

في المرة القادمة، بدلاً من الرد بالارتباك، ستكون مسلحًا بالمعرفة ومجموعة أدوات التشخيص. تصحيح الأخطاء سعيد!