0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

本記事はWSL2を介してGenesisのロボットアームの学習(manipulation)を試す時に発生した「Cannot find matching vulkan UUID for GPU」というエラーとその対処を紹介する記事になります。

Genesisとは、ロボットの機械学習に特化した物理シミュレータになります。

このgenesis-worldのexamplesの中にある学習をいくつか試していたのですが、ロボットアームの学習をしようとした時にエラーが出て学習ができませんでした。

結果としてはWSL2+Genesisという環境によって起こった、WSL2定番のエラーだったため、本記事では私が行った対処を共有しようと思います。

環境

項目 内容
OS(ホスト) Windows11 + WSL2(2.7.10.0)
Ubuntu 24.04 LTS
CUDAバージョン 12.6(PyTorchのcu126ビルドに対応)
Python 3.11.0
Genesis (genesis-world) v1.2.0
GPU NVIDIA GeForce RTX 3060

また、想定するディレクトリ構造については、以前書いた以下の記事の通りです。

出たエラー

まずはターミナルを開き、以下のコマンドでUbuntuと仮想環境を立ち上げます。

# Ubuntu24.04にログイン
wsl -d Ubuntu-24.04

# プロジェクト直下に移動
cd ~/projects/genesis-rl-lab 

# 仮想環境起動
source .venv/bin/activate

その後、genesis-worldのロボットアーム学習を開始してみます。

python third_party/genesis-world/examples/manipulation/grasp_train.py -e arm-grasp-v1 -B 8192 --max_iterations 301

すると学習が始まらず以下のエラーが出ました。

# (前略)

Error at /project/src/render/vk/backend.cpp:553 in
madrona::render::vk::Backend::findPhysicalDevice(...)
Cannot find matching vulkan UUID for GPU 
Aborted (core dumped)

重要なのは中2行の、「madronaパッケージ内のfindPhysicalDeviceメソッドを呼び出した際、GPUに対応するvulkanのUUIDが見つからなかった」という文言です。

エラーメッセージの意味

madronaとは

このmadronaというのは、GenesisのBatchRendererの中身です(パッケージ名gs-madrona)。
Genesisでの学習時、数千環境ぶんのカメラ画像を一括でGPUレンダリングするための専用バックエンドとなります。

Cannot find matching vulkan UUID for GPUとは

madronaは動作上、同じ1枚のGPUをCUDAとVulkanの両方から掴む必要があります。
物理計算・テンソル処理はCUDA側、描画はVulkan側でやって、その間でメモリを共有するためです。

この時、CUDA側で認識しているGPUとVulkan側で認識しているGPUが同一デバイスであることを保証するために、デバイスUUIDで突合せをします。findPhysicalDeviceメソッドがこの処理にあたります。

Cannot find matching vulkan UUID for GPUは一致するVulkanデバイスが1つも見つからなかったという意味です。つまり、CUDAで設定されているGPUが、Vulkan側で認識されていないから起こったエラーとなります。

原因の診断

nvidia-smiではGPUがちゃんと認識されていました。

$ nvidia-smi
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 610.47                 KMD Version: 610.47        CUDA UMD Version: 13.3     |
+-----------------------------------------+------------------------+----------------------+
| GPU  Name                  Driver-Model | Bus-Id          Disp.A | Volatile Uncorr. ECC |

しかし、vulkaninfo --summaryでは

  • deviceType = PHYSICAL_DEVICE_TYPE_CPU
  • deviceName = llvmpipe

となっており、ソフトウェア(CPU)レンダラとなっていました。

$ vulkaninfo --summary
# (前略)
Devices:
========
GPU0:
        ...
        deviceType         = PHYSICAL_DEVICE_TYPE_CPU
        deviceName         = llvmpipe (LLVM 20.1.2, 256 bits)
        driverID           = DRIVER_ID_MESA_LLVMPIPE
        driverName         = llvmpipe
        ...

よって、Vulkanから見えているのはCPUソフトレンダラだけという事がわかりました。

次に、ls /usr/share/vulkan/icd.d/ls /usr/lib/wsl/lib/ | grep -i nvidiaも調べた所、nvidia_icd.jsonlibGLX_nvidia.so.0も存在しないことがわかり、WSLのドライバスタックがそもそもVulkan描画ライブラリを積んでいないことがわかりました。

$ ls /usr/share/vulkan/icd.d/
asahi_icd.json         intel_hasvk_icd.json  lvp_icd.json      radeon_icd.json
gfxstream_vk_icd.json  intel_icd.json        nouveau_icd.json  virtio_icd.json

$ ls /usr/lib/wsl/lib/ | grep -i nvidia
libnvidia-encode.so
libnvidia-encode.so.1
libnvidia-gpucomp.so
libnvidia-gpucomp.so.610.43.02
libnvidia-ml.so.1
libnvidia-ngx.so.1
libnvidia-opticalflow.so
libnvidia-opticalflow.so.1
nvidia-ngx-updater
nvidia-smi

対処方法

Vulkanが対象のGPUを認識できない場合の定番の対処は、/usr/share/vulkan/icd.d/にNVIDIA用のICDマニフェスト(nvidia_icd.json)を自作し、library_pathlibGLX_nvidia.so.0を指定することだそうです。参考1 参考2

