تمت كتابة هذا المنشور بواسطة فيليب شميد وتم نشره في الأصل على كود philschmid.de ويمكن العثور عليه هنا.
لقد صدم إصدار Deepseek R1 الصناعة. لماذا؟ حسنًا، DeepSeek-R1 هو نموذج مفتوح ينافس OpenAI’s o1 في مهام الاستدلال المعقدة، ويتم تقديمه باستخدام نهج تحسين السياسة النسبية للمجموعة (GRPO) ونهج التدريب متعدد المراحل الذي يركز على RL. لم يقوموا بإصدار النموذج فحسب، بل قاموا أيضًا بإصدار ورقة بحثية حول كيفية القيام بذلك.
وصفوا في الورقة “لحظة آها” عند استخدام RL النقي لتدريب النموذج. خلال هذه المرحلة، يتعلم DeepSeek-R1-Zero (الاختبار الأول لـ DeepSeek-R1) كيفية تخصيص المزيد من وقت التفكير لمشكلة ما من خلال إعادة تقييم نهجها الأولي دون أي تعليقات بشرية أو بيانات تصف كيفية القيام بذلك. يصفون هذه بأنها “لحظة آها” على النحو التالي:
هذا السلوك ليس فقط شهادة على القدرات الاستدلالية المتنامية للنموذج ولكنه أيضًا مثال آسر لكيفية أن يؤدي التعلم المعزز إلى نتائج غير متوقعة ومتطورة.
في منشور المدونة هذا، نريد إعادة إنشاء “لحظة aha” الصغيرة لـ DeepSeek-R1 باستخدام تحسين السياسة النسبية للمجموعة (GRPO) ولعبة العد التنازلي. سنقوم بتدريب نموذج مفتوح باستخدام التعلم المعزز في محاولة لتعليمه التحقق الذاتي وقدرات البحث كل ذلك بمفرده لحل لعبة العد التنازلي. لعبة العد التنازلي عبارة عن لغز أرقام حيث يستخدم اللاعبون مجموعة من الأرقام المرسومة عشوائيًا والعمليات الحسابية الأساسية (+، -، ×، ÷) للوصول إلى الرقم المستهدف أو الاقتراب منه قدر الإمكان.
Target Number: 952
Available Numbers: 25, 50, 75, 100, 3, 6
(100 × (3 × 3)) + (50 + 6 / 3) = 952
يركز منشور المدونة على التدريب الموزع باستخدام Deepspeed وvLLM. تم تشغيله على وحدات معالجة الرسومات 4x NVIDIA H100.
- إعداد بيئة التطوير
- مثال للتدريب الموزع على GRPO باستخدام Deepspeed وvLLM
- النتائج وملاحظات التدريب
ملحوظة: هذه المدونة مستوحاة من Jiayi Pan الذي اكتشف الفكرة في البداية وأثبتها بنموذج صغير.
ولكن قبل أن نبدأ، دعونا نلقي نظرة على تحسين السياسة النسبية للمجموعة (GRPO) ونفهم كيف يعمل.
تحسين السياسة النسبية للمجموعة (GRPO)
يعد تحسين السياسة النسبية للمجموعة (GRPO) بمثابة خوارزمية تعلم معززة لتحسين قدرات التفكير لدى LLMs. تم تقديمه في ورقة DeepSeekMath في سياق التفكير الرياضي. تقوم GRPO بتعديل تحسين السياسة القريبة التقليدية (PPO) من خلال إلغاء الحاجة إلى نموذج دالة القيمة. وبدلاً من ذلك، يقوم بتقدير خطوط الأساس من نتائج المجموعة، مما يقلل من استخدام الذاكرة والحمل الحسابي. يمكن استخدام GRPO، الذي يستخدمه فريق Qwen الآن أيضًا، مع المكافآت القائمة على القواعد/الثنائيات بالإضافة إلى نماذج المكافآت العامة لتحسين نماذج المساعدة.
- أخذ العينات: قم بإنشاء مخرجات متعددة لكل موجه باستخدام السياسة الحالية
- تسجيل المكافأة: يتم تسجيل كل جيل باستخدام وظيفة المكافأة، ويمكن أن تكون (قائمة على القواعد أو على أساس النتائج)
- حساب الميزة: يتم استخدام متوسط المكافأة للمخرجات المتولدة كخط أساس. يتم بعد ذلك حساب ميزة كل حل داخل المجموعة بالنسبة إلى خط الأساس هذا. يتم تطبيع المكافأة داخل المجموعة.
- تحسين السياسة: تحاول السياسة تعظيم هدف GRPO، والذي يتضمن المزايا المحسوبة ومصطلح تباعد KL. وهذا يختلف عن كيفية تنفيذ PPO لمصطلح KL ضمن المكافأة.

