Skip to content

フック ​

フックは、Projectで何かが起きたとき(きっかけ)に、決めておいたJobを起動する仕組みです。左のサイドバーの「実行」にある[Hooks]で開きます。モデル登録後の自動実行はモデルの登録だけをきっかけにしますが、フックはRunの終了、checkpointの保存、外部からのwebhookもきっかけにでき、実行先にsiteも選べます。

フックは所有者の権限でJobを起動し、作るRunの作成者も所有者になります。所有者は、最初はフックを作った人です。

こんなときに向いています ​

  • 学習Runが終わったら、そのRunのモデルと出力データで評価を回したい
  • 学習中にcheckpointを保存するたびに、評価を回したい
  • GitHubへのpushやデータの更新を合図に、外からJobを起動したい
  • 決まった設定のJobを、本文(JSON)だけ変えて手で起動したい

きっかけ ​

きっかけ起動するときJobに渡すもの
手動・起動APIフックの詳細の[手動で起動]か、API・Python SDKから起動したとき起動したときの本文(JSON)
モデルバージョンの登録モデルバージョンを登録したとき。学習中に登録したバージョンは、学習Runが終わるのを待ちます登録されたモデルバージョン
Runの終了Runが終わったとき。失敗・中止も含みます([Runの終了状態]で絞れます)選べば、そのRunのモデルバージョンと出力データセットバージョン
arrayの終了arrayのすべての番号の最後の試行が終わったとき選べば、すべての番号の出力データセットバージョン
checkpointの保存学習RunがSDKでcheckpointを保存したときそのcheckpoint(Jobの中ではMMT_INPUT_CHECKPOINT_DIR、ふつうは/mmt/inputs/checkpoint)
外部webhook署名の合うPOSTを受け取ったとき送られた本文
  • MLflowのcheckpoints/step-N/に置いたcheckpointでは起動しません。ファイルが揃った時点が分からないためです。SDKのrun.log_checkpoint()を使ってください(学習の途中再開)。
  • 学習中に登録したモデルバージョンは、学習Runが成功すると起動します。失敗・中止したときは起動しません。7日待っても終わらないときも起動しません。
  • 同じ出来事では1回だけ起動します。webhookの再送や、終わったRunの再開と再終了でも、Jobは増えません。

Jobの中では、きっかけの内容を/mmt/context/trigger-payload.json(環境変数MMT_TRIGGER_PAYLOAD_FILE)として読めます。手動の起動では起動したときの本文、webhookでは送られた本文(JSONのオブジェクトでなければ{"body": "<本文>"})、そのほかのきっかけでは{"event": "run_finished", "runId": …}のような出来事の説明が入ります。

フックを作る ​

フックを作れるのはProjectのeditor以上です。

  1. [Hooks]を開き、右上の[フックを作成]を押します。
  2. 次の項目を入力して[作成]を押します。
  3. 一覧に追加されたフックを選び、詳細に設定が表示されることを確かめます。

作るときに、コードバージョン、実行先、Runtime、GPU、入力を、実際に起動するときと同じように確かめます。起動できない設定のフックは作れません。

きっかけ ​

項目内容
名前フックの名前。例:学習後の評価
きっかけ上の表から選びます
署名の形式外部webhookのとき。GitHub(X-Hub-Signature-256)かMMT(X-MMT-Signature)(webhookで起動する)
checkpointごとの起動checkpointの保存のとき。下の表
何個ごとに起動するか[checkpointごとの起動]が「k個ごと」のとき。1〜100,000
checkpointごとの起動動き
毎回保存のたびに起動します(既定)
k個ごとそのRunのk個ごとに起動します
最新だけ(評価中に増えた分は最新の1つにまとめる)評価のJobが動いている間に来たcheckpointは、最新の1つだけが待ち、前の評価が終わると起動します
実行中なら飛ばす評価のJobが動いている間に来たcheckpointでは起動しません

きっかけの絞り込み ​

