コンテンツへスキップ

モデル学習の設定とルート

model_trainingブロックの全キー、実行がキューに入り、スコアが測られ、保存される仕組み、管理者用とエージェント用のルート、よくある実行エラーの対処を示します。

v2.14.0の新機能

このページは、Potatoの設定のmodel_trainingブロックと、実行を開始した後に何が起こるかについてのリファレンスです。対象は、研究を運用していて、実行を制限したい、実行を別のマシンに送りたい、モデルの予測をアノテーターに見せたい、あるいはスクリプトから学習を始めたいと考える担当者です。以下のすべてのキー、既定値、ルート、メッセージは、Potatoのコードに照らして確認されています。最初の実行には、最初のモデルを学習するから始めてください。トレーナーとそのパラメーターはトレーナーに載っています。

完全な設定

次の設定は、商品レビューで感情分類器を学習します。auto_retrainは、新しいアノテーションが25件増えるたびにsklearn-textを再学習します。sklearn-textは、既定のTF-IDF特徴量ならCPUで学習し、通常のPotatoのインストール以外に何も必要としません。したがって、頻繁な自動実行でもコストはほとんどかかりません。書き戻しでは、信頼度が0.8以上のすべての予測がアノテーターに表示されます。include_unlabeledがあると、実行は、まだ誰もラベルを付けていないレビューも予測します。hf-text-classificationの既定値とgpu-serverバックエンドは、Trainingページから手動で開始した実行に使われます。

yaml
annotation_task_name: "Review sentiment with model training"
task_dir: "."
data_files:
  - "data/reviews.json"
item_properties:
  id_key: "id"
  text_key: "text"
output_annotation_dir: "annotation_output"
user_config:
  allow_all_users: true
 
annotation_schemes:
  - annotation_type: "radio"
    name: "sentiment"
    description: "Is this review positive or negative?"
    labels: ["positive", "negative"]
 
model_training:
  enabled: true
  split_seed: 0
  splits: {train: 0.7, val: 0.15, test: 0.15}
  aggregation: consensus
  retain_runs: 5
  queue_max: 10
  max_wall_seconds: 3600
  max_ram_mb: 8192
  num_threads: 4
  trainer_params:
    sklearn-text:
      classifier: sklearn.linear_model.LogisticRegression
      classifier_kwargs: {max_iter: 1000}
    hf-text-classification:
      model_name: answerdotai/ModernBERT-base
      epochs: 4
      lora: true
  auto_retrain:
    enabled: true
    trainer: sklearn-text
    schemas: [sentiment]
    min_interval_s: 600
    update_frequency: 25
  writeback:
    schemas: [sentiment]
    min_confidence: 0.8
    include_unlabeled: true
  backends:
    gpu-server:
      type: ssh
      host: gpu-server
      python: /opt/conda/bin/python3
      gpus: auto
      min_free_gpu_mb: 4000

split_seedは、研究の期間中、固定したままにしてください。シードを変えると、すべての項目が割り当て直され、ホールドアウトされていた項目が学習に入り、以降のスコアは以前のスコアと比較できなくなります。min_confidenceのしきい値0.8は出発点で、適切なしきい値は最初のホールドアウトスコアによって変わります。事前ラベルはアノテーターをモデルの答えに引き寄せるので、そのスコアが事前ラベルの表示を裏づけてから、include_unlabeledをオンにしてください。

model_trainingのキー

すべてのキーはmodel_trainingの下にあります。

