これまでのML開発は「学習」部分の工夫が肝だった

蒲生弘郷氏:残り20分になりましたが、ちょっとここからは重い、GPT開発についてです。「ML開発の今まで」。「GPTはすごいしAzureの説明はわかったよ」という話になるんですが、実際にどう作ればいいのか知っていかないとなかなか厳しいところもあるので、ここの説明をしたいと思います。

ここから先はけっこう専門的な内容も入っていきつつも、基本コードは出てきません。プログラミングコードは出てこないし、なんとか理解してもらえる内容も含まれているので、ビジネスサイドの方に関しては、わかる範囲のところまでお付き合いいただければ幸いです。

ML開発って、例えば「Kaggle」がMLコンペとかで出されてきたように、今までは「このAIモデルをデータを使って学習して出てきたモデルを、先ほどもあったようなAPIとかエンドポイントみたいなところに入れてあげて、データを渡したら返ってくる」ようなかたちがベスプラとして定着しつつあった。

(スライドを示して)左の学習部分の工夫が開発の肝だったというところは、今までデータサイエンスに関わってきたみなさまであれば、おそらく頷ける(こと)かなと思います。

“学習させたかのように振る舞わせる”ためのアイデア「Prompt Processing」

ただ、先ほども文章生成の過程で出てきたように、GPTのモデル、LLMのモデルについては、単純に学習データだけじゃなくてプロンプトも参考にしながら文章を生成する性質があるので、プロンプトを工夫して、あたかも学習をさせたかのように振る舞わせることが可能になってきています。

私はこの中では「揮発的な学習」という呼び方をしましたが、プロンプトエンジニアリング(Prompt Engineering)という新しいパラダイムが生まれてきていて、プロンプト、いわゆる入力を工夫してあげることによって、チャットの振る舞いを変えられる。

だから先ほどのAzureのプレイグラウンドが用意されているんですが、いくつかそのアイデアを紹介したいと思います。中で実際の事例を見せるので、そこで理解いただければなと。

1つ目は、AIが解釈しやすく処理するためのPrompt Processing。これは、私の今回の発表の中での独自用語にはなっていますが、例えば「顧客のエンゲージメントを高める方法を教えてください」というかたちで、ちょっと雑なプロンプトを投げてみると、やはりGPTも雑な回答しか返してきません。雑というか、「何を答えていいのかがわからない」というかたちで、とりあえず雑多な情報の中から当たり障りのない情報を返してくるかたちになっています。

ただ、ここを「多国籍食品を販売するECサイトを運営していて、優良顧客へのエンゲージメント強化に関して、具体的な施策を挙げよ」「字数はこれぐらいだ」というかたちでやってあげると、明らかに具体的で、かつ形式もしっかりとした回答を返してくれます。

こういった少ない情報とかの場合、より具体的に指示を明確に書くことが重要で、こういったテクニックはユーザー側として「こういうふうに使ったほうがいいよ」というプロンプトエンジニアリングのテクニックみたいな感じで、いろいろな方がブログで紹介しています。

ただ、サービスを立てていく、アプリを立てていく場合には、ユーザーに依存して「ユーザーにがんばってもらおう」みたいなかたちは、やはりやるわけにはいかないところもあります。そこに依存せず、優良なプロンプトに仕上げていく工夫もけっこう必要になってくるかなと思います。

1つ目が追加質問。「情報が足りていなかったら聞いてください」というかたちで、あらかじめ教え込んでおくことによって、ユーザーが雑なプロンプトを送ってきた場合には追加情報をインタラクティブに得る工夫をしていくケースが1個あります。

もう1つは、Bing Chatで行われているようなテキスト補完をしてあげて、ストレスなく追加情報をもらっていくことであったり、日本語以外の言語を活用するということですね。日本語だとちょっと意味合いがわかりにくいようなところでも、GPTは基本的には英語のほうが学習データが多かったりするので、バックエンドで翻訳して投げてあげるみたいなことをやるケースもあります。

また、プログラミング言語みたいなところで指示を与えておく。バックエンドのメッセージはユーザーからは見えないので、プログラミング言語で指示を与えておくと、日本語で指示を与えていくよりかは明確に何をするのかがわかるので、そういった概念も生まれているかたちになります。