手動・起動APIと外部webhook以外のきっかけでは、どの出来事で起動するかを絞り込めます。空の項目では絞り込みません。条件に合わない出来事では起動せず、実行履歴も残しません。

項目内容
モデル系列対象のモデル系列
実験対象のExperiment
Runの実行種別学習、推論など
Runの終了状態完了、失敗、中止。Runの終了とarrayの終了のときだけ選べます(モデルバージョンの登録とcheckpointの保存の時点では、学習Runがまだ終わっていないため)
Runのタグ(JSON・すべて一致)例:{"dataset": "speech-v3"}。すべてのタグが一致するRunだけで起動します

起動するJob ​

項目内容
ExperimentsRunを記録するExperiment
実行種別学習、ファインチューニング、推論、評価、データ処理
モデルバージョン固定のバージョン、または「きっかけのRunのモデルバージョンを使う」(Runの終了、arrayの終了、checkpointの保存)。モデルバージョンの登録では欄が無く、登録されたバージョンで起動します
コードバージョン実行種別とモデル系列に合うものだけを選べます
入力データセットバージョン毎回渡すデータセットバージョン。任意
きっかけのRunの出力データセットバージョンも入力にするRunの終了とarrayの終了のとき
コンピュータコードバージョンのRuntimeを使えるコンピュータだけを選べます
GPU(選ばなければCPUのみ)SSH・Localのコンピュータを選ぶと出ます。コンピュータに登録したGPUをチェックボックスで選びます。選ばなければCPUだけで実行します。GPUの無いコンピュータでは「このコンピュータにはGPUがないため、CPUのみで実行します。」と出ます
GPU数、制限時間、arrayの個数、arrayで分ける入力データセットバージョンsiteのとき。arrayの個数を入れると、1回の起動でarrayを作ります
パラメータ(JSON)、タグ(JSON)automation.とmmt.で始まるタグはサーバーが付けるので使えません
最大試行回数1〜100。既定は1です。自動の再実行の上限で、Jobsの[新しいRunで再実行]で人が流し直す分は数えません
失敗したら最初から再実行する、時間切れなら最新のcheckpointから再実行するsiteのとき。フックのJobが自動で再実行されるのは、これを選んだときです
このJobのコードから子Jobを作れる(ドライバー)Jobのコードが、自分のJob tokenで子Jobを作れるようにします

フックの詳細の[Jobごとの資源]には、SSH・LocalではGPU ID、siteではGPU数・制限時間・arrayの個数をまとめて出します。

手動投入のsiteを選ぶと、「この実行先は手動投入のsiteです。フックが作ったJobは、所有者がsiteのログインノードでmado-tracking submitを実行するまで待機します。」と出ます。一覧と詳細の実行先にも「手動投入」の印が付きます。投入のしかたは外部のコンピュータ(site)を参照してください。

起動の制限 ​

項目内容
前のJobが終わる前のイベント「すべて起動する」(既定)か「前のJobが実行中ならイベントをスキップする」。後者では、このフックのJobが動いている間に来た出来事では起動しません(後で起動もしません)
1時間あたりの起動回数の上限1〜10,000。既定は60です。直近1時間の起動が上限に達している間は、出来事が来ても起動しません

手動で起動する ​

きっかけが「手動・起動API」のフックは、詳細の「手動で起動」から起動できます。起動できるのはProjectのeditor以上で、フックが有効なときだけです。

  1. 必要なら[本文(JSON・任意)]にJSONのオブジェクトを書きます。256KiBまでです。
  2. [手動で起動]を押し、確認で[起動する]を押します。
  3. 「起動を受け付けました(Jobを登録)。その後の結果は実行履歴で確認できます。」と出たら、[実行履歴]かJobsで進み具合を確かめます。

本文は、Jobの中で/mmt/context/trigger-payload.json(環境変数MMT_TRIGGER_PAYLOAD_FILE)として読めます。

