SageMaker Ground Truthのパフォーマンス可視化を調査した

2024.04.26

NTT東日本の中村です。

SageMaker Ground Truthのパフォーマンスの可視化について、調査しました。

SageMaker Ground Truthの概要

SageMaker Ground Truthは、教師データを効率良く作成するサービスです。数百、数千に及ぶ教師データを作成する際、複数のワーカー(作業者)を割り当て、ブラウザ経由で、Annotation(教師データ)の作成・レビュー・評価を行います。

こういったサービスはアノテーションツール(サービス)と呼ばれており、OSSで自分で教師データ作成を行えるものから、クラウドベースで教師データの作成を依頼できるものなど、幅広い手法が用意されています。

やっていること

機械学習の為に教師データを必要としており、SageMaker Ground Truthを使用し、動画から静止画のフレームを抽出しして、Amazon Cognitoに登録された社内メンバーにアノテーションの作業をお願いしていました。

社内メンバーはブラウザ経由で静止画を表示して、対象のオブジェクトにBouding Boxを設定していきます。 (画像はイメージです)

この作業が数十枚〜数百枚あり、実際は1つの画像に50~100のBoundingBoxを設定していくため 非常に時間の掛かる作業になります。

今回のアノテーション

  • ビデオフレームのオブジェクト検出(Bounding Box)
  • 動画ファイルをGround Truth に渡し、静止画として切り出したものを、ラベル付けしている
  • 非ストリーミングラベル付けジョブである
  • ワーカーはprivate Workforceである

という前提で調査しています。

困っていたこと

進捗を管理したいとなったとき、SageMaker Ground Truthのジョブで進行具合を確認できます。この画像です。

「12本の動画のうち、10本の動画が完了した」ことを表しているのですが 「個々の動画の中の静止画がどのくらい処理されたのか」「誰が処理したのか」等の情報をUIから得ることができません。

もう少し詳しく状況を把握したいと思い、Ground Truthのドキュメントから、出来ることを調査しました。

ジョブとタスクの調査

ジョブ

ジョブは、ラベル付けプロジェクト全体を表す単位です。複数の静止画や動画など、ラベル付けの対象を登録することができます。 ワーカーはこのジョブに参加し、ラベル付けを行います。

ジョブの作成方法ですが、 S3のバケットを指定すると、存在する動画ファイルを全て検出し、自動で静止画のスライスを行います。 オプションで、動画ファイルからスライスするフレームの単位を指定し、任意の秒数で切り出すことで、切り出す静止画の枚数を制御できます。 例えば、30fpsの動画であれば、300フレームごとに切り出すことで、10秒ごとの静止画の切り出しを設定します。 切り出した静止画は、ジョブに登録されます。

今回は、一つのラベリングジョブに複数の動画(からスライスした静止画)がひも付きます。
「データセットオブジェクト」は、親となる動画を指し、「データオブジェクト」は、静止画を示します。

ジョブのAPI

  • CreateLabelingJobs
  • ListLabelingJobs
  • DescribeLabelingJob
  • ListLabelingJobsForWorkteam

ジョブの作成や、詳細情報を取得できます。

ジョブの管理

CloudWatch Eventsを使用して、ジョブのステータスが変わった時にイベントを取得できます。 信頼ポリシーを追加したIAMと、aws events put-ruleコマンドによるイベントルールの作成が必要です。

ジョブの完了時、Cloudwatchで下記のイベントを取得できます。

LabelingJobStatus = Completedで、ジョブが完了したことを表しています。

 {
     "version": "0",
     "id": "ff6a4ba0-b8f3-9b4a-e71a-606b0f042192",
     "detail-type": "SageMaker Ground Truth Labeling Job State Change",
     "source": "aws.sagemaker",
     "account": "hogehoge",
     "time": "2024-04-21T05:49:11Z",
     "region": "ap-northeast-1",
     "resources": [
         "arn:aws:sagemaker:ap-northeast-1:hogehoge:labeling-job/20240410-gray"
     ],
     "detail": {
         "LabelingJobStatus": "Completed"
     }
 }

ジョブの開始・終了のイベントはあると便利ですが、ワーカーの個々の進捗を図る、という目的には粒度が大きすぎるため、やはりタスクのステータスが欲しくなります。

タスク

タスクは、個々のワーカーに割り当てられるラベル付けの作業単位です。 Ground Truthは、ジョブに紐づいた静止画等のデータオブジェクトをタスクに小さく分割し、ワーカーに割り当てます。 タスクは、ワーカーが一度に処理できる分量のデータを含むように(詰め込みすぎないように)設計されています。

