لماذا ينام معالج GPU أثناء تشغيل النماذج الضخمة؟ وكيف أيقظته Hugging Face

تشغيل نموذج لغة كبير (LLM) على خوادم السحابة قد يكلف نحو 120 دولاراً في اليوم لبطاقة H200 واحدة. أي مهندس أو باحث يستأجر هذه الموارد يريد استغلال كل قرش يدفعه. لكن المفاجأة: معالج GPU يقضي حوالي ربع وقته في حالة ‘انتظار’، لا يعمل شيئاً مفيداً. هذه المشكلة ليست في النموذج نفسه، بل في طريقة التنسيق التقليدية بين CPU وGPU أثناء عملية الاستدلال (inference). فريق Hugging Face نشر مؤخراً شرحاً تقنياً وتنفيذاً عملياً لحل هذه المشكلة عبر ما يسمى ‘المباعدة غير المتزامنة’ (asynchronous batching)، وهو أسلوب يسمح بتشغيل CPU وGPU بالتوازي لتحقيق تسريع مجاني يصل إلى 24%.

من أين يأتي وقت الخمول؟

في الطريقة المعتادة (synchronous batching)، يعمل الـ CPU والـ GPU بالتناوب: يقوم CPU بتجهيز الدفعة التالية من الطلبات وتحديث جداول الذاكرة، ثم ينقل البيانات إلى GPU. GPU ينفذ الحسابات ويولّد الرموز الجديدة، ويعيد النتائج إلى CPU. خلال هذه الدورة، لا يعمل الطرفان معاً أبداً. في التجربة التي أجراها الفريق على نموذج بحجم 8 مليارات معامل وبحجم دفعة 32، استغرق توليد 8 آلاف رمز (token) 300.6 ثانية، منها 24% كان GPU خاملاً ينتظر CPU. لو قُضي على هذا الخمول، لانخفض الزمن إلى 228 ثانية فقط – دون أي تغيير في النموذج أو kernel.

الفكرة: فك الارتباط بين المهام

الحل بسيط نظرياً: ابدأ بتحضير الدفعة (N+1) بينما الدفعة N قيد التنفيذ على GPU. لكن التطبيق يتطلب إجابات عن أسئلة تقنية مثل: كيف يمكن تشغيل مهمة على GPU ثم استرجاع السيطرة فوراً إلى CPU؟ كيف نضمن أن البيانات جاهزة لكل مهمة في الوقت المناسب؟ الإجابة تكمن في استخدام CUDA streams. CUDA stream هي قائمة انتظار منظمة من العمليات (نقل بيانات، حسابات kernel، مزامنة) تنفَّذ بالترتيب داخل نفس الدفق، لكن الأقسام المختلفة (streams) يمكن أن تعمل بالتوازي. بفصل عمليات CPU وعمليات GPU إلى مسارات مختلفة، يصبح من الممكن أن يجهز CPU الدفعة التالية بينما GPU مشغول بالدفعة الحالية.

التنفيذ العملي في مكتبة transformers

طبق فريق Hugging Face هذا الأسلوب في مكتبة transformers ضمن وحدة التجميع المستمر (continuous batching). تمت إضافة آليات لاستباق تحضير الدفعات وتحرير GPU من التوقف عند الانتهاء من كل خطوة. النتيجة: لا حاجة لتعديل النموذج أو kernels؛ فقط إعادة تنظيم تدفق العمل بين المعالجين. ولا تزال هناك تفاصيل حول كيفية التعامل مع KV cache و FlashAttention، لكن الفكرة الأساسية أثبتت فعاليتها.

ماذا يعني هذا للمستخدم العربي؟

إذا كنت تدير خادم استدلال (inference server) على Inference Endpoints أو منصات سحابية أخرى، فهذه التحديثات تترجم مباشرةً إلى تخفيض في التكاليف أو زيادة في الإنتاجية. يمكنك خدمة عدد أكبر من المستخدمين بنفس بطاقة GPU، أو استخدام بطاقة أقل تكلفة لنفس الحمولة. الأهم أن التحسين يأتي ‘مجاناً’ بعد تثبيت أحدث إصدار من transformers وتفعيل الوضع غير المتزامن في إعدادات التوليد.

ما زال هناك مجال للمتابعة

المقال المنشور هو الثاني في سلسلة عن كفاءة استدلال LLM، بعد مقال سابق عن التجميع المستمر الأساسي. من المتوقع أن تستمر الأبحاث في تحسين تزامن الأجهزة، وقد نشهد قريباً تطبيقات لهذه التقنية على نماذج أكبر وأنظمة متعددة GPUs. للمطورين المهتمين، يمكن الاطلاع على كود التنفيذ الكامل والتعمق في تفاصيل CUDA streams و FlashAttention من الروابط أدناه.

التطبيقات والروابط الرسمية

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

روابط مذكورة في المصدر

المصدر: Hugging Face Blog