Python SDKからも起動できます。人のAPI tokenを使います。Jobの中のJob tokenではフックを起動できません。

python
from mado_tracking import Client

with Client() as client:
    client.trigger_hook("PROJECT_ID", "HOOK_ID", {"ref": "refs/heads/main"}, idempotency_key="deploy-42")

同じidempotency_keyで送り直しても、起動は1回です。省くとSDKが付けます。

webhookで起動する ​

始める前に ​

API serverにMMT_HOOK_SECRET_KEY(base64の32 byte。openssl rand -base64 32で作れます)の設定が要ります。設定が無いと、きっかけが外部webhookのフックを作れません。サーバーの管理者に設定を頼んでください。この鍵を替えると、それまでのwebhookのフックは受け付けなくなるので、作り直して送信元の秘密鍵も替えます。

作る ​

  1. [フックを作成]で[きっかけ]を「外部webhook」にし、[署名の形式]を選んで作成します。
  2. 作成するとすぐに「Webhookの設定」が開き、「署名の秘密鍵」と「受け口のURL」がコピーボタン付きで出ます。
  3. 送信元に受け口のURLと秘密鍵を設定してから、[閉じる]を押します。

秘密鍵はこの画面で一度だけ表示します。閉じると二度と表示できません。受け口のURL(https://<この画面のホスト>/api/hooks/<フックのID>/webhook)は、後からでもフックの詳細にコピーボタン付きで出ます。APIをこの画面と別の名前で公開しているときは、そのホストにpathを付けます。

署名の形式 ​

署名の形式送信元の設定再送の判定
GitHub(X-Hub-Signature-256)GitHubのリポジトリのWebhooksで、Payload URLに受け口のURL、Content typeにapplication/json、Secretに秘密鍵を設定しますX-GitHub-Deliveryが同じ再送は1回として扱います
MMT(X-MMT-Signature)X-MMT-Signature: t=<unix秒>,v1=<HMAC-SHA256(秘密鍵, "<t>.<本文>")の16進>を付けて送ります。時刻のずれは5分まで受け付けますX-MMT-Deliveryが同じ再送は1回として扱います

再送を判定するヘッダが無い要求は、それぞれ別の出来事として起動します。LANの中の送信元やCIからは、MMTの形式が使えます。

bash
body='{"dataset":"speech-v3"}'
t=$(date +%s)
sig=$(printf '%s.%s' "$t" "$body" | openssl dgst -sha256 -hmac "$WEBHOOK_SECRET" -hex | sed 's/^.* //')
curl -sS -X POST "https://tracking.example.internal/api/hooks/$HOOK_ID/webhook" \
  -H 'Content-Type: application/json' -H "X-MMT-Signature: t=$t,v1=$sig" \
  -H "X-MMT-Delivery: $(uuidgen)" -d "$body"
応答意味
202受け付けました。executionIdが実行履歴の記録です
401署名が一致しません
409フックが無効です

本文は256KiBまでです。受け口のURLを外へ公開するときは、入口のproxyで/api/hooks/*/webhookだけを通してください。

設定を変える ​

フックの設定は作成後に変えられません。変えられるのは、有効・無効と所有者だけです。過去の起動がどの設定で動いたかを、後から確かめられるようにするためです。

  • 一覧の[操作]の[無効にする][有効にする]で切り替えます(editor以上)。無効にすると、以後の出来事では起動しません。待っている実行も起動しなくなります。
  • 設定を変えたいときは、フックの詳細で[複製して新しく作る]を押します。今の設定を写した作成画面(「フックを複製して作成」、名前は<元の名前>(複製))が開くので、変えたいところだけ直して[作成]を押します。元のフックはそのまま残るので、不要なら[無効にする]で止めます。
  • 外部webhookのフックを複製すると、新しい受け口と秘密鍵になります。送信元の設定も変えてください。
  • フックはまだ削除できません。無効にしたフックは、一覧に「無効」として残ります。

所有者をService Accountへ移す ​

フックを作った人がProjectのeditorでなくなると、そのフックは「起動せず(所有者がプロジェクトの権限を失っている)」になり、Jobを起動しなくなります。長く使うフックは、人に紐付かないService Accountへ所有者を移しておきます。

  1. Projectの設定で、roleがeditorかadminのService Accountを作ります。tokenを発行する必要はありません(API tokenとService Account)。
  2. フックの詳細の「Service Accountへ移す」で、[移管先のService Account]を選び、[Service Accountへ移す]を押して確定します。
  3. 一覧と詳細の[所有者]が、そのService Accountになったことを確かめます。

移管できるのはProject adminと全体管理者です。移管先は、同じProjectの有効なService Accountで、roleがeditorかadminのものに限ります。以後の起動はそのService Accountの権限で動き、作るRunの作成者もそのService Accountになります。フックを作った人の記録([作成者])は変わらず、移管は監査ログに残ります。

実行先がPrivateのコンピュータなら、そのコンピュータの所有者が作ったService Accountへ移します。ほかの人が作ったService Accountではそのコンピュータを使えないため、起動に失敗します(コンピュータと公開範囲)。

実行履歴を見る ​

[実行履歴]のタブ(フックの詳細の[実行履歴を見る]からも開けます)に、起動ごとの記録が新しい順に並びます。[表示するフック]で1つのフックに絞り込めます。古い記録は[さらに読み込む]で読み込みます。

列内容
作成日時出来事を受け取った日時
フックどのフックか(すべてのフックを表示しているとき)
結果下の表
対象きっかけの出来事(手動、モデルバージョン、Run、array、checkpoint、webhook)。モデルバージョン、Run、arrayは押すとその画面へ移ります
Jobの状態作ったJobの状態
関連[Runを開く][Jobを開く][array][待っているRun]
ジョブエラー起動に失敗した理由
結果意味
Jobを登録JobかarrayのJobを作りました
Runの終了待ち学習中に登録したバージョンで、学習Runの終了を待っています。checkpointの保存の「最新だけ」で、前の評価の終了を待っているときにも出ます
起動せず(理由)条件により起動しませんでした。理由は下の表です
起動に失敗JobやRunを作れませんでした。理由は[ジョブエラー]に出ます。出来事そのものは取り消しません
起動せずの理由意味
同じ連鎖でこのフックが起動済みこのフックが起動したJobの終了で、同じフックがまた起動しようとしました。フックが自分のJobで起動し続けることはありません
連鎖の深さが上限(10段)を超えるフックとドライバーのつながりが10段を超えました
1時間あたりの起動回数の上限直近1時間の起動が上限に達しました
前のJobが終わっていない「前のJobが実行中ならイベントをスキップする」か「実行中なら飛ばす」で、このフックのJobがまだ動いています
所有者がプロジェクトの権限を失っている所有者がProjectのeditorでなくなりました
新しいcheckpointに置き換え「最新だけ」で、より新しいcheckpointが来ました
きっかけのRunが失敗・停止学習中に登録したバージョンの学習Runが、成功しませんでした
Runの終了待ちの期限切れ学習Runが7日待っても終わりませんでした
フックが無効待っている間にフックが無効にされました

失敗したJobを流し直す ​

フックのJobの最大試行回数は、既定で1(自動の再実行なし)です。失敗したJobは、Jobsの[新しいRunで再実行]で人が流し直せます。最大試行回数に達したJobも流し直せます。流し直せるのは、Jobの作成者(フックの所有者)とProject adminです。再実行したJobにも、起動元としてフックが出ます。詳しくはJobsの画面を参照してください。

権限 ​

操作必要な権限
フックと実行履歴を見るviewer以上
フックの作成、有効・無効の切り替え、手動の起動editor以上(API tokenはjobs:write)
所有者の移管Project adminか全体管理者(API tokenはadmin scope)
webhookの受け口へ送る署名の秘密鍵を持つ送信元(ログインは要りません)