सामग्री पर जाएं

GPU सर्वर, SLURM क्लस्टर या NAT के पीछे की मशीन पर प्रशिक्षण

Potato के प्रशिक्षण रन को ssh GPU सर्वर, SLURM कंप्यूट नोड या पोलिंग एजेंट पर भेजें, हर एक की config, जाँच कमांड और आम विफलताओं के साथ।

v2.14.0 में नया

यह ट्यूटोरियल Potato के मॉडल प्रशिक्षण को एनोटेशन सर्वर से हटाकर GPU वाली मशीन पर ले जाता है। ट्यूटोरियल उस अध्ययन एडमिन के लिए है जिसका एनोटेशन सर्वर छोटा क्लाउड VM या लैपटॉप है, और जिसके GPU किसी लैब सर्वर, विश्वविद्यालय क्लस्टर या ऐसे वर्कस्टेशन पर हैं जिससे सर्वर जुड़ नहीं सकता। तीनों रिमोट बैकएंड में से हर एक के लिए पेज बताता है कि बैकएंड कब चुनें, रिमोट मशीन पर क्या इंस्टॉल होना चाहिए, config, जाँच कमांड, रन के दौरान क्या होता है, रन कैसे रद्द करें, और सबसे संभावित विफलताएँ कौन-सी हैं। ट्यूटोरियल मानता है कि आपके पास ऐसा प्रोजेक्ट है जो एनोटेशन सर्वर पर पहले से प्रशिक्षित होता है, जैसे अपना पहला मॉडल प्रशिक्षित करें का समीक्षा प्रोजेक्ट।

रन के चलने की चार जगहें

बैकएंड वह जगह है जहाँ प्रशिक्षण रन चलता है। Potato में local बैकएंड हमेशा होता है, जो एनोटेशन सर्वर पर एक सबप्रोसेस है। बाकी बैकएंड आप model_training.backends के नीचे नामित करते हैं:

प्रकारट्रेनर कहाँ चलता हैरिमोट पक्ष कौन शुरू करता हैमॉडल फ़ाइलें कहाँ पहुँचती हैं
localएनोटेशन सर्वर, एक सबप्रोसेस मेंPotatoरन की artifacts/ डायरेक्टरी
sshssh से पहुँचने लायक मशीन, जैसे लैब GPU सर्वरPotato, ssh के ज़रिएवापस artifacts/ में कॉपी होती हैं
slurmक्लस्टर का कंप्यूट नोड, बैच जॉब के रूप मेंPotato, लॉगिन नोड पर ssh से, फिर sbatchवापस artifacts/ में कॉपी होती हैं
agentऐसी मशीन जहाँ Potato नहीं पहुँच सकता, जैसे NAT के पीछे का वर्कस्टेशनआप, potato training agent सेप्रशिक्षण मशीन पर

जब एनोटेशन सर्वर ssh कुंजी से GPU मशीन में लॉगिन कर सकता हो, तब ssh चुनें। जब GPU SLURM शेड्यूलर के पीछे हों और जिस मशीन में आप लॉगिन कर सकते हैं वह लॉगिन नोड हो, तब slurm चुनें। जब सर्वर से GPU मशीन तक कोई कनेक्शन खोला न जा सके, तब agent चुनें, क्योंकि एजेंट हर कनेक्शन खुद खोलता है। घरेलू राउटर या कैंपस फ़ायरवॉल के पीछे का वर्कस्टेशन एजेंट का सामान्य मामला है। हर बैकएंड से भविष्यवाणियाँ और रन का परिणाम सर्वर तक पहुँचते हैं, इसलिए ट्रेनर कहीं भी चला हो, राइट-बैक और होल्ड-आउट स्कोर एक ही तरह काम करते हैं। decision-calibrate को छोड़कर हर ट्रेनर किसी भी बैकएंड पर चलता है।

प्रोजेक्ट config

नीचे की config पहले ट्यूटोरियल का समीक्षा प्रोजेक्ट है, जिसमें तीनों रिमोट बैकएंड जोड़े गए हैं। असली प्रोजेक्ट को केवल वे बैकएंड चाहिए जो आप इस्तेमाल करते हैं, और हर बैकएंड का अपना अनुभाग नीचे है। 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

सर्वर शुरू करने से पहले config जाँचें:

bash
potato validate config.yaml --strict