1. إعداد بيئة التطوير
خطوتنا الأولى هي تثبيت Hugging Face Libraries وPytorch وvllm وtrl والمحولات ومجموعات البيانات. إذا لم تكن قد سمعت عن trl بعد، فلا تقلق. إنها مكتبة جديدة فوق المحولات ومجموعات البيانات، مما يجعل من السهل ضبط وRLHF ومواءمة LLMs المفتوحة.
%pip install "torch==2.5.1" tensorboard "setuptools<71.0.0" --index-url https://download.pytorch.org/whl/cu121
%pip install flash-attn
%pip install --upgrade \
"transformers==4.48.1" \
"datasets==3.1.0" \
"accelerate==1.3.0" \
"hf-transfer==0.1.9" \
"deepspeed==0.15.4" \
"trl==0.14.0"
%pip install "vllm==0.7.0"
ملاحظة: قد تحتاج إلى إعادة تشغيل النواة لاستخدام الحزم المحدثة.
سوف نستخدم Hugging Face Hub كخدمة لإصدار النماذج عن بعد. وهذا يعني أننا سنقوم تلقائيًا بإرسال نموذجنا وسجلاتنا ومعلوماتنا إلى المركز أثناء التدريب. يجب عليك التسجيل في Hugging Face لهذا الغرض. بعد أن يكون لديك حساب، سوف نستخدم login الاستفادة من huggingface_hub حزمة لتسجيل الدخول إلى حسابنا وتخزين الرمز المميز (مفتاح الوصول) على القرص.
from huggingface_hub import login
login(token="", add_to_git_credential=True)
2. مثال للتدريب الموزع على GRPO باستخدام Deepspeed وvLLM
سنستخدم مجموعة بيانات Jiayi-Pan/Countdown-Tasks-3to4، التي تحتوي على عينات تحتوي على 3 إلى 4 أرقام وحلول. كنموذج، سنستخدم Qwen/Qwen2.5-3B-Instruct وهو نموذج تم ضبطه لتعليمات المعلمة 3B. وهذا يجعل من السهل عرض “لحظة آها” حيث يمكنها بالفعل اتباع التعليمات. اكتشف جياي بان أن النموذج يحتاج إلى جودة معينة حتى يتمكن من تعلم عملية التفكير، بدءًا من أكثر من 1.5 مليار معلمة.
تدعم TRL تحسين السياسة النسبية للمجموعة (GRPO) من خلال GRPOTrainer مخصص لمواءمة LLMs من بيانات التفضيلات، كما هو موضح في DeepSeekMath: دفع حدود الاستدلال الرياضي في نماذج اللغة المفتوحة. ال GRPOTrainer هي فئة فرعية من Trainer من transformers مكتبة ويدعم جميع الميزات نفسها، بما في ذلك التسجيل، وفحص التفتيش، والتدريب الموزع، والضبط الدقيق الفعال للمعلمات (PEFT).
ال GRPOTrainer يدعم نماذج مكافآت النتائج العامة (ORM) ووظائف المكافآت المخصصة، التي يمكن استخدامها لتنفيذ نماذج المكافآت القائمة على القواعد. في ورقة Deepseek R1، قاموا بتطبيق نماذج المكافآت القائمة على القواعد للتحقق من صحة الحلول التي تم إنشاؤها. في المثال الخاص بنا، سنتبع نهجًا مشابهًا، حيث سنقوم بإنشاء وظيفتين للمكافأة:
- مكافأة التنسيق: يتحقق مما إذا كان التنسيق الذي تم إنشاؤه صحيحًا
<think> [thinking] </think><answer> [answer] </answer> - مكافأة الدقة: يستخرج المعادلة من
<answer>العلامة وتقييمها مقابل الهدف وإذا تم استخدام كل رقم مرة واحدة.
ملاحظة: صحيح <answer> في مثالنا يشمل المعادلة، على سبيل المثال <answer> 55 + 36 - 7 - 19 </answer>
أضاف Hugging Face TRL دعمًا للتدريب الموزع باستخدام Deepspeed واستخدام vLLM لتوليد أسرع. لقد قمت بإعداد البرنامج النصي run_r1_grpo.py وملف التكوين receipes/grpo-qwen-2.5-3b-deepseek-r1-countdown.yaml لتشغيل التدريب.
تم اختبار هذا التكوين والتحقق من صحته على عقدة مزودة بـ 4x H100 بسعة 80 جيجابايت، حيث تستغرق الخطوة الواحدة حوالي 45-60 ثانية، حيث يمكننا الاستفادة من vLLM للتوليد وDeepSpeed للتدريب الموزع. لذلك نحن بحاجة للتأكد من أننا قمنا بتعيين بشكل صحيح num_processes إلى عدد وحدات معالجة الرسومات لديك – 1 حيث سيتم استخدام آخر وحدة مع vLLM للإنشاء. إذا كنت تستخدم المزيد من وحدات معالجة الرسومات، فأنت بحاجة إلى تغيير vllm_device في ملف التكوين لآخر فهرس GPU، على سبيل المثال، إذا كان لديك 8 وحدات معالجة رسومات تحتاج إلى تعيينها vllm_device=7 و الخاص بك num_processes إلى 7.
أمر تشغيل التدريب:
accelerate launch --num_processes 3 --config_file configs/accelerate_configs/deepspeed_zero3.yaml scripts/run_r1_grpo.py --config receipes/grpo-qwen-2.5-3b-deepseek-r1-countdown.yaml
مع التدريب الموزع الأمثل، تستغرق الخطوة الواحدة مع 8 أجيال لكل عينة على 4x H100 80GB حوالي 45-60 ثانية. يستغرق التدريب الكامل لـ 450 خطوة حوالي 6 ساعات.
3. النتائج وملاحظات التدريب
يحفظ البرنامج النصي الإكمالات العشوائية في ملف completion_samples المجلد، الذي يمكنك استخدامه لفحص تقدم النموذج. ويشمل completion_samples.txt و success_completion_samples.txt. ال completion_samples.txt يشمل جميع الإكمالات، في حين أن success_completion_samples.txt الذي يحل المعادلة بشكل صحيح. يمكنك العثور أدناه على ملاحظات تدريبية مثيرة للاهتمام حول كيفية تغير الأداء بمرور الوقت، بالإضافة إلى سجلات Tensornoard وعينات الاستدلال الناجحة.
يمكن العثور على النموذج الذي يحتوي على نقاط التحقق لكل خطوة 25 في philschmid/qwen-2.5-3b-r1-countdown.
المعلمات الفائقة
لقد بدأت التجربة باستخدام المعلمات الفائقة من ورقة DeepSeekMath بمعدل تعلم 1e-6 وبيتا (معامل KL) قدره 0.04، مما أدى إلى دورات تدريبية غير مستقرة بعد حوالي 150 خطوة. قمت بإجراء بعض عمليات الاجتثاث الصغيرة وخفضت معدل التعلم إلى 5e-7 والبيتا إلى 0.001، بناءً على اختبار من OpenRLHF. لم أتمكن من اختبار مدى زيادة num_generations من 8 إلى 64 سيؤثر على التدريب. 64 هي قيمة التوليد التي تم استخدامها في ورقة DeepSeekMath. يمكن العثور على جميع المعلمات الأخرى في ملف التكوين grpo-qwen-2.5-3b-deepseek-r1-countdown.yaml.
ملاحظات التدريب:
- في حوالي 50 خطوة، تعلم النموذج التنسيق الصحيح
<think>...</think>\n<answer>...</answer>. - عند 100 خطوة، تبلغ نسبة النجاح في حل المعادلة حوالي 25%. يبدأ النموذج في “التفكير” بالكلمات (انظر الأمثلة أدناه).
- عند 200 خطوة، يبدو أن الأداء يتقارب بشكل أبطأ بكثير، وقد وصلنا إلى معدل نجاح يصل إلى 40% تقريبًا. يبدأ النموذج في تعلم “تنسيق” جديد حيث يقوم بحل المعادلة المشابهة لكيفية القيام بذلك برمجيًا، من خلال تجربة مجموعات مختلفة ومراجعة النتائج، راجع “نماذج الاستدلال الناجحة بين الخطوة 200 و450”.
- في 450 خطوة نحصل على نسبة نجاح 50% في حل المعادلة. لا يزال الأداء يتحسن ببطء ويحافظ النموذج على شكله الجديد من الخطوة 200.
لدي 3 افتراضات محتملة حول سبب تحول النموذج من “استدلال الكلمات” إلى “التنفيذ البرمجي”:
- Qwen 2.5 3B ليس قويًا بدرجة كافية أو صغيرًا، يذكر Deepseek أنك بحاجة إلى نموذج أساسي قوي جدًا.
- وظائف المكافأة ليست جيدة بما فيه الكفاية، وهي تكافئ النموذج لحل المعادلة. يمكننا أن نحاول إجباره على استخدام الكلمات، على سبيل المثال وجود رقم لحالة تكرار الكلمة. (لا نعرف الكثير عن وظائف المكافأة من Deepseek)
- قد يؤدي التدريب على مهام لعبة العد التنازلي فقط إلى إجبار النموذج على تعلم الطريقة الأكثر فعالية لحل المعادلة حيث لا يلزم وجود تنسيقات أخرى.
- لم ندرب النموذج لفترة كافية، ففي ورقة R1 أظهروا صورًا للتدريب لأكثر من 8000 خطوة.
نتائج Tensorboard

