ستة عشر يومًا من الحوسبة على وحدة معالجة رسوميات واحدة
تشغيل طويل واحد
يستغرق ANDREA-120M حوالي 23 يومًا على RTX 4090 (FP16، 6 خطوات/دقيقة، 200 ألف خطوة). استهلاك الطاقة، انهيارات النواة، تعطل الوكيل، & التغييرات المتعمدة في الإعدادات كلها تحدث خلال تلك الفترة. بدون نقاط التفتيش، يُهمل أي تعثر التشغيل بأكمله.
فقدت الإصدار v1 27 ألف خطوة بسبب خطأ واحد (lr=0.001 عدواني جدًا) لأن أقرب نقطة تفتيش كانت عند نقطة الإطلاق. امتص v2 ذلك الدرس: تردد نقاط التفتيش انخفض إلى كل 100 خطوة، & معالج إشارات CUDA يضمن كتابة نقطة تفتيش عند SIGTERM.
ثلاثة أدوار
يقوم نقطة التفتيش بخدمة ثلاث وظائف في وقت واحد:
1. نقطة الاسترداد. إذا توقف العملية، أو أعاد الجهاز التشغيل، أو حدث ذعر في النواة: استأنف من أحدث step_NNNNNN.bin.
2. نقطة تحول مصقولة. الخطوة 112,619: غيّر المنهج دون إعادة تدريب. يجبر SIGUSR1 على نقطة تفتيش نظيفة، يتوقف الوكيل، يتم تقديم حدود علوية وسفلية جديدة، ويستأنف CUDA من النقطة المحفوظة تحت سياسة جديدة.
3. فرع التدقيق. قارن بين إعدادين في نفس الأوزان الابتدائية: انسخ نقطة تفتيش، شغّل فرعين متفرعين للأمام، راقب أيّهما يتقارب.
كل 100 خطوة تعطي حوالي 17 دقيقة من التدريب بين عمليات الكتابة بمعدل 6 خطوات/دقيقة. 100 خطوة تتطابق أيضًا مع sample_every: كل نقطة تفتيش تتوافق مع فحص عينة جديد واحد، & كل فحص عينة يتوافق مع نقطة قابلة للاسترداد.
ثلاثة أدوار لملف واحد
خمس مناطق في ملف واحد
التنسيق
كل ملف step_NNNNNN.bin يحتوي على خمس مناطق متتالية:
[int32 step] [int32 n_params] [n_params x float32 weights] [n_params x float32 m] [n_params x float32 v]
منطقة بمنطقة
الرأس (8 بايت إجمالي). رقم خطوة 32 بت يخبرنا أين يقع هذا اللقطة في التدريب؛ عدد معاملات 32 بت يخبرنا بمدى كبر كل من المصفوفات الثلاث التالية.
الأوزان (n_params × 4 بايت). كل معامل متعلم، مسطح. الترتيب يطابق مكرر معاملات النموذج: تضمينات الرموز والمواضع، ثم أوزان الاهتمام والـMLP لكل طبقة، ثم رأس الإخراج.
أول لحظة آدم m (n_params × 4 بايت). متوسط متحرك أسي لتدرجات الماضي (beta1 = 0.9). نفس شكل الأوزان. مطلوب لاستئناف AdamW.
لحظة آدم الثانية v (n_params x 4 بايت). المتوسط المتحرك الأسي لتدرجات المربعة السابقة (beta2 = 0.999). نفس شكل الأوزان. مطلوب لاستئناف AdamW.
الحجم الإجمالي
إجمالي البايتات = 8 + 12 x n_params. ANDREA-12M (12.8M معلمة): 154 ميغابايت على القرص (147 ميغابايت مدور). ANDREA-120M (~120M معلمة) FP32: ~1.44 جيجابايت. ثلاث مصفوفات بنفس الشكل، مكدسة جنبًا إلى جنب، مع رأس صغير.
لماذا نحفظ m & v
آدم العادي يتتبع معدلات التعلم لكل معلمة عبر m & v. إسقاطهما عند كتابة نقطة التفتيش & تشغيل مستأنف يبدأ بزخم صفري & تقدير تباين صفري، ما يعادل معدل تعلم 0 لخطوة واحدة ثم ارتفاع مفاجئ. ارتفاع الخسارة؛ يمكن للنموذج الخروج من حوضه الحالي. حفظ m & v يجعل الاستئناف متطابقًا بتات (باستثناء عشوائية dataloader) مع الخط الأساسي الذي لم يتوقف أبدًا.
تحديد حجم نقطة التفتيش الواحدة
SIGTERM & SIGUSR1
لماذا يتعامل CUDA مع الإشارات
يتم تشغيل التدريب كعملية أمامية طويلة الأمد. عندما يريد الوكيل أو المشغل إيقاف وحدة معالجة الرسوميات، يتم إرسال إشارة إلى محرك CUDA. بدون معالج، تقتل SIGTERM الافتراضية العملية فوراً: يتم تجاهل حساب التدرج الجاري، وتفقد أحدث الأوزان منذ آخر نقطة حفظ. مع معالج، يكتب المحرك نقطة حفظ أولاً ثم يخرج بشكل نظيف.
SIGTERM: كتابة وخروج
يتم إرسالها بواسطة زر إيقاف، أو systemctl stop، أو kill من وكيل أب. ينهي CUDA الخطوة الحالية، يكتب step_NNNNNN.bin على القرص، ثم يخرج. الاسترداد من هذه الحالة يحتاج فقط إلى أحدث .bin: لا عمل يُفقد سوى الخطوة الجزئية الجارية.
SIGUSR1: كتابة واستمرار
يتم إرسالها عند الطلب بواسطة المشغل أو سكريبت الوكيل. ينهي CUDA الخطوة الحالية، يكتب step_NNNNNN.bin، ثم يستمر في التدريب كما لو لم يحدث شيء. مفيد لـ: تشغيل نقطة تدقيق قبل تغيير إعدادات؛ التقاط الأوزان في لحظة معروفة الجودة؛ محاذاة نقطة حفظ مع تشغيل تصنيف جودة عينة خارجي.
تسلسل الدوران البولندي (الخطوة 112,619)
1. يرسل المشغل SIGUSR1 إلى CUDA. يتم كتابة نقطة التفتيش عند الحدود التالية لـ 100 خطوة (الخطوة 112,700).
2. يوقف المشغل الوكيل.
3. يتم أرشفة .samples.json & .state.json (يتم حفظ سجل العينة وحالة البانديت كسجل تاريخي).
4. يبقى .loss.json في مكانه. تاريخ التدريب التراكمي؛ لا يتم أرشفته أبدًا.
5. يعيد تشغيل الوكيل تحت حدود عليا وسفلية جديدة.
6. يستأنف CUDA من step_112700.bin مع بانديت جديد لكن أوزان كاملة، m، & v.
تستمر سجل الخسائر دون انقطاع عبر نقطة التحول. يتم إعادة تعيين سجل العينة بشكل نظيف. يحصل Bandit على بداية جديدة تحت السياسة الجديدة.
اختيار الإشارة
تاريخ التدريب التراكمي
ثلاثة ملفات جانبية
بجانب كل نقطة تفتيش، يحتفظ الوكيل بثلاثة ملفات جانبية JSON في مجلد التشغيل:
- .loss.json -- إدخال واحد لكل خطوة، دائمًا. ~200,000 إدخال بنهاية التشغيل. تاريخ التدريب التراكمي.
- .samples.json -- عينات مولدة حديثة للتدقيق. إعادة تعيين عند نقاط التلميع.
- .state.json -- سحب ذراع البانديت، مكافآت EMA، عدادات المراحل. إعادة تعيين عند نقاط التلميع.
ما الذي يُعاد تعيينه، وما الذي يستمر
الانقلابات البولندية هي تغييرات في السياسة، وليست إعادة تعيين للتشغيل. أوزان النموذج، m، v، وتاريخ الخسارة جميعها تستمر دون انقطاع. مكافآت البانديت المتراكمة لا تستمر: الحدود الجديدة والأسقف تحدد سياسة مختلفة، ويجب على البانديت إعادة التعلم تحت السياسة الجديدة من حالة نظيفة.
لماذا يبقى .loss.json
تاريخ الخسارة يعمل كسجل تدقيق للتشغيل. كل ادعاء منشور عن ANDREA-120M (متوسط متحرك أسي للخسارة في الخطوة 110K، تعافي الانقلاب البولندي، التقارب في الخطوة 112K) يعود إلى إدخالات في هذا الملف. أرشفة .loss.json بين المراحل ستجبر القراء على لصق الشظايا معًا لإعادة بناء التشغيل؛ الحفاظ عليه كإضافة فقط وغير معدل يحافظ على الأصل.
درس الذراع الزومبي
الخطوة 112,619 وجدت ذراع repo-docstrings في .state.json يحمل وزن 1.546 من تشغيل سابق. كانت حالة البانديت محفوظة عبر إعادة تشغيل سابقة لكن مصدر البيانات لم يعد متاحًا، مما أنتج سحوبات زومبي مشوهة لحساب الاستكشاف. الدرس: حالة البانديت مسموح لها بالانجراف عبر إعادات التشغيل بطرق مفاجئة. تاريخ الخسارة هو الملف الوحيد الذي يجب أن يظل غير معدل طوال عمر التشغيل الكامل.
قاعدة واحدة تحكمهم جميعًا
قم بأرشفة .samples.json & .state.json بحرية بين المراحل. لا تقم أبدًا بأرشفة .loss.json. أحدث .loss.json هو دائمًا سجل التدريب الرسمي.
تطبيق القاعدة
ما تم بناؤه ولماذا
خمس قرارات
1. الإيقاع: كل 100 خطوة. دقة نقطة الاسترداد ~17 دقيقة. يتوافق مع sample_every بحيث يتوافق كل نقطة تفتيش مع تدقيق عينة جديدة واحدة.
2. الصيغة: رأس + 3 مصفوفات. أدنى حد ممكن: رأس 8 بايت يخبرنا بحجم كل مصفوفة تالية. لا تضخيم في البيانات الوصفية. استئناف مطابق تمامًا للبتات عند حفظ m & v.
3. الإشارات: SIGTERM & SIGUSR1. دورين، إشارتان. إغلاق systemd الافتراضي يحصل على نقطة تفتيش نظيفة عبر SIGTERM؛ نقاط التدقيق عند الطلب تحصل على نقطة تفتيش نظيفة عبر SIGUSR1 دون التوقف.
4. استمرارية الخسارة: لا يتم أرشفتها أبدًا. تستمر تاريخ التدريب التراكمي عبر نقاط التلميع، إعادة التشغيل، & تغييرات السياسة. مسار تدقيق واحد للتشغيل بأكمله.
5. حالة البانديت: يُسمح بإعادة التعيين. تعيش سياسة البانديت تحت تكوين واحد في كل مرة. نقاط التلميع تعيد التعيين؛ تستمر تاريخ الخسارة. عمرين مختلفين يشتركان في نفس دليل التشغيل.
ما يرتبط به هذا الدرس
- Activity 23 (grow_a_language_model_sample_audit). sample_every cadence matches checkpoint cadence; both fire every 100 steps.
- Activity 24 (grow_a_language_model_microgpt_to_andrea). v1 collapse, v2.5 patch, v3 polish pivot all required clean checkpoints to operate.
- Activity 10 (grow_a_language_model_adamw). Saving m & v in the checkpoint matters because AdamW's update rule depends on both. Drop them & resume diverges.
حقيقة هندسية أخيرة
الكود يدوم أطول من المؤلفين. البنية التحتية تدوم أطول من البنائين. تنسيق نقطة تفتيش بسيط يدوم أطول من كل مخطط استئناف معقد وعد بتخطي حفظ حالة المحسن. وفر البايتات؛ وفر التشغيل.