タグアーカイブ rosservise

著者:yamamoto.yosuke

ChatGPT と ROS – 文書生成 ROS ラッパー利用編(Completion API)

本シリーズ前回の記事 ChatGPT と ROS – 調査編 では ChatGPT の ROS を介した利用について少し調べてみたことをお伝えしました.

今回は OpenAI API の ROS ラッパーの中で Completion API を利用している ROS1 の Python ラッパ https://github.com/davesarmoury/openai_ros を使ってみた様子を紹介します.

実行環境

今回は次の環境で OpenAI API の ROS を介した実行を行っています.

  • Ubuntu 20.04
  • ROS Noetic
  • OpenAI API の利用が有効なアカウントを持っている
    • API Key を取得済

OpenAI API は新規登録後 3ヶ月 の期限がありますが 5ドル分 の無料クレジットが付与されるのでお試し利用することができます.(2023年8月中旬時点)

API Key の取得は OpenAI API の Web ページでログインした状態で下記リンク先の API keys のページから取得します.

インストールとビルド

実行環境の準備が整いましたらインストールとビルドを行います.

ROS のインストール

ROS は既にインストールされているようでしたら改めてインストールする必要はありません.

加えて下記の catkin ツール関係もインストールしておきます.

$ sudo apt install python3-osrf-pycommon python3-catkin-tools

OpenAI Python ライブラリのインストール

OpenAI の Python ライブラリが必要ですので pip からインストールします.

$ sudo apt install python3-pip
$ pip install --upgrade openai

ワークスペースの作成とビルド

今回は openai_ws という名前のワークスペースを作成してソースコードのクローンとビルドを行っています.

$ mkdir -p ~/openai_ws/src
$ cd ~/openai_ws/src/
$ git clone https://github.com/davesarmoury/openai_ros.git
$ cd ~/openai_ws/
$ rosdep install -y -r --from-paths src --ignore-src
$ catkin build
$ source ~/openai_ws/devel/setup.bash

openai_ros の実行

ワークスペースでビルドした openai_ros の ROS プロセスを実行します.

まず1つ目のターミナルで API Key を環境変数 OPENAI_API_KEY として export で設定しておきます.$ export OPENAI_API_KEY="sk-..."sk-... の部分は各自の OpenAI API アカウントで作成した API Key の内容に置き換えてください.

OpenAI の Completion API を利用するための ROS サービスサーバを実行するために openai.launch を起動します.

ターミナル 1

$ source ~/openai_ws/devel/setup.bash
$ export OPENAI_API_KEY="sk-..."
$ roslaunch openai_ros openai.launch max_tokens:=256

2つ目のターミナルから1つ目のターミナルで実行している OpenAI Completion API の ROS サービスにプロンプトを “Write a poem about OpenAI” としてサービスコールを行います.

ターミナル 2

$ source ~/openai_ws/devel/setup.bash
$ rosservice call /get_response '{prompt: "Write a poem about OpenAI"}'
finish_reason: "stop"
text: "\n\nOpenAI, a force of nature,\nA tool of the future,\nA way to explore the unknown,\n\
  A way to make the world better.\n\nA way to make machines smarter,\nA way to make\
  \ them think,\nA way to make them learn,\nA way to make them act.\n\nA way to make\
  \ them understand,\nA way to make them act,\nA way to make them do,\nA way to make\
  \ them react.\n\nOpenAI, a force of nature,\nA tool of the future,\nA way to explore\
  \ the unknown,\nA way to make the world better."
model: "text-davinci-003"
completion_tokens: 134
prompt_tokens: 6
total_tokens: 140

Completion API から ROS サービス経由で応答が帰ってきました.text: に応答内容があります.

text 部分の改行コードなどを除くと次のようになっています.

OpenAI, a force of nature,
A tool of the future,
A way to explore the unknown,
A way to make the world better.

A way to make machines smarter,
A way to make them think,
A way to make them learn,
A way to make them act.

A way to make them understand,
A way to make them act,
A way to make them do,
A way to make them react.

OpenAI, a force of nature,
A tool of the future,
A way to explore the unknown,
A way to make the world better.

…だそうです.

プロンプトを日本語で例えば '{prompt: "OpenAI についての40字以 内のポエムを書いてください"}' 記述しても応答はありますが rosservice のコールの応答をそのままコンソール出力した状態ですと text: 内は文字コード化されていて可読性がありませんでした.

注)コマンド全文は枠内を横スクロールして表示してください.

$ rosservice call /get_response '{prompt: "OpenAI についての40字以 内のポエムを書いてください"}'
finish_reason: "stop"
text: "\n\nOpenAI\u306F\u3001\u4EBA\u985E\u306E\u672A\u6765\u3092\u5B88\u308B\u305F\u3081\
  \u306B\u3001AI\u3092\u4F7F\u3063\u3066\u6280\u8853\u3092\u767A\u5C55\u3055\u305B\
  \u308B\u3002\u79C1\u305F\u3061\u306F\u3001AI\u3092\u4F7F\u3063\u3066\u3001\u3088\
  \u308A\u826F\u3044\u672A\u6765\u3092\u5275\u9020\u3057\u3088\u3046\u3002"
model: "text-davinci-003"
completion_tokens: 81
prompt_tokens: 31
total_tokens: 112
$