キー既定値意味
enabledfalseTrainingページ、/admin/trainingの下のルート、/api/trainingの下のエージェント用ルートを登録します。enabled: trueがないと、ルートは存在しません。
retain_runs5実行の台帳に残す、完了した実行の数。実行の予測がまだ保存されている場合を除き、古い実行は台帳から外れます。実行のディレクトリはディスクに残ります。
grace_seconds20キャンセルされた実行が終了するまでの猶予の秒数。この後、Potatoはプロセスを強制終了します。0以上で、ジョブとともに、タイプがssh、slurm、agentのバックエンドに送られます。
queue_max10進行中の実行の後ろで待てる実行の数。
split_seed0項目をtrain、val、testの分割に割り当てるときのシード。
splits{train: 0.7, val: 0.15, test: 0.15}分割の割合。合計が1になるよう正規化されます。名前はtrain、val、testで、trainは必須です。
aggregationconsensus複数のアノテーターの項目へのラベルを1つのラベルにする方法。consensusは、研究のアノテーターが複数のときDawid-Skeneモデルを当てはめ、当てはめに失敗すると多数決に戻ります。majorityは多数決を取ります。
max_wall_seconds未設定1回の実行の制限時間。Potatoは、ローカルの実行では実行がイベントを報告するたびに、sshまたはエージェントの実行では毎秒、確認します。
max_ram_mb未設定setrlimitで設定する、学習プロセスのアドレス空間の上限。上限のないプラットフォームでは、実行は警告をログに出して続行します。
deviceautoauto、cpu、cuda、cuda:N、mps。autoは、CUDA、AppleのMetal、CPUの順に選びます。
num_threads未設定環境変数がすでに設定されていない限り、実行にOMP_NUM_THREADS、MKL_NUM_THREADS、OPENBLAS_NUM_THREADSを設定します。
auto_retrainオフアノテーションが届くたびの再学習。auto_retrainを参照してください。
writebackなし予測を事前ラベルとして公開します。writebackを参照してください。
backendlocalほかのバックエンドを指定しない実行のバックエンド。
backendsなし名前付きのssh、slurm、agentバックエンド。バックエンドを参照してください。
max_predictions_mb512リモートのエージェントがアップロードできるpredictions.jsonlの最大サイズ。
trainer_paramsなしトレーナー名をキーとするパラメーターの既定値。
tilingenabled: auto検出とセグメンテーションのトレーナーのために、大きな画像をタイルに切ります。tilingを参照してください。

実行自身のparamsはtrainer_paramsを上書きし、後者はトレーナーの既定値を上書きします。トレーナーが受け取らないパラメーター名は、trainer_paramsの下にあればサーバーの起動時に、そうでなければ実行の開始時に拒否されます。トレーナーに、この順序が例とともに載っています。

auto_retrain

自動再学習は、アノテーションが保存されるたびに、新しい実行が必要かどうかを確認します。

キー既定値意味
enabledfalse確認をオンにします。
trainerなしトレーナー名。必須です。
schemasなし学習するスキーム。必須です。
min_interval_s600前回の実行が終わってから、次の実行が始まるまでの秒数。
update_frequency25前回の自動実行から、次の実行が始まるまでの新しいアノテーションの数。
params{}APIの実行のparamsと同じ、トレーナーのパラメーター。
backendmodel_training.backend自動実行のバックエンド。
accept_licencefalse確認を求めるトレーナー(ultralytics-detect、ultralytics-segment、layoutlmv3)のライセンスを確認したことにします。確認がないと、これらのトレーナーの自動実行は見送られます。

確認が実行を見送ると決めたとき、その理由はGET /admin/training/api/statusのskip_reasonフィールドに、たとえば「waiting for 3 more annotation(s)」や「a run is already in progress」と表示されます。自動実行がキューに入ることはありません。キューが空になった後に保存された次のアノテーションが、学習できるアノテーションが増えた状態で、再び確認します。Potatoはアノテーション数をメモリ上に保持するので、再起動の後は、以前に学習したことのあるプロジェクトでも、再起動からの新しいアノテーションを数えます。

writeback

書き戻しは、アノテーターにどの予測を見せるかを決めます。

キー既定値意味
schemas[]予測をアノテーターに見せるスキーム。空のリストでは何も表示されません。
min_confidence0.0しきい値に届かない予測は、保存されますが表示されません。信頼度のない予測は通過します。
fieldpredictions事前ラベルを書き込む項目のフィールド。
include_unlabeledfalseまだ誰もラベルを付けていない項目も予測し、それらの項目にも事前ラベルを付けます。include_unlabeledがないと、実行が予測するのは、実行自身のvalとtestの項目だけです。

tiling

検出とセグメンテーションのトレーナーは、各画像を数百ピクセルにリサイズします。そのサイズでは、全スライド画像や衛星画像の中の物体は失われてしまいます。そのため、image_annotation、microscopy、geo_annotationのスキームでは、実行の学習データを作るときに、Potatoが大きな画像をタイルに切ります。画像の分割は、画像を切る前に決まるので、1枚のスライドのタイルが2つの分割に分かれることはありません。予測は画像全体に対応づけられ、ホールドアウトスコアは画像全体で計算されます。視覚モデルのチュートリアルでは、スライドと地図での実際の使い方を扱います。

