[VAMS] NVIDIA Isaac Lab のトレーニング機能で SO-ARM101 の Reach を強化学習させてみました

[VAMS] NVIDIA Isaac Lab のトレーニング機能で SO-ARM101 の Reach を強化学習させてみました

VAMSのIsaac Labパイプラインにカスタムロボット環境を持ち込み、SO-ARM101のReachタスクを学習させる方法を紹介します。つまずいた点や実装の工夫もまとめました。
2026.06.19

1 はじめに

製造ビジネステクノロジー部の平内(SIN)です。

VAMS(Visual Asset Management System)は、3D/ビジュアルアセットをクラウド管理する AWS のオープンソース基盤ですが、Web UI から NVIDIA Isaac Lab を使ったトレーニングを操作できるパイプラインが用意されています。

https://aws.amazon.com/jp/blogs/news/gpu-accelerated-robotic-simulation-training-with-nvidia-isaac-lab-in-vams/

ただし、この Isaac Lab のパイプラインには、SO-ARM101 は含まれていませんでした。そこで、MuammerBay が配布する SO-ARM101 用のパッケージを「カスタム環境(tar.gz)」として使用し、以前のブログで作業した Reach(強化学習)タスクの差分も乗せて学習を回してみました。

カスタム環境は S3 にアップロードして取り込みますが、そのままでは VAMS 側でタスクが gym.register されず、学習を動かすにはいくつか手を加える必要がありました。

本稿では、こちらの構築手順や、つまずいた点などを紹介させていただきます。

最終的に、SO-ARM101 の Reach タスクを VAMS 上で学習させ、学習済みポリシーをアセットとして保存するところまで確認できました。

024
025

2 構成

VAMS の構成は以下のとおりです。
利用した VAMS のバージョンは、v2.5.1 です。

026
https://aws.amazon.com/jp/blogs/news/gpu-accelerated-robotic-simulation-training-with-nvidia-isaac-lab-in-vams/

VAMSでは、インスタンスの起動・停止は、AWS Batch が担っていますが、keepWarmInstance: falseと設定することで、常時起動は0台となり、ジョブ実行時のみの起動とすることができます。

なお、起動する GPU インスタンスの種類は VAMS のコンストラクトで定義されており、候補は優先順に g6(L4)→ g6e(L40S)→ g5(A10G)となっていました。

027
https://github.com/awslabs/visual-asset-management-system/blob/main/infra/lib/nestedStacks/pipelines/simulation/isaacLabTraining/constructs/isaacLabTraining-construct.ts

なお、Isaac Lab パイプラインは OpenSearch に依存しないため、Serverless の常駐費を回避するため、OpenSearch は無効化しました。

3 作業手順

作業全体の流れと各スクリプトは GitHub に公開しています。詳細な手順は README / runbook を参照してください。

(1) NGC 認証

Isaac Lab の学習コンテナは nvcr.io/nvidia/isaac-lab をベースにビルドするため、NVIDIA NGC へのログインが必要です。ログインしていないとイメージ取得で Access Denied になります。

$ docker login nvcr.io
# Username: $oauthtoken
# Password: NGC の API キー

(2) デプロイ

deploy.sh が、VAMS の clone・カスタム環境向けパッチ適用・cdk deploy までを行います。

$ bash scripts/deploy.sh

完了後の Outputs から、Web UI の URL・Cognito ユーザープール ID・アセット用 S3 バケット名を控えておきます。

002

(3) 管理者ログイン

管理者ユーザのメールはダミーのため、CLI から Cognito でパスワードを設定してから、cdk の Outputs で表示された URL で、ログインします。

$ aws cognito-idp admin-set-user-password \
  --user-pool-id <UserPoolId> --username administrator \
  --password '<大文字を含むパスワード>' --permanent --region ap-northeast-1
vams-core-prod-ap-northeast-1.WebsiteEndpointURLOutput = https://xxxxxxxxxxxxxxx.cloudfront.net

003
004

(4) Database とアセットを作成する

学習対象を入れる「Database」と「アセット」を Web UI で作成します。

左メニュー「Manage → Databases」→ 右上「Create Database」。Database ID に任意の名前(例 so-arm101-db)を入力して作成します。

005
006
007

左メニュー「Manage → Create Asset」から、いま作った Database を選び、Asset 名(例 soarm101)を入力して作成します。学習を起動するだけならファイルのアップロードは不要です。

008
009
010
011
012
013

