コンテンツへスキップ

GPUサーバー、SLURMクラスター、NATの内側のマシンで学習する

Potatoの学習の実行を、ssh接続のGPUサーバー、SLURMの計算ノード、ポーリングするエージェントに送ります。各設定、確認コマンド、よくある失敗を説明します。

v2.14.0の新機能

このチュートリアルでは、Potatoのモデル学習を、アノテーションサーバーからGPUのあるマシンへ移します。対象は、アノテーションサーバーが小さなクラウドVMやノートPCで、GPUが研究室のサーバー、大学のクラスター、またはサーバーから接続できないワークステーションにある研究の管理者です。3つのリモートバックエンドそれぞれについて、そのバックエンドを選ぶ場面、リモートマシンに必要なインストール、設定、確認コマンド、実行中に起きること、実行のキャンセルの方法、最もよく見る失敗を説明します。このチュートリアルは、最初のモデルを学習するのレビュープロジェクトのように、すでにアノテーションサーバー上で学習できるプロジェクトを前提とします。

実行を動かせる4つの場所

バックエンドは、学習の実行が動く場所です。Potatoには、アノテーションサーバー上のサブプロセスであるlocalバックエンドが常にあります。ほかのバックエンドは、model_training.backendsの下に名前をつけて定義します。

種類トレーナーが動く場所リモート側を起動する主体モデルのファイルの行き先
localアノテーションサーバー上のサブプロセスPotato実行のartifacts/ディレクトリ
sshsshで接続できるマシン(研究室のGPUサーバーなど)Potato(ssh経由)artifacts/にコピーして戻される
slurmクラスターの計算ノード(バッチジョブとして)Potato(ログインノードへssh接続し、sbatchを使う)artifacts/にコピーして戻される
agentPotatoから接続できないマシン(NATの内側のワークステーションなど)あなたがpotato training agentで起動学習用マシン上

アノテーションサーバーがsshの鍵でGPUマシンにログインできるなら、sshを選びます。GPUがSLURMスケジューラーの背後にあり、ログインできるマシンがログインノードなら、slurmを選びます。サーバーからGPUマシンへ接続を開けないなら、agentを選びます。エージェントがすべての接続を自分で開くからです。エージェントを使うのは、家庭用ルーターやキャンパスのファイアウォールの内側にあるワークステーションが典型的な場合です。予測と実行の結果はどのバックエンドからもサーバーに届くため、書き戻しとホールドアウトスコアは、トレーナーがどこで動いても同じように働きます。decision-calibrateを除くすべてのトレーナーが、どのバックエンドでも動きます。

プロジェクトの設定

次の設定は、最初のチュートリアルのレビュープロジェクトに、3つのリモートバックエンドをすべて加えたものです。実際のプロジェクトに必要なのは使うバックエンドだけで、各バックエンドの説明は後述の節にあります。max_wall_seconds: 3600は、1時間以内に終わらない実行を停止します。sshとagentのバックエンドでは、サーバーが1秒ごとにこの制限を確認するため、リモートマシンで固まった実行が、制限を超えて実行キューを占有することはありません。

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

検証コマンドは、バックエンドの種類が受け取らないキー、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"}'

設定にないバックエンド名は、409で拒否されます。自動の再学習は、auto_retrain.backendが別のバックエンドを指定しない限りmodel_training.backendを使い、auto_retrainの全体はループの中のモデルで説明します。バックエンドにかかわらず、同時に動く実行は1つで、別の実行の進行中に開始した実行はキューで待ちます。

このマシンで学習する

実行をほかへ移す前に、ローカルの実行がどのデバイスを使うかを確認します。既定のdevice: autoでは、ローカルの実行はまずCUDA、次にAppleのMetal(mps)、最後にCPUを使い、device: cuda:1は特定の1つのGPUを指定します。確認コマンドは、ローカルの実行が使うデバイスを表示します。

bash
potato training check local config.yaml

Apple siliconのMacでは、このコマンドはlocal: this machine, Apple Metal (mps)と表示します。要求したデバイスが存在しない場合は、CPUまたは別のアクセラレーターに切り替わり、実行のログに警告が出ます。答えがCPUで、トレーナーがトランスフォーマーをファインチューニングするなら、実行を後述のリモートバックエンドに移してください。ローカルの実行のdevice、num_threads、max_ram_mbは、設定に挙げてあります。

sshで接続するGPUサーバー

sshバックエンドは、アノテーションサーバーがsshで接続できるマシン、典型的には研究室のGPUサーバーで、トレーナーを動かします。リモート側のものはPotato自身がすべて起動するため、PythonとトレーナーのパッケージをのぞけばPotatoの手動のインストールも起動も要りません。Potatoは最初の実行のときに自分のPythonソースをGPUホストにコピーし、ソースが変わるまでそのコピーを再利用するので、GPUホストにPotatoをインストールする必要はありません。

sshバックエンドの要件

アノテーションサーバーを動かすアカウントには、GPUホストにプロンプトなしでログインできるsshの鍵が必要です。PotatoはsshをBatchMode=yesで実行するため、パスワードのプロンプトが出ると、実行は固まらずにただちに失敗します。そのアカウントでssh gpu.example.org trueを実行して成功する必要があり、パスフレーズつきの鍵は、ssh-agentが鍵を保持していれば使えます。hostの値はsshが受け付ける任意の名前で、~/.ssh/configのエイリアスも使えます。user、port、identity_fileの各キーは、それぞれ-l、-p、-iとしてsshに渡されます。

