محتويات الدورة

PyTorch / التخزين والاسترجاع والتنفيذ المحول / الدرس 13

العروض والتجاور والتعديلات الموضعية

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

وقت القراءة التقريبي: 5 دقيقةتاريخ مراجعة المحتوى
في هذه الصفحة

أهداف الدرس

  • قراءة الشكل وخطوات التخزين كوصفين مختلفين.
  • تمييز العروض والنسخ المحتملة وclone وdetach.
  • شرح كيف يبطل تعديل موضعي حساب الانتشار العكسي.

لا يحدد الشكل وحده اجتياز التخزين

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

يتبع سلوك النسخ العملية المختارة

ينقل البرنامج التوضيحي موتر float64 على CPU ويستدعي contiguous على العرض غير المتجاور قبل تغيير الأصل. يرى العرض تسعة وتسعين لأنه يشارك التخزين؛ وتحتفظ النسخة المادية بصفر. قد تعيد contiguous الموتر القائم عندما يتحقق شرطها أصلاً؛ فلا يعني المثال أن كل استدعاء ينشئ تخزيناً مستقلاً. تحتاج عملية view علاقة متوافقة بين الشكل وخطوات التخزين. قد تعيد reshape وflatten عرضاً أو نسخة وفق الشروط الموثقة؛ وينبغي ألا تعتمد الشيفرة على نتيجة ملكية غير مضمونة.

python برنامج توضيحي للمعالج المركزي وفق وثائق PyTorch 2.14؛ لم تتوفر torch والخرج المتوقع مشتق
import torch
x = torch.arange(6,dtype=torch.float64,device="cpu").reshape(2,3)
transposed = x.t()
owned = transposed.contiguous()
x[0,0] = 99.0
print("strides", x.stride(), transposed.stride())
print("first values", transposed[0,0].item(), owned[0,0].item())
print("contiguous", transposed.is_contiguous(), owned.is_contiguous())
الناتج المتوقع
strides (3, 1) (1, 3)
first values 99.0 0.0
contiguous False True

يشارك العرض المنقول التخزين، بينما تنسخ contiguous هذا المدخل غير المتجاور. لا تتطلب الموترات تدرجات؛ ولم ينفذ تخطيط موتر أو تعديل في torch.

تاريخ التدرج واستقلال التخزين سؤالان منفصلان

تنشئ clone بيانات موتر منسوخة مع حفظ علاقة قابلة للتفاضل عادة عندما يتطلبها وضع التدرج والمدخل. توقف detach علاقة autograd لكنها تشارك المصدر تخزينه. لذلك ليس الموتر المفصول لقطة مستقلة يمكن تعديلها دون ضرر تلقائياً. قد تحتاج قيمة منفصلة ومستقلة مقصودة العمليتين، مثل detach().clone()، وفق غرض صريح. يوضح مرافق القوائم ملكية التخزين فقط ولا يعيد دلالات التدرج هذه. اختر النسخ للملكية والتحكم بالتدرج للاشتقاق، ولا تستخدم أي المصطلحين بديلاً عن الآخر.

python مثال مرافق حتمي بالمكتبة القياسية نُفذ فعلياً
storage = [float(x) for x in range(6)]
def transpose_row(i):
    return [storage[i+j*3] for j in range(2)]
owned = [transpose_row(i) for i in range(3)]
storage[0] = 99.0
print("shared first row", transpose_row(0))
print("copied first row", owned[0])
print("transpose offsets", [[i+j*3 for j in range(2)] for i in range(3)])
الناتج المتوقع
shared first row [99.0, 3.0]
copied first row [0.0, 3.0]
transpose offsets [[0, 3], [1, 4], [2, 5]]

يوضح نموذج إزاحات القوائم المنفذ مشاركة التخزين وملكيته. ولا ينفذ خطوات Tensor أو أهلية view أو عدادات إصدار الموتر أو فحوص autograd.

يتفاعل التعديل الموضعي مع قيم محفوظة للاشتقاق

قد تعدل عملية ينتهي اسمها بشرطة سفلية أو إسناد عبر فهرس تخزين موتر قائم. قد يحتاج autograd قيمة سابقة حفظت أثناء المرور الأمامي، ويمكن لتتبع إصدار الحالة كشف تغيرها قبل backward. للموترات الورقية التي تتطلب تدرجاً قيود موثقة أيضاً على التحديث الموضعي المتتبع. قد يلائم no-grad تحديثاً مخططاً على أسلوب المحسن، لكنه لا يصحح تعديلاً اعتباطياً بين الأمام والخلف. لا تسكت الخطأ بفصل كل شيء أو اختصارات تخزين خفية؛ حدد الحالة الرياضية التي يفترض أن تستخدمها المشتقة.

اختبر مشاركة التخزين عند الحد الذي يحتاجها

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

الأخطاء الشائعة وإصلاحها

تغيرت لقطة مفصولة عندما تغير مصدرها

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

افتُرض أن إعادة التشكيل تنسخ دائماً أو تشارك دائماً

لماذا يحدث؟
استُنتجت الملكية من اسم واجهة مريح.
كيف تصلحه؟
اختر العملية الموثقة واطلب النسخ صراحة عند الحاجة.
كيف تتجنب تكراره؟
احفظ مثالاً غير متجاور في فحوص الملكية.

فشل backward بعد الكتابة فوق قيمة وسيطة

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

اختبر فهمك

1. لماذا تصبح أول قيمة منقولة تسعة وتسعين بينما تحتفظ owned بصفر؟

اعرض الحل المشروح

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

2. لماذا لا تكفي detach وحدها للقطة تشخيص قابلة للتعديل مستقلاً؟

اعرض الحل المشروح

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

أهم ما تعلمته

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

المراجع الرسمية