نظرة شاملة على أدوات FX المستخدمة بواسطة Meta: تحسين نماذج PyTorch باستخدام تحويل الرسم البياني

يعد وضع الرسم البياني في PyTorch أكثر أداءً. تقدم هذه المقالة Torch.FX، وهي أداة قوية يمكنها التقاط وتحسين الرسم البياني لبرامج PyTorch.
1. المقدمة
يدعم PyTorch وضعين للتنفيذ: الوضع المتلهف ووضع الرسم البياني.
في الوضع الحريص، يتم تنفيذ المشغلات في النموذج فورًا عند قراءتها. من السهل استخدامه وأكثر ودية لممارسي التعلم الآلي، لذلك تم تعيينه كوضع التنفيذ الافتراضي.
في وضع الرسم البياني، يتم تجميع المشغلات أولاً في رسم بياني ثم تجميعها وتنفيذها ككل. إنه يتمتع بأداء أعلى وبالتالي يتم استخدامه على نطاق واسع في الإنتاج الفعلي.
على وجه التحديد، يدعم وضع الرسم البياني دمج المشغل. من خلال دمج مشغلين، يمكن تقليل إجمالي النفقات العامة لقراءات الذاكرة وإطلاق النواة أو توطينها.
الاندماج يمكن أن يكون أفقيا:يقوم بتنفيذ عملية واحدة (مثل BatchNorm) يتم تطبيقها على عدة متغيرات ودمجها في مصفوفة واحدة.
يمكن أن يكون الاندماج عموديًا أيضًا:دمج نواة مع نواة أخرى تتطلب إخراج النواة الأولى (مثل ReLU متبوعًا بالالتفاف).
Torch.FX (المختصر باسم FX) عبارة عن مجموعة أدوات متاحة للجمهور تدعم تنفيذ وضع الرسم البياني كجزء من حزمة PyTorch. يمكن:
1. احصل على الرسم البياني من برنامج PyTorch
2. السماح للمطورين بكتابة التحويلات على الرسم البياني الذي تم الحصول عليه
لقد استخدمت Meta في السابق FX لتحسين معدل إنتاج التدريب لنماذج الإنتاج. ستقدم هذه المقالة التحسين القائم على FX والذي طورته Meta لإظهار كيفية تحسين أداء نماذج PyTorch المنشورة باستخدام تحويل الرسم البياني.
الثاني خلفية
تُستخدم جداول التضمين على نطاق واسع في أنظمة التوصية.سيقدم هذا القسم المعرفة الأساسية حول FX وجدول التضمين.
2.1. FX
الشكل 1 هو مثال بسيط يوضح كيفية تحويل برنامج PyTorch باستخدام FX.تتكون من ثلاث خطوات:
- احصل على الرسم البياني من البرنامج
- تعديل الرسم البياني (في هذه الحالة، نستخدم GELU بدلاً من RELU)
- إنشاء برنامج جديد من الرسم البياني المعدل

توفر واجهة برمجة التطبيقات FX العديد من الوظائف الأخرى لفحص وتحويل الرسوم البيانية لبرنامج PyTorch.
2.2. جدول التضمين

