はじめに
始まりは、「え!、LLM知らないの?」でした。
LLMは、Large Language Modelsの略で、日本語では「大規模言語モデル」というらしい。
なるほど話題になったChatGPTなどはLLMを使っているということで、意味は理解できました。
LLMを使ったロボットを制御する試みもあると聞いて、興味が湧きました。
マニピュレータを扱うことが多いことから、LLMとマニピュレータについて調べることにしました。
調査する中でLLMとロボットを使ったものがリスト化されていました。
この中で、マニピュレータ関連は以下のリストになります。
https://github.com/GT-RIPL/Awesome-LLM-Robotics?tab=readme-ov-file#manipulation
マニピュレータを使ったLLM関連もかなりありますね。
この中で「VoxPoser」のページにインパクトがあったことと、すごくわかりやすそうだったので、これを調べることにしました。
VoxPoserについて
「Composable 3D Value Maps for Robotic Manipulation with Langage Models」とあります。
マニピュレーション用の手先軌道を作るのが主な機能のようです。
概念を示しているのが、VoxPoserページにある以下の図です。
利用者が
「Open the top drawer. Please also watch out for tha vase!」
と入力すると、マニピュレータが花瓶を避けて一番上の引き出しを開けます。
具体的には、以下の動画にあるように動きます。
https://voxposer.github.io/media/videos/teaser.mp4
疑問?
ここで疑問がわきました。
どうやってLLMがVoxPoserが作ったライブラリのコードを生成・実行しているのか?
LLMについての知識が浅いのかもしれませんが、
ものすご~く知りたくなりました。
具体的には、VoxPoserの内部でChatGPTのAPIを使って処理しています。
どのように「Open the top drawer. Please also watch out for tha vase!」からVoxPoserで定義しているpythonコードに変換しているのかについて、ソースコードを調べました。
調査結果
調査で四苦八苦した部分は省略します…。
VoxPoserでは、ChatGPTに質問だけをPromptとして入力するのではなく、
以下のような構成でPromptとして入力していました。
・お願い事項
・回答例
・質問
上記の構成でChatGPTのPromptとして入力すると、回答例を参考にして返事を返してくれます。
回答例にVoxPoserで定義しているコードを記述しているので、その内容に合わせた内容を返してくれます。
VoxPoserでは、ChatGPTのAPIを再帰的に3段階コールして、マニピュレータの制御や物体認識のAPIに変換していました。ChatGPTからの回答の一部を再度ChatGPTにお願いする場合を2段階としています。3段階とは、2段階目の回答から再度ChatGPTにお願いしていることを指します。
感覚的にはわかったのですが、実際に試してみたくなりました。
そこで、調査内容が合っているかを実際のChatGPTで試してみました。
試した内容
以下、確認した内容です。
回答例のコードは、私が適当に考えた架空のものです。
下記の例では日本語にしていますが、本当は英語の方が良いですね。
また、回答例は多い方が良いと思いますが、簡単に確認したいので少な目にしました。
[お願い事項]
あなたは、ロボットアームを制御する経験豊富なpythonプログラマーです。
ロボットアームを制御するためのpythonコードの作成を手伝ってもらいたいです。
Queryの例を提示するので、これを参考にpythonコードを作成してください。
私の質問は、繰り返さないでください。
import文は含めず、外部関数も呼び出せるものとしてください。
また、テキストによる説明も不要です。
[回答例]
# Query: 「ドア」をゆっくりなスピードで開けてください。
pos1 = get_pose(「ドア」手前15cm)
pos2 = get_pose(「ドア」)
speed = set_speed(0.5x)
move(pos1) # アームを「ドア」手前移動
open_gripper(True) # グリッパを開く
move(pos2) # アームを「ドア」に移動
open_gripper(False) # ドアを握る
move(pos1) # アームを「ドア」手前に移動
# done
# Query: 「マグカップ」に気を付けながら、「青いブロック」を「黄色のブロック」の上においてください。
pos1 = get_pose(「マグカップ」, around=10cm)
pos2 = get_pose(「青いブロック」手前15cm)
pos3 = get_pose(「青いブロック」)
pos4 = get_pose(「黄色ブロック」の上)
speed = set_speed(1.0x)
move(pos1) # アームを「マグカップ」の周辺に移動
move(pos2) # アームを「青いブロック」手前15cmに移動
open_gripper(True) # グリッパを開く
move(pos3) # アームを「青いブロック」に移動
open_gripper(False) # 「青いブロック」を持つ
move(pos4) # アームを「黄色ブロック」の上に移動
open_gripper(True) # 「黄色いブロック」に置く
# done
[質問]
# Query: 一番上の引き出しを開けてください。それと、花瓶には気を付けてください。
上記をChatGPT4.0のPromptとして入力すると
以下の回答が返ってきました。
pos1 = get_pose('花瓶', around=10cm)
pos2 = get_pose('一番上の引き出し手前15cm')
pos3 = get_pose('一番上の引き出し')
speed = set_speed(0.8x)
move(pos1) # アームを「花瓶」の周辺に移動
move(pos2) # アームを「一番上の引き出し」手前に移動
open_gripper(True) # グリッパを開く
move(pos3) # アームを「一番上の引き出し」に移動
open_gripper(False) # 引き出しを握る
move(pos2) # アームを「一番上の引き出し」手前に移動
# done
2つの回答例しか示していないですが、引き出しを開けるコードが出力されました。
すごいですね。ちょっと感動しました!
VoxPoserではpythonを使っていますので、回答のtextを解析してexec関数を使ってpythonコードを実行していました。
また、回答例の書き方も下記のように工夫しているようです。
https://github.com/huangwl18/VoxPoser/tree/main/src/prompts/rlbench
1段階目の質問パターンは、「planner_prompt.txt」で、2段階目のパターンは、「composer_prompt.txt」です。その他は、3段階目になります。
まとめ
ChatGPTで簡単な質問を繰り返していくパターンはよく使っているのですが、今回のような使い方もあるとは「目から鱗」でした。制御する対象やロボットの動作を上手くグルーピングして回答例を作ればVoxPoserのようにロボットも制御できることがわかりました。
LLMにフォーカスして調査しましたが、VoxPoserの考え方もすごいですね。アームの手先軌道のみを扱うので、ロボットはなんでもよいことになります。こちらも「目から鱗」でした。