使用 NVIDIA Isaac Sim 和 NVIDIA TAO 開發和部署 AI 機器人

作者 NVIDIA

從製造汽車到協助外科醫師和運送披薩,機器人不僅自動化,且能將人工任務加快數倍。隨著 AI 問世,您可以打造出能更有效地感知周圍環境,並在幾乎不需要人為介入下做出決定之更智慧化的機器人。

以在倉庫中移動裝載物的自主機器人為範例。它必須感知周圍的自由空間、偵測和避開路徑中的任何障礙物,並做出「即時」決定,毫無延遲地挑選出新路徑。

這就是挑戰。表示需要建構由經過訓練和最佳化,可以在該環境中運作之 AI 模型驅動的應用程式。其必須收集大量的高品質資料,並開發出高度準確的 AI 模型以驅動應用程式。這些是將應用程式從實驗室轉移至實際環境時面臨的主要障礙。

本文說明如何使用 NVIDIA Isaac 平台和 TAO 框架解決資料挑戰和模型建立挑戰。使用機器人模擬應用程式 NVIDIA Isaac Sim 建立虛擬環境,並產生合成資料。NVIDIA TAO 工具套件是具有內建轉移學習的低程式碼 AI 模型開發解決方案,相較於從零開始訓練,可以使用一小部分的資料微調預先訓練模型。最後,使用 NVIDIA Isaac ROS 將最佳化模型部署至機器人上,並在真實世界中啟用。

Diagram shows an overview of workflow with synthetic data generation using NVIDIA Isaac Sim and training a pretrained model with TAO in a simulated environment, evaluate the results and collect more data if necessary. The model is then pruned and retrained again in the simulated environment. The model then is moved to the next phase where it is fine-tuned on real-world data and eventually deployed. 
圖 1:使用 NVIDIA Isaac Sim 在合成資料上訓練 TAO 工具套件模型,以適應真實世界使用案例的工作流程概覽。

先決條件

在開始之前必須具備下列資源,才能進行訓練和部署:

  • NVIDIA GPU 驅動程式版本:>470
  • NVIDIA Docker:2.5.0-1
  • 雲端或內部部署 NVIDIA GPU:
    • NVIDIA A100
    • NVIDIA V100
    • NVIDIA T4
    • NVIDIA RTX 30×0(NVIDIA Isaac Sim 可支援 NVIDIA RTX 20 系列)
    • NVIDIA Jetson Xavier 或 Jetson Xavier NX
  • NVIDIA TAO 工具套件:4.22。若需要更多資訊,請參閱 TAO 工具套件快速入門指南
  • NVIDIA Isaac SimIsaac ROS

使用 NVIDIA Isaac Sim 產生合成資料

本節概述在 NVIDIA Isaac Sim 中產生合成資料的步驟。合成資料是電腦模擬或演算法產生的加註資訊。在難以取得真實資料或取得成本昂貴時,合成資料可以協助解決資料挑戰。

NVIDIA Isaac Sim 提供三種產生合成資料的方法:

  • Replicator 編譯器
  • Python 指令碼
  • GUI

於此示範中,我們選擇使用 Python 指令碼,透過領域隨機化(domain randomization)產生資料。領域隨機化會改變在模擬環境中定義場景的參數,包括場景中各種物件的位置、比例,以及模擬環境的光照、物件的色彩和紋理等。

增加領域隨機化以同時改變場景的許多參數,可以提高資料集的品質,並將模型暴露在真實世界中的各種領域參數下,以提升模型的效能。

於此範例中,使用兩種環境訓練資料:倉庫和小房間。後續步驟包括將符合物理定律的物件加入場景中。我們使用來自於 NVIDIA Isaac Sim 的範例物件,包括來自 YCB 資料集的日常物件。

Picture of cans, and bottles randomly placed on the floor. Another picture of a box placed underneath the cart along with some additional boxes placed in a warehouse type environment.
圖 2:來自簡單房間和倉庫環境的模擬影像範例

在安裝 NVIDIA Isaac Sim 後,Isaac Sim App Selector 提供了一個在資料夾中開啟的選項,包含 python.sh 指令碼。其可用於執行指令碼以產生資料。

依據列出的步驟產生資料。

選擇環境以及為場景新增攝影機

