كل خطوة في الـ Transformer محسوبة بالأرقام على جملة وحدة من الإنجليزي للعربي: الـ Embedding، ترميز الموقع، الـ Attention، الـ Decoder والـ Softmax النهائي.
متوسط ~30 دقيقة AI Applicationsأول خطوة: كل كلمة بتتحول لـ vector (قائمة أرقام). نفترض الـ embedding dimension = 4 (بالواقع 512).
"I" → [0.2, 0.5, 0.1, 0.8] "love" → [0.9, 0.3, 0.7, 0.2] "learning" → [0.4, 0.6, 0.5, 0.9]
هاي الأرقام الموديل بتعلمها وقت التدريب — كلمات بمعنى قريب بكون vectors قريبة من بعض.
الـ Transformer بعالج كل الكلمات بنفس الوقت (بالتوازي)، فما بعرف إنه "I" أول كلمة و"learning" ثالث كلمة.
نضيف vector خاص لكل موقع بالجملة باستخدام دوال sin و cos:
PE(pos, 2i) = sin(pos / 10000^(2i/d)) PE(pos, 2i+1) = cos(pos / 10000^(2i/d))
حيث: pos = موقع الكلمة (0, 1, 2, ...) | i = رقم البُعد | d = حجم الـ embedding (= 4)
الموقع 0 ("I"):
PE(0,0) = sin(0 / 10000^(0/4)) = sin(0) = 0.00 PE(0,1) = cos(0 / 10000^(0/4)) = cos(0) = 1.00 PE(0,2) = sin(0 / 10000^(2/4)) = sin(0) = 0.00 PE(0,3) = cos(0 / 10000^(2/4)) = cos(0) = 1.00 → PE₀ = [0.00, 1.00, 0.00, 1.00]
الموقع 1 ("love"):
PE(1,0) = sin(1) = 0.84 PE(1,1) = cos(1) = 0.54 PE(1,2) = sin(0.01) = 0.01 PE(1,3) = cos(0.01) = 1.00 → PE₁ = [0.84, 0.54, 0.01, 1.00]
الموقع 2 ("learning"):
PE(2,0) = sin(2) = 0.91 PE(2,1) = cos(2) = -0.42 PE(2,2) = sin(0.02) = 0.02 PE(2,3) = cos(0.02) = 1.00 → PE₂ = [0.91, -0.42, 0.02, 1.00]
"I" = [0.2, 0.5, 0.1, 0.8] + [0.00, 1.00, 0.00, 1.00] = [0.20, 1.50, 0.10, 1.80] "love" = [0.9, 0.3, 0.7, 0.2] + [0.84, 0.54, 0.01, 1.00] = [1.74, 0.84, 0.71, 1.20] "learning" = [0.4, 0.6, 0.5, 0.9] + [0.91,-0.42, 0.02, 1.00] = [1.31, 0.18, 0.52, 1.90]
كل كلمة بتسأل: "مين من الكلمات الثانية مهم إلي عشان أفهم معناي؟"
لكل كلمة بنضرب الـ vector بثلاث مصفوفات وزن:
Q = X × Wq (Query — شو عم بدور عليه؟) K = X × Wk (Key — شو عندي؟) V = X × Wv (Value — شو القيمة اللي بعطيها؟)
نفترض بعد الضرب (بحجم مبسط 3):
Q K V
"I" [1, 0, 1] [0, 1, 1] [1, 0, 0]
"love" [0, 1, 0] [1, 1, 0] [0, 1, 0]
"learn" [1, 1, 0] [0, 0, 1] [0, 0, 1]
أ) ضرب Q × Kᵀ (كل query مع كل key):
مثال: score لكلمة "I" مع كل الكلمات:
"I" مع "I": Q_I · K_I = [1,0,1]·[0,1,1] = 0+0+1 = 1 "I" مع "love": Q_I · K_love = [1,0,1]·[1,1,0] = 1+0+0 = 1 "I" مع "learn": Q_I · K_learn = [1,0,1]·[0,0,1] = 0+0+1 = 1
كل الـ scores:
"I" "love" "learn"
"I" → [ 1, 1, 1 ]
"love" → [ 1, 1, 0 ]
"learn" → [ 0, 2, 1 ]
ب) القسمة على √dₖ (scaling):
dₖ = 3 → √3 ≈ 1.73
"I" "love" "learn"
"I" → [0.58, 0.58, 0.58]
"love" → [0.58, 0.58, 0.00]
"learn" → [0.00, 1.15, 0.58]
ج) تطبيق Softmax (تحويل لاحتمالات):
softmax بحول كل صف لاحتمالات مجموعها = 1:
"I" "love" "learn"
"I" → [0.33, 0.33, 0.33] ← بنتبه لكل الكلمات بالتساوي
"love" → [0.39, 0.39, 0.22] ← بنتبه لـ "I" ونفسه أكتر
"learn" → [0.19, 0.59, 0.22] ← بنتبه لـ "love" أكتر!
د) الضرب بـ V (الحصول على المخرج):
output_I = 0.33×[1,0,0] + 0.33×[0,1,0] + 0.33×[0,0,1] = [0.33, 0.33, 0.33] output_love = 0.39×[1,0,0] + 0.39×[0,1,0] + 0.22×[0,0,1] = [0.39, 0.39, 0.22] output_learn = 0.19×[1,0,0] + 0.59×[0,1,0] + 0.22×[0,0,1] = [0.19, 0.59, 0.22]
بدل ما نعمل attention وحدة، نعمل 8 بالتوازي — كل وحدة اسمها head.
كل head بتعلم علاقة مختلفة:
1. لكل head: اعمل Self-Attention بشكل مستقل (بأوزان مختلفة) head₁ = Attention(Q×W₁ᵠ, K×W₁ᵏ, V×W₁ᵛ) head₂ = Attention(Q×W₂ᵠ, K×W₂ᵏ, V×W₂ᵛ) ... head₈ = Attention(Q×W₈ᵠ, K×W₈ᵏ, V×W₈ᵛ) 2. ادمج كل النتائج: MultiHead = Concat(head₁, head₂, ..., head₈) × Wᴼ
Head 1 output for "learn": [0.19, 0.59, 0.22] (تعلم علاقة المعنى) Head 2 output for "learn": [0.45, 0.10, 0.45] (تعلم علاقة الموقع) Concat: [0.19, 0.59, 0.22, 0.45, 0.10, 0.45] × Wᴼ → [0.30, 0.40, 0.30] (النتيجة النهائية)
output = x + Sublayer(x)
يعني: المدخل الأصلي بنجمعه مع مخرج الطبقة.
LayerNorm(x) = (x - μ) / √(σ² + ε) × γ + β
حيث: μ = المتوسط | σ² = التباين | γ, β = معاملات قابلة للتعلم
x (المدخل الأصلي لـ "learn"): [1.31, 0.18, 0.52]
attention output: [0.19, 0.59, 0.22]
بعد Residual: [1.31+0.19, 0.18+0.59, 0.52+0.22] = [1.50, 0.77, 0.74]
μ = (1.50 + 0.77 + 0.74) / 3 = 1.00
σ² = ((0.50)² + (-0.23)² + (-0.26)²) / 3 = 0.12
√(σ² + ε) ≈ 0.35
LayerNorm = [(1.50-1.00)/0.35, (0.77-1.00)/0.35, (0.74-1.00)/0.35]
= [1.43, -0.66, -0.74]
بعد الـ attention، كل كلمة بتمر بشبكة عصبية صغيرة:
FFN(x) = max(0, x×W₁ + b₁) × W₂ + b₂
input: [1.43, -0.66, -0.74] بعد W₁ + b₁: [2.1, -0.3, 1.5, -1.2] بعد ReLU (max 0): [2.1, 0.0, 1.5, 0.0] ← السالب صار 0 بعد W₂ + b₂: [0.8, 0.5, 0.3] ← رجع للحجم الأصلي
الـ Decoder بشتغل كلمة كلمة. نفترض وصلنا لمرحلة توليد الكلمة الثالثة وعندنا:
مدخلات الـ Decoder حتى الآن: ["أنا", "أحب", ???]
نفس Self-Attention بالزبط — بس مع قناع (mask):
Scores قبل الـ mask:
"أنا" "أحب" ???
"أنا" → [0.8, 0.5, 0.3]
"أحب" → [0.6, 0.9, 0.4]
??? → [0.3, 0.7, 0.8]
Mask (المثلث السفلي فقط):
"أنا" "أحب" ???
"أنا" → [0.8, -∞, -∞ ] ← "أنا" بشوف بس حاله
"أحب" → [0.6, 0.9, -∞ ] ← "أحب" بشوف "أنا" وحاله
??? → [0.3, 0.7, 0.8] ← ??? بشوف كل اللي قبله
بعد Softmax:
"أنا" → [1.00, 0.00, 0.00]
"أحب" → [0.43, 0.57, 0.00]
??? → [0.17, 0.37, 0.46]
هون الـ Decoder بشوف مخرجات الـ Encoder:
Q = من الـ Decoder (الكلمة اللي عم نولدها)
K = من الـ Encoder ("I", "love", "learning")
V = من الـ Encoder ("I", "love", "learning")
Q لـ ???: [0.5, 0.8, 0.3] Scores مع كل كلمة إنجليزية: ??? مع "I": 0.5×0.2 + 0.8×0.5 + 0.3×0.1 = 0.53 ??? مع "love": 0.5×0.9 + 0.8×0.3 + 0.3×0.7 = 0.90 ??? مع "learning": 0.5×0.4 + 0.8×0.6 + 0.3×0.5 = 0.83 بعد softmax: [0.22, 0.40, 0.38]
آخر خطوة — مخرج الـ Decoder بمر بـ:
1. Linear Layer: بحول الـ vector لحجم المفردات (مثلاً 50,000 كلمة) 2. Softmax: بحول لاحتمالات مخرج الـ Decoder لـ ???: [0.25, 0.60, 0.15] بعد Linear (نفترض 5 كلمات بس للتبسيط): ["أنا": 0.02, "أحب": 0.05, "التعلم": 0.85, "كتاب": 0.03, "بيت": 0.05] أعلى احتمال → "التعلم" (0.85) ✅
┌──────────────────────── ENCODER ────────────────────────┐ │ │ │ "I love learning" │ │ ↓ │ │ [Input Embedding] → vectors لكل كلمة │ │ ↓ │ │ [+ Positional Encoding] → إضافة معلومات الموقع │ │ ↓ │ │ [Multi-Head Self-Attention] → كل كلمة تنتبه للباقي │ │ ↓ │ │ [+ Residual + LayerNorm] │ │ ↓ │ │ [Feed-Forward Network] → شبكة عصبية لكل كلمة │ │ ↓ │ │ [+ Residual + LayerNorm] │ │ ↓ │ │ ══► مخرجات الـ Encoder (تُرسل للـ Decoder) │ │ │ └──────────────────────────────────────────────────────────┘ ┌──────────────────────── DECODER ────────────────────────┐ │ │ │ "أنا أحب" (الكلمات اللي ولّدناها لحد هلأ) │ │ ↓ │ │ [Output Embedding + Positional Encoding] │ │ ↓ │ │ [Masked Multi-Head Self-Attention] → ما بشوف المستقبل │ │ ↓ │ │ [+ Residual + LayerNorm] │ │ ↓ │ │ [Cross-Attention] → Q من هون، K+V من الـ Encoder │ │ ↓ │ │ [+ Residual + LayerNorm] │ │ ↓ │ │ [Feed-Forward Network] │ │ ↓ │ │ [+ Residual + LayerNorm] │ │ ↓ │ │ [Linear → Softmax] → احتمال كل كلمة بالقاموس │ │ ↓ │ │ ══► "التعلم" ← الكلمة اللي احتمالها أعلى │ │ │ └──────────────────────────────────────────────────────────┘
| المعلومة | القيمة |
|---|---|
| عدد طبقات الـ Encoder بالورقة الأصلية | 6 |
| عدد طبقات الـ Decoder | 6 |
| حجم الـ Embedding (d_model) | 512 |
| عدد الـ Heads | 8 |
| حجم كل Head (dₖ) | 512/8 = 64 |
| حجم الـ Feed-Forward الداخلي | 2048 |
| الورقة الأصلية | "Attention Is All You Need" (2017) |
| المؤلفين | Vaswani et al. (Google) |
| الـ Optimizer | Adam (مع learning rate متغير) |