キー既定値意味
enabledautoautoは、スライド形式(.svs、.ndpi、.mrxs、.scnなど)と、長辺がauto_min_side以上の画像をタイルに切ります。trueはすべての画像を、falseはどれも切りません。
auto_min_side4096autoが画像のタイル化を始める、長辺の長さ(ピクセル)。
tile_size1024タイルの1辺。トレーナーから見えるピクセルで数えます。
overlap128隣り合うタイルが共有するピクセル数。tile_sizeの半分が上限です。オーバーラップは物体と同じ大きさ以上にしてください。そうしないと、大きな物体が断片で見つかります。
downsample1タイルの1ピクセルあたりのフル解像度のピクセル数。
mppなしタイルの1ピクセルあたりのミクロン数。解像度が記録されたスライドではdownsampleを上書きします。
background0.25物体のあるタイル1枚につきサンプリングする、空のタイルの数。一部だけアノテーションされたスライドにはbackground: 0を設定してください。
max_predict_tiles2000画像1枚で予測するタイルの最大数。組織が最も多く写ったタイルが残されます。
min_visible0.4物体がそのタイルで学習されるために、タイルの内側にある必要がある物体の割合。
tissue_threshold0.05モデルがそのタイルを予測するために、組織である必要があるスライドのタイルの割合。

スライドは、学習データを作るマシン上で、pip install "potato-annotation[wsi]"でインストールされるopenslideで読み込まれます。リモートのバックエンドはタイルをダウンロードし、スライドそのものをダウンロードすることはありません。

実行キュー

同時に実行されるのは1つの実行だけです。別の実行が進行中にTrainingページまたはAPIから開始した実行は、拒否されずに待ちます。開始のリクエストは、queued: trueと実行のpositionを付けて202を返し、実行テーブルは、その実行をwaiting #NとCancel runボタンつきで表示します。進行中の実行が終わると、最も古い待機中の実行が始まります。

待機中の実行は実行の台帳のレコードなので、キューは再起動をまたいで残り、サーバーが戻ると最初の待機中の実行が始まります。前のサーバーが実行の途中だった実行は、同時にinterruptedと記録されます。待機中の実行の学習データは、実行が始まるときに作られるので、実行は、その時点に存在するアノテーションで学習します。存在しないスキームを指定した開始のように、拒否されるはずの開始は、実行の順番が来たときではなく、すぐに拒否されます。待っている間にスキームやトレーナーが設定から消えた実行は、invalid_when_dequeuedで失敗し、次の実行が始まります。

リクエストの本文に"queue": falseを送ると、キューの順番の代わりに409が返ります。すでにqueue_maxの実行が待っているときは、新しい開始に429が返ります。GET /admin/training/api/statusは、待機中の実行を、queueの下に順に並べます。

実行前の検査

potato validateはmodel_trainingブロックのすべての問題を一度に報告し、サーバーも同じ問題で起動を拒否します。

bash
potato validate config.yaml --strict

検査の対象は次のとおりです。

  • train、val、test以外の名前を持つsplits、0未満または数値でない割合、合計が0になる割合、またはtrainのない分割の指定。
  • writebackまたはauto_retrainにないキー、スキームではないwriteback.schemasのエントリ、0から1の外にあるmin_confidence。accept_licenseは、accept_licenceの綴りの誤りとして報告されます。
  • fieldがwriteback.fieldと異なる、有効なpre_annotationブロック。そのようなブロックの下では、学習の事前ラベルは表示されません。
  • auto_retrain.enabledのとき、存在しないトレーナーやスキーム、トレーナーが学習できないスキーム、トレーナーが受け取らないパラメーターや型の誤ったパラメーター、backendsにないbackend、local以外のバックエンドでのdecision-calibrate。
  • trainer_paramsの下にある、トレーナーが受け取らないパラメーター、または型の誤ったパラメーター。dpの内側では、各キーとその範囲も検査されます。
  • 0未満または数値でないgrace_seconds、あるいは0未満または整数でないretain_runsやsplit_seed。
  • backendsの下にある、typeがないまたは未知であること、その型にないキー、hostのないsshバックエンド、auto、none、GPUの番号以外のgpusの値、localという名前のリモートバックエンド、定義されていないmodel_training.backend。

potato training checkは、実行がバックエンドを使う前に、1つのバックエンドを検査します。localでは、このコマンドは実行が使うデバイスを表示します。たとえば、Appleシリコンを搭載したMacではlocal: this machine, Apple Metal (mps)です。sshバックエンドでは、このコマンドは、Pythonのバージョン、すべてのGPUとその空きメモリ、実行が割り当てられるGPU、リモートのインタープリターに足りない学習用パッケージを報告します。TrainingページのCheckボタンは同じ検査を実行し、--jsonは報告をJSONで出力します。

bash
potato training check local config.yaml
potato training check gpu-server config.yaml

TrainingページまたはAPIから開始した実行は、開始時にもう一度検査されます。ステータスコードはルートに載っています。

バックエンド

