التدريب على خادم GPU أو عنقود SLURM أو جهاز خلف NAT
أرسل تشغيلات التدريب في Potato إلى خادم GPU عبر ssh أو عقدة حوسبة SLURM أو وكيل يستطلع الخادم، مع التهيئة لكل منها وأمر الفحص وأشيع الأعطال.
جديد في v2.14.0
ينقل هذا الدرس تدريب النماذج في Potato من خادم التعليق التوضيحي إلى جهاز فيه GPU. الدرس موجّه إلى مسؤول دراسة يكون خادم التعليق التوضيحي لديه جهازاً سحابياً صغيراً أو حاسوباً محمولاً، وتكون وحدات GPU لديه على خادم مختبر أو عنقود جامعي أو محطة عمل لا يستطيع الخادم الاتصال بها. تغطي الصفحة، لكل خلفية من الخلفيات البعيدة الثلاث، متى تختارها، وما يلزم تثبيته على الجهاز البعيد، والتهيئة، وأمر الفحص، وما يحدث أثناء التشغيلة، وكيف تلغي تشغيلة، وأرجح الأعطال التي ستواجهها. يفترض الدرس مشروعاً يدرّب أصلاً على خادم التعليق التوضيحي، مثل مشروع المراجعات في درّب نموذجك الأول.
أربعة أماكن لتنفيذ التشغيلة
الخلفية هي المكان الذي تُنفَّذ فيه تشغيلة التدريب. لدى Potato دائماً الخلفية local، وهي عملية فرعية على خادم التعليق التوضيحي. وتسمّي الخلفيات الأخرى تحت model_training.backends:
| النوع | أين يعمل المُدرِّب | من يشغّل الطرف البعيد | أين تستقر ملفات النموذج |
|---|---|---|---|
local | خادم التعليق التوضيحي، في عملية فرعية | Potato | مجلد artifacts/ للتشغيلة |
ssh | جهاز يستطيع Potato بلوغه عبر ssh، مثل خادم GPU في مختبر | Potato، عبر ssh | تُنسخ إلى artifacts/ |
slurm | عقدة حوسبة في عنقود، بوصفها مهمة دفعية | Potato، عبر ssh إلى عقدة تسجيل الدخول، ثم sbatch | تُنسخ إلى artifacts/ |
agent | جهاز لا يستطيع Potato بلوغه، مثل محطة عمل خلف NAT | أنت، بالأمر potato training agent | على جهاز التدريب |
اختر ssh حين يستطيع خادم التعليق التوضيحي تسجيل الدخول إلى جهاز GPU بمفتاح ssh. واختر slurm حين تقع وحدات GPU خلف مجدوِل SLURM ويكون الجهاز الذي تسجّل الدخول إليه عقدة تسجيل دخول. واختر agent حين يتعذر فتح أي اتصال من الخادم إلى جهاز GPU، لأن الوكيل يفتح كل اتصال بنفسه. ومحطة العمل خلف موجّه منزلي أو جدار حماية جامعي هي الحالة المعتادة للوكيل. تصل التنبؤات ونتيجة التشغيلة إلى الخادم من كل خلفية، فتعمل الكتابة الراجعة ودرجة العناصر المحجوزة بالطريقة نفسها أياً كان المكان الذي عمل فيه المُدرِّب. يعمل كل مُدرِّب ما عدا decision-calibrate على أي خلفية.
تهيئة المشروع
الملف أدناه هو مشروع المراجعات من الدرس الأول مضافاً إليه الخلفيات البعيدة الثلاث كلها. لا يحتاج المشروع الحقيقي إلا إلى الخلفيات التي تستخدمها، ولكل خلفية قسمها أدناه. يوقف max_wall_seconds: 3600 أي تشغيلة لم تنته في ساعة. وعلى خلفية ssh أو agent يفحص الخادم الحد كل ثانية، فلا تحجز تشغيلة عالقة على جهاز بعيد طابور التشغيلات أكثر من الحد:
annotation_task_name: "Review Sentiment"
task_dir: "."
data_files:
- "data/reviews.json"
item_properties:
id_key: "id"
text_key: "text"
output_annotation_dir: "annotation_output"
admin_api_key: "change-me"
annotation_schemes:
- annotation_type: "radio"
name: "sentiment"
description: "Is this review positive or negative?"
labels: ["positive", "negative"]
model_training:
enabled: true
backend: gpu-server # the default for runs; leave out to keep runs local
max_wall_seconds: 3600
writeback:
schemas: ["sentiment"]
include_unlabeled: true
min_confidence: 0.6
backends:
gpu-server:
type: ssh
host: gpu.example.org
python: /opt/conda/bin/python3
gpus: auto
min_free_gpu_mb: 4000
cluster:
type: slurm
host: login.cluster.example.org
python: /opt/conda/bin/python3
job_python: /shared/envs/train/bin/python
remote_dir: /shared/projects/me/potato-training
gres: gpu:1
time: "04:00:00"
prelude: ["module load cuda/12.4"]
lab-workstation:
type: agent
queue_timeout_s: 3600تحقّق من ملف التهيئة قبل تشغيل الخادم:
potato validate config.yaml --strictيبلّغ المدقّق عن مفتاح لا يقبله نوع الخلفية، وعن خلفية ssh أو slurm بلا host، وعن remote_dir في SLURM تحت /tmp، وعن model_training.backend لا يسمّي أي خلفية. ولا يبدأ الخادم عند الأخطاء نفسها، فيوقف الخطأ الإملائي pyhton الخادم عند البدء بدلاً من إرسال التشغيلات إلى python3 الافتراضي.
قائمة Runs on وواجهة API
في صفحة التدريب على /admin/training قائمة Runs on تسرد كل خلفية مع نوعها ومضيفها، مثل gpu-server (ssh to gpu.example.org). يحدد model_training.backend المدخل الذي تختاره القائمة أولاً، ويسجّل جدول التشغيلات مكان تنفيذ كل تشغيلة في العمود Ran on. والتشغيلة التي تبدأ عبر API تسمّي خلفيتها في الحقل backend من جسم الطلب:
curl -X POST -H "X-API-Key: $KEY" -H "Content-Type: application/json" \
http://localhost:8000/admin/training/api/runs \
-d '{"trainer": "hf-text-classification", "schemas": ["sentiment"], "backend": "cluster"}'يُرفض اسم الخلفية غير الموجود في ملف التهيئة بالرمز 409. تستخدم إعادة التدريب التلقائية model_training.backend ما لم يسمّ auto_retrain.backend خلفية أخرى، ويغطي النموذج في الحلقة الإعداد auto_retrain بالكامل. وتُنفَّذ تشغيلة واحدة في كل مرة أياً كانت الخلفية، والتشغيلة التي تبدأ أثناء تشغيلة جارية تنتظر في الطابور.
التدريب على هذا الجهاز
افحص أي جهاز تحصل عليه التشغيلة المحلية قبل أن تنقل التشغيلات إلى مكان آخر. مع القيمة الافتراضية device: auto، تأخذ التشغيلة المحلية CUDA أولاً، ثم Metal من Apple (mps)، ثم المعالج، ويسمّي device: cuda:1 وحدة GPU بعينها. يطبع أمر الفحص الجهاز الذي ستستخدمه التشغيلة المحلية:
potato training check local config.yamlعلى جهاز Mac بمعالج Apple silicon يطبع الأمر local: this machine, Apple Metal (mps). والجهاز الذي تطلبه ولا يوجد يعود إلى المعالج أو إلى مسرّع آخر، مع تحذير في سجل التشغيلة. وحين يكون الجواب CPU ويضبط المُدرِّب محوِّلاً ضبطاً دقيقاً، انقل التشغيلة إلى خلفية بعيدة من الخلفيات أدناه. تسرد صفحة التهيئة المفاتيح device وnum_threads وmax_ram_mb للتشغيلات المحلية.
خادم GPU عبر ssh
تشغّل خلفية ssh المُدرِّب على جهاز يستطيع خادم التعليق التوضيحي بلوغه عبر ssh، وهو عادةً خادم GPU في مختبر. يبدأ Potato كل شيء في الطرف البعيد بنفسه، فلا يُثبَّت هناك شيء ولا يُشغَّل يدوياً سوى Python وحزم المُدرِّب. ولا يحتاج مضيف GPU إلى تثبيت Potato، لأن Potato ينسخ شيفرته المصدرية بنفسه إلى المضيف في التشغيلة الأولى ويعيد استخدام النسخة إلى أن يتغير المصدر.
متطلبات خلفية ssh
يحتاج الحساب الذي يعمل به خادم التعليق التوضيحي إلى مفتاح ssh يسجّل الدخول إلى مضيف GPU بلا مطالبة. يشغّل Potato الأمر ssh مع BatchMode=yes، فتفشل التشغيلة فوراً عند ظهور مطالبة بكلمة مرور بدلاً من أن تتعلق. يجب أن ينجح الأمر ssh gpu.example.org true بذلك الحساب، ويصلح مفتاح بعبارة مرور إذا كان ssh-agent يحمل المفتاح. وقيمة host أي اسم يقبله ssh، ويصلح اسم مستعار من ~/.ssh/config. وتُمرَّر المفاتيح user وport وidentity_file إلى ssh بالخيارات -l و-p و-i.
يحتاج مضيف GPU إلى Python 3.8 أو أحدث وإلى حزم المُدرِّب الذي تشغّله. وهذه الحزم لـhf-text-classification هي torch وtransformers وpeft، أي محتويات الإضافة potato-annotation[train-text]. تذكر صفحة المُدرِّبات أمر التثبيت لكل مُدرِّب. وحين ينقص مفسّر المضيف حزمة، وجّه python إلى مفسّر يملك الحزمة، أو أدرج الحزمة تحت packages. مع ضبط packages، ينشئ Potato بيئة افتراضية تحت remote_dir بالخيار --system-site-packages ويثبّت الحزم المدرجة فيها مرة واحدة. ويبقى إصدار torch المبني على CUDA في المضيف ظاهراً داخل البيئة:
model_training:
enabled: true
backends:
gpu-server:
type: ssh
host: gpu.example.org
python: /opt/conda/bin/python3
packages: ["transformers>=4.46.0", "peft>=0.13.0"]
gpus: auto
min_free_gpu_mb: 4000
num_threads: 8مع gpus: auto، تأخذ كل تشغيلة وحدة GPU الأكثر ذاكرة حرة وترفض البدء حين لا تملك أي وحدة ما يبلغ min_free_gpu_mb من ذاكرة حرة (الافتراضي 2000). يقارن Potato الذاكرة الحرة لا الاستخدام، لأن البطاقة منخفضة الاستخدام على خادم مشترك قد تكون ذاكرتها الحرة قليلة. اضبط min_free_gpu_mb قرب الذاكرة التي يحتاجها مُدرِّبك. يثبّت gpus: "1" وحدة GPU رقم 1، ويثبّت "0,1" وحدتين، ويدرّب gpus: none على المعالج. والمضيف الذي لا GPU فيه أصلاً يدرّب على معالجه تحت auto أيضاً. يضبط num_threads المتغيرات OMP_NUM_THREADS وMKL_NUM_THREADS وOPENBLAS_NUM_THREADS للتشغيلة. وبعض الخوادم المشتركة تضبط OMP_NUM_THREADS=1 في صدفات تسجيل الدخول، ويتجاوز num_threads قيمة صدفة تسجيل الدخول.
أمر الفحص لخلفية ssh
شغّل الفحص من خادم التعليق التوضيحي، بالحساب الذي يعمل به الخادم:
potato training check gpu-server config.yamlيتصل الأمر ويبلّغ عن إصدار Python البعيد، وعن كل وحدة GPU مع ذاكرتها الحرة واستخدامها، وعن وحدة GPU التي ستحصل عليها التشغيلة، وعن حزم التدريب التي ينقصها المفسّر البعيد. وتوسَم وحدة GPU التي لا نوى لها في torch المثبّت بالعبارة (torch there has no kernels for it)، ويتخطى gpus: auto هذه الوحدة. يطبع --json التقرير نفسه بصيغة JSON. وينتهي الأمر بالرمز 0 إذا أمكن بدء تشغيلة وبالرمز 1 خلاف ذلك. ويجري الزر Check بجوار القائمة Runs on الفحص نفسه من صفحة التدريب.
خطوات تشغيلة ssh
يؤدي Potato الخطوات التالية في كل تشغيلة:
- يتصل بالأمر
sshويفتح توجيهاً عكسياً من مقبس يونكس في/tmpالبعيد إلى خادم التعليق التوضيحي. - يفحص المفسّر، ويقرأ
nvidia-smi، ويختار وحدة GPU. - ينسخ شيفرة Potato المصدرية إلى
remote_dir/code/<hash>حين ينقص المضيف ذلك الإصدار، وينشئ البيئة الافتراضية حين يُضبطpackagesوتكون البيئة غير موجودة. القيمة الافتراضية لـremote_dirهي~/.cache/potato-training. - يشغّل
python -m potato.training.agentللتشغيلة. يصل رمز التشغيلة إلى الوكيل عبر الدخل القياسي ولا يظهر أبداً في سطر أوامر، لأن أسطر الأوامر مرئية لكل حساب على الخادم المشترك. - ينزّل الوكيل حزمة العناصر والتصنيفات والوسائط الخاصة بالتشغيلة. ويشغّل الوكيل عامل التدريب نفسه الذي تشغّله الخلفية المحلية، ويرسل التقدم والتنبؤات والنتيجة عبر المقبس.
- حين تنجح التشغيلة، ينسخ Potato مجلد القطع الناتجة إلى
artifacts/للتشغيلة، ويحذف مجلد المهمة البعيد، ويغلق الاتصال.
يتبع سطر الخطوة في صفحة التدريب هذه المراحل، مثل copying Potato's code to gpu.example.org وwaiting for the agent on gpu.example.org. ويذكر سجل التشغيلة Python المضيف ووحدة GPU التي حصلت عليها التشغيلة.
يعيد الضبط الدقيق الكامل نسخ النموذج كله، وعلى وصلة بطيئة يستغرق نموذج حجمه 330 MB دقائق. ويعرض سطر الخطوة مقدار ما وصل من النموذج. تبقى الملفات الأكبر من max_artifact_mb (الافتراضي 2048) على مضيف GPU وتُذكر في سجل التشغيلة. ويترك fetch_artifacts: false كل ملفات النموذج على مضيف GPU، ويُبقي keep_remote: true مجلد المهمة البعيد للفحص. ويحتاج دفع Hugging Face Hub من صفحة التشغيلة إلى ملفات النموذج على خادم التعليق التوضيحي، فلا يُدفع من صفحة التشغيلة نموذجٌ بقي على مضيف GPU.
يُنشأ مقبس يونكس بالوضع 0600، فلا يستطيع الاتصال عبره إلا الحساب الذي سجّل Potato الدخول به. وتصل الطلبات عبر المقبس إلى خادم التعليق التوضيحي بوصفها طلبات حلقة محلية. والخادم الذي يبدأ مع debug: true يمنح الطلبات المحلية صلاحية المسؤول. وعندئذ يملك كل من يستطيع استخدام ذلك الحساب على مضيف GPU صلاحية المسؤول على خادم الاستكشاف أثناء تشغيلة جارية. أبقِ debug معطّلاً على خادم يدرّب عبر ssh.
الإلغاء ومهلة نبضات الحياة
يصل Cancel run في صفحة التدريب إلى الوكيل عبر المقبس، في استجابة تقرير التقدم التالي للوكيل. يرسل الوكيل SIGTERM إلى العامل، وSIGKILL إذا ظل العامل يعمل بعد model_training.grace_seconds (الافتراضي 20)، وهي القيمة التي يرسلها الخادم مع المهمة. والمهمة الآتية من خادم Potato أقدم لا تحمل grace_seconds، فينتظر الوكيل حينئذ 20 ثانية. وعلى الخادم تنتهي التشغيلة بوصفها ملغاة حين تمر grace_seconds، ويغلق الخادم جلسة ssh الخاصة بالوكيل. والتشغيلة التي لا يرسل وكيلها شيئاً مدة heartbeat_timeout_s (الافتراضي 120) تفشل، ويحتوي agent.log في مجلد التشغيلة على آخر ما أخرجه الوكيل.
عنقود SLURM
خلفية slurm مخصصة لعنقود تقع وحدات GPU فيه خلف مجدوِل SLURM. والجهاز الذي يستطيع Potato بلوغه عبر ssh في عنقود كهذا هو عقدة تسجيل دخول لا GPU فيها، ولا تستطيع عقد الحوسبة بلوغ Potato أصلاً. لذلك يشغّل Potato الوكيل على عقدة تسجيل الدخول، كما تفعل خلفية ssh، ولا يرسل الوكيل إلى عقدة حوسبة إلا عامل التدريب بالأمر sbatch. ويعود التقدم عبر ملف على تخزين تشترك فيه عقدة تسجيل الدخول وعقد الحوسبة.
متطلبات خلفية SLURM
تحتاج عقدة تسجيل الدخول إلى مفتاح ssh بلا مطالبة وإلى Python 3.8 أو أحدث للوكيل، كما يحتاج مضيف خلفية ssh. وتحتاج أيضاً إلى sbatch وsqueue وscancel في PATH. ويستدعي الوكيل scontrol كذلك حيث يوجد الأمر في العنقود. لا يستدعي Potato srun ولا sacct أبداً، فيعمل عنقود عُطّل فيه srun ولا قاعدة محاسبة فيه. والمفتاح remote_dir مطلوب ويجب أن يقع على تخزين تشترك فيه عقد الحوسبة، لأن المهمة تقرأ الحزمة وتكتب النموذج هناك. ويبلّغ المدقّق عن خطأ إذا وقع remote_dir تحت /tmp أو /var/tmp، لأن هذين المجلدين محليان لكل عقدة.
تحتاج عقد الحوسبة إلى مفسّر فيه حزم المُدرِّب، يسمّيه job_python. ولا يُدعم packages في خلفية SLURM، لأن البيئة الافتراضية المنشأة على عقدة تسجيل الدخول قد لا تعمل على عقد الحوسبة. وجّه job_python إلى بيئة موجودة على عقد الحوسبة، وضع تحميل الوحدات أو تفعيل البيئة في prelude:
model_training:
enabled: true
backends:
cluster:
type: slurm
host: login.cluster.example.org
python: /opt/conda/bin/python3 # on the login node, for the agent
job_python: /shared/envs/train/bin/python # on the compute nodes, for the worker
remote_dir: /shared/projects/me/potato-training # storage the compute nodes share
partition: gpu
gres: gpu:1
time: "04:00:00"
prelude: ["module load cuda/12.4"]كل مفتاح ssh ينطبق على خلفية SLURM ما عدا gpus وpackages. تأتي وحدات GPU من gres، ويضبط المجدوِل CUDA_VISIBLE_DEVICES للوحدات التي يمنحها. والمهمة بلا gres لا تحصل على GPU. وتقابل إعدادات SLURM خيارات sbatch:
| المفتاح | الافتراضي | المعنى |
|---|---|---|
job_python | python الخاص بالخلفية | مفسّر العامل على عقد الحوسبة. |
gres | لا شيء | sbatch --gres، مثل gpu:1 أو gpu:A6000:1. |
time | 04:00:00 | sbatch --time. فوق 6 ساعات يبلّغ potato validate وبدء الخادم عن تحذير، كما تصف الفقرة التالية. |
partition | الافتراضي في العنقود | sbatch --partition. |
nice | 0 | sbatch --nice، من 0 إلى 2000. |
cpus_per_task وmem | الافتراضيان في العنقود | sbatch --cpus-per-task و--mem. |
sbatch_options | [] | خيارات إضافية، مثل ["--requeue", "--constraint=a100"]. يضبط Potato --output و--chdir و--job-name و--parsable بنفسه، ويبلّغ المدقّق عن خطأ لهذه الخيارات هنا. |
prelude | [] | أسطر صدفة تُشغَّل في المهمة قبل العامل. |
poll_interval_s | 30 | الثواني بين استدعاءات squeue، وحدها الأدنى 10. |
exit_grace_s | 180 | الثواني المنتظَرة لظهور رمز خروج مهمة منتهية على عقدة تسجيل الدخول، وحدها الأدنى 20. |
job_name | potato-train | بادئة اسم المهمة، يليها أول 8 محارف من معرّف التشغيلة. |
يجعل time الأكبر من 6 ساعات كلاً من potato validate وبدء الخادم يبلّغان model_training.backends.cluster.time is 12:00:00. A job that holds a GPU for more than 6 hours is long on a shared cluster; check its policy، ويفشل potato validate --strict عند هذا التحذير. وحين تسمح سياسة العنقود بالمهمة الأطول، أقرّ التحذير لهذه الخلفية وحدها في كتلة validation من المستوى الأعلى، التي لا يقرؤها إلا potato validate:
validation:
acknowledge:
- "model_training.backends.cluster.time is"يُطابَق كل مدخل مع نص التحذير بوصفه سلسلة جزئية حساسة لحالة الأحرف لا يقل طولها عن 12 محرفاً، ويُنقل التحذير المطابَق إلى قائمة التحذيرات المُقَرّة ولا يُفشل --strict بعد ذلك. والمدخل الذي يسمّي الخلفية يُقِرّ التحذير لتلك الخلفية وحدها. والمدخل القصير جداً أو الذي لا يطابق أي تحذير يصبح تحذيراً مستقلاً.
أمر الفحص لخلفية SLURM
potato training check cluster config.yamlيسجّل الفحص الدخول إلى عقدة تسجيل الدخول ويتأكد من وجود sbatch وsqueue وscancel في PATH ومن أن remote_dir ليس تحت /tmp. ويذكر التقرير إصدار Python على عقدة تسجيل الدخول وjob_python الذي ستشغّله المهمة. ولا يستطيع الفحص أن يرى الحزم الموجودة على عقد الحوسبة، فتظهر الحزمة الناقصة على عقدة حوسبة تشغيلةً فاشلة مع خطأ الاستيراد في سجل التشغيلة. شغّل مهمة أولى قصيرة بقيمة time صغيرة لاكتشاف مثل هذه المشكلات مبكراً.
خطوات تشغيلة SLURM
يتصل Potato بعقدة تسجيل الدخول وينسخ شيفرته إليها، كما في خلفية ssh. ثم يؤدي الوكيل الخطوات التالية:
- ينزّل الحزمة إلى
remote_dir/jobs/<run>/. - يكتب
job.shويرسل السكربت بالأمرsbatch --parsable. ويسجّل سجل التشغيلةSubmitted SLURM jobمع معرّف المهمة والخيارات. - في مجلد المهمة، يكتب العامل على عقدة الحوسبة أحداثه في
events.jsonlوأخطاءه فيstderr.logورمز خروجه فيexit_code. ويذهب خرج SLURM نفسه إلىslurm.out. - يقرأ الوكيل
events.jsonlكلما نما الملف ويمرّر التقدم إلى الخادم. ويشغّل الوكيلsqueueمرة كلpoll_interval_s، ويسجّل سجل التشغيلة كل تغيّر في حالة المهمة في الطابور، مثلSLURM job 4242: PENDING (Priority)ثمRUNNING on node07. - حين تنتهي المهمة، يرفع الوكيل التنبؤات ويبلّغ النتيجة. وتعود القطع الناتجة إلى الخادم ويُزال مجلد المهمة، كما في خلفية ssh.
يرسل Cancel run الأمر scancel --full --signal=TERM إلى المهمة، ثم scancel عادياً إذا لم يتوقف العامل. وحين تنقطع جلسة ssh إلى عقدة تسجيل الدخول يلغي الوكيل مهمته، ويُفرَج عن حجز GPU. وحين ينهي المجدوِل مهمة بنفسه، تفشل التشغيلة بسبب المجدوِل، وهو يُقرأ من scontrol show job أو slurm.out. ومن الأسباب التي يبلّغ عنها Potato بلوغ حد الوقت، وعطل العقدة، والاستباق، ونفاد الذاكرة، وأمر scancel من خارج Potato.
تشغّل مجموعة اختبارات Potato تسلسل SLURM على بديل عن sbatch وsqueue وscancel، وتغطي إرسال المهمة وحالة الطابور وتمرير التقدم والإلغاء. وتختلف حدود الأقسام وسياسة الاستباق من عنقود إلى آخر، فراقب سجل تشغيلة مهمتك الأولى على أي عنقود جديد.
يستطيع وكيل يُشغَّل يدوياً على عقدة تسجيل دخول تبلغ الخادم أن يرسل إلى SLURM أيضاً، بالأمر potato training agent --server ... --backend <name> --workdir <shared dir> --slurm-config slurm.json. يضم الملف slurm.json الإعدادات الواردة في الجدول أعلاه بوصفها كائن JSON، ويجب أن يقع --workdir على تخزين تشترك فيه عقد الحوسبة.
جهاز لا يستطيع Potato بلوغه
خلفية agent مخصصة لجهاز لا يستطيع خادم التعليق التوضيحي الاتصال به، مثل محطة عمل خلف NAT. يشغّل شخص ما potato training agent على ذلك الجهاز، ويستطلع الوكيل الخادم بحثاً عن مهام. لا يحتاج الوكيل إلى منفذ وارد، لأنه يفتح كل اتصال بنفسه. ويصل الإلغاء إلى الوكيل في استجابة الخادم لتقرير التقدم التالي للوكيل. وتبقى ملفات النموذج على جهاز التدريب، ولا يعود إلا التنبؤات والنتيجة.
متطلبات خلفية agent
يحتاج جهاز التدريب إلى Potato مثبّتاً وإلى حزم المُدرِّب الذي تشغّله وإلى مسار شبكي إلى عنوان URL لخادم التعليق التوضيحي. ولـhf-text-classification يغطي تثبيت واحد Potato وحزم المُدرِّب:
pip install "potato-annotation[train-text]"لا يحتاج الخادم إلا إلى مدخل الخلفية. تقبل خلفية agent المفاتيح type وdescription وheartbeat_timeout_s (الافتراضي 120) وqueue_timeout_s، ولا مفتاح غيرها:
model_training:
enabled: true
backends:
lab-workstation:
type: agent
queue_timeout_s: 3600تسجيل الوكيل وتشغيله
أصدر رمزاً للخلفية على خادم التعليق التوضيحي:
potato training register lab-workstation config.yamlيطبع الأمر الرمز مرة واحدة، مع الأوامر التي تُشغَّل على جهاز التدريب:
Token for backend 'lab-workstation' (shown once; registering again replaces it):
<token>
On the training machine:
export POTATO_TRAINING_TOKEN=<token>
potato training agent --server http://<this-server>:8000 --backend lab-workstationشغّل الوكيل على جهاز التدريب بعنوان URL الحقيقي للخادم:
export POTATO_TRAINING_TOKEN=<the token>
potato training agent --server https://annotate.example.org --backend lab-workstationيشغّل الوكيل مهام خلفيته إلى أن توقفه. يقرأ --token-file الرمز من ملف بدلاً من POTATO_TRAINING_TOKEN، ويسمّي --python المفسّر الذي يعمل فيه عامل التدريب، والافتراضي هو مفسّر الوكيل نفسه. ويخرج --once بعد مهمة واحدة، ويُبعد --workdir ملفات الوكيل عن ~/.cache/potato-training، ويُبقي --keep حزمة كل مهمة. وتسجيل الاسم من جديد يصدر رمزاً جديداً ويُبطل الرمز القديم.
يطبع potato training check lab-workstation config.yaml سجل رمز الخلفية، مع ضبط last_seen متى اتصل وكيل. وقبل التسجيل يطبع الأمر no token issued yet وأمر التسجيل الواجب تشغيله.
خطوات تشغيلة agent
تنتظر التشغيلة لخلفية agent في الحالة queued إلى أن يطلب وكيل عملاً. ومع queue_timeout_s: 3600 تفشل التشغيلة بعد ساعة بلا وكيل، ومن دون queue_timeout_s تنتظر التشغيلة إلى أن تلغيها. ينزّل الوكيل الحزمة بوصفها ملف tar.gz ويستأنف التنزيل المنقطع من حيث توقف، حتى خمس محاولات. ثم يشغّل الوكيل العامل، ويرسل التقدم، ويرفع predictions.jsonl، ويبلّغ رمز الخروج. ويردّ الخادم بالرمز 413 على ملف تنبؤات أكبر من max_predictions_mb (الافتراضي 512).
تبقى ملفات النموذج على جهاز التدريب تحت --workdir، ويسمّي artifact_uri في سجل التشغيلة المضيف والمجلد. وإذا تعذّر على الوكيل بلوغ الخادم مدة 300 ثانية أثناء تشغيلة، ألغى الوكيل التشغيلة بنفسه. والتشغيلة التي لا يرسل وكيلها شيئاً مدة heartbeat_timeout_s تفشل على الخادم بالرسالة No word from the agent on lab-workstation for 120 seconds.
الأعطال الشائعة
يعطي كل مدخل الرسالة الواردة في سجل التشغيلة أو تقرير الفحص، ثم الحل. والقائمة الكاملة لكل خلفية ولكل مُدرِّب في قسم استكشاف الأخطاء في الوثائق الأصلية.
ssh to gpu.example.org failed: Permission denied. يحتاج Potato إلى مفتاح يعمل بلا مطالبة. يجب أن ينجحssh gpu.example.org trueمن حساب الخادم./opt/conda/bin/python3 was not found on gpu.example.org. اضبطpythonفي الخلفية على مفسّر موجود على المضيف.No GPU has 4000 MB free. كل وحدات GPU على المضيف أكثر انشغالاً مما يسمح بهmin_free_gpu_mb. يسردpotato training check gpu-server config.yamlالوحدات. انتظر، أو اخفض العتبة، أو ثبّت وحدة بـgpus: "1".Trainer 'hf-text-classification' could not be imported. ينقص المفسّر البعيد حزمة يحتاجها المُدرِّب. وجّهpythonإلى مفسّر فيه الحزمة، أو أدرج الحزمة تحتpackages. وفي خلفية SLURM أصلح البيئة التي يسمّيهاjob_python.This host's torch has no kernels for any of its GPUs. بُني torch البعيد لوحدات GPU أحدث من وحدات المضيف. ثبّت إصدار torch مبنياً لتلك الوحدات، أو استخدم مضيفاً آخر.No word from the agent on gpu-server for 120 seconds. اختفى الجهاز البعيد أو الشبكة. وفي خلفية ssh يحتويagent.logفي مجلد التشغيلة على آخر ما أخرجه الوكيل.The copy from gpu.example.org sent nothing for 180 s. توقفت الشبكة إلى المضيف أثناء نسخ النموذج عائداً. تنبؤات التشغيلة مخزّنة أصلاً، ولا ينقصartifacts/إلا ملفات النموذج.login.cluster.example.org has no sbatch on PATH, so it cannot submit jobs. ليسhostعقدة تسجيل الدخول في العنقود، أو أن الأوامر فيPATHلا تضبطه إلا صدفة تسجيل الدخول. اضبطPATHتحتenvالخاص بالخلفية.SLURM job 4242 ended before the worker finished: it reached its time limit. ارفعtimeفي الخلفية، أو درّب على عناصر أقل. واضبطkeep_remote: trueلإبقاءslurm.outللقراءة بعد إخفاقات المجدوِل الأخرى.- تشغيلة على خلفية agent تبقى في الطابور. لا وكيل بهذا اسم الخلفية يستطلع الخادم. شغّل وكيلاً بالأمر
potato training agent --backend lab-workstation، وافحص الرمز بـCheck في صفحة التدريب. nvrtc: error: failed to open libnvrtc-builtins.so.13.0. torch في المضيف وحزمتهnvidia-cuda-nvrtcلإصدارين مختلفين من CUDA. ثبّتnvidia-cuda-nvrtcالمطابقة لبناء torch، أو وجّهpythonإلى مفسّر آخر.
قراءات إضافية
- تغطي نظرة عامة على تدريب النماذج صفحة التدريب وحلقة التدريب ونشر نموذج على Hugging Face Hub.
- تسرد التهيئة كل مفتاح في
model_trainingودرجات العناصر المحجوزة ومكان تخزين التشغيلات. - يغطي الضبط الدقيق للنماذج اللغوية الكبيرة المُدرِّبات التي تحتاج في الغالب إلى GPU بعيد، مع LoRA وأوزان أساسية بدقة 4 بت.
- في المرجع الأصلي عن أماكن تنفيذ التشغيلات جدول المفاتيح الكامل لكل خلفية، ويوثّق قسم بروتوكول الوكيل المسارات لمن يكتب وكيله الخاص.