في نظام التوصية،يتم تمثيل الميزات المتفرقة (على سبيل المثال، معرف المستخدم، ومعرف القصة) بواسطة جدول تضمين.
جدول التضمين E عبارة عن مصفوفة HxD، حيث H هو حجم التجزئة وD هو بُعد متجه التضمين. كل صف من E هو متجه من الأرقام العشرية العائمة.
تتمثل وظيفة التجزئة المميزة في تعيين ميزة متفرقة إلى قائمة فهرس E، مثل [S1، S2، …، Sk]، حيث 0 ≤ Si
للاستفادة الكاملة من وحدة معالجة الرسوميات، تتم معالجة الميزات المتفرقة عادةً على دفعات.كل كيان في الدفعة لديه قائمة خاصة به من الفهارس. إذا كانت الدفعة تحتوي على كيانات B، فيمكن فهمها ببساطة على أنها تمثيل يحتوي على قوائم فهرس B.
سيكون التمثيل الأكثر صرامة هو دمج قوائم الفهرس B في قائمة فهرس واحدة وإضافة قائمة بأطوال الفهرس (واحدة لكل كيان في الدفعة).
على سبيل المثال، إذا كانت الدفعة تحتوي على 3 كيانات، فإن قائمة الفهارس الخاصة بها تكون على النحو التالي:
- الكيان 1: المؤشرات = [10، 20]
- الكيان 2: المؤشرات = [5، 9، 77، 81]
- الكيان 3: المؤشرات = [15، 20، 45]
ثم سيكون مؤشر وطول حجم الدفعة الكامل هو:
- المؤشرات = [10، 20، 5، 9، 77، 81، 15، 20، 45]
- الأطوال = [2، 4، 3]
إن مخرجات استعلام جدول التضمين للدفعة بأكملها عبارة عن مصفوفة BxD.
3. 3 تحويلات FX
لقد قامت PyTorch بتحديث ثلاثة تحويلات FX لتسريع الوصول إلى جدول التضمين، والتي سيتم تقديمها واحدة تلو الأخرى في هذا القسم.
فيما يلي 3.1 حول تحويل الجمع بين عدة موترات إدخال صغيرة في موتر واحد كبير؛ 3.2 حول تحويل دمج سلاسل الحوسبة المتوازية المتعددة إلى سلسلة حوسبة واحدة؛ و3.3 حول التحول في الاتصالات والحوسبة المتداخلة.
3.1 دمج ميزات الإدخال المتفرقة
يمكن تمثيل كل ميزة إدخال متفرقة في دفعة ما على هيئة قائمتين: قائمة فهرس وقائمة طول B، حيث يمثل B حجم الدفعة.
في PyTorch، يمكن أن توجد كلتا القائمتين كموترات.عندما يتم تشغيل نموذج PyTorch على وحدة معالجة الرسوميات (GPU)، يتم عادةً تخزين جدول التضمين في ذاكرة وحدة معالجة الرسوميات (GPU) (وهي أقرب إلى وحدة معالجة الرسوميات وتتمتع بنطاق ترددي أعلى للقراءة والكتابة من ذاكرة وحدة المعالجة المركزية).
عندما تكون هناك حاجة لاستخدام ميزات الإدخال المتفرقة، يجب نسخ كلا الموترين من وحدة المعالجة المركزية إلى وحدة معالجة الرسومات أولاً. ومع ذلك، تتطلب كل نسخة من ذاكرة المضيف إلى الجهاز تشغيل نواة، وهو ما يستغرق وقتًا أطول من نقل البيانات الفعلي.
إذا كان النموذج يستخدم العديد من ميزات الإدخال المتفرقة، فقد يصبح هذا النسخ عنق زجاجة للأداء (على سبيل المثال، ستتطلب 1000 ميزة إدخال متفرقة نسخ 2000 موتر من المضيف إلى الجهاز).
أحد التحسينات لتقليل عدد memcpys من المضيف إلى الجهاز هو الجمع بين ميزات الإدخال المتفرقة المتعددة قبل إرسالها إلى الجهاز.
على سبيل المثال، نظراً لميزات الإدخال الثلاثة التالية:
- Feature_A: المؤشرات = [106، 211، 7]، الأطوال = [2، 1]
- Feature_B: المؤشرات = [52، 498، 616، 870، 1013]، الأطوال = [3، 2]
- Feature_C: المؤشرات = [2011، 19، 351، 790]، الأطوال = [1، 3]
الشكل المركب هو:
الميزات_A_B_C: المؤشرات = [106، 211، 7، 52، 498، 616، 870، 1013، 2011، 19، 351، 790]، الأطوال = [2، 1، 3، 2، 1، 3]
لذلك بدلاً من نسخ 3×2=6 موتر من المضيف إلى الجهاز، يلزم نسخ موترين فقط.
يوضح الشكل 3 (ب) تنفيذ هذا التحسين، والذي يتكون من عنصرين:
- جانب وحدة المعالجة المركزية:تم تعديل خط أنابيب الإدخال لدمج مؤشرات جميع الميزات المتفرقة في موتر واحد وجميع الأطوال في موتر آخر. يتم بعد ذلك نسخ هذين الموترين إلى وحدة معالجة الرسوميات.
- جانب وحدة معالجة الرسوميات:باستخدام FX، قم بإدراج عامل Permute_and_Split في الرسم البياني للنموذج لاستعادة مؤشرات الميزات الفردية وموترات الطول من الموترات المدمجة وإرسالها إلى العقد المقابلة في اتجاه مجرى النهر.