GPUホストには、Python 3.8以降と、実行するトレーナーのパッケージが必要です。hf-text-classificationの場合は、potato-annotation[train-text]のextraの中身であるtorch、transformers、peftがそのパッケージです。各トレーナーのインストール方法は、トレーナーのページにあります。ホストのインタープリターにパッケージが足りない場合は、pythonをそのパッケージのあるインタープリターに向けるか、パッケージをpackagesに挙げます。packagesを設定すると、Potatoはremote_dirの下に--system-site-packagesつきで仮想環境を作り、挙げたパッケージを1回だけその環境にインストールします。ホスト自身の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を選び、min_free_gpu_mb(既定は2000)の空きがあるGPUがなければ、開始を拒否します。共有サーバーでは、使用率の低いカードでも空きメモリが少ないことがあるため、Potatoは使用率ではなく空きメモリを比べます。min_free_gpu_mbは、トレーナーが必要とするメモリ量に近い値にしてください。gpus: "1"はGPU 1を、"0,1"は2つの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、リモートのインタープリターに足りない学習用パッケージを報告します。インストールされているtorchにカーネルがないGPUには(torch there has no kernels for it)と表示され、gpus: autoはそのGPUを飛ばします。--jsonは同じ報告をJSONで出力します。実行を開始できる場合、コマンドは0で終了し、そうでなければ1で終了します。Runs onメニューの横のCheckボタンは、Trainingページから同じ確認を実行します。

sshの実行のステップ

Potatoは、実行ごとに次のステップを行います。

  1. sshで接続し、リモートの/tmpにあるunixソケットからアノテーションサーバーへ戻るリバースフォワードを開きます。
  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/にコピーして戻し、リモートのジョブディレクトリを削除して、接続を閉じます。

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ホストに残したモデルは、実行ページから公開できません。

unixソケットはモード0600で作られるため、Potatoがログインしたアカウントだけがこのソケットを通じて接続できます。ソケットを通るリクエストは、アノテーションサーバーにはループバックのリクエストとして届きます。debug: trueで起動したサーバーは、ループバックのリクエストに管理者権限を与えます。そのため、実行の進行中は、GPUホストでそのアカウントを使える人なら誰でも、デバッグ用サーバーの管理者権限を得られます。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バックエンドのホストと同じく、プロンプトなしのsshの鍵と、エージェント用のPython 3.8以降が必要です。ログインノードでは、sbatch、squeue、scancelがPATH上にある必要もあります。クラスターにコマンドがあれば、エージェントは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文字が続きます。

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でそのスクリプトを投入します。実行のログには、ジョブIDとフラグとともにSubmitted SLURM jobが記録されます。
  3. ジョブのディレクトリでは、計算ノード上のワーカーがイベントをevents.jsonlに、エラーをstderr.logに、終了コードをexit_codeに書きます。SLURM自身の出力はslurm.outに入ります。
  4. エージェントはevents.jsonlが伸びるのに合わせて読み、進捗をサーバーに中継します。エージェントはpoll_interval_sごとに1回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のテストスイートは、sbatch、squeue、scancelの代役に対してSLURMの手順を実行し、ジョブの投入、キューの状態、進捗の中継、キャンセルをカバーしています。パーティションの制限とプリエンプションのポリシーはクラスターごとに異なるため、新しいクラスターでの最初のジョブでは、実行のログを見守ってください。

サーバーに接続できるログインノードで手動で起動したエージェントも、potato training agent --server ... --backend <name> --workdir <shared dir> --slurm-config slurm.jsonでSLURMに投入できます。ファイルslurm.jsonには、上の表の設定をJSONオブジェクトとして書き、--workdirは計算ノードが共有するストレージ上にある必要があります。

Potatoから接続できないマシン

agentバックエンドは、アノテーションサーバーから接続できないマシン、例えばNATの内側のワークステーション向けです。そのマシンで誰かがpotato training agentを起動すると、エージェントがサーバーにジョブをポーリングします。エージェントがすべての接続を自分で開くため、受信用のポートは要りません。キャンセルは、エージェントの次の進捗報告へのサーバーの応答としてエージェントに届きます。モデルのファイルは学習用マシンに残り、予測と結果だけが戻ります。

agentバックエンドの要件

学習用マシンには、Potato、実行するトレーナーのパッケージ、アノテーションサーバーのURLへのネットワーク経路が必要です。hf-text-classificationの場合は、次の1回のインストールで、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

このコマンドはトークンを1回だけ表示し、学習用マシンで実行するコマンドも示します。

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は1つのジョブのあとで終了し、--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では、エージェントが現れないまま1時間が過ぎると実行が失敗し、queue_timeout_sがなければ、実行はキャンセルするまで待ちます。エージェントはバンドルをtar.gzファイルとしてダウンロードし、途切れたダウンロードは止まった位置から、最大5回まで再開します。続いてエージェントはワーカーを動かし、進捗を送り、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へのモデルの公開を説明します。
  • 設定には、model_trainingのすべてのキー、ホールドアウトスコア、実行の保存先が載っています。
  • LLMのファインチューニングでは、リモートのGPUが最も必要になりやすいトレーナーを、LoRAと4ビットのベース重みとともに説明します。
  • 上流の実行の場所のリファレンスには、各バックエンドのキーの完全な表があり、エージェントのプロトコルの節には、自作のエージェントを書く人向けにルートが記載されています。