(5) カスタム環境(tar.gz)を作成し、S3 へアップロードする

SO-ARM101 のロボット定義と Reach タスクを tar.gz にまとめ、アセット用の S3 バケットにアップロードします。

AssetS3Bucket は、cdk の Output AssetS3BucketNameOutput0 に出力された名前になります。

$ bash custom-env/build-custom-env.sh
$ aws s3 cp custom-env/dist/so-arm101-reach-grasp-env.tar.gz \
  s3://<AssetS3Bucket>/custom-env/so-arm101-reach-grasp-env.tar.gz --region ap-northeast-1

生成: xxxx/custom-env/dist/so-arm101-reach-grasp-env.tar.gz
次: VAMS のアセットへアップロード 学習 config task Isaac-SO-ARM101-Reach-Grasp-v0 を指定
upload: so-arm101-reach-grasp-env.tar.gz to s3://xxxxxxxx/custom-env/so-arm101-reach-grasp-env.tar.gz

(6) パイプラインに学習設定(Input Parameters)を入れる

「どのタスクを・どのカスタム環境で学習するか」を、Isaac Lab 学習パイプラインに設定します。

左メニュー「Orchestrate & Automate → Pipelines」を開きます。
一覧から isaaclab-training を選択し、「Edit」をクリックします。
「Input Parameters」欄に次の JSON を貼り付け、「Update Pipeline」で保存します。

{
  "trainingConfig": {
    "mode": "train",
    "task": "Isaac-SO-ARM101-Reach-Grasp-v0",
    "rlLibrary": "rsl_rl",
    "numEnvs": 4096,
    "maxIterations": 500,
    "customEnvironmentS3Uri": "s3://<AssetS3Bucket>/custom-env/so-arm101-reach-grasp-env.tar.gz"
  },
  "computeConfig": { "numNodes": 1 }
}

cdk deploy を再実行すると、この設定は既定値(Cartpole)に戻ります。

014
015

(7) ワークフローを実行する

Isaac Lab パイプラインは GLOBAL データベースに属しており、autoRegisterWithVAMS によってデプロイ時に GLOBAL のワークフロー(isaaclab-training)が自動登録されています。これをアセットに対して実行します。

Manage → Assets and Filesから、アセット soarm101 を開きます

016

Workflowsタブ から Execute Workflowをクリックします。

017

「Select Workflow」で、isaaclab-training (GLOBAL) を選択し、Execute Workflowをクリックします。

018

「Execute Workflow」を押すと、AWS Batch で GPU インスタンスが起動し、SO-ARM101 の Reach タスクの学習が始まります。

019

インスタンスが上がっている状況は、AWS BatchのジョブやEC2インスタンスでも確認できます。

020

021

(8) 学習を確認する

学習の進行は、AWS Batch のログ(CloudWatch の /aws/batch/job)で確認できます。SO-ARM101 固有の報酬(Episode_Reward/end_effector_position_trackingposition_success_1cm など)が出力され、学習が進むにつれて上昇していきます。

022

学習が完了すると、学習済みポリシー(checkpoints/model_*.pt)と metrics.csv が、アセットの File Manager に登録されます。

023

(9) 後片付け

検証が終わったら、必ずスタックを削除します。使用していなくても、NAT Gateway などに課金があることにご注意ください。

$ bash scripts/destroy.sh

4 VAMS の Isaac Lab パイプラインとカスタム環境の仕組み

(1) パイプラインの有効化

VAMS は複数の処理パイプラインを持ち、config.jsonapp.pipelines.useXXX.enabled で「どれをデプロイするか」を選びます。今回は、Isaac Lab を設定しています。

"pipelines": {
  "useIsaacLabTraining": {
    "enabled": true,
    "acceptNvidiaEula": true,   // 未設定だとコンテナビルドが失敗する
    "keepWarmInstance": false   // GPU の常時起動を避ける
  }
}

useIsaacLabTrainingenabled: true で Isaac Lab 学習パイプライン(Batch GPU 環境・学習コンテナ・Lambda・Step Functions)がデプロイされ、Web UI の Pipelines/Workflows 一覧に isaaclab-training / isaaclab-evaluation が登録されます。