3.2 الاندماج الأفقي لسلاسل الحوسبة بدءًا من الوصول إلى جدول التضمين
في نموذج الإنتاج، من الشائع أن يكون هناك 10 جداول تضمين لكل وحدة معالجة رسومية. لأسباب تتعلق بالأداء،يتم تجميع الاستعلامات الخاصة بهذه الجداول معًا بحيث يتم دمج مخرجاتها في موتر واحد كبير.(انظر الجزء الأحمر في الشكل 4(أ)).
لحساب مخرجات ميزة واحدة،استخدم عامل التقسيم لتقسيم موتر كبير إلى N موتر صغير(حيث N هو عدد الميزات) ثم يتم تطبيق الحساب المطلوب على كل موتر.
كما هو موضح في الشكل 4 (أ)، فإن الحساب المطبق على كل مخرجات الميزة O هو Tanh(LayerNorm(O)). يتم تجميع جميع نتائج الحساب في موتر كبير ثم تمريرها إلى المشغل التالي (Op1 في الشكل 4 (أ)).
التكلفة الأساسية لوقت التشغيل هنا هي تكلفة تشغيل نواة وحدة معالجة الرسوميات.على سبيل المثال، عدد عمليات إطلاق نواة وحدة معالجة الرسوميات في الشكل 4(أ) هو 2*N+3 (كل شكل بيضاوي في الشكل يمثل نواة وحدة معالجة الرسوميات). يؤثر هذا على الأداء نظرًا لأن وقت تنفيذ LayerNorm وTanh على وحدة معالجة الرسوميات قصير جدًا مقارنة بوقت تشغيل النواة.
بالإضافة إلى ذلك، قد يقوم عامل التقسيم بإنشاء نسخة إضافية من موتر إخراج متجه التضمين، مما يستهلك ذاكرة وحدة معالجة الرسوميات الإضافية.
إن استخدام FX لتنفيذ تحسين يسمى الاندماج الأفقي يمكن أن يقلل بشكل كبير من عدد عمليات تشغيل نواة وحدة معالجة الرسومات(في هذا المثال، عدد عمليات تشغيل نواة وحدة معالجة الرسوميات بعد التحسين هو 5، انظر الشكل 4(ب)).
استخدم عامل Add_middle_dim بدلاً من التقسيم الصريح لإعادة تشكيل موتر التضمين ثنائي الأبعاد للشكل (B، NxD) إلى موتر ثلاثي الأبعاد للشكل (B، N، D). بعد ذلك يتم تطبيق LayerNorm واحد على البعد الأخير. يتم تطبيق Tanh على نتيجة LayerNorm. أخيرًا، يتم استخدام عامل Remove_middle_dim لاستعادة نتيجة Tanh إلى موتر ثنائي الأبعاد.
نظرًا لأن Add_middle_dim وRemove_middle_dim يقومان فقط بإعادة تشكيل الموتر،لا يتم إنشاء نسخ إضافية، وبالتالي يمكن أيضًا تقليل استهلاك ذاكرة وحدة معالجة الرسومات.


3.3 التداخل بين الحوسبة والاتصالات
يتم عادةً تدريب نماذج التوصية للإنتاج على أنظمة وحدة معالجة الرسوميات الموزعة.نظرًا لأن سعة ذاكرة الجهاز لكل وحدة معالجة رسومية ليست كافية لحمل جميع جداول التضمين في النموذج، فيجب توزيعها عبر وحدات معالجة رسومية متعددة.
أثناء خطوة التدريب، تحتاج وحدة معالجة الرسومات إلى قراءة/كتابة قيم الميزات من جدول التضمين على وحدات معالجة الرسومات الأخرى.يُطلق على هذا الأمر اسم التواصل الشامل للجميع، ويمكن أن يشكل عقوبة كبيرة على الأداء.
من خلال تنفيذ التحويل من خلال FX، من الممكن تداخل الحساب مع الاتصالات الشاملة للجميع.يوضح الشكل 5(أ) مثالاً لرسم بياني نموذجي مع إمكانية الوصول إلى جدول متجه التضمين (EmbeddingAllToAll) ومشغلات أخرى. كما هو موضح في الشكل 5 (ب)، بدون أي تحسين، يتم تنفيذها بشكل متسلسل على تيار وحدة معالجة الرسوميات (GPU) واحد.
استخدم FX لتقسيم EmbeddingAllToAll إلى EmbeddingAllToAll_Request وEmbeddingAllToAll_Wait، وترتيب المشغلين المستقلين بينهما.

3.4 الملخص

لاكتشاف النماذج التي قد تستفيد من هذه التحولات، قام المطورون بتحليل بيانات الأداء التي تم جمعها بواسطة MAIProf للنماذج التي تعمل في مركز البيانات الوصفي.نُظهِر أن هذه التحولات تحقق تسريعًا بمقدار 2-3 مرات على مجموعة من نماذج الإنتاج مقارنةً بالوضع الحريص.
الرابع خاتمة
من منظور الأداء، يُفضل وضع الرسم البياني في PyTorch على الوضع المتحمّس المستخدم في بيئات الإنتاج. FX هي أداة قوية لالتقاط وتحسين الرسوم البيانية لبرنامج PyTorch. تقدم هذه المقالة ثلاثة تحويلات FX لتحسين نماذج توصية الإنتاج داخل Meta.
أخيرًا، آمل أن يتمكن المزيد من مطوري PyTorch من استخدام تحويل الرسم البياني لتحسين أداء النموذج.
—— نهاية ——