実行はバックエンドで動き、TrainingページのRuns onメニューには、設定されたバックエンドが並びます。model_training.backendが既定を決め、APIの実行やauto_retrainは、backendで別のバックエンドを指定できます。Potatoのバックエンドは4種類です。

型トレーナーが動く場所トレーナーを起動する主体
localこのマシン上のサブプロセス。常に利用でき、既定です。Potato
sshGPUサーバーなど、Potatoがsshで到達できる別のマシン。Potato、ssh経由
slurmクラスターの計算ノード上のバッチジョブ。Potato、ログインノードへのsshに続けてsbatch
agentNATの内側のワークステーションなど、Potatoから到達できないマシン。人がpotato training agentで起動

sshバックエンドはBatchModeをオンにした鍵認証を使うので、パスワードのプロンプトはハングせずに失敗します。slurmバックエンドが使うのはsbatch、squeue、scancelだけで、scontrolを提供するクラスターではscontrolも使い、計算ノードが共有するストレージ上のremote_dirが必要です。エージェントのバックエンドは、すべての接続をエージェントが開くので、受信ポートを必要としません。localという名前はこのマシンのために予約されていて、decision-calibrateはlocalでしか動きません。GPUサーバー、SLURMクラスター、NATの内側のマシンで学習するでは、3種類のリモートの型をそのキーとともに通しで説明しています。

ホールドアウトスコア

どの実行も、実行自身の予測を、valとtestの項目で、統合した人手ラベルに対してスコアリングします。指標名には、val_macro_f1やtest_f1のように分割名が含まれます。ラベルがあって予測がない項目は不正解として数えられるので、難しい項目を除いてトレーナーのスコアを上げることはできません。<split>_coverageは、予測が付いた項目の割合を報告します。

代表のスコアは、実行テーブルのHeld-out score列に表示され、ツールチップに分割と指標が示されます。代表のスコアは、valとtestのうち項目がある最初のほうで、最初のスキームの代表の指標です。トレーナーがvalのスコアで最良のチェックポイントを選んだときは、トレーナーがすでにvalのスコアを見ているので、Potatoはtestを先に試します。最良のエポックを保持するファインチューニングのトレーナー、たとえばhf-text-classification、torchvision-detect、llm-sftは、代表のスコアをtestから取ります。sklearn-text、setfit、rdkit-property、判断モデルのトレーナー、推論ブリッジは、valで何も選ばないので、これらのトレーナーの実行は、valに項目があるときはいつでも、代表のスコアをvalから取ります。valにもtestにも項目がない実行は、「not scored」と表示されます。

代表の指標はスキームのアノテーションタイプによって決まり、次の表は一般的なタイプを示しています。

アノテーションタイプ代表の指標
radio, select, likertmacro-F1(正解率と、数値のlikertラベルでは平均絶対誤差も)
multiselectmicro-F1(macro-F1と完全一致も)
span開始、終了、ラベルが一致するスパンのF1
textトークンF1(完全一致も)
binaryモードのpairwise引き分けと答えられていない項目に対する正解率
rankingKendallのtau
image_annotation, microscopy, geo_annotationIoU 0.5でのCOCO mAP(map_50)、map_50_95も記録
audio_annotationIoU 0.5以上で同じラベルを持つ区間のF1
speech_transcriptword_accuracy、1から単語誤り率を引いた値
volume_annotationmean_dice

トークンF1は、正しい単語を誤った順序で使った答えにも点を与えるので、トークンF1は完全一致と合わせて読んでください。検出の代表の指標は、0.5から0.95の平均ではなくIoU 0.5を使います。1つの物体に対する2人のアノテーターのボックスが、IoU 0.9で重なることはめったにないからです。アップストリームのホールドアウトスコアの表には、すべてのアノテーションタイプの指標が載っています。

書き戻し

実行が成功すると、Potatoは実行の予測を保存し、4つの検査を通った予測を、各項目のpredictionsフィールド、またはwriteback.fieldが指すフィールドに書き込みます。検査はこの順序で行われ、実行の書き戻しレポートが、見送りの数を数えます。

  1. train分割の項目には、事前ラベルを付けません。 この検査は、台帳に残っているすべての実行のtrain分割に及び、以前の実行が項目に残した事前ラベルは、後の実行がその項目で学習したときに取り下げられます。
  2. writeback.schemasにあるスキームだけが公開されます。 リストは既定で空なので、学習を有効にしても、アノテーターに見えるものは変わりません。
  3. 却下されたペアは見送られます。 モデルレビューでrejectの判定が付いた項目とスキームのペアは、二度と表示されません。
  4. 信頼度のしきい値が適用されます。 min_confidenceに届かない予測は、保存されますが公開されません。

