المستوى: مبتدئ — المقال ده لأي حد سمع عن ChatGPT وعايز يفهم القطعة الأساسية اللي بتخلّيه "يفهم" الجملة. مفيش شرط تعرف رياضيات متقدمة.
آلية الانتباه (Attention): إزاي الذكاء الاصطناعي بيعرف الكلمة بتشير لمين
بعد ما تخلّص المقال ده هتفهم القطعة اللي بنى عليها ChatGPT وClaude وكل نماذج اللغة الحديثة. اسمها Attention، وهي السبب إن النموذج بيربط الكلمات ببعض صح بدل ما يقراها واحدة واحدة.
المشكلة باختصار
خُد الجملة دي: "القطة التعبانة قعدت لأنها كانت نعسانة". لما توصل لكلمة "أنها"، دماغك بيعرف فورًا إنها بتتكلم عن "القطة" مش عن أي حاجة تانية. النموذج لازم يعمل نفس الربط ده. من غير آلية تربط الكلمات بذكاء، النموذج بيتوه في الجمل الطويلة ويغلط في المعنى.
الفكرة بمثال بسيط: الحفلة الصاخبة
تخيّل إنك في حفلة زحمة وصوت عالي. ناس كتير بتتكلم في وقت واحد. فجأة حد في الطرف التاني نطق اسمك. هتلاقي دماغك ركّز على الصوت ده لوحده وفلتر باقي الضوضاء.
ده بالظبط اللي بيعمله الانتباه. لكل كلمة، النموذج بيقرّر: مين الكلمات التانية المهمة ليّا دلوقتي؟ وبيدّي كل كلمة "وزن". الكلمة المهمة بتاخد وزن عالي، والباقي وزن قليل. كلمة "أنها" بتدّي وزن كبير لـ "القطة"، ووزن صغير لباقي الكلمات.
الشرح العلمي: Query و Key و Value
دلوقتي بعد ما وضحت الصورة، نبقى دقيقين. كل كلمة النموذج بيحوّلها لـ 3 حاجات (كلها قوائم أرقام):
- Query (استعلام): يعني "أنا بدوّر على إيه؟".
- Key (مفتاح): يعني "أنا بعرض إيه للكلمات التانية؟".
- Value (قيمة): يعني "المعلومة اللي هقدّمها لو حد ركّز عليّا".
النموذج بيضرب الـ Query بتاع كل كلمة في الـ Key بتاع كل كلمة تانية. الناتج بيقوله قد إيه الكلمتين مرتبطين. بعدها بيمرّر النتايج على دالة اسمها softmax علشان تحوّلها لأوزان مجموعها 1. الأوزان دي هي "الانتباه". أخيرًا بيجمع الـ Values مضروبة في الأوزان دي، فيطلع تمثيل جديد لكل كلمة "شايف" سياقها كله. لأن كل كلمة بتبص على كل الكلمات في نفس الجملة، الآلية دي اسمها Self-Attention.
مثال تنفيذي: انتباه في أقل من 20 سطر
الكود ده بيحسب self-attention بسيط بـ NumPy. انسخه وشغّله زي ما هو:
import numpy as np
def softmax(x):
e = np.exp(x - x.max(axis=-1, keepdims=True))
return e / e.sum(axis=-1, keepdims=True)
# 4 كلمات، كل كلمة متمثّلة بـ 3 أرقام (تمثيل مبسّط)
X = np.array([
[1.0, 0.0, 1.0], # القطة
[0.9, 0.1, 0.8], # التعبانة
[0.2, 1.0, 0.1], # قعدت
[1.0, 0.1, 0.9], # أنها
])
d = X.shape[1]
Q, K, V = X, X, X # في الواقع بتتضرب في مصفوفات متعلَّمة
scores = Q @ K.T / np.sqrt(d) # قد إيه كل كلمة قريبة من التانية
weights = softmax(scores) # أوزان الانتباه (مجموع كل صف = 1)
output = weights @ V # التمثيل الجديد مع السياق
print(np.round(weights, 2))
# صف "أنها" هيدّي أعلى وزن لـ "القطة" لأن تمثيلهم متقارب