文字コード表示 解決法1 – ascii2uni を使う

文字コード表示を文字コード変換の ascii2uni で解決してみます.ascii2uni を使うため uni2ascii をインストールします.

$ sudo apt install uni2ascii

ターミナル 2

ROS サービスコールの結果に対して | ascii2uni -a U -q をパイプしてコード変換を行います.

注)コマンド全文は枠内を横スクロールして表示してください.

$ rosservice call /get_response '{prompt: "OpenAI についての40字以 内のポエムを書いてください"}' | ascii2uni -a U -q
finish_reason: "stop"
text: "\n\nOpenAIは,人類の未来を守るため\
  に𰀚Iを使って技術を発展させ\
  る.私たちは𰀚Iを使って,よ\
  り良い未来を創造しよう."
model: "text-davinci-003"
completion_tokens: 81
prompt_tokens: 31
total_tokens: 112
$ 

一部文字化けしてしまっているようです.おそらく \u3001(=読点「,」) + AI\u3001A + I と判断して違う文字を表示しようとしているようです.「文字コードの”読点”」+「平文英数字」の組み合わせ以外は大体 ascii2uni で表示できそうです.

文字コード表示 解決法2 – Python を使う

文字コード化されたものは Python の print() 内で解決されて可読性のある日本語の状態で出力されますので,今回の openai_ros の ROS サービスを Python からコールするプログラム openni_get_completion.py を書きました.

openni_get_completion.py

#!/usr/bin/env python3

import sys
import rospy

from openai_ros.srv import Completion, CompletionResponse


def get_response_client(prompt):
  request = '{prompt: ' + str(prompt) +'}'
  rospy.wait_for_service('get_response')
  try:
    get_response = rospy.ServiceProxy('get_response', Completion)
    response = get_response(request, 0)
    return response
  except rospy.ServiceException as e:
    print ("Service call failed: %s"%e)


if __name__ == "__main__":
  if len(sys.argv) == 2:
    prompt = str(sys.argv[1])
  else:
    prompt = "Write a poem about OpenAI"
  
  print("Prompt: %s\n" % (prompt))
  
  response = get_response_client(prompt)
  
  print("Response: \n%s\n" % (response))
  print("Text: %s\n" % (response.text))

先程の ターミナル1 で openai.launch を実行している状態で ターミナル2 から openni_get_completion.py を実行します.

ターミナル 2

$ source ~/openai_ws/devel/setup.bash
$ rosrun openai_ros openai_get_completion.py 
Prompt: Write a poem about OpenAI

Response: 
finish_reason: "stop"
text: "\n\nOpenAI, a force of nature,\nA powerful tool of creation,\nAble to learn and adapt,\n\
  Able to think and create.\n\nA tool of the future,\nA tool of the present,\nA tool\
  \ of the past,\nA tool of the ages.\n\nA tool of the people,\nA tool of the world,\n\
  A tool of the universe,\nA tool of the gods.\n\nOpenAI, a force of nature,\nA powerful\
  \ tool of creation,\nAble to learn and adapt,\nAble to think and create."
model: "text-davinci-003"
completion_tokens: 124
prompt_tokens: 11
total_tokens: 135

Text: 

OpenAI, a force of nature,
A powerful tool of creation,
Able to learn and adapt,
Able to think and create.

A tool of the future,
A tool of the present,
A tool of the past,
A tool of the ages.

A tool of the people,
A tool of the world,
A tool of the universe,
A tool of the gods.

OpenAI, a force of nature,
A powerful tool of creation,
Able to learn and adapt,
Able to think and create.

$ 

実行時にプロンプトの引数を渡していないのでプログラム内に書かれてるデフォルトのプロンプト “Write a poem about OpenAI” に対する英語のポエムが返ってきています.英語でも Python の print() で出力すると改行コードが見えなくなるので読みやすくなっています.

次は引数として日本語のプロンプト “OpenAI についての40字以内のポエムを書いてください.” を渡して openni_get_completion.py を実行します.

ターミナル 2

$ rosrun openai_ros openai_get_completion.py "OpenAI についての40字以内のポエムを書いてください."
Prompt: OpenAI についての40字以内のポエムを書いてください.

Response: 
finish_reason: "stop"
text: "\n\nOpenAI\u306F\u672A\u6765\u3092\u7167\u3089\u3059\u5149\u3001\u672A\u6765\u3092\
  \u5207\u308A\u958B\u304F\u92ED\u3044\u5203\u3002\u79C1\u305F\u3061\u306E\u672A\u6765\
  \u3092\u8C4A\u304B\u306B\u3057\u3066\u304F\u308C\u308B\u3002"
model: "text-davinci-003"
completion_tokens: 58
prompt_tokens: 39
total_tokens: 97

Text: 

OpenAIは未来を照らす光,未来を切り開く鋭い刃.私たちの未来を豊かにしてくれる.

$ 

日本語でも可読性のある整形された状態で読めました.そうなんですね…

ポエムはさておき,openai_ros パッケージを利用して OpenAI の Completion API を ROS から英語と日本語のどちらでも利用することができました.

今回の記事はここまでです.


本シリーズ次回の記事は OpenAI の Chat Completion API を ROS から利用する Python プログラムを OpenAI の ChatGPT に教えてもらいながら作成した様子を紹介する予定です.