書き戻しが人手のラベルを変えることはありません。予測は項目のデータに入り、アノテーションは各アノテーターのユーザー状態にあるからです。事前ラベルは、アノテーターが編集できる入力済みの答えとして表示されます。たとえば、選択肢は選択された状態で、自由記述の答えはスキームのテキストボックスに入った状態で表示され、pre_annotationブロックは必要ありません。事前ラベルがアノテーターの答えになるのは、アノテーターが事前ラベルを編集するか、次に進んだときだけです。したがって、誰も編集せず、誰も先に進んでいない事前ラベルが、学習ラベルになることはありません。ai_support.holdoutが、研究の支援なしの比較グループに入れたアノテーターと項目のペアには、事前ラベルが表示されず、そのペアに送られる項目データからは、writeback.fieldとpre_annotation.fieldの両方が除かれます。書き戻しレポートはGET /admin/training/api/statusのwritebackフィールドで、レポートのsummaryは、実行が何も公開しなかった理由を示します。

Potatoは、項目とスキームごとに1つの予測を保持し、新しい実行の予測が古い実行の予測を置き換えます。新しい予測が保存されても、min_confidence未満、空、または却下のために表示されないときは、古い実行の事前ラベルは項目からすぐに外れ、書き戻しレポートは、その項目をn_superseded_clearedに数えます。データとともに提供された事前ラベルには手を触れません。起動時には、writeback.schemasのスキームの保存済みの予測が、同じ4つの検査のもとで項目データに書き戻されるので、事前ラベルは再起動をまたいで残ります。実行の事前ラベルを取り下げるには、DELETE /admin/training/api/runs/<run_id>/predictionsを送ります。このリクエストは、保存された予測を削除し、項目から事前ラベルを外します。

修正された項目と固定された項目は常に学習する

2種類の項目は、安定した分割での位置にかかわらず、以降のすべての実行のtrain分割に入ります。

  • レビュー担当者が修正した項目。 モデルレビューのcorrectの判定は、人がモデルの答えを直したことを意味します。修正は、モデルが最も苦手な項目から生まれるので、valやtestにある修正済みの項目は、モデル自身の誤りのサンプルでモデルのスコアを測ることになります。acceptとrejectの判定は、項目をそのままの場所に残します。
  • 固定された項目。 カタログページのスライスの横にあるTrain on theseは、そのスライスに一致する項目、たとえば組み込みのmodel-found-nothingスライスを固定します。固定された項目は、誰かがその項目にラベルを付けた後に学習します。

ホールドアウトの項目をtrainに移した実行は、その数とともに警告をログに出します。その実行のホールドアウトスコアは、それらの項目を除いて計算されるので、以前の実行のスコアと直接比較することはできません。その数は、学習データのmanifest.jsonのstats.forced_trainにあります。

分割をデータセットのバージョンとして保存する

実行ページのKeep this split as a datasetは、実行のval、test、またはtrainの項目を、合意された人手ラベルとともに、データセットの新しいバージョンとして保存します。データセットのバージョンは、その後変わることがないので、後のモデルとLLMのプロンプトを、まったく同じ項目で比較できます。この機能にはdatasets.enabled: trueが必要です。保存される各バージョンは1つの分割を保持し、データセットの前のバージョンに追加するのではなく、ゼロから始まります。実行2のvalの項目を実行1の項目に足すと、実行2が学習した項目が含まれてしまうからです。各例のinputsには事前ラベルのフィールドが含まれないので、評価がモデルの答えを読むことはできません。

事前ラベルの出どころ

GET /admin/model-reviewは、レビューキューの項目のうち、事前ラベルが学習の実行で書かれたものについて、項目ごとにprovenanceを含みます。スキームごとに、エントリは、実行のid、トレーナー、実行のホールドアウトスコアを示します。データとともに提供された事前ラベルには、エントリがありません。

実行の保存場所

各実行には、<task_dir>/<output_annotation_dir>/training/runs/<run_id>/にディレクトリがあります。

パス内容
bundle/学習データ。train.jsonl、val.jsonl、test.jsonl、include_unlabeledのときのunlabeled.jsonl、labels.json、manifest.json、media/。
artifacts/model_card.json、predictions.jsonl、モデル。たとえばsklearn-textのmodel.pkl、トランスフォーマーのトレーナーのmodel/ディレクトリ。
spec.json実行に求められた内容。
events.jsonl, stdout.log, stderr.log実行の進行イベントと出力。
agent.logsshバックエンドでの、リモートのエージェント自身の出力。
bundle.tar.gzリモートバックエンドで、エージェントがダウンロードしたとおりの、メディアを含む学習データ。