あとはプロンプトテンプレート。やはり構造化されてるデータのほうがGPTもわかりやすいので、単純に自然言語で打たせるんだけれど、入ってくる情報はフォーマットに規定してあげたものに渡して毎回同じ入力をしてあげるといったかたちで、裏側で考慮してあげる取り組みもできる。

あとは、後でちょっと近いところで出てくるんですけど、GPTが解釈しやすいような文章にユーザーのプロンプトから「修正をしてくれ」と処理をかけさせてあげて、GPT自ら修正をかけさせた上で解釈させるといったような取り組みも出てきています。

あとはチャット以外のUI。チャットボットを作ろうとなると、どうしてもチャットしかUIを入れないみたいなことってけっこうありがちなんですが、実はチャットを全部打つのってけっこう大変で。全部打たせるんじゃなくて、プルダウンとかラジオボタンとかチェックボックスとか、今まであったようなものでポチポチっと押させてあげるほうが楽なケースも必ずあるんです。

そうなってくると、やはりそういうUIの工夫をしてあげて、なるべくユーザーにストレスを与えないように(しながら)情報を多く聞き出すといったかたちで、今までのUIの活用はこれからも重要になってきます。

落合陽一さんとかがやられていた、音声認識(を活用すること)で(ユーザーには)しゃべっ(てもらっ)ちゃうみたいなUIを用意してあげるというところ。BingのiOS版とかになってくると、そういった取り組みもされていたり(します)。こういうかたちがまず1つ。

“学習させたかのように振る舞わせる”ためのアイデア「Few-shot Learning」

2つ目がFew-shot Learning、例示で精度を高めるかたちになります。先ほどのプレイグラウンドの画面でもありましたが、基本的にGPTモデルというのは「どういう振る舞いをしてあげるのか」という指示と、「ユーザーがこう答えてきたらこうやって答えましょう」と回答フォーマットを規定させて、練習してあげると良い回答を返してくれるような性質があります。

例えば「あなたは日本語会話の先生です。ユーザーと対話しつつ、ユーザーが記載した日本語の自然さに対して0から100点までの点数と、不自然な点があれば指摘を最高100文字で付与してください」「こういう回答形式でスコアリングと指摘と本文、メッセージに対する返答を書いてくださいね」といったかたちで例示をかけてあげる。

実際にGPTで試した内容になっていますが、「こんにちは。今日メッチャ楽しい日な気するだけど、あなたどう思うね?」みたいなかたちで打ってあげると、「『メッチャ楽しい日な気する』は、『とても楽しい気がする』のほうが自然じゃないですか?」という指摘を返しながら、本文に対する回答を下に書いてくれる。

こういったFew-shotは非常に大事で、先ほどのプレイグラウンドの中に設定する場面もあるので、そこを有効に使ってもらえればと思います。

“学習させたかのように振る舞わせる”ためのアイデア「Chain of Thought」

それから段階的な推論。これは非常に重要なキーワードになってきますが、Chain of Thought、思考の連鎖と言われる概念も出てきています。

GPTモデルは「ステップバイステップで考えてみましょう」と言ってあげると、正確性が増してくる性質があります。例えば(GPTは)計算問題がけっこう苦手だったりする。いわゆる中学生とかがよくやるあれですね。「20,000+15と20,000-15を工夫して計算しなさい」みたいな問題を与えて普通にやると間違えてしまう。

そこを、「段階的に記述しましょう」という記述を与えてあげることによって、正解を出せるようになる。

これは一番簡単なかたちになってきますが、ステップバイステップで考える。つまり思考過程をいくつか書いてあげることによって、自分自身が考慮する文脈を自ら生成するようになります。

人間もそうだと思うんですけれども、書いて自分の考えをまとめて出していけば出していくほど、文脈が多ければ多いほど、正解がわかるようになることはけっこうある。途中式を書いていったほうが答えは当然出しやすいと思います。それとやはり同じ性質がGPTの中にもあって、そこを利用して回答精度を高めるかたちになっています。

Chain of Thoughtを略すとCoTとなりますが、CoTを使っていくケースはいろいろなプロンプトエンジニアリングのテクニックの中に用いられています。