しかし、/usr/lib/wsl/lib/libGLX_nvidia.so.0が存在しなかったため、この方法が使えませんでした。

そもそもネイティブLinux用のNVIDIA Vulkan ICD(libGLX_nvidia.so.0)は/dev/nvidia*デバイスを前提としており、/dev/dxg経由でGPUにアクセスするWSL2では動作しないため、WSL2にはこのライブラリが同梱されていないようです。


今回のケースで考えられる解決策は、以下のとおりです。

  • Vulkan ICD/描画ライブラリが同梱されていた版のWindows用NVIDIAドライバに戻す
  • madrona(BatchRenderer)を使わないようスクリプト側を修正する

Genesisのスクリプトを読んでみると、今回試そうと思っていたロボットアームの強化学習(RL)は状態ベースで画像は要らない、つまりmadronaの起動が必要ないことがわかりました。
よって、今回はスクリプトから不要にmadronaを起動させないようスクリプトを小規模修正することにしました。

スクリプトの修正

grasp_env.py__init__ の冒頭付近(self.rgb_image_shapeの直後あたり、49行目の後)にフラグを追加

# カメラ(ステレオsensor)が必要かを一元判定する
# - visualize_camera: デバッグ表示
# - record_video: 動画記録
# - use_cameras: BC/評価で明示的にONにするための拡張フラグ
self.use_cameras = bool(
    env_cfg.get("use_cameras", False)
    or env_cfg.get("visualize_camera", False)
    or env_cfg.get("record_video", {})
)

② ステレオsensor生成ブロック(113〜138行)をif self.use_cameras:で囲む

if self.use_cameras:
    if _ENABLE_MADRONA and gs.backend == gs.cuda:
        CameraOptions = BatchRendererCameraOptions
        cam_kwargs = dict(use_rasterizer=True)
    else:
        CameraOptions = RasterizerCameraOptions
        cam_kwargs = {}

    self.left_cam = self.scene.add_sensor(
        CameraOptions(
            res=(self.image_width, self.image_height),
            pos=(1.25, 0.3, 0.3),
            lookat=(0.0, 0.0, 0.0),
            fov=60,
            **cam_kwargs,
        )
    )
    self.right_cam = self.scene.add_sensor(
        CameraOptions(
            res=(self.image_width, self.image_height),
            pos=(1.25, -0.3, 0.3),
            lookat=(0.0, 0.0, 0.0),
            fov=60,
            **cam_kwargs,
        )
    )

_reset_idxのキャッシュ無効化(241〜242行)もガードする

# Invalidate camera caches after state change
if self.use_cameras:
    self.left_cam._stale = True
    self.right_cam._stale = True

grasp_train.py:教師あり学習(BC)でカメラが必要なので、そこだけ明示ON(1行)
BC(--stage=bc)はステレオ画像を使うので、フラグを立てておきます。
env_cfg["num_envs"] = ... の行の近く(グラフ環境生成の直前)に:

env_cfg["use_cameras"] = args.stage == "bc"

env_cfg["visualize_camera"] = True を、ステージと--recordに応じて決める形に置き換える

env_cfg["num_envs"] = 10
env_cfg["box_fixed"] = False

# ステレオsensorはCUDA上でBatchRenderer(madrona/Vulkan)を通る。
# 画像を消費するBC評価か、ステレオ動画を記録するときだけ必要。
# 状態ベースのRL評価ではOFFにし、madronaを初期化させない(WSL2のVulkanクラッシュ回避)。
needs_stereo = (args.stage == "bc") or args.record
env_cfg["use_cameras"] = needs_stereo
env_cfg["visualize_camera"] = needs_stereo

これでスクリプトの修正は完了です。

結果

修正後、先ほどのコマンドを使ってロボットアーム学習を開始します。

python third_party/genesis-world/examples/manipulation/grasp_train.py -e arm-grasp-v1 -B 8192 --max_iterations 301

しばらくすると学習が完了します。


学習が完了したら、以下のコマンドで評価シミュレータを開始してみましょう。

python third_party/genesis-world/examples/manipulation/grasp_eval.py -e arm-grasp-v1 --stage rl

しばらくすると、ロボットアームがターゲットの赤い箱にアームを伸ばすことが確認できます。

ロボットアーム.jpg

残った課題

今回はロボットアームの強化学習のみを行う予定だったので、強化学習(RL)時にmadronaを通らせない方法を選びました。

もし、強化学習で生成したモデルを元にした教師あり学習(BC)までやるにはVulkanのGPU認識問題を解決する必要があります。WSL2でVulkanにGPUを認識させる方法として以下の記事が参考になります。

ただし、それでmadrona(BatchRenderer)が要求するVulkan拡張まで揃うかは別途検証が必要です。

まとめ

本記事ではWSL2でGenesisのロボットアームの学習(manipulation)を試す時に発生したVulkanがGPUを認識しない問題と、Genesisのスクリプトを修正することで強化学習のみ実行する手順を紹介しました。

サンプルスクリプトを動かす段階で、カメラ画像を使用するにあたってのエラーを知ることができたのは幸運だったかもしれません。またGenesisを使ったPythonスクリプトを読むいい機会になりました。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?