(2) 学習コンテナ(__main__.py

学習の本体は、AWS Batch の GPU コンテナ内で実行される __main__.py です。VAMS が Step Functions 経由でジョブを起動すると、このスクリプトが動きます。

GitHub: backendPipelines/simulation/isaacLabTraining/container/main.py

主な処理は次のとおりです。

  1. ジョブ設定 JSON を受け取り、task / numEnvs / customEnvironmentS3Uri などを解釈
  2. customEnvironmentS3Uri があれば、S3 から tar.gz を取得して pip インストール
  3. ./isaaclab.sh -p scripts/reinforcement_learning/rsl_rl/train.py --task ... で学習を実行
  4. 成果物(checkpoints / metrics)を S3(アセット)へアップロード
  5. Step Functions に完了を通知

(3) カスタム環境(tar.gz)

Isaac Lab 標準に含まれないロボット/タスクは、pip インストール可能な Python パッケージとして持ち込みます。今回の tar.gz の構造は次のとおりです。

so-arm101-reach-grasp-env.tar.gz
├── pyproject.toml
└── src/isaac_so_arm101/
    ├── robots/trs_so101/   # SO-ARM101 のロボット定義(URDF / メッシュ)
    └── tasks/reach/        # Reach-Grasp タスク(gym.register / 報酬 / PPO 設定)

build-custom-env.sh で、ベース(MuammerBay)に fork(furuya02)の Reach-Grasp 差分を重ね、tar.gz 化しています。

(4) タスク登録

Isaac Lab のタスクは、定義モジュールが import された時 gym.register(...) により自動登録されるのですが、VAMS の train.py では、それがうまく動作しませんでした。

そこで、学習コンテナ側(__main__.py)で、カスタム環境をインストールした直後に、標準 train.py の import isaaclab_tasks の直後へ import isaac_so_arm101.tasks を入れました。

これにより Isaac-SO-ARM101-Reach-Grasp-v0 を学習できるようになりました。

5 スクリプト

(1) deploy.sh

VAMS の clone・パッチ適用・設定反映・デプロイを行います。

  • BUILDX_NO_DEFAULT_ATTESTATIONS=1 を設定(後述)
  • Location API キーの残骸を削除(再デプロイ衝突の防止)
  • custom-env/patch-vams-container.sh でカスタム環境向けのコンテナ修正を適用
  • config/config-patch.jq で OpenSearch none / Isaac Lab 有効化 / VPC を反映
  • cdk deploy --all

(2) build-custom-env.sh

ベース(MuammerBay)と fork(furuya02)を clone し、Reach-Grasp の差分を重ねて tar.gz を生成しています。pyproject に gymnasium.envs エントリポイントを追記する処理も含みます。

(3) patch-vams-container.sh

VAMS の学習コンテナ(__main__.py)に、カスタム環境を通すための修正を当てています。

  1. pip install -e <archive>pip install --no-deps <archive> に変更
  2. インストール後に、標準 train.py へカスタム環境のタスク import を差し込む処理を追加

(4) destroy.sh

cdk destroy --all でスタックを削除します。Location API キーの削除を含みます。

6 つまずき

作業中につまずいた点を紹介させてください。

  • コンテナビルドが pull access denied for cdk-<hash> で失敗: 新しめの buildx と Rancher Desktop / containerd image store の組み合わせで、docker run できない形式のイメージが生成されることがありました。BUILDX_NO_DEFAULT_ATTESTATIONS=1 を設定して回避しました(環境依存だと思います)。
  • pip install -e がアーカイブ非対応: tar.gz には使えなかったため、--no-deps での通常インストールに変更しました。
  • タスク登録: 前述のとおり、標準 train.py への import 追加で対応しました。
  • ステータスの確認はログで: 学習が失敗していても VAMS の表示が「成功」になる場合がありました。ログでの確認が必要だと思います。
  • 削除時の残リソース: destroy 時に一部リソース(Location API キーやサブネットに残る ENI など)が残って失敗することがありました。対処は README のトラブルシュートにまとめました。

7 最後に

VAMS の Isaac Lab トレーニング機能を使って、SO-ARM101 の Reach タスクを GPU 上で学習させ、学習済みポリシーをアセットとして管理するところまで確認できました。Web UI からマネージドに学習を回せるのは、非常に快適な環境だと思いました。

なお、「VAMS で Isaac Lab を試す」だけであれば、カスタム環境は不要です。Isaac Lab 標準のタスク(Isaac-Cartpole-Direct-v0Isaac-Reach-Franka-v0 など)であれば、Input Parameters の task に標準タスク名を指定するだけで学習できます。

本記事で使用したコードは、以下に置きました。

furuya02/vams-isaac-lab-so-arm101-reach

この記事をシェアする

関連記事