वैलिडेटर ऐसी कुंजी बताता है जो बैकएंड का प्रकार नहीं लेता, बिना host वाला ssh या slurm बैकएंड, /tmp के नीचे का SLURM remote_dir, और ऐसा model_training.backend जो किसी बैकएंड को नामित नहीं करता। सर्वर भी इन्हीं त्रुटियों पर शुरू नहीं होता, इसलिए गलत वर्तनी वाली pyhton रनों को डिफ़ॉल्ट python3 पर भेजने के बजाय सर्वर को शुरू होते समय ही रोक देती है।

Runs on मेनू और API

/admin/training का Training पेज एक Runs on मेनू रखता है, जो हर बैकएंड को उसके प्रकार और होस्ट के साथ सूचीबद्ध करता है, जैसे gpu-server (ssh to gpu.example.org)। model_training.backend वह प्रविष्टि तय करता है जिसे मेनू पहले चुनता है, और Runs तालिका अपने 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"}'

जो बैकएंड नाम config में नहीं है, उसे 409 के साथ अस्वीकार कर दिया जाता है। स्वचालित पुनःप्रशिक्षण model_training.backend का उपयोग करता है, जब तक auto_retrain.backend कोई दूसरा बैकएंड न नामित करे, और auto_retrain का पूरा ब्योरा चक्र में मॉडल में है। बैकएंड कोई भी हो, एक समय में एक रन चलता है, और किसी रन के चलते समय शुरू किया गया दूसरा रन कतार में रुकता है।

इसी मशीन पर प्रशिक्षण

रनों को कहीं और ले जाने से पहले जाँचें कि स्थानीय रन को कौन-सा डिवाइस मिलता है। डिफ़ॉल्ट device: auto के साथ स्थानीय रन पहले CUDA लेता है, फिर Apple का Metal (mps), फिर CPU, और device: cuda:1 एक GPU को नामित करता है। जाँच कमांड वह डिवाइस छापता है जो स्थानीय रन इस्तेमाल करेगा:

bash
potato training check local config.yaml

Apple silicon वाले Mac पर कमांड local: this machine, Apple Metal (mps) छापता है। जो डिवाइस आप माँगते हैं पर मौजूद नहीं है, वह रन के लॉग में चेतावनी के साथ CPU या किसी दूसरे एक्सेलेरेटर पर लौट आता है। जब उत्तर CPU हो और ट्रेनर ट्रांसफ़ॉर्मर फ़ाइन-ट्यून करता हो, तब रन को नीचे के किसी रिमोट बैकएंड पर ले जाएँ। Config स्थानीय रनों के लिए device, num_threads और max_ram_mb सूचीबद्ध करता है।

ssh से GPU सर्वर

ssh बैकएंड ट्रेनर को ऐसी मशीन पर चलाता है जहाँ एनोटेशन सर्वर ssh से पहुँच सकता है, आम तौर पर लैब GPU सर्वर। रिमोट पक्ष पर सब कुछ Potato खुद शुरू करता है, इसलिए Python और ट्रेनर के पैकेजों के अलावा वहाँ हाथ से कुछ इंस्टॉल या शुरू नहीं करना पड़ता। GPU होस्ट पर Potato इंस्टॉल होना ज़रूरी नहीं है, क्योंकि Potato पहले रन पर अपना Python सोर्स होस्ट पर कॉपी करता है और सोर्स बदलने तक उसी कॉपी का दोबारा उपयोग करता है।

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 के साथ एक वर्चुअल एनवायरनमेंट बनाता है और सूचीबद्ध पैकेज उसमें एक बार इंस्टॉल करता है। होस्ट का अपना CUDA वाला torch बिल्ड एनवायरनमेंट के भीतर दिखता रहता है:

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 लेता है और तब शुरू होने से मना कर देता है जब किसी GPU के पास min_free_gpu_mb (डिफ़ॉल्ट 2000) खाली न हो। Potato उपयोग दर के बजाय खाली मेमोरी की तुलना करता है, क्योंकि साझा सर्वर पर कम उपयोग दर वाले कार्ड के पास भी कम मेमोरी खाली हो सकती है। min_free_gpu_mb को अपने ट्रेनर की ज़रूरत वाली मेमोरी के आसपास रखें। gpus: "1" GPU 1 को पिन करता है, "0,1" दो GPU पिन करता है, और gpus: none CPU पर प्रशिक्षित करता है। जिस होस्ट में कोई GPU नहीं है, वह auto के तहत भी अपने CPU पर प्रशिक्षित करता है। 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 ऐसे GPU को छोड़ देता है। --json वही रिपोर्ट JSON के रूप में छापता है। रन शुरू हो सकता हो तो कमांड 0 से और अन्यथा 1 से बाहर निकलता है। Runs on मेनू के पास का Check बटन Training पेज से वही जाँच चलाता है।

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 शुरू करता है। रन का टोकन एजेंट तक stdin से पहुँचता है और किसी कमांड लाइन में कभी नहीं दिखता, क्योंकि साझा सर्वर पर कमांड लाइनें हर खाते को दिखती हैं।
  5. एजेंट रन का आइटमों, लेबलों और मीडिया का बंडल डाउनलोड करता है। एजेंट वही प्रशिक्षण वर्कर चलाता है जो स्थानीय बैकएंड चलाता है, और प्रगति, भविष्यवाणियाँ और परिणाम सॉकेट से वापस भेजता है।
  6. रन सफल होने पर Potato आर्टिफ़ैक्ट डायरेक्टरी रन के artifacts/ में वापस कॉपी करता है, रिमोट जॉब डायरेक्टरी हटाता है, और कनेक्शन बंद करता है।