実行の台帳は、プロジェクトのデータベースの<task_dir>/project.sqliteにあり、実行、実行ごとの各項目の分割、学習に固定された項目、保存された予測、エージェントのトークン、Hugging Face Hubへのプッシュを記録します。retain_runsは台帳を整理しますが、予測がまだ保存されている実行は整理しないので、すべての事前ラベルを、それを書いた実行にたどることができます。整理は、実行のディレクトリをディスクに残します。

LoRAの実行はアダプターだけを保存し、そのサイズは数メガバイトから数百メガバイトで、実行が予測するときに、model_nameでベースモデルを読み込みます。フルファインチューニングは、モデル全体を保存します。環境変数POTATO_MODEL_CACHEにディレクトリを設定すると、学習プロセスは、HF_HOME、TRANSFORMERS_CACHE、SENTENCE_TRANSFORMERS_HOMEがすでに設定されていない限り、そのディレクトリをそれらに使います。エアギャップのマシンでは、トレーナーが指定するモデルを、あらかじめそのディレクトリに置いてください。

ルート

Trainingページとそのページが使うJSONのルートは/admin/trainingの下にあり、管理者のアクセスが必要です。管理者のアクセスとは、管理者のセッション、またはX-API-Keyヘッダーのことです。ブラウザーからのPOSTとDELETEのリクエストは、同一オリジンでなければなりません。PotatoのOpenAPI仕様は、26の学習操作すべてにx-potato-requires-config: model_training.enabled: trueを付けています。

ルート目的
GET /admin/training実行フォーム、実行の一覧、トレーナーを備えたTrainingページ。
GET /admin/training/runs/<run_id>1つの実行のページ。状態、指標、イベント、各項目の分割。
GET /admin/training/api/trainersすべてのトレーナーと、その種類、モダリティ、ライセンス、インストールの状態。
GET /admin/training/api/schemas研究のスキームと、各スキームの種類、各スキームに合うトレーナー。
GET /admin/training/api/status現在または直近の実行と、その状態、進捗、指標、警告、skip_reason、writeback、queue。
GET /admin/training/api/runs実行の履歴。?limit=の既定は50、最大は500です。
POST /admin/training/api/runs実行を開始します。実行が始まると200、実行が待つときはqueued: trueとpositionを付けて202が返ります。
GET /admin/training/api/runs/<run_id>1つの実行のレコードと、review(レビューの判定のもとでの実行の予測の適合率)。
GET /admin/training/api/runs/<run_id>/events実行のイベントログ。?limit=の既定は200です。
POST /admin/training/api/runs/<run_id>/cancel進行中の実行、または待機中の実行をキャンセルします。それ以外の実行idには400。
DELETE /admin/training/api/runs/<run_id>/predictions実行の保存済みの予測と事前ラベルを取り下げます。
POST /admin/training/api/runs/<run_id>/push-to-hub実行のモデルをHugging Face Hubに公開します。Hugging Face Hubへの公開を参照してください。
POST /admin/training/api/runs/<run_id>/pin-split本文{"dataset": name, "split": "val"}で、分割をデータセットのバージョンとして保存します。
GET /admin/training/api/backends設定されたバックエンド。
POST /admin/training/api/backends/<name>/checkpotato training checkと同じように、バックエンドを検査します。
GET /admin/training/api/pinned理由ごとにまとめた、固定された項目。
POST /admin/training/api/pinned{"slice": name}または{"instance_ids": [...]}で、項目をtrainに固定します。
DELETE /admin/training/api/pinned挙げたinstance_idsの固定を解除し、本文に何も挙げなければ、固定されたすべての項目の固定を解除します。

実行のリクエストは、trainer、schemas(リスト、または1つの名前)、params、backend、accept_licence、queueを受け取ります。どのトレーナーも、最初に挙げたスキームしか学習しません。次のリクエストは、例のsentimentスキームでsklearn-textの実行を開始します。

bash
curl -X POST -H "X-API-Key: $KEY" -H "Content-Type: application/json" \
  http://localhost:8000/admin/training/api/runs \
  -d '{"trainer": "sklearn-text", "schemas": ["sentiment"]}'

拒否された開始は、errorに理由を示します。

ステータス条件
400本文にトレーナーまたはスキームがない、トレーナーまたはスキームが未知である、トレーナーが学習できないスキームである、プロジェクトが実行できないトレーナーである、またはライセンスの確認が必要なトレーナーで、リクエストがaccept_licence: trueを設定するまでneeds_licence_ack: trueが返る場合
409トレーナーが受け取らない、または型や範囲の誤ったパラメーター、未知のバックエンド、local以外のバックエンドでのdecision-calibrate、または"queue": falseで、すでに実行が進行中である場合
429すでにqueue_maxの実行が待っている場合

