はじめに
生成AI初心者が生成AI関連技術についてお勉強した内容の整理です。
主に実践部分では watsonx.ai を使用して試していきます。
関連記事
生成AI Study - (1) 基礎知識の整理
生成AI Study - (2) LangChain入門
生成AI Study - (3) RAG入門
生成AI関連技術/用語についての整理
基盤モデル / LLM(Large Language Model)
生成AI(Generative AI)というのは、その名の通りコンテンツを"生成"することができるAI技術を指します。
生成AIが注目される以前のAI技術の利用形態としては以下のようなイメージになると思います。
用途ごとにディープラーニング等の技術を利用して大量のデータを学習させたモデルを作成し、それを使って各種タスク(チャットの応答や文書要約など)を行うという流れだったと思います。この場合プロジェクトごとに大量の学習データを準備しそれを元に学習をさせてモデルを構築しなければならないので、精度の高いモデルを作成することは非常に大変な作業であることは容易に想像がつきます。
一方で生成AIの利用形態としては以下のようなイメージになります。
昨今の生成AIは、超大量データを事前学習させた"基盤モデル"と呼ばれる汎用的なモデルを使って様々な用途でテキストや画像を生成できます。特筆すべきは、汎用的でありながら生成されるコンテンツの精度もかなり高いという点です。
これにより、個別にモデルを生成させる手間をかけることなく、出来合いの基盤モデルを使うことで様々な場面でAI技術の応用がしやすくなったということになります。
生成AIはこの基盤モデルを使って様々なコンテンツ(テキスト、画像、音声など)を生成する技術を指します。基盤モデルは"汎用的"とは言えやはり"万能"ではなく、様々な基盤モデルが世の中には登場してきており、扱うコンテンツや分野によってそれぞれ得手不得手はあります。言語処理に特化した基盤モデルはLLM(Large Language Model)と呼ばれ、自然言語を扱いたい様々な場面での応用が期待されています。
LLMは基本テキスト情報を扱うことがメインですが、最近ではマルチモーダルLLMというテキスト以外に画像や音声などを一緒に扱うことができるLLMも出てきています。
ちなみにこのLLMも日進月歩で進化しており、OpenAIをはじめGoogle、IBM、Mistral AI, Meta Platformsといったベンダーが次々と精度の高いLLMを提供しています。ちなみにIBMが提供しているGraniteというLLMはオープンソースとして提供されています。
参考: IBMニュースリリース: IBM、オープンソース、製品、エコシステムの革新により、エンタープライズAIを大規模に推進するwatsonxの次章を発表
プロンプト
生成AIを使用する場合というのは、基本的に何かコンテンツを生成させる目的で使用するので、何を生成させたいかという"指示"を与える必要があります。この"指示"のことを"プロンプト"と呼んでいます。
何かのQ&Aを行う場合は質問内容をプロンプトとして与えることになりますし、文章の要約をさせたいのであれば、対象の文章と、「これを要約してください」というような指示をプロンプトとして与えることになります。
Chat GPTやGeminiでのChatのやり取りをイメージすると分かりやすいですが、Chatに入力する文そのものがプロンプトそのものです。
プロンプト・エンジニアリング
LLMによりテキストを生成させる際には、精度の高い(求める結果に近い)内容のものを生成させるためには、プロンプトの与え方が肝になります。プロンプトとして与える情報や指示は基本的には自然言語で与えることになりますが、LLMの特性や学習データによってそれぞれクセがあります。
そのため、精度の高い結果を得るためには、前提条件を明確にする、例となるサンプルを一緒に付与する、といったプロンプトの与え方を工夫する必要があり、このプロンプトの工夫をすることをプロンプト・エンジニアリングと呼びます。
LLMは提供されているものをそのまま使うことになるので、大量の学習データを用意したり学習させたりという大がかりな作業は伴いません。比較的容易に行える、精度を高めるための手法です。
例えば、指示文と期待する生成結果の例をいくつか一緒に与えたうえで、その例にならってこういうことをしてください、というような指示の与え方が、回答精度を上げるための1つの有効な方法として知られています。これはfew-shotプロンプティングと呼ばれます。
プロンプト・チューニング
人手で行うプロンプトの与え方の工夫が "プロンプト・エンジニアリング"と呼ぶのに対し、プロンプトのカスタマイズ部分をAI技術を使って行う(?)ことを、プロンプト・チューニングと呼ぶようです。
それぞれハード・プロンプト、ソフト・プロンプトとも呼ばれるようです。
プロンプト・チューニングでは、プロンプト自体を学習可能なパラメータとして扱う、プロンプトの一部をモデルに学習させて調整する、という感じのことをするようです。簡単に試せる環境が無いためいまひとつピンと来ていませんが、それなりに学習データを準備してチューニングを行わせる必要があるようなので、なかなか一筋縄ではいかなそうな感じです。
※ここでは、プロンプト・エンジニアリング、プロンプト・チューニングの違いはこちらのIBMさんの記事を参考にしています。
参考: What is prompt-tuning?
プロンプト・エンジニアリングとプロンプト・チューニングは実際の現場でも混同して使われているケースがちょくちょくあるような気がします。この辺りの言葉の定義はまだ共通認識として広まりきっていない印象です。
ファイン・チューニング
個別のタスクに関連する学習データを準備し、それを既存のLLMに対して追加学習させることでLLM自体をチューニングして個別タスクに対する回答精度を高めようとするアプローチです。
結果に影響を与えるくらいの大量の学習データの準備やLLMに追加学習させるための専用の環境が必要になるので、それなりに体力のいる手法です。特に、ベースとするLLMの元々の学習データの規模が大きければ、そこに影響を与えるほどの追加学習をさせるには、相当な規模の学習データを準備しなければならないものと推察されます。
プロンプト・エンジニアリング、プロンプト・チューニング、ファイン・チューニングのイメージを図示するとこんな感じでしょうか。
トークン
LLMでは文字列を単語などのある塊単位で扱いますが、この単位を"トークン"と呼びます。トークンの扱われ方はLLMによってそれぞれ異なり、一度に扱えるトークン数の上限もLLMによって異なります。
トークン数の上限は、入力となる文字列、生成される文字列、両方に影響します。
それなりのサイズのコードを扱うのであれば、トークン数の上限の大きな(性能のよい)LLMを使用する必要があります。ただし、基本的にはその分使用料金もお高くなることになります。
扱うコードのサイズや生成させる情報量によっては、このトークン数の上限というのが重要な考慮点になります。
LLMの動作についての補足
基本動作
LLMの基本的な動作としては、ある文字列を入力として与えると、事前学習した膨大な学習データを元に、入力文字列の後に続くであろうトークン(≒単語)を予測して生成します。これをある一定の意味が完了するまで繰り返します。
例えば、「日本の首都は」という入力に対して、内部的には以下のような処理が行われてそれに続く文字列を生成することになります。
一般的によく利用されるChatGPTやGeminiなどのチャット形式のインターフェースでの利用イメージとはちょっとズレがあるように感じますが、ベースとなっているのは上の動作です。
チャット形式のインターフェースでは、通常、質問や指示をプロンプトとして入力することで期待する結果を生成させる、という使い方をすることが多いと思います。例えば、「LLMとはなんですか?」や「このPythonコードの意味を解説してください」といった具合です。
このような質問や指示に対して期待した通りの文字列が返されるのは、そのようなチャット形式で使われることを想定してLLMがファイン・チューニングされている、というのが主な要因の一つとして挙げられます。
最近では、SFT(Supervised Fine-Tuning)、いわゆる教師ありファインチューニング、と呼ばれる手法で構築されたモデルが広く使われています。「質問と理想的な回答」「指示と理想的な実行結果」といった高品質な「入出力ペア」のデータセットで再学習することにより、質問や指示に対してその意図に従った結果が返りやすいようチューニングされているという訳です。
※もちろんLLMによって特性は異なるため、チャット形式とは別の使い方を見据えてチューニングされたLLMもありますので、用途に応じて適切な特性を持つLLMを選択する必要があります。
プロンプトの与え方
最近のLLM(主にChat形式で利用される想定のもの)では、プロンプトとして与えられた情報を、System Prompt、User Prompt の2種類に分類して認識されるものが増えている傾向にあります。System Prompt、User Promptそれぞれの意味合いは主に以下の通りです。
- System Prompt: LLMに与える役割、制約、振る舞いに関する指示
- User Prompt: ユーザーからの具体的な質問やタスクの指示
つまり、プロンプトを与える際に、System Promptとして"あなたはPythonの専門家です"というような役割を与えた上で、User Promptとして"このコードの意味を解説してください"というような具体的な指示を与える、ということをすると期待する回答が生成しやすくなる傾向にあります。
これは、最近提供されているLLMでは教師ありファインチューニングにて、このようなSystem Prompt、User Promptを意識した学習データによってチューニングされているためです。
また、プロンプト・エンジニアリングの手法として、入力とそれに対する出力の具体例をサンプルとして一緒に与えると、出力結果の精度が上がることが知られています。プロンプト手法としてプロンプトに具体例をどれだけ含めるかによって、その手法の呼称が決められています。
Zero-shot プロンプティング
プロンプトに具体例を1つも含めずにLLMに指示を投げる方法です。
以下の文章を要約してください。
文章: 大規模言語モデル(LLM)は、膨大な量のテキストデータで事前学習された人工知能モデルです。これらのモデルは、人間の言語を理解し、生成する能力を持ち、質問応答、要約、翻訳、コンテンツ生成など、様々な自然言語処理タスクに利用されています。近年、Transformerアーキテクチャの進歩と計算リソースの増加により、LLMの性能は飛躍的に向上しました。
LLMは大量のテキストデータで事前学習されたAIモデルで、人間の言語を理解・生成し、様々なNLPタスクに活用されます。近年、Transformerアーキテクチャと計算リソースの進歩により性能が向上しました。
1-shot プロンプティング
プロンプトに具体例を1だけ含めてLLMに指示を投げる方法です。
例にならって以下の映画レビューの感情を「ポジティブ」または「ネガティブ」に分類してください。
例:
レビュー: この映画は本当にひどかった。時間の無駄。
感情: ネガティブ
レビュー: 映像が美しく、ストーリーも感動的でした。
感情:
ポジティブ
Few-shot プロンプティング
プロンプトに具体例を2つ以上含めてLLMに指示を投げる方法です。
例にならって以下の文章のキーワードを3つ抽出してください。
例1:
文章: 人工知能は、機械学習と深層学習の技術を基盤としており、医療診断や自動運転など多岐にわたる分野で応用されています。
キーワード: 人工知能, 機械学習, 医療診断
例2:
文章: 持続可能な開発目標(SDGs)は、2030年までに達成を目指す国際社会の共通目標であり、貧困の撲滅や気候変動対策など17の目標から構成されています。
キーワード: SDGs, 貧困, 気候変動
文章: 量子コンピューターは、量子力学の原理を利用して、従来のコンピューターでは解決が困難な問題を高速に処理する次世代の技術です。
キーワード:
量子コンピューター, 量子力学, 次世代技術
x-shot プロンプティング
Zero-shot, 1-shot, Few-shot の概念をまとめて x-shotプロンプティングと表現したりすることもあるようです。
※注意
これらは、1度にLLMに投げるプロンプトの中に具体例(入力と期待する出力結果のサンプル)をどれだけ含めるかによって呼称が変わるということです。いずれのケースでもLLMにリクエストを投げる回数は1回です。
Few-shotというと、LLMに対して複数回リクエストを発行する、ということだと誤解するケースがあるようですが、そうではありません。(その理屈で言うとじゃぁZero-shotって一体ナニ?ってなってしまいますしね...)
生成AIが生成する"モノ"
生成AIはそもそも大量のデータを学習させてその情報を元に、指示を解釈してその指示に沿った確からしい何かを生成するというものです。こういうプロンプトを与えるとこういうコンテンツが生成される、という確実な方法というのはありません。とあるサービスをAPIで呼び出す際にはインターフェースの仕様、すなわち、どういう作法で呼び出せばどういう結果が返るかという厳密な約束事があり、それに準拠するように動作しますが、学習ベースで"あいまいな"情報をそれらしく処理してくれる生成AIには当然のようにそのような厳密な仕様というのは存在しません。
生成されるコンテンツは事前学習されたデータを元に予測された結果なので、学習されていない情報は当然ながら加味されません。精度は上がってきているとはいえ、厳密性、確実性が担保されるものではありません。それどころか、ハルシネーション(幻覚、幻影の意)と呼ばれる、"もっともらしいが実は誤った回答"を生成する可能性があることも知られています。
そのような状況を前提として生成AIを扱う必要があります。
生成AIの向き/不向き
AIブームに乗っかってなんでもかんでも生成AIを使いましょうという風潮があるように感じます。生成AIのポテンシャルはすさまじいものがありますし、技術の進歩も目覚ましいので、いろんな場面で活用を検討するのは良いことだと思います。しかし、生成AIはあくまで道具の1つでしかないはずですが、それを使うことが目的化しているのではないかと思える場面も散見されます。
生成AIの性能やできることの範囲は広がってきていますが万能ではありませんし、向き不向きがあります。
生成AIはあくまで学習データを基準として入力に対して確率論的に正しそうな出力を生成するというものですので、全てにおいて生成AIを適用するのが最適解とは言えないはずです。
例えば、複数のExcelファイルから情報を抽出してそれらを組み合わせて加工して別のデータを作る、みたいな煩雑な処理を手作業で行っていたとします。
煩雑だったとしてもその手順は一定のルールに従って確実に実施すべきものであるのならば、それを生成AIを使って自動化するのは適切でしょうか? 大量の構造化された情報の中からピンポイントで特定のデータを抽出するというのは生成AIでは難しいですし、それらしいプロンプトを頑張って作って生成AIにデータを加工させたとしても不確実性はある程度残ります。
それよりは、仕様を明確にしてExcelのマクロやPythonスクリプト等でロジックを組み立てて実装する方が確実だよね、となることもあるのではないでしょうか。仕様が明確にできれば、ExcelマクロやPythonスクリプト自体はそれこそ生成AIで生成させれば開発コストは軽減できますし、きちんとテストした上で利用すれば確実性も担保できますね。
システム化の要件や何か解決すべき課題があったときに、どの部分で生成AIを活用できそうか、そもそも生成AIを利用することが適切かどうかはきちんと精査する必要があると考えます。
少し毛色が違う話になりますが、以前"メインフレーム"と"AI"の位置づけについて考察した記事を書いたことがありますのでよろしければそちらもどうぞ。
AI旋風の中でメインフレームとAIの位置づけを考える