تخطّي إلى المحتوى

التدريب على خادم 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 يفحص الخادم الحد كل ثانية، فلا تحجز تشغيلة عالقة على جهاز بعيد طابور التشغيلات أكثر من الحد:

yaml
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

تحقّق من ملف التهيئة قبل تشغيل الخادم:

bash
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 من جسم الطلب:

bash
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 بعينها. يطبع أمر الفحص الجهاز الذي ستستخدمه التشغيلة المحلية:

bash
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 في المضيف ظاهراً داخل البيئة:

yaml
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

شغّل الفحص من خادم التعليق التوضيحي، بالحساب الذي يعمل به الخادم:

bash
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 الخطوات التالية في كل تشغيلة:

  1. يتصل بالأمر ssh ويفتح توجيهاً عكسياً من مقبس يونكس في /tmp البعيد إلى خادم التعليق التوضيحي.
  2. يفحص المفسّر، ويقرأ nvidia-smi، ويختار وحدة GPU.
  3. ينسخ شيفرة Potato المصدرية إلى remote_dir/code/<hash> حين ينقص المضيف ذلك الإصدار، وينشئ البيئة الافتراضية حين يُضبط packages وتكون البيئة غير موجودة. القيمة الافتراضية لـremote_dir هي ~/.cache/potato-training.
  4. يشغّل python -m potato.training.agent للتشغيلة. يصل رمز التشغيلة إلى الوكيل عبر الدخل القياسي ولا يظهر أبداً في سطر أوامر، لأن أسطر الأوامر مرئية لكل حساب على الخادم المشترك.
  5. ينزّل الوكيل حزمة العناصر والتصنيفات والوسائط الخاصة بالتشغيلة. ويشغّل الوكيل عامل التدريب نفسه الذي تشغّله الخلفية المحلية، ويرسل التقدم والتنبؤات والنتيجة عبر المقبس.
  6. حين تنجح التشغيلة، ينسخ 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:

yaml
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_pythonpython الخاص بالخلفيةمفسّر العامل على عقد الحوسبة.
gresلا شيءsbatch --gres، مثل gpu:1 أو gpu:A6000:1.
time04:00:00sbatch --time. فوق 6 ساعات يبلّغ potato validate وبدء الخادم عن تحذير، كما تصف الفقرة التالية.
partitionالافتراضي في العنقودsbatch --partition.
nice0sbatch --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_s30الثواني بين استدعاءات squeue، وحدها الأدنى 10.
exit_grace_s180الثواني المنتظَرة لظهور رمز خروج مهمة منتهية على عقدة تسجيل الدخول، وحدها الأدنى 20.
job_namepotato-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:

yaml
validation:
  acknowledge:
    - "model_training.backends.cluster.time is"

يُطابَق كل مدخل مع نص التحذير بوصفه سلسلة جزئية حساسة لحالة الأحرف لا يقل طولها عن 12 محرفاً، ويُنقل التحذير المطابَق إلى قائمة التحذيرات المُقَرّة ولا يُفشل --strict بعد ذلك. والمدخل الذي يسمّي الخلفية يُقِرّ التحذير لتلك الخلفية وحدها. والمدخل القصير جداً أو الذي لا يطابق أي تحذير يصبح تحذيراً مستقلاً.

أمر الفحص لخلفية SLURM

bash
potato training check cluster config.yaml

يسجّل الفحص الدخول إلى عقدة تسجيل الدخول ويتأكد من وجود sbatch وsqueue وscancel في PATH ومن أن remote_dir ليس تحت /tmp. ويذكر التقرير إصدار Python على عقدة تسجيل الدخول وjob_python الذي ستشغّله المهمة. ولا يستطيع الفحص أن يرى الحزم الموجودة على عقد الحوسبة، فتظهر الحزمة الناقصة على عقدة حوسبة تشغيلةً فاشلة مع خطأ الاستيراد في سجل التشغيلة. شغّل مهمة أولى قصيرة بقيمة time صغيرة لاكتشاف مثل هذه المشكلات مبكراً.

خطوات تشغيلة SLURM

يتصل Potato بعقدة تسجيل الدخول وينسخ شيفرته إليها، كما في خلفية ssh. ثم يؤدي الوكيل الخطوات التالية:

  1. ينزّل الحزمة إلى remote_dir/jobs/<run>/.
  2. يكتب job.sh ويرسل السكربت بالأمر sbatch --parsable. ويسجّل سجل التشغيلة Submitted SLURM job مع معرّف المهمة والخيارات.
  3. في مجلد المهمة، يكتب العامل على عقدة الحوسبة أحداثه في events.jsonl وأخطاءه في stderr.log ورمز خروجه في exit_code. ويذهب خرج SLURM نفسه إلى slurm.out.
  4. يقرأ الوكيل events.jsonl كلما نما الملف ويمرّر التقدم إلى الخادم. ويشغّل الوكيل squeue مرة كل poll_interval_s، ويسجّل سجل التشغيلة كل تغيّر في حالة المهمة في الطابور، مثل SLURM job 4242: PENDING (Priority) ثم RUNNING on node07.
  5. حين تنتهي المهمة، يرفع الوكيل التنبؤات ويبلّغ النتيجة. وتعود القطع الناتجة إلى الخادم ويُزال مجلد المهمة، كما في خلفية 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 وحزم المُدرِّب:

bash
pip install "potato-annotation[train-text]"

لا يحتاج الخادم إلا إلى مدخل الخلفية. تقبل خلفية agent المفاتيح type وdescription وheartbeat_timeout_s (الافتراضي 120) وqueue_timeout_s، ولا مفتاح غيرها:

yaml
model_training:
  enabled: true
  backends:
    lab-workstation:
      type: agent
      queue_timeout_s: 3600

تسجيل الوكيل وتشغيله

أصدر رمزاً للخلفية على خادم التعليق التوضيحي:

bash
potato training register lab-workstation config.yaml

يطبع الأمر الرمز مرة واحدة، مع الأوامر التي تُشغَّل على جهاز التدريب:

text
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 الحقيقي للخادم:

bash
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 إلى مفسّر آخر.

قراءات إضافية