エージェントのプロトコル

model_training.enabledは、学習エージェントが呼び出すルートも/api/trainingの下に登録します。エージェントは、エージェントのトークンをAuthorization: Bearer <token>として送り、トークンがない、または無効なときは401が返ります。バックエンドの登録には、代わりに管理者のAPIキーが必要です。potato/training/protocol.pyは、新しいエージェントを書く人のためにプロトコルを記述しており、potato/training/agent.pyはリファレンス実装です。

ルート目的
POST /api/training/backends/registerX-API-Keyを付けて、バックエンド名にエージェントのトークンを発行します。potato training registerがこのルートを呼びます。
POST /api/training/backends/<name>/heartbeatアイドル状態のエージェントが、稼働していることを報告します。別のバックエンドに発行されたトークンには403。
GET /api/training/jobs/next?wait=30ロングポーリング。ジョブがあれば200、wait秒以内にジョブが届かなければ204。
GET /api/training/jobs/<run_id>ジョブ、ジョブのspec、ジョブがキャンセルされたかどうか。
GET /api/training/jobs/<run_id>/bundleメディアを含む、tar.gz形式の学習データ。ルートはRangeリクエストに応答するので、エージェントは中断したダウンロードを、最大5回まで再開します。バンドルがなくなると410。
POST /api/training/jobs/<run_id>/progress進行のイベント。キャンセルはレスポンスで返ります。
POST /api/training/jobs/<run_id>/predictionspredictions.jsonl。max_predictions_mbを超えると413。
POST /api/training/jobs/<run_id>/complete終了コードと最終イベント。

QLoRA

llm-sft、llm-dpo、hf-text-classification、vlm-sft、reward-modelは、lora: {quantize: 4bit}を受け取ります。これはQLoRA(Dettmers et al., 2023)の設定です。ベースモデルは4ビットのNF4の重みと二重量子化で読み込まれ、その上でLoRAアダプターが、GPUがbf16に対応していればbf16で学習されます。quantize: 8bitは中間の選択肢で、予測のときもベースモデルが同じ方法で読み込まれます。

yaml
model_training:
  trainer_params:
    llm-sft:
      model_name: Qwen/Qwen2.5-7B-Instruct
      lora: {quantize: 4bit}

4ビットでは、ベースの重みが占めるメモリは、同じ重みをbf16で持つ場合の4分の1で、そこに活性化、アダプター、オプティマイザーの状態が加わります。PotatoはまだGPU上でのQLoRAの実行のメモリを測っていないので、実行自身の「Peak GPU memory」の行から計画してください。すべてのトランスフォーマーの実行は、終わりにその行をログに出します。QLoRAにはCUDAのGPUと、そのマシンのCUDAに合ったbitsandbytesのビルドが必要です。実行は、モデルを読み込む前に、GPU上でいくつかの数値を量子化して両方を検査し、2つのバージョンが合わないときは、エラーが両方のバージョンを示します。LLMファインチューニングのチュートリアルでは、SFTとDPOの実行でQLoRAを使います。

Hugging Face Hubへの公開

モデルがPotatoサーバー上にある成功した実行の実行ページには、Publish to the Hugging Face Hubがあります。プッシュは、モデルと、実行から作られたREADME.mdのモデルカードをアップロードします。モデルカードには、トレーナー、ベースモデルとアダプター、スキームとラベル、分割のサイズ、ホールドアウトスコアとそのスコアを測った分割、実行とバンドルのidが記されます。dpの実行のカードには、使われたイプシロンと目標、デルタ、保証の対象となるtrain分割を示す「Differential privacy」の行も加わります。実行が目標またはデルタの値を記録していない場合、その行は記録のない値を省きます。

アップロードされるのは、artifacts/ディレクトリ全体ではなく、決まったファイルのリストです。リストには、.safetensors、.bin、.pt、.pklなどの重みのファイル、保存されたmodel/ディレクトリの設定とトークナイザーのファイル、ローカルのパスをファイル名に置き換えたmodel_card.json、calibration.jsonが含まれます。プロジェクトの項目に対するモデルの答え(predictions.jsonlと、判断モデルのraw_answers.jsonl)は、サーバーに残ります。チェックポイント、オプティマイザーの状態、一部のトレーナーが作る学習データのコピー(yolo_data/、wev_data/、laya_data/)、artifacts/の外を指すシンボリックリンクも、同じく含まれません。