Training पेज की चरण पंक्ति इन्हीं अवस्थाओं का अनुसरण करती है, जैसे 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 से प्रशिक्षण देता है, उस पर debug बंद रखें।

रद्द करना और हार्टबीट टाइमआउट

Training पेज का Cancel run एजेंट तक सॉकेट से पहुँचता है, एजेंट की अगली प्रगति रिपोर्ट के उत्तर में। एजेंट वर्कर को SIGTERM भेजता है, और यदि model_training.grace_seconds (डिफ़ॉल्ट 20) के बाद भी वर्कर चल रहा हो तो SIGKILL भेजता है, जिसे सर्वर जॉब के साथ भेजता है। पुराने 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 बैकएंड के होस्ट को चाहिए। लॉगिन नोड को PATH पर sbatch, squeue और scancel भी चाहिए। जहाँ क्लस्टर में scontrol कमांड है, वहाँ एजेंट उसे भी बुलाता है। Potato srun या sacct कभी नहीं बुलाता, इसलिए जिस क्लस्टर में srun बंद है और कोई अकाउंटिंग डेटाबेस नहीं है, वहाँ भी यह काम करता है। remote_dir आवश्यक है और उसे कंप्यूट नोडों के साझा स्टोरेज पर होना चाहिए, क्योंकि जॉब वहीं से बंडल पढ़ती है और वहीं मॉडल लिखती है। वैलिडेटर /tmp या /var/tmp के नीचे के remote_dir पर त्रुटि बताता है, क्योंकि वे डायरेक्टरियाँ हर नोड के लिए स्थानीय हैं।

कंप्यूट नोडों को job_python से नामित ऐसा इंटरप्रेटर चाहिए जिसमें ट्रेनर के पैकेज हों। SLURM बैकएंड पर packages समर्थित नहीं है, क्योंकि लॉगिन नोड पर बना वर्चुअल एनवायरनमेंट कंप्यूट नोडों पर चल न पाए। 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"]

gpus और packages को छोड़कर हर ssh कुंजी SLURM बैकएंड पर लागू होती है। GPU gres से मिलते हैं, और शेड्यूलर जिन GPU की अनुमति देता है उनके लिए CUDA_VISIBLE_DEVICES सेट करता है। बिना gres वाली जॉब को कोई GPU नहीं मिलता। SLURM की सेटिंग sbatch के फ़्लैग से इस तरह जुड़ती हैं:

कुंजीडिफ़ॉल्टअर्थ
job_pythonबैकएंड का pythonकंप्यूट नोडों पर वर्कर का इंटरप्रेटर।
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_s30squeue कॉल के बीच के सेकंड, कम से कम 10।
exit_grace_s180खत्म हुई जॉब का एग्ज़िट कोड लॉगिन नोड पर दिखने तक प्रतीक्षा के सेकंड, कम से कम 20।
job_namepotato-trainजॉब नाम का उपसर्ग, जिसके बाद रन ID के पहले 8 अक्षर आते हैं।