タスクの注意点ですが、親となる動画から作成された静止画の枚数が少ない場合、分割されたタスクに含まれる静止画も少なくなってしまいます。 よってタスクに含まれている静止画の数は一定ではない=タスクの数と労働の量は必ずしも比例しません。 このため、タスクの消化数だけで作業量を図るのが難しくなっています。

また、このタスクについては、APIが存在しないので

  • どういったタスクが発生しているか
  • そのタスクにどのくらいのデータオブジェクトが詰め込まれたのか
  • そのタスクは誰が実行しているのか

の確認ができないため、API経由でチェックを行うのは難しそうです。

タスクの管理

特に設定を行わなくても、Cloudwatch Logsにワーカーのタスク単位のイベントが出力されます。 より詳細にイベントを追うことができますが、あくまでタスク単位であり、「タスク内のどの静止画を処理したか」レベルの細かいイベントは出力されません。 cognito_sub_idが出力されているので、cognitoからユーザ情報を辿ることもできます。

/aws/sagemaker/groundtruth/WorkerActivity

{
     "worker_id": "private.ap-northeast-1.322634f12596f420",
     "task_accepted_time": "2024-04-25T08:01:12.600",
     "task_submitted_time": "",
     "task_returned_time": "",
     "task_declined_time": "",
     "workteam_arn": "arn:aws:sagemaker:ap-northeast-1:hogehoge:workteam/private-crowd/inspection",
     "labeling_job_arn": "arn:aws:sagemaker:ap-northeast-1:hogehoge:labeling-job/inspection",
     "work_requester_account_id": "hogehoge",
     "job_reference_code": "ZfAWcikVoaT3geyO",
     "job_type": "Private",
     "event_type": "TasksAccepted",
     "event_timestamp": "1714032072",
     "cognito_user_pool_id": "ap-northeast-1_wx6tBkp7R",
     "cognito_sub_id": "e0403866-990a-4eff-8eb6-cc0fb5d83c9e",
     "oidc_sub_id": "",
     "oidc_issuer_url": ""
 }

event_typeで、タスクのステータスを確認できます。

  • TasksAccepted:タスクを開始した
  • TaskSubmitted:タスクを完了として送信した
  • TaskReturned:タスクを(時間が無いなどの理由で)作業中のものを破棄して、返却した(他のワーカへ再割当される)
  • TaskDeclined:タスクを拒否した(不適切なタスクと判断したことになり、他のワーカへ再割当されない)

実績のある完了は、event_type = TasksSubmittedとなるので、これをカウントすると良さそうです。 前述の通り、タスクの数と労働の量は完全には比例しないのですが、得られる情報としてはここが限界と思われます。

以上を踏まえて、可視化の方法です。

可視化

以上を踏まえて、可視化の方法です。

ログメトリクス

お手軽に可視化したい場合、Amazon CloudWatchメトリクスが用意されており、ステータスを確認できます。 下のグラフは、時系列でタスクの消化数を可視化しています。

BIツールで可視化

個人的にはLookerStudioをよく使いますが、今回はAWS内で完結させるべく、QuickSightで進めます。

Cloudwatch Logsのイベントログを、CSVに変換していきます。

export.sh

 #!/bin/bash
 
 LOG_GROUP_NAME="/aws/sagemaker/groundtruth/WorkerActivity"
 OUTPUT_FILE="output.csv"
  
 aws logs describe-log-streams --log-group-name $LOG_GROUP_NAME --query 'logStreams[].[logStreamName]' --output text |  while read STREAM; do
   aws logs get-log-events --log-group-name $LOG_GROUP_NAME --log-stream-name $STREAM --query 'events[].[message]' --start-from-head --output text
 done | jq -Rrs '[ split("\n") | .[] | select(length > 0) | fromjson ] |
         (map(keys) | add | unique) as $cols | map(. as $row | $cols | map($row[.])) as $rows | $cols, $rows[] | @csv'> $OUTPUT_FILE

変換後のCSV

変換したCSVを、QuickSightのデータセットとしてアップロードします。

全レコードを格納した上で、フィルタでevent_type=TaskSubmittedのみに限定して、グラフを表示できました。

7人くらいで作業するはずだったのですが・・・おかしい・・3人しか作業していない・・・のようなことも分かりますね。 今回はタスクの消化数にフォーカスしましたが、平均的なタスク消化時間や、タスクの中断率も可視化できそうです。

まとめ

SageMaker Groud Truthのパフォーマンス可視化について調査を行いました。 ジョブ、タスクの管理はCloudwatch経由で情報を取得でき、CloudwatchメトリクスやBIツールで、可視化を行うことができます。 それより細かい粒度(データオブジェクトを何枚処理した?等)は追跡できないのが現状と思われました。

ラベル付け大変な作業をお願いすることになるので、ワーカーと良いコミュニケーションが行えるよう、可視化の環境も整えていきたいですね。