フォームは、誤ったプッシュや公開のプッシュを、いくつかの方法で防ぎます。

  • リポジトリ名を2回入力し、2つの名前が一致したときにだけプッシュが進みます。
  • Privateは既定でオンです。Privateがオンの間、Potatoは既存の公開リポジトリにはプッシュせず、APIは409を返します。
  • フォームは、Hugging Faceの書き込みトークンを保持するサーバー上の環境変数の名前(既定はHF_TOKEN)を指定します。トークンそのものをページに入力することはありません。変数名にはTOKENが含まれるか、HF_で始まる必要があり、値はhf_で始まる必要があるので、ほかの変数の値がHubに届くことはありません。
  • リポジトリが存在するかどうかをHubが答えられないときは、何もプッシュされず、プッシュが作ったリポジトリは、その後アップロードに失敗したときに、もう一度削除されます。
  • モデルカードのライセンスは、あなたが指定したHubのライセンスidで、たとえばapache-2.0です。指定がなければ、カードにはベースモデルのライセンスが適用されると記されます。ultralytics-detect(AGPL-3.0)のように、ライセンスの確認が必要なトレーナーは、プッシュにも同じ確認が必要です。
  • fetch_artifacts: falseでリモートホストに残されたモデル、またはエージェントのバックエンドで学習したモデルは、サーバーからプッシュできず、エラーがモデルの場所を示します。

プッシュは1回につき1つのコミットです。実行ページには、すべてのプッシュが、リポジトリ、公開範囲、コミットとともに一覧され、台帳は誰がプッシュしたかを記録します。APIでは、POST /admin/training/api/runs/<run_id>/push-to-hubの本文が、repo_id、confirm_repo_id、private(既定はtrue)、token_env(既定はHF_TOKEN)、licence、accept_licenceを受け取ります。ルートは、成功すればコミットとともに201、名前の不一致、トークン変数がない、モデルファイルがない、ライセンスが未確認の場合は400、Hubが拒否したときは502を返します。

トラブルシューティング

以下の項目は、最初のセットアップで最も起こりやすいエラーを扱います。アップストリームのトラブルシューティングの一覧は、GPUドライバー、CUDAのビルド、トレーナー固有のメッセージを扱います。

  • /admin/trainingが404を返す。 model_training.enabledがtrueではなく、Potatoはキーがtrueのときだけルートを登録します。
  • 「Only N items in the train split」。 より多くの項目にアノテーションするか、実行のparamsのmin_instancesを下げてください。train分割は、既定ではラベル付きの項目の70%です。
  • 「Schema 'x' has 1 distinct label(s) in the data」。 分類器には、使われているラベルが少なくとも2つ必要です。
  • 「No resolved annotations to train on」。 実行で指定したスキームが、アノテーションされているスキームと異なるか、まだ誰も何もアノテーションしていません。
  • 実行が事前ラベルを公開しなかった。 GET /admin/training/api/statusのwritebackレポートを読んでください。「No predictions were published: write-back is not enabled for any schema」は、writeback.schemasが空であることを意味し、見送りの数は、各検査が何件の予測を除いたかを示します。
  • <trainer> does not take <name>。 実行の中、またはtrainer_paramsの下のパラメーターが、綴りの誤りか、別のトレーナーのものです。メッセージは、トレーナーが受け取る名前を一覧で示します。
  • マシンのメモリが尽きた後に、実行が強制終了された。 プロセスはSIGKILLで終了しており、たいていはメモリ不足のキラーによるものです。より小さなモデルか少ない項目を使うか、max_ram_mbを設定して、実行が自分の制限の内側で失敗するようにしてください。
  • 「Stopped: the run took longer than model_training.max_wall_seconds」。 実行が制限時間に達しました。max_wall_secondsを上げるか、より少ない項目で学習してください。
  • 「The GPU ran out of memory」。 batch_sizeを下げ、実効バッチを保つためにgradient_accumulationを上げるか、lora: trueまたはlora: {quantize: 4bit}を設定してください。llm-sftでは、gradient_checkpointing: trueを設定するか、より小さなモデルを選んでください。
  • 「ssh to host failed: Permission denied」。 PotatoはBatchMode=yesでsshを実行するので、ssh <host> trueは、サーバーのアカウントからプロンプトなしで成功しなければなりません。パスフレーズ付きの鍵は、ssh-agentが鍵を保持していれば動作します。
  • エージェントのバックエンドの実行が待機のままになる。 そのバックエンド名のエージェントが、問い合わせをしていません。potato training agent --backend <name>でエージェントを起動し、TrainingページのCheckでトークンを確認してください。

関連ドキュメント

参考文献