はじめに
こんにちは、株式会社Preferred Roboticsで「カチャカ」というロボットを開発しています、ソフトウェアエンジニアの渡辺貴史です。学生時代は東大のRoboTechでNHKロボコンをやっていました(四足歩行の代で、私はMDを焼いたり謎のオブジェクトを投げたりしていました)。修士の稲見研を経て、今年からは社会に出て家庭用ロボットを愛でています。
さて、基盤モデル×Robotics Advent Calendar 2023
12月14日の担当ということで、私が愛してやまない弊社製品「カチャカ」が来春リリースを予定(予定)しているLLM連携機能について、その概要と少し技術トークを書こうと思います。
ゴリゴリの研究系というよりは、商用製品でもうこんなことがやられているんだ!というのをご紹介する記事です。
公にイキっておくことで、開発速度が高まることに期待をしています。
カチャカ
私のTwitterのTLでは既に全員が持っているのですが(?)、一応知らない人もいると思うのでご紹介します。
2023年5月に発売した「カチャカ」という家庭用ロボットは、家屋の間取りを把握し、地図中の場所から場所へ、専用の家具ユニットを運んでくれるロボットです。
ファミレスでよく見る猫チャンに似ていますが、家具(棚)と一体化したり分離したりできるので、1台で複数を家具を扱うことができるのが特徴です。価格やサイズなど様々な観点で家庭用にチューンされていることも大きな特徴のひとつです。
配膳・下げ膳が一番想像しやすいですが、机の上の物をぜんぶカチャカに奪ってもらうというお片付け戦略が意外と良かったりします。
ユースケースを狭めずに広く効用を言えば、「これまで動かなかったものが、自動で動くようになる」といえます。私はもう絶対にゴミ箱まで歩いていったりしないし、食器を片付けるのに何度も往復とか絶対しません。
浮いた時間はコーディングか筋トレをしています。
カチャカオタク
(実はこれ、製品の宣伝ではなく、オタクの趣味のお裾分けなんです…!)
一応社名を帯びた記事なので、真面目に宣伝チックな導入をさせていただきましたが、一介のオタクとしてはやはり「えっっこのロボットいくらでも好きに弄り倒していいの???こんなに出来がいいのに??!!本当に??」という毎日の喜び、この幸福を、皆さんにぜひお伝えしたいのであります。
ChatGPTのAPIが公開された今年の3月、大喜びでカチャカと繋ぎんで遊びました。今年の3月にもう製品レベルのロボットでLLM連携して遊べてたって、控えめに言って幸せすぎませんか?
LiDARも前後カメラもToFもついていて、SLAMできて、スマホでデバッグできて、、
しかも生活の役にまで立ってしまう。そんなことがあろうかという話です。
私は開発者なので内部コードを弄れるズル人間なのですが、なんと今年の8月からAPI機能を公開しており、PythonやROS2でのバインディングもご用意しています。つまり、どなたでも弄り倒すことが可能になっているんです。幸せのお裾分けです。みなさんもぜひ、Open InterpreterでKachaka APIを叩き、ご家庭のGPUを熱々にフル回転させ、ご自身で学習した基盤モデルに足を生やしてください。以上、布教活動でした。
LLM連携
これまでカチャカの強みのひとつとして語られていたのは、PFNの持つNNモデル最適化や推論高速化の技術に支えられたエッジでの推論です。限られた計算資源の中で音声認識や物体検出、床領域のセグメンテーションなどタスクに特化した様々な小さいモデルを巧みに操り、ナビゲーションをはじめとするリアルタイムな諸機能で高い性能を発揮しています。一方、何をどこへ運ぶのかという上位意思決定の部分は人間による具体的な「〇〇を□□に持っていって」という指示に委ねられており、知能のアナロジーの意味では、大脳は持たないが優れた小脳を持つロボット、というのが、現状のカチャカです。
これに対して、ChatGPTをはじめとするLLM(大規模言語モデル)の登場により可能になるのが、大脳の存在、つまり状況判断や言語理解、またそこからの行動生成の知能です。より具体的には例えば、人間が自由に、自然に話しかけると、それに応じて気を利かせて物を運ぶ、といったことが可能になります。(下の動画は10月のCEATECで公開した、自由な音声入力に応じて行動するデモです)
人間は宣言的に、期待する状況を言うだけで、(ロボットが可能な範囲で)それが実現される。インタラクティブにアクセスできる執事として、家庭の中を動き回れるようになるわけです。これが持つ意味は大きく、家庭用ロボットとしてのコミュニケーション能力や利便性の向上だけではなく、「自動で物を動かす」という技工的な(技術を必要とするはずの)概念が自然言語を操るすべての人のもとに提供されることを意味します。
これはオフィスでの私が自然言語で指示をする様子ですが、条件分岐や繰り返しといった本来プログラミングを要するようなタスクでかつ物理的に物が動く、ということが、いとも簡単に実現されています。すべての人にロボットを、というのが私の夢ですが、それに大きく一歩近づくのを感じています。
カチャカのLLM連携の面白い(難しい)ところ
LLMがだいぶんコモディティ化してきて、RAGによる知識の検索や、画像や図面などの自動生成などのサービスが多数ローンチされている昨今ですが、家庭用ロボットをいわばドラえもん化しようというこの取り組みはLLMアプリケーションとしては一風変わっていて、大変面白いテーマです。
というのも、「気が利く」という個人の趣向に依存する問題の解を導くということ、そして逆に動作生成の自由度はさほど高くないこと(ロボットアームのピッキングタスク等も流行りですが、カチャカはそのあたりは作り込んだ小脳に閉じています)から、論文が毎日出てくる流行りのアーキテクチャとはやや毛色が異なり、またベンチマークも難しいので、頭を悩ませつつ開発を進めています。(この辺もいつか公開できるといいなと思っています)
また、インテグの部分でも時間や課金、セキュリティなど様々な観点で制約を考慮しつつ進める必要があり、家庭で動く製品ロボットとしての難しさを感じています。次項では、そのインテグ周りの話を少しご紹介します。
Lua
LLMには最終的に、行動をプログラムとして生成させています。
先述の通り、カチャカにはPythonから利用できるAPI機能がありますが、LLM連携機能ではこのAPI機能は利用せず、内部にLuaの言語処理系を組み込んでいます。(後述の理由もありますが、これは単にAPIとしてブリッジする際の無駄なオーバーヘッドはないほうがよいからです)
ところで、私は生まれて間もないころからLuaを書いているので大した違和感はないのですが、
LLM連携機能搭載のお披露目をしたCEATEC(展示会)のあと、数多くのメディアに取材・記事掲載をいただいた中で、日経クロステックさんの記事の題が「プリファードの家庭向けロボ、大規模言語モデル経由で操作 生成コードはLuaを採用」とLuaに注目するものになっていました。
確かに、生成コード=Pythonみたいな流行りの中であえて外している感があるので、ちょっと気になるところかもしれません。
なんでLua?
以下のような利点から、Luaを選びました。もしかしたらもっと良い選択肢があったかもしれないですが、私は思いつきませんでした。いい案があったら後学のために教えて下さい。
- インジェクションされたときの被害が小さいこと
- Fine Tuningをそんなに頑張らなくてもLLMがまともに書けること
- ストリーミング実行がしやすいこと
1つめのインジェクションの話は意外と大事です。まずファイル操作をはじめとするOSの諸機能には触らせないようにしないと、色々な悪さができてしまいます。外部ライブラリのimportなども困りの種で、Pythonでこのあたりをうまく制限した処理系をC++から呼び出して使う、というのは中々に骨の折れる作業です。Luaでは、ビルトイン関数としてカチャカのAPI(例えば家具を運ぶのはmove_shelf("S01", "L01")
)を叩けるようにし、かつ標準ライブラリはstringとtableだけに絞ると、やりたいことに対して必要十分な言語が完成します。家庭用のロボットなので、この堅さはとても嬉しいです。
2つ目のLLMが上手にプログラムを書けること、というポイントは、まずLuaがそれなりにユーザーが多く、公開された文書も多いことが大きいです。加えて、上述の通りすべてのAPIをビルトインの関数のように与えてimportのシステムを省くことで、LLMに求められるコーディング力を格段に下げることができます。PythonのカチャカAPIを読ませてFine Tuningなしでコード生成をさせると、やはり鈍臭さがかなり目立ちました。ゼロショットでライブラリを扱わせるのはLLMのコード生成においてまだ課題があるようです。一方で、-- 家具S01をL01に運ぶ
というコメント行に続けてmove_shelf("S01", "L01")
と続けることはLLMにとって非常に容易で、生成を誤ることは基本的にありません。
3つ目に、ストリーミング実行がしたいという需要があります。待ち時間を短くするためには、出てきたそばから実行可能コード片があればすぐに実行したいわけです。この観点で、インデント言語は(不可能ではありませんが)やや扱いづらいものになっています。Luaは制御構文が必ずendで閉じられるので、「あるコード片Sが実行可能化どうか」は「SをダミーのStubで実行して、Syntax Errorにならないか」と一致してくれるので、とても性質がよいです。
いくつかの理由でLuaを選定しましたが、いかがでしょうか。そんなに深い話でもないですが、今後ロボット体内で同様のことをされる人の参考になれば幸いです。
ちなみにLuaは記法に少しクセがあるので、人間が書くとすぐに間違えます。(example selectorに入れるコードを自分で書いていてよく嘘を書いてしまう。)AIに書いてもらうのがおすすめです。
Json Stream Parser
Luaの項でも触れましたが、ストリーミングで実行するというのはUXの観点でいま現在においては重要な工夫になっています。
この実装でさし当たった面白い問題として、「JSONをストリームで受け取ってパースしないといけない」というのがありました。
Function CallingあるいはJSON Modeでの出力をストリーミングで受け取って、必要な情報が出揃い次第それを反映し、特に生成コードの部分はJSONとしてはパースが途中だけど言語処理系には投げる、という奇妙なことをすることになります。
ここで必要なのが、Json Stream Parserです。
ググっても意外と出てこなくて、この需要を満たすものに中々出会えなかったので自分で実装しました。
JSONの記法自体はそこまで複雑ではないので、ストリーム中の状態は割と簡単な状態遷移図で書くことができます。ならば実装は容易だろうと思っていたのですが、これが意外と大変でした。
JSONの文字列のクォーテーションは一重引用符(')と二重引用符(")との間でブレがあったり、非ascii文字をメタにutf-8エンコードして送ってきたりするので、LLMの気まぐれJSONに対応しつつパースしなければいけません。なんとも大変泥臭い作業でしたが、LLMならではのインテグ上の問題として面白いな、と思いました。
いまクローズドで書いちゃってますが、切り出してそのうちGitHubで公開しようと思います。
おわりに
家庭用ロボットカチャカの紹介と、来春リリース予定のLLM連携機能について、概要と少しマニアックな工夫の小咄をさせていただきました。
LLMをはじめとする基盤モデルの応用は、今後間違いなく加速していきます。私はその波を乗りこなしつつ、家庭用ロボットというフィールドをもっともっと盛り上げていきたいと思っています。
そのファーストペンギンとして、また誰かのアイディアのプラットフォームとして、色々な形でカチャカが活躍できるよう、日々開発に取り組んで参ります。もし興味を持っていただけたら、ぜひカチャカをご自宅にお迎えいただければと思います。
メリークリスマス。そして良いお年を。
おわり