عينات الاستدلال الناجحة حتى الخطوة 200
<think> First, I need to think about the numbers we have: 14, 70, and 80. To get 85, I think 80 might be a good starting point because it's right in between 85. If I subtract or add 80, it won't lead to 85 easily. Next, 70 seems to be a good intermediate number, especially to use in conjunction with 14.
Now, I can think about different combinations using addition, subtraction and multiplication/division. If I take 80 - 70 = 10, which is not needed. So, I need to find a way to use 14. If I subtract 14 from 80, I get 66, which still isn't 85. If I subtract 70 from 80, I get 10 again, this isn't constructive yet.
Multiplication could create numbers larger than the target 85. Let's consider division: If I divide 70 by 14, I get 5. Then if I add this result to 80, I get 85. This combination seems promising: 80 - (70 / 14) = 80 - 5 = 75, this still isn't quite right. Let me correct my approach: Let's use division and then addition. If I take 80 / (70 / 14) → 80 / 5 = 16, and then 80 - 16 = 64, still incorrect. Let me simplify: 80 / (70 / 14) → 80 / 5 = 16, and then 80 - 16 gives 64 again, let me correct: 80 - (70 / 14) → 80 - 5 = 75, but I need 85. Thus I will use the combinations in a slightly different order to insert numbers: I get 80 + (70 / 14) = 80 + 5 = 85</think>
<answer> 80 + (70 / 14) </answer>
<think> First, I need to consider how I can use the numbers 1, 21, and 90 to reach 68. I can try different combinations of operations. Let's try to use subtraction and addition. If I subtract 90 from 21, I get -69, which is too far from 68. Now, if I add 1 to 90, I get 91, which is also not right. Another way is to see what happens if I subtract 21 from 90, which gives me 69. This is closer but still not 68. Let me use multiplication instead of subtraction. 90 * 1 = 90. Now, if I try to reduce this slightly by subtracting 21, I am not getting close to 68.
Now, let's try another multiplication. I'll think of 1 * (larger value) + (smaller value). Let's try 1 * 90 + 21. This evaluates to 90 + 21 = 111, which is too much. Instead, I will try: 90 / 1 + 21 - 7. But this gives a division by 7, which seems complex. Let's re-evaluate: I'll use 1 to divide 21: 21 / 1 = 21. Now, subtract 21 from 90, and add 1, we have 90 - 21 = 69, using one...
Hey, wait on re-evaluating I will subtract 21 from 90, and include 1 to complete the solution: 90 - (21 + 1) which would be 68.</think>
<answer> 90 - (21 + 1) </answer>
<think> First, I need to consider the numbers we have: 59, 80, and 66. I need to use these numbers to get 45. Let's try to use subtraction first since it can quickly reduce large numbers.
Let's see if we can get close by subtracting or adding these numbers. If I subtract 66 from 80, I get 14. Then I need to make this 14 equal 45 when combined with 59. That gives me 14 + 59 = 73, which is too high.
Now let's try adding numbers. If I add 59 and 66, I get 125. Then I would need to subtract 80 from 125 to get 45, but 80 is too large to fit well with this.
Let me try a different approach. What if I subtract 66 from 80 first and then add 59? That would be 14 + 59 = 73, which is still not 45.
Hmm, I need to think of another combination. What if I start with 59 and then add 80 and subtract 66? That would be (59 + 80) - 66, let me calculate it. That equals 139 - 66, which is 73.
That's still not 45, so let me try rearranging it slightly: maybe 80 - 66 + 59 would be closer to 45. Calculating again: 80 - 66 is 14, then adding 59 gives 73.
This way doesn't work either. Let's flip this: maybe (59 + 66) - 80. Let me check: that's 125 - 80, which equals 45.</think>
<answer>(59 + 66) - 80</answer>
<think> First, I need to find a combination of the numbers 61, 4, 94, and 21 that can be manipulated using basic arithmetic operations to equal 50. One way to approach this is to look for numbers that can be used to reach a target number close to 50 and then adjust with the remaining numbers.
Let's try combining 94 and 21 first:
94 + 21 = 115
Now, we need to get from 115 to 50. We can try subtracting 65:
115 - 65 = 50
Now we need to find a way to get 65 using the remaining numbers 61 and 4. We can try:
61 - 4 = 57
Now we need to get from 57 to 65. Adding 8 would give us that:
57 + 8 = 65
So, we need to find a way to get 8 using 61 and 4. We can try:
61 - 94 = -36
This is negative, so let's try dividing:
61 / 94 = 0.648987...
This is not helping, so let's try multiplication and division in a different way:
(61 - 4) * (94 / 21) = 57 * 4.476... = 254.4
This is not working either. Let's try a different approach:
(94 - 61) = 33
Now we have:
33 + 21 = 54
We need to adjust from 54 to 50, so we can:
54 - 4 = 50
So, the equation becomes:
(94 - 61) + (21 - 4) = 50
</think>
<answer>(94 - 61) + (21 - 4)</answer>
<think> First, I'll consider the possibility of directly subtracting two numbers to get close to 31. If I subtract 57 from 63, I get 7. Now, if I subtract this 7 from 25, I get 25 - 7 = 18. Far from 31, so this doesn't work.
Next, let's try adding and subtracting. Dividing 63 by 25 will give a decimal, so that's unlikely to work. Now, let's see if adding and subtracting in another order could work. For example, let's try 63 - 25, and then we see this gets us 38. Now, we need a way to get to 31 from here. Subtracting 7 from 38 would work, but we can't figure out how to create that 7 from the given numbers.
Hmm, let me try to incorporate all numbers by adding and subtracting. If I try 63 + 25, I get 88. This is quite far from 31, but if 88 - 57, I get 31 exactly!
This seems to be the equation: 63 + 25 - 57 equals 31.
</think>
<answer> 63 + 25 - 57 </answer>
عينات الاستدلال الناجحة بين الخطوة 200 و450
<think> We need to use the numbers 39, 16, and 55 with basic arithmetic operations to get 78. Let's try different combinations:
- 55 + 39 - 16 = 84 - 16 = 68 (too low)
- 55 + 16 - 39 = 71 - 39 = 32 (too low)
- 55 - 16 + 39 = 39 + 39 = 78 (this works)
So, the equation is 55 - 16 + 39 = 78. </think>
<answer> 55 - 16 + 39 </answer>
<think> We need to use the numbers 21, 5, and 40 with basic arithmetic operations to get 24. Let's try different combinations:
- 21 - 5 - 40 = -15
- 21 - 5 + 40 = 56
- 21 + 5 - 40 = -14
- 21 * 5 / 40 = 2.1 (not an integer, let's try another)
- 40 * 5 / 21 = 9.52 (not 24)
- 40 / 5 - 21 = 9 - 21 = -12
- 5 * 40 / 21 = 100 / 21 ~= 4.76 (not 24)
- 5 + 40 - 21 = 24 ! This works.
</think>
<answer> 5 + 40 - 21 </answer>
<think> We need to use the numbers 75, 99, 62, and 34 with basic arithmetic operations to get 72. Let's try different combinations:
- 99 - 75 + 62 - 34 = 92 - 34 = 58 (too high)
- 99 - 75 - 62 + 34 = 24 - 62 + 34 = -38 + 34 = -4 (too low)
- 99 + 75 - 62 - 34 = 174 - 96 = 78 (too high)
- 99 + 75 - 62 + 34 = 174 + 34 - 62 = 208 - 62 = 146 (too high)
- 99 - 75 + 62 + 34 = 24 + 96 = 120 (too high)
- 75 + 99 - 62 - 34 = 174 - 96 = 78 (too high)
- 75 + 99 - 62 + 34 = 174 + 34 - 62 = 208 - 62 = 146 (too high)
- 75 + 62 - 99 + 34 = 137 - 99 + 34 = 38 + 34 = 72
So, 75 + 62 - 99 + 34 equals 72.
</think>
<answer> 75 + 62 - 99 + 34 </answer>
خاتمة
قد يكون إصدار DeepSeek R1 وورقة البحث الخاصة به بمثابة نقطة توقف لتطوير العلوم المفتوحة والمصادر المفتوحة. بعد أسبوع واحد فقط من إصدار DeepSeek، تمكنا من إعادة إنتاج نسخة بسيطة من “الاستدلال” المستفادة من R1 باستخدام GRPO ولعبة العد التنازلي. في حين أن تنفيذنا يركز على مهمة محددة بدلاً من التفكير العام والتقارب في تنسيق “استدلال” محدد للغاية، فإنه يظهر أن الطريقة تعمل.
وبالنظر إلى عام 2025، فمن الواضح أننا على أعتاب تقدم أكثر أهمية. ستصبح RL أكثر سهولة في الوصول إليها وسهلة الاستخدام، وسيستكشف المزيد من الباحثين والمطورين إمكاناتها، ولكنها تتطلب أيضًا قدرًا أكبر من الحوسبة كما كان من قبل ومقارنتها بالضبط الدقيق الخاضع للإشراف.
أنا متحمس لعام 2025. إذا كانت لديك أي أسئلة أو أفكار، فلا تتردد في التواصل معي.
إذا كان هذا يبدو مثيرًا للاهتمام، فنحن نحب مساعدتك! سواء أكان الأمر يتعلق بالمساهمة في التعليمات البرمجية، أو الانضمام إلى المناقشات حول Hugging Face.