その1つがSelf Consistency。先ほどやったステップバイステップというところ。1つのステップを経由するだけじゃなくて、ステップをたくさん経由させて仮説1とか仮説2とか仮説3とかどんどん出していった上で回答させていくと、1つの文脈だけじゃなくて、いろいろな可能性を考慮しながら答えが出せるから、回答精度が向上したという論文が発表された例があります。

(これからする話を)厳密に言うと、論文で説明している例と(比較すると)少し単純化したものになってきます。例えば「難しい問いについて推論するチャットボットですから、仮説を3つ出してから最終回答を出してください」とシステムプロンプトに入れてあげると、「東京23区の人口を推定してみてください」「人口は1億2,000万人というところのみを使ってください」というかたちになります。

答え自体は例になるので、23区の人口は1,200万人から1,500万人。当たらずも遠からずみたいなかたちになっていますが、いくつかの仮説を考慮した上で回答ができる。

“学習させたかのように振る舞わせる”ためのアイデア「Recursively Criticizes and Improves」

それからGPT自身に出力の再帰的な修正をさせる、Recursively Criticizes and Improvesという考え方が出てきています。

先ほども出てきましたが、GPTにGPTの出力を吟味させて修正を繰り返させるというやり方をすることによって、プログラミングコードなどにおいて、コンピューターの言語生成に有効だとされています。

これはどういうものかとお話しすると、例えばコードを生成させるようなことを1回する場合には、「コードを記載してください」。「コードを記載した後は、どんな修正が必要か1回考えてみましょう。修正が必要だったらコードを記載しましょう。またさらに修正が必要だったら考えましょう」「3回考えたら最終コードを出してくださいね」というかたちでプロンプトを設定しておく。

実際にこれを試してみました。タイタニックのデータセットを使って、分類問題としてLightGBMをトレーニングしようと思います。実験管理に「MLflow」を使って、交差検証を使って、学習済みモデルはMLflowを使って保存して、欠損値補完はしないで、みたいなかたちで細かい指示を出してあげた時、普通にやってみるとけっこう間違えたりするし、エラーが出てきたりするんですが、これを実際にシステムプロンプトの中に入れてあげました。

(画面を示して)小さいので見えにくい部分があるかもしれませんが、この上で実際の回答を答えさせてみようと思います。

回答フォーマットに従って、まずコードを生成します。かなりたくさん指示を出したので、コードを生成するのにも時間がかかっています。でもレスポンスが返ってくるのが非常に速かったので、さすがgpt-3.5-turboだなと。Azureはやはり個別の環境で作っているので、なかなかレスポンスはいいかなという感じですね。

こうやってコードを書くと、吟味1では「今回は修正は必要ありません」と出てきました。

事前のシミュレートでは、吟味の中で「こことここのコードに修正が必要だ」と出してきたんですけど。この(ように)コードを出してきます。

私は実際にこのコードを試しで入れてみて「VSCode」でさせてみたんですが、1回目だとやはりエラーが出たものの、2回目以降だとエラーが修正されてきちんと通るようなかたちで返ってきました。

もちろん、この自分の吟味だけでコードを修正するだけじゃなくて、実際にエラーメッセージを吐かせて、「そのエラーメッセージを考慮してまた修正しなさい」するやり方もあります。

こういった「何回も吟味をさせていく」ところは、改善においては非常に重要です。もちろんプロンプトを消費するのでお金がかかってくる部分だとは思いますが、精度のいい回答、特に厳密なものを返していきたい場合には、けっこう有効なテクニックだと考えられます。

今、簡単に「吟味してくださいね」みたいなことを言ったんですが、プロンプトが吟味する観点っていっぱいあったりします。例えば、1回目の吟味だとこれに関して吟味して、2回目だとここに気をつけてください。3回目だとここに気をつけてくださいみたいな感じで、吟味の仕方を詳細に指示してあげたり、あるいは例示してあげたり、Few-shotで加えてあげたりみたいなやり方もするようです。

実際に(スライドの下に記載した)論文で出ていたんですが、非常におもしろかったので、ドキュメントが公開されたらぜひとも見てもらえればと思います。

ここの吟味をさらにもう1回、「ステップバイステップで考える」とか、「自分自身にまた考えさせる」みたいなプロセスを加えていくという、さらに発展版みたいなことにもどんどん取り組まれているようです。

(次回に続く)