Systems & Efficiency2023متقدم13 دقيقة قراءة
FlashAttention-2: انتباه أسرع بتوازٍ أفضل وتوزيع عمل أذكى
FlashAttention-2: Faster Attention with Better Parallelism and Work Partitioning
Dao, Tri — ICLR 2024
المشكلة
نجح في خفض استهلاك الذاكرة من تربيعي إلى خطّي وحقّق تسريعاً بمقدار 2‑4×، لكنه كان يستغلّ 25‑40% فقط من الطاقة الحسابية النظرية للمعالج الرسومي. في المقابل، عمليات ضرب المصفوفات المُحسَّنة (GEMM) تصل عادةً إلى 80‑90%. السبب في هذه الفجوة أمران: أولاً توزيع العمل بين كتل الخيوط والأشرطة لم يكن مثالياً، وثانياً وجود عمليات حسابية غير مصفوفية كانت تمنع نوى المُوتِّرات المتخصّصة من العمل بكامل كفاءتها.
الإسهام
ثلاث تحسينات مُوجَّهة تُضاعف معاً سرعة FlashAttention. الأولى: تعديلات خوارزمية تُقلّل العمليات غير المصفوفية عبر تأجيل تطبيع softmax إلى النهاية وتخزين قيمة logsumexp واحدة بدلاً من حفظ القيمة القصوى والمجموع كلٍّ على حدة. الثانية: توزيع الحلقة الخارجية على بُعد طول التسلسل حتى تبقى جميع وحدات المعالجة المتدفّقة مشغولة حتى مع الدُّفعات الصغيرة. الثالثة: التحوّل من تقسيم المفاتيح (split-K) إلى تقسيم الاستعلامات (split-Q) على مستوى الأشرطة داخل كل ، ما يُلغي تزامن الذاكرة المشتركة بين الأشرطة في .
الأثر
أصبح FlashAttention-2 نواة الانتباه المعتمدة فعلياً في نماذج اللغة الكبيرة وتشغيلها. بوصوله إلى 50‑73% من الطاقة النظرية للمعالج الرسومي، صار تدريب السياقات الطويلة (أكثر من 16 ألف رمز) مُجدياً اقتصادياً. أُدمج في PyTorch وHugging Face وفي كل إطار عمل رئيسي تقريباً لتدريب النماذج الكبيرة، وأثّرت أفكاره مباشرةً في FlashAttention-3 وFlash-Decoding وفي التوجّه الأوسع نحو تصميم خوارزميات واعية بالعتاد في التعلّم العميق.
تخيّل مطبخ مطعم وقت الذروة. FlashAttention الأصلي كان كطاهٍ ذكي اكتشف أنه يستطيع تحضير المكوّنات على دفعات صغيرة فوق سطح العمل الضيّق بدلاً من الذهاب والعودة إلى الثلاجة الكبيرة في كل مرة.
لكن المطبخ ظلّ بطيئاً، لأن المساعدين كانوا يتزاحمون على نافذة تسليم واحدة، وكل واحد ينتظر الآخر ليُنهي قبل أن يبدأ.
FlashAttention-2 يُعيد توزيع الأدوار: كل مساعد يأخذ محطّته الخاصة ويُعدّ أطباقه باستقلالية تامة — لا تسليم ولا انتظار. الوصفات نفسها والطعام نفسه، لكن المطبخ الآن يعمل بكامل طاقته تقريباً.
واقع العتاد: لماذا الذاكرة أهم من الحساب
المعالجات الرسومية الحديثة ليست مجرد آلات حساب سريعة — بل منظومات معقّدة ذات متعدّدة المستويات. في المستوى الأبعد تقع ذاكرة HBM: سعتها كبيرة (40‑80 غيغابايت في A100) لكنها أبطأ نسبياً (1.5‑2.0 تيرابايت/ثانية). أما على الشريحة نفسها فتوجد ذاكرة SRAM: حجمها ضئيل (192 كيلوبايت لكل وحدة معالجة متدفّقة) لكنها فائقة السرعة (نحو 19 تيرابايت/ثانية). فرق السرعة بينهما يبلغ 10 أضعاف تقريباً.
الفكرة المحورية في FlashAttention وFlashAttention-2 هي أن حساب مقيّد أساساً بنقل البيانات لا بالحساب ذاته. المعالج يُمضي معظم وقته في نقل البيانات بين HBM وSRAM، لا في إجراء العمليات الحسابية فعلياً. التنفيذ التقليدي يبني مصفوفة الانتباه الكاملة ومخرج softmax في ذاكرة HBM — أي أنه يقرأ ويكتب عنصر لتسلسل بطول . وحين يتجاوز قيمة 4096، يصبح نقل البيانات هو العائق الحقيقي لا الحساب.
المعالجات الرسومية تمتلك أيضاً مُصمَّمة خصيصاً لضرب المصفوفات. على A100 تُنجز هذه النوى 312 تيرا عملية/ثانية بنصف الدقة (FP16/BF16)، بينما الحساب العام بدقة FP32 لا يتجاوز 19.5 تيرا عملية/ثانية. بمعنى آخر، كل عملية غير مصفوفية تُكلّف عملياً 16 ضعف تكلفة عملية ضرب مصفوفات. فلسفة FlashAttention-2 مبنيّة على هذا التباين: اجعل المعالج يقضي أكبر وقت ممكن في ضرب المصفوفات، وقلّل كل ما عدا ذلك إلى الحدّ الأدنى.
مراجعة FlashAttention: التقسيم إلى بلاطات والـ softmax المتدفّق
قبل الدخول في التحسينات، لنُراجع بإيجاز ما يفعله FlashAttention. الانتباه بصورته التقليدية يحسب ثم يُطبّق softmax على كل صف ليحصل على ، ثم يحسب . المشكلة أن هذا يتطلّب بناء مصفوفتَي كاملتين (S وP) في ذاكرة HBM.
FlashAttention يتفادى ذلك عبر أسلوب : يُقسّم Q وK وV إلى كتل صغيرة تتّسع في SRAM. لكل زوج كتل، يحسب درجات الانتباه محلياً ويُطبّق softmax ويضرب في كتلة V المقابلة ثم يُراكم النتيجة. التحدّي هنا أن softmax عملية شاملة — تحتاج القيمة القصوى والمجموع على الصف بأكمله. تقنية الـ softmax المتدفّق تحلّ ذلك عبر الاحتفاظ بإحصاءات جارية: قيمة قصوى ومجموع أُسّي يُحدَّثان مع كل كتلة جديدة. عند وصول كتلة جديدة تُحدَّث الإحصاءات ويُعاد ضبط المخرج الجزئي، فتبقى النتيجة النهائية مطابقة تماماً — بدون أي تقريب.
بهذا الأسلوب تنخفض الذاكرة من إلى ويتحقّق تسريع بمقدار 2‑4× بفضل تقليل القراءة والكتابة من وإلى HBM. لكنّ هناك أداءً مُهدَراً لا يزال يمكن استرجاعه.
التحسين الأول: عمليات غير مصفوفية أقل
التحسين الأول يستهدف خطوة التطبيع في الـ softmax المتدفّق. في FlashAttention الأصلي، بعد معالجة كل كتلة K-V جديدة، يُطبَّع كلا حدَّي تحديث المخرج بالقسمة على :
الملاحظة المفتاحية في FlashAttention-2 هي أن هذا التطبيع يمكن تأجيله. بدلاً من القسمة على في كل خطوة، يحتفظ الخوارزم بمخرج جارٍ غير مُطبَّع ولا يقسم إلا مرة واحدة في النهاية:
بهذا تُحذف عملية قسمة واحدة من كل كتلة — وهي عملية غير مصفوفية مُكلفة. علاوة على ذلك، بدلاً من تخزين القيمة القصوى والمجموع كلٍّ على حدة لـ، يُخزّن FlashAttention-2 حاصل دمجهما في قيمة واحدة هي الـ logsumexp: . هذا يُنصّف الحِمل الحسابي الإضافي ويُبسّط التمرير العكسي.
التحسين الثاني: التوازي على بُعد طول التسلسل
في FlashAttention الأصلي، يتوزّع العمل على بُعدَين فقط: وعدد رؤوس الانتباه. كل كتلة خيوط تتولّى رأس انتباه واحداً من تسلسل واحد. معالج A100 يضمّ 108 وحدة معالجة متدفّقة (SMs)، وتحتاج إلى نحو 80 كتلة خيوط على الأقل لإشغاله فعلياً. فلو كان حجم الدُّفعة 1 وعدد الرؤوس 32، لن تحصل إلا على 32 كتلة — ما يترك وحدات معالجة كثيرة خاملة.
FlashAttention-2 يُضيف بُعداً ثالثاً للتوازي: طول التسلسل. الحلقة الخارجية تمرّ على كتل الصفوف من Q، وكل تكرار مستقلّ تماماً عن البقية (يقرأ K وV بالكامل لكنه يكتب في شريحته الخاصة من المخرج). هذا النوع من التوازي مثالي لأنه لا يتطلّب أي تنسيق بين الكتل.
بعد هذا التعديل يصبح العدد الكلّي لكتل الخيوط الدُّفعة × الرؤوس × (N / حجم_الكتلة)، وهو ما قد يبلغ الآلاف في التسلسلات الطويلة. حتى تسلسل طويل واحد برأس انتباه واحد يكفي الآن المعالج بالكامل. وهذا هو السيناريو الأكثر أهمية عملياً — تدريب السياقات الطويلة مع نماذج كبيرة ودُفعات صغيرة.
في التمرير العكسي يعمل التوازي بأسلوب مشابه لكن مع فارق مهم. الحلقة الخارجية هنا تمرّ على كتل الأعمدة من K وV (لا كتل الصفوف من Q). كل كتلة عمود تُراكم dK وdV باستقلالية تامة. الاستثناء هو dQ: تحديثه مُشترك بين كتل الأعمدة، إذ قد تحتاج عدة كتل خيوط إلى الكتابة في الشريحة نفسها من dQ. الحل هو استخدام الجمع الذرّي (atomic addition)، وهو آلية تزامن خفيفة تسمح بالتحديث المتزامن دون الحاجة لحواجز تزامن كاملة.
التحسين الثالث: توزيع عمل أذكى بين الأشرطة
حتى داخل كتلة خيوط واحدة، هناك عدة (كل شريط مجموعة من 32 خيطاً) تحتاج إلى تقاسم العمل فيما بينها. الطريقة التي تتقاسم بها هذا العمل تُحدّد كمّ التواصل المطلوب عبر الذاكرة المشتركة — وهذا التواصل مُكلف.
في FlashAttention كانت الاستراتيجية هي تقسيم المفاتيح (split-K): تُوزَّع K وV على 4 أشرطة، بينما تتشارك كلها في Q. كل شريط يحسب جزءاً من ثم يضربه في جزئه من V. المشكلة أن النتائج الجزئية تحتاج دمجاً — كل شريط يكتب نتيجته في الذاكرة المشتركة، ثم تتوقّف جميع الأشرطة للتزامن، ثم يقرأ شريط واحد الأجزاء ويجمعها. دورة الكتابة-التزامن-القراءة هذه هي عنق الزجاجة.
FlashAttention-2 يقلب المعادلة إلى تقسيم الاستعلامات (split-Q): تُوزَّع Q على الأشرطة بينما تتشارك كلها في K وV. الآن كل شريط يعمل على صفوفه الخاصة من Q باستخدام K وV كاملتين، ويُنتج شريحته من المخرج مباشرةً. لا حاجة لأي تواصل بين الأشرطة. الصورة الذهنية: أعطِ كل عامل قائمة أسئلته الخاصة (Q) ودعهم جميعاً يقرأون من المرجع نفسه (K وV) — كل عامل يكتب إجاباته وحده دون الحاجة لمساعدة أحد.
تحسين إضافي: قناع سببي أذكى
في نمذجة اللغة ، يضمن أن كل رمز لا ينتبه إلا للرموز التي سبقته. على مستوى المصفوفة، كل عنصر فوق القطر يُصفَّر (يُعيَّن بقيمة ). وبما أن FlashAttention يعمل بالكتل أصلاً، يمكنه تخطّي أي كتلة تقع بالكامل فوق القطر — أي نحو نصف الكتل في التسلسلات الطويلة. هذا التخطّي وحده يمنح تسريعاً بمقدار 1.7‑1.8×.
FlashAttention-2 يُحسّن الأمر أكثر: بالنسبة للكتل التي يمرّ القطر من خلالها، لا يُطبَّق القناع إلا داخل تلك الكتلة الواحدة التي تقع على حافة القطر. أما الكتل الواقعة بالكامل تحت القطر فلا تحتاج لأي تقنيع. النتيجة أن عبء القناع ينحصر في كتلة واحدة لكل صف بدلاً من تطبيقه عنصراً عنصراً على أجزاء كبيرة من المصفوفة.
النتائج: مضاعفة الإنتاجية
حين تتضافر التحسينات الثلاثة، يكون الأثر كبيراً. على معالج A100 بسعة 80 غيغابايت، يصل FlashAttention-2 إلى 230 تيرا عملية/ثانية في التمرير الأمامي (73% من الحدّ النظري) و196 تيرا عملية/ثانية في التمرير العكسي (63%). في المقابل، FlashAttention الأصلي لا يتجاوز 124 أمامياً و113 عكسياً. أي أن التسريع يبلغ نحو ضعفين بشكل شبه ثابت.
وحين نقارن بالانتباه التقليدي في PyTorch، تتّسع الفجوة أكثر: FlashAttention-2 أسرع بـ 3‑10 أضعاف بحسب طول التسلسل وبُعد الرأس، مع استهلاك ذاكرة بدلاً من .
على مستوى التدريب الكامل، يصل FlashAttention-2 إلى 225 تيرا عملية/ثانية لكل معالج A100 عند تدريب نماذج بأسلوب GPT بـ 2.7 مليار معامل وسياق بطول 8 آلاف رمز. هذا يُمثّل 72% من النظرية للنموذج — وهي نسبة قريبة جداً من الحدّ العتادي. للمقارنة، التدريب نفسه بدون FlashAttention لا يتجاوز 80 تيرا عملية/ثانية، أي أبطأ بمقدار 2.8×. وكلّما طال التسلسل زاد المكسب: عند سياق 8 آلاف يبلغ التسريع 2.8× مقارنة بالتنفيذ التقليدي، بينما عند سياق 2 آلاف يبلغ 1.4× فقط.
دعم الانتباه متعدّد الاستعلامات والانتباه المُجمَّع
نماذج اللغة الكبيرة الحديثة تعتمد بشكل متزايد على الانتباه متعدّد الاستعلامات (MQA) والانتباه المُجمَّع (GQA) لتقليص حجم ذاكرة KV المؤقتة أثناء . في MQA تتشارك جميع رؤوس الاستعلام في رأس مفاتيح-قيم واحد، وفي GQA تتشارك مجموعات من رؤوس الاستعلام في رأس واحد. كلا الأسلوبين يُقلّل حجم البيانات المنقولة أثناء التوليد.
FlashAttention-2 يدعم هذه الأنماط بشكل طبيعي: بدلاً من نسخ رؤوس K وV فعلياً لمطابقة عدد رؤوس Q، يستخدم مؤشرات فهرسة ذكية تجعل عدة مجموعات من Q تقرأ من بيانات K-V نفسها دون تكرارها. في التمرير العكسي تُجمَع التدرّجات dK وdV عبر رؤوس الاستعلام المتشاركة. أهمية هذا الدعم أنه يعني أن FlashAttention-2 لا يُسرّع التدريب فحسب، بل يُسرّع أيضاً بنيات الاستدلال المُستخدمة فعلياً في الإنتاج.
التمرير الأمامي الكامل لـ FlashAttention-2
لنجمع كل ما سبق في صورة الخوارزم الكامل لـالتمرير الأمامي. الحلقة الخارجية تمرّ على كتل صفوف Q، وكل كتلة تُسنَد إلى كتلة خيوط مستقلة للتوازي. الحلقة الداخلية تمرّ على كتل أعمدة K وV. في كل خطوة يحسب الخوارزم درجات الانتباه المحلية ويُحدّث إحصاءات softmax الجارية ويُراكم المخرج دون تطبيع. التطبيع لا يحدث إلا مرة واحدة في النهاية.
مبسَّط لإظهار الفكرة — ليس التنفيذ الحقيقي.
# Q, K, V: [N, d] في HBM؛ Br, Bc: أحجام الكتل
# الحلقة الخارجية: كل تكرار = كتلة خيوط واحدة (متوازية على الصفوف) for i in range(ceil(N / Br)):
Qi = حمّل_من_HBM(Q[i*Br : (i+1)*Br]) # حمّل كتلة Q إلى SRAM
Oi = أصفار(Br, d) # المُراكِم (غير مُعاد قياسه)
li = أصفار(Br) # مجموع الأُسُّيّات الجاري
mi = أملأ(Br, -∞) # القيمة القصوى الجارية لكل صف
# الحلقة الداخلية: المرور على كتل K وV
for j in range(ceil(N / Bc)):
Kj, Vj = حمّل_من_HBM(K[j], V[j]) # حمّل كتلة K, V
Sij = Qi @ Kj.T # درجات الانتباه المحلية
# تحديث إحصاءات softmax الجارية
mi_new = max(mi, rowmax(Sij))
P_tilde = exp(Sij - mi_new) # بسط softmax المحلي
li = exp(mi - mi_new) * li + rowsum(P_tilde)
# تراكم المخرج غير المُعاد قياسه (لا قسمة على li هنا!)
Oi = diag(exp(mi - mi_new)) * Oi + P_tilde @ Vj
mi = mi_new
# تطبيع واحد في النهاية فقط
Oi = diag(1 / li) * Oi
Li = mi + log(li) # تخزين logsumexp للتمرير العكسي
اكتب_في_HBM(Oi, Li)الخط الزمني: سلالة FlashAttention
2018
الـ Softmax المتدفّق (ميلاكوف وغيملشين)
اقترحا طريقة لحساب softmax بتمريرة واحدة عبر تتبّع القيمة القصوى والمجموع بشكل متواصل. هذه التقنية هي الأساس الذي يسمح بحساب الانتباه كتلةً كتلة دون الحاجة لبناء مصفوفة الانتباه الكاملة في الذاكرة.
2022
FlashAttention (داو وآخرون)
جمع بين التبليط والـ softmax المتدفّق وإعادة الحساب في خوارزم انتباه واعٍ بنمط الوصول للذاكرة. خفض الذاكرة من O(N²) إلى O(N) وحقّق تسريعاً بمقدار 2‑4× بدون أي تقريب. اعتُمد على نطاق واسع في الصناعة.
2023
FlashAttention-2 (هذه الورقة)
ضاعف سرعة FlashAttention بتقليل العمليات غير المصفوفية والتوازي على بُعد طول التسلسل والتحوّل إلى توزيع split-Q على الأشرطة. بلغ 73% من الإنتاجية النظرية القصوى على معالجات A100.
2023
Flash-Decoding (داو وآخرون)
نقل أفكار FlashAttention-2 إلى مرحلة الاستدلال عبر التوازي على بُعد طول ذاكرة KV المؤقتة، ما أتاح توليد النصوص من سياقات طويلة بكفاءة عالية.
2024
FlashAttention-3 (شاه وآخرون)
استفاد من إمكانيات معالجات Hopper الجديدة (النقل غير المتزامن TMA ونوى المُوتِّرات من الجيل الرابع ودقة FP8) ليدفع كفاءة الانتباه أقرب ما يمكن إلى الحدّ العتادي على معالجات H100.
المرجعTri Dao. FlashAttention-2: Faster Attention with Better Parallelism and Work Partitioning. ICLR, 2024.
مصطلحات هذه الورقة
- FlashAttentionFlashAttention
- آلية الانتباهAttention
- التبليطTiling
- softmax المتدفقOnline Softmax
- الذاكرة الساكنةSRAM
- الذاكرة عالية النطاقHBM
- وحدة معالجة الرسومياتGPU
- دمج النواةKernel Fusion
- معدل التدفق والإنتاجيةThroughput
- التمرير الأماميForward Pass
- التمرير الخلفيBackward Pass
- قناع سببيCausal Mask
- الانتباه المتعدد المساراتMulti-Head Attention
- انتباه الاستعلام المُجمَّعGrouped Query Attention
- سوفت ماكسSoftmax