6 घंटे से ऊपर का time 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 से सबमिट करता है। रन का लॉग जॉब ID और फ़्लैग के साथ Submitted SLURM job दर्ज करता है।
  3. जॉब डायरेक्टरी में कंप्यूट नोड का वर्कर अपने इवेंट events.jsonl में, अपनी त्रुटियाँ stderr.log में और अपना एग्ज़िट कोड exit_code में लिखता है। SLURM का अपना आउटपुट slurm.out में जाता है।
  4. एजेंट events.jsonl को फ़ाइल के बढ़ने के साथ पढ़ता है और प्रगति सर्वर तक पहुँचाता है। एजेंट हर poll_interval_s में एक बार squeue चलाता है, और रन का लॉग जॉब की कतार-स्थिति का हर बदलाव दर्ज करता है, जैसे 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 जो कारण बताता है उनमें समय सीमा, नोड की विफलता, प्रीएम्प्शन, मेमोरी खत्म होना, और Potato के बाहर से किया गया scancel शामिल हैं।

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 और चलाने लायक register कमांड छापता है।

agent रन के चरण

agent बैकएंड का रन queued अवस्था में तब तक प्रतीक्षा करता है जब तक कोई एजेंट काम न माँगे। queue_timeout_s: 3600 के साथ, एजेंट न होने पर रन एक घंटे बाद विफल होता है, और queue_timeout_s के बिना रन तब तक प्रतीक्षा करता है जब तक आप रन रद्द न कर दें। एजेंट बंडल को tar.gz फ़ाइल के रूप में डाउनलोड करता है और टूटे डाउनलोड को वहीं से फिर शुरू करता है जहाँ वह रुका था, अधिकतम पाँच प्रयासों तक। फिर एजेंट वर्कर चलाता है, प्रगति पोस्ट करता है, predictions.jsonl अपलोड करता है और एग्ज़िट कोड बताता है। सर्वर max_predictions_mb (डिफ़ॉल्ट 512) से बड़ी भविष्यवाणी फ़ाइल को 413 से जवाब देता है।

मॉडल फ़ाइलें प्रशिक्षण मशीन पर --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 GPU सूचीबद्ध करता है। प्रतीक्षा करें, सीमा घटाएँ, या gpus: "1" से एक GPU पिन करें।
  • 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 से नए GPU के लिए बना था जो होस्ट में हैं। उन 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 पर हैं जो केवल लॉगिन शेल सेट करता है। बैकएंड के env के नीचे PATH सेट करें।
  • SLURM job 4242 ended before the worker finished: it reached its time limit। बैकएंड में time बढ़ाएँ, या कम आइटमों पर प्रशिक्षित करें। शेड्यूलर की दूसरी विफलताओं के बाद slurm.out पढ़ने के लिए उसे रखने हेतु keep_remote: true सेट करें।
  • agent बैकएंड पर रन कतार में अटका रहता है। उस बैकएंड नाम वाला कोई एजेंट पोल नहीं कर रहा। potato training agent --backend lab-workstation से एजेंट शुरू करें, और Training पेज पर Check से टोकन जाँचें।
  • nvrtc: error: failed to open libnvrtc-builtins.so.13.0। होस्ट का torch और उसका nvidia-cuda-nvrtc पैकेज अलग CUDA संस्करणों के लिए हैं। torch बिल्ड से मेल खाता nvidia-cuda-nvrtc इंस्टॉल करें, या python को दूसरे इंटरप्रेटर की ओर इंगित करें।

आगे पढ़ें

  • मॉडल प्रशिक्षण का अवलोकन Training पेज, प्रशिक्षण चक्र और Hugging Face Hub पर मॉडल प्रकाशित करना समझाता है।
  • Config हर model_training कुंजी, होल्ड-आउट स्कोर और रन कहाँ सहेजे जाते हैं, सूचीबद्ध करता है।
  • LLM को फ़ाइन-ट्यून करना उन ट्रेनरों को कवर करता है जिन्हें अक्सर रिमोट GPU चाहिए, LoRA और 4-बिट बेस वज़न के साथ।
  • रन कहाँ चलते हैं का अपस्ट्रीम संदर्भ हर बैकएंड की पूरी कुंजी तालिका देता है, और एजेंट प्रोटोकॉल अनुभाग अपना एजेंट लिखने वालों के लिए रूट दर्ज करता है।