def add_camera_to_viewport(self):
  # Add a camera to the scene and attach it to the viewport
  self.camera_rig = UsdGeom.Xformable(create_prim("/Root/CameraRig", "Xform"))
  self.camera = create_prim("/Root/CameraRig/Camera", "Camera")

為地板新增語意 ID:

def add_floor_semantics(self):
  # Get the floor from the stage and update its semantics
  stage = kit.context.get_stage()
  floor_prim = stage.GetPrimAtPath("/Root/Towel_Room01_floor_bottom_218")
  add_update_semantics(floor_prim, "floor")

透過物理在場景中新增物件:

def load_single_asset(self, object_transform_path, object_path, usd_object):
  # Random x, y points for the position of the USD object 
  translate_x , translate_y = 150 * random.random(), 150 * random.random()
  # Load the USD Object
  try:
      asset = create_prim(object_transform_path, "Xform",
               position=np.array([150 + translate_x, 175 + translate_y, -55]), 
               orientation=euler_angles_to_quat(np.array([0, 0.0, 0]),
               usd_path=object_path)
	# Set the object with correct physics
      utils.setRigidBody(asset, "convexHull", False)

將領域隨機化元件初始化:

def create_camera_randomization(self):
  #  A range of values to move and rotate the camera       
  camera_tranlsate_min_range, camera_translate_max_range = (100, 100, -58),
                                                            (220, 220, -52)      
  camera_rotate_min_range, camera_rotate_max_range = (80, 0, 0), (85, 0 ,360)

  # Create a Transformation DR Component for the Camera
  self.camera_transform = self.dr.commands.CreateTransformComponentCommand(
                              prim_paths=[self.camera.GetPath()], 
                              translate_min_range=camera_tranlsate_min_range,
                              translate_max_range=camera_translate_max_range,
                              rotate_min_range=camera_rotate_min_range,
                              rotate_max_range=camera_rotate_max_range,
                              duration=0,5).do()

確保模擬中的攝影機位置和屬性與真實世界的屬性類似。必須為地板新增語意 ID,才能產生正確的自由空間分割遮罩。如前所述套用領域隨機化,以提高模型的 sim2real 效能。

我們的指令碼是以 NVIDIA Isaac Sim 文件中提供的離線資料產生範例為起點。此使用案例已進行變更,包括透過物理將物件新增至場景、更新領域隨機化,以及為地板新增語意。我們為資料集產生了將近 30,000 張影像及其對應的分割遮罩。

使用 TAO 工具套件進行訓練、調整和最佳化

在本節中,將使用 TAO 工具套件,透過產生的合成資料微調模型。在此任務中,我們選擇使用 NGC 提供的 UNET 模型進行實驗。

!ngc registry model list nvidia/tao/pretrained_semantic_segmentation:*

設定資料、規格檔案(TAO 規格)和實驗目錄:

%set_env KEY=tlt_encode
%set_env GPU_INDEX=0
%set_env USER_EXPERIMENT_DIR=/workspace/experiments
%set_env DATA_DOWNLOAD_DIR=/workspace/freespace_data
%set_env SPECS_DIR=/workspace/specs

下一步是挑選模型。

挑選適合的預先訓練模型

預先訓練 AI 和深度學習模型是已在代表性資料集上進行訓練,並透過權重和偏差進行微調的模型。相較於從零開始訓練,您可以透過僅使用一小部分資料的套用轉移學習,輕鬆快速地微調預先訓練模型。

在預先訓練模型的領域中,部分模型將執行特定任務,例如偵測人、汽車、車牌等。

首先,我們選擇具有 ResNet10 和 ResNet18 骨幹的 U-Net 模型。從模型獲得的結果顯示在真實世界資料中,牆壁和地板是合併為單一實體,而不是兩個單獨的實體。即使模型呈現出高準確度的模擬影像效能,情況也是如此。

BackBone 已修剪 資料集大小 影像大小 訓練評估
    訓練 Val   F1 分數 mIoU (%) 期數
RN10 NO 25K 4.5K 512×512 89.2 80.1 50
RN18 NO 25K 4.5K 512×512 91.1 83.0 50
表 1:在來自 NGC 平台的不同預先訓練模型上,針對 TAO進行實驗。

我們使用不同的骨幹和影像大小進行實驗,以觀察延遲(FPS)與準確度之間的取捨。表中的所有模型都相同(UNET),僅骨幹不同。

Images of a carpeted floor with objects scattered around. The blue areas represent blocked space and the red areas are free space.
圖 3:ResNet18 模型的預測。(左)模擬影像,(右)真實世界影像。

根據結果顯然,我們需要更適合使用案例的不同模型。我們選擇 NGC 目錄中 PeopleSemSeg 模型。該模型已針對「人」類別,在五百萬個物件上進行預先訓練,資料集是由攝影機高度、人群密度和視野(FOV)組成。此模型也可以將背景和自由空間分割為兩個單獨的實體。

此模型在使用同一個資料集進行訓練後,平均 IOU 提高了超過 10%,產生的影像清楚呈現出地板與牆壁之間更理想的分割。

BackBone 已修剪 資料集大小 影像大小 訓練評估
訓練 Val F1 分數 mIoU (%) 期數
PeopleSemSegNet 25K 4.5K 512×512 98.1 96.4 50
PeopleSemSegNet 25K 4.5K 960×544 99.0 98.1 50
表 2:使用 PeopleSemSegNet 可以訓練模型進行實驗
Images shows a carpeted floor with objects scattered around.
圖 4:使用合成資料(左)和真實世界資料(右),在 peoplesemseg TAO 模型上進行轉移學習的預測結果。

圖 4 呈現在使用真實世界資料微調 PeopleSemSeg 模型之前,從機器人的觀點,識別模擬影像和真實世界影像的自由空間。意即使用純 NVIDIA Isaac Sim 資料訓練的模型。

主要的重點在於,雖然可能有許多預先訓練模型可以完成任務,但是重要的是挑選最接近目前應用程式的模型。於此情形下,可以使用TAO 的專用模型。

!tao unet train --gpus=1 --gpu_index=$GPU_INDEX \
              -e $SPECS_DIR/spec_vanilla_unet.txt \
              -r $USER_EXPERIMENT_DIR/semseg_experiment_unpruned \
              -m $USER_EXPERIMENT_DIR/peoplesemsegnet.tlt  \
              -n model_freespace \
              -k $KEY

在訓練模型後,於驗證資料上評估模型效能:

!tao unet evaluate --gpu_index=$GPU_INDEX -e$SPECS_DIR/spec_vanilla_unet.txt \
-m $USER_EXPERIMENT_DIR/semseg_experiment_unpruned/weights/model_freespace.tlt \
    -o $USER_EXPERIMENT_DIR/semseg_experiment_unpruned/ \
    -k $KEY

對於 NVIDIA Isaac Sim 資料上的模型效能和 Sim2Sim 驗證效能感到滿意之後,請修剪模型。

為了能以最小延遲執行此模型,請將模型最佳化,以便在目標 GPU 上執行。有兩種方式可以達成此目的:

  • 修剪:TAO 工具套件中的修剪功能可以自動移除不需要的層和神經元,有效縮減模型大小。必須重新訓練模型,才能恢復修剪期間損失的準確度。
  • 訓練後量化:TAO 工具套件中的另一項功能可以進一步縮減模型大小。可以將精度從 FP32 變更為 INT8,以提升效能,不會犧牲準確度。

首先,修剪模型:

!tao unet prune \
    -e $SPECS_DIR/spec_vanilla_unet.txt \
    -m $USER_EXPERIMENT_DIR/semseg_experiment_unpruned/weights/model_freespace.tlt \
    -o $USER_EXPERIMENT_DIR/unet_experiment_pruned/model_unet_pruned.tlt \
     -eq union \
     -pth 0.1 \
     -k $KEY

重新訓練和修剪模型:

!tao unet train --gpus=1 --gpu_index=$GPU_INDEX \
              -e $SPECS_DIR/spec_vanilla_unet_retrain.txt \
              -r $USER_EXPERIMENT_DIR/unet_experiment_retrain \
              -m $USER_EXPERIMENT_DIR/unet_experiment_pruned/model_unet_pruned.tlt \
              -n model_unet_retrained \
              -k $KEY

對於已修剪模型的 Sim2Sim 驗證效能感到滿意之後,請進入下一步,微調真實世界資料。

!tao unet train --gpus=1 --gpu_index=$GPU_INDEX \
              -e $SPECS_DIR/spec_vanilla_unet_domain_adpt.txt \
              -r $USER_EXPERIMENT_DIR/semseg_experiment_domain_adpt \
              -m $USER_EXPERIMENT_DIR/semseg_experiment_retrain/model_unet_pruned.tlt\
              -n model_domain_adapt \
              -k $KEY

結果

表 1 所示為未修剪模型與已修剪模型之間的結果摘要。根據在 NVIDIA Jetson Xavier NX 上測量的結果,相較於原始模型,選擇用於部署的最終修剪和量化模型縮小了 17 倍,推論效能加快了 5 倍。

模型 資料集 訓練評估   推論效能
已修剪 微調真實世界資料 訓練集 驗證集 F1 分數 (%) mIoU (%) 精度 FPS
模擬 模擬 0.990 0.981 FP16 3.9
模擬 模擬 0.991 0.982 FP16 15.29
模擬 真實 0.680 0.515 FP16 15.29
Real 真實 0.979 0.960 FP16 15.29
真實 真實 0.974 0.959 INT8 20.25
表 3:Sim2Sim 和 Sim2Real 的結果

模擬資料的訓練資料集包含 25K 張影像,用於微調的真實世界影像訓練資料僅包含 44 張影像。真實影像的驗證資料集僅包含 56 張影像。在真實世界資料方面,我們是在三種不同的室內場景中收集資料集。模型的輸入影像大小為 960×544。使用 NVIDIA TensorRT trtexec 工具測量推論效能。

Four images showing the results obtained from the model chosen for deployment. The images show clear delineation between the floor, walls, and obstacles directly in front of the robot.
圖 5:在微調真實世界資料之後,來自於機器人的真實世界影像結果

使用 NVIDIA Isaac ROS 進行部署

本節說明使用 NVIDIA Isaac ROS 將經過訓練和最佳化的模型,部署在搭載 Jetson Xavier NX 之 iRobot Create 3 機器人上的步驟。Create 3 和 NVIDIA Isaac ROS 影像分割節點都是在 ROS2 上執行。

此範例使用 /isaac_ros_image_segmentation/isaac_ros_unet GitHub 儲存庫,部署自由空間分割。

Picture of a carpeted floor with objects on it and the same picture using free space identification results.
圖 6:在 ROS2 中使用 rqt_image_viewer 產生的影像和分割遮罩。(左)在 Create 3 機器人上使用 USB 攝影機,(右)使用 isaac-ros-image-segmentation 節點。

請從 /NVIDIA-ISAAC-ROS/isaac_ros_image_segmentation GitHub 儲存庫執行下述步驟,以使用自由空間分割模型。

建立 Docker 互動式工作空間:

$isaac_ros_common/scripts/run_dev.sh your_ws

複製所有套件相依性:

建立與取得工作空間:

$cd /workspaces/isaac_ros-dev
$colcon build && . install/setup.bash

從工作機器下載經過訓練的自由空間識別(.etlt)模型:

$scp <your_machine_ip>:<etlt_model_file_path> <ros2_ws_path>

將經過加密的 TLT 模型(.etlt)和格式轉換成 TensorRT 引擎計畫。針對 INT8 模型執行以下命令:

tao converter -k tlt_encode  \
               -e  trt.fp16.freespace.engine \
               -p input_1,1x3x544x960,1x3x544x960,1x3x544x960 \
               unet_freespace.etlt

依據 Isaac ROS 影像分割的解說操作:

  • 將 TensorRT 模型引擎檔案保存在正確的目錄中。
  • 建立 config.pbtxt。
  • 更新 isaac_ros_unet 啟動檔案中的模型引擎路徑和名稱。
  • 重建與執行以下命令:
$ colcon build --packages-up-to isaac_ros_unet && . install/setup.bash
$ ros2 launch isaac_ros_unet isaac_ros_unet_triton.launch.py

總結

本文示範從在 NVIDIA Isaac Sim 中產生合成資料開始,使用 TAO 工具套件進行微調,然後使用 NVIDIA Isaac ROS 部署模型的端對端工作流程。

NVIDIA Isaac Sim 和 TAO 工具套件都是排除 AI 框架複雜性的解決方案,讓您可以在生產中建立和部署 AI 機器人應用程式,無須具備任何 AI 專業知識。