LLMによる電子メールの分類
2024年12月16日 月曜日
CONTENTS
【IIJ 2024 TECHアドベントカレンダー 12/16の記事です】
このブログ・シリーズの2回目の記事では、コンテンツの生成と微調整について探りました。GPT-2を使い、精度を高めるためのモデルの微調整(fine-tuning)の役割とともに、おとぎ話を生成する方法を示しました。
LLMシリーズの最終回となる今回は、プロンプト・エンジニアリング(単にプロンプティングと呼ばれることも多い)に焦点を当て、LLMの出力の制御において、その重要性を説明します。このアプローチを理解することは、モデルの微調整を行わずに、特定のユースケースのためにLLMを利用するような時に重要です。説明のために、LLMによるテキスト分類を、職場等で利用されそうな簡単な例を通して紹介します。
なぜプロンプティングが重要なのか?
LLMは本質的に確率論的であり、同じ入力に対して異なる出力を生成します。
プロンプティングは、LLMに明確で構造化された指示を与えることで、LLMの出力を制御することができます。このアプローチは、モデルが同じ入力に対して一貫した出力を生成するのに役立ちます。
これは、テキストの分類のような、一貫性が不可欠で、与えられた入力に対して常に同じ分類結果が返されることを保証するような特定のタスクを実行するようLLMに指示することを可能にする上で、重要です。この一貫性を達成するために、プロンプトには明確でわかりやすい指示を含める必要があります。
プロンプトは、リソースの制約により微調整が不可能な場合に非常に便利です。プロンプトを注意深く作成することで、モデルの応答範囲を制限し、特定の目的に向かって誘導することができます。さらに、プロンプトはLLMとのインタラクションをよりコントロールしやすくし、カスタマイズを可能にし、無関係な応答を減らすことができます。
LLMにテキスト分類を促すには?
LLMは、適切なプロンプトが与えられれば、特定のタスクを上手くこなすことができます。ここでは、テキスト分類のための簡単なプロンプトを設定する方法を説明します。Llama 3 8Bを使って電子メール分類器を作成する例で説明します。私たちの目的は、ある企業のカスタマーサポートチームのためのツールを作成することです。
メールを次の3つのカテゴリに分類するようLlama 3 8Bに設定します:
- スパム:カスタマーサポートや会社の製品・サービスに関係のないメール
- テクニカルサポート:顧客からの技術的な問題に関するメール
- 新規顧客:製品やサービスに関する潜在顧客からのメール
このシステムを使用することで、カスタマーサポートチームはメールをより効率的に管理し、顧客からの問い合わせを適切な場所に届くようにすることができます。
このシステムを作るのは難しいでしょうか?実は、それほど難しくはありません。明確な指示とともにプロンプトを作成するだけです。最初の記事では、llama.cppライブラリを使ってコンピュータ上で LLM を実行する方法を紹介しました。ここでは、再びllama.cppを使いますが、今回は、こちらのPythonバージョンを利用します。
まず、llama.cppライブラリをpipを使ってインストールします:
pip install llama-cpp-python
ライブラリをインストールしたら、まずHugging Faceから Llama 3 8Bをダウンロードします。Llama 3はMeta社の最新大規模言語モデルのひとつで、80億パラメータと700億パラメータの2つのバージョンがあります。今回のユースケースでは、軽量で、ほとんどのコンピュータで動作する80億パラメータ・バージョンを使用します。
wget https://huggingface.co/SanctumAI/Meta-Llama-3-8B-Instruct-GGUF/resolve/main/meta-llama-3-8b-instruct.Q5_K_M.gguf
モデルをダウンロードしたら、Pythonのllama.cppを使って初期化します。GPU上で動作するように、n_gpu_layers
パラメータを-1
に設定します。
from llama_cpp import Llama llm = Llama( model_path="meta-llama-3-8b-instruct.Q5_K_M.gguf", n_gpu_layers=-1 )
次に、プロンプト・テンプレートの設定に進みます。ここで少し立ち止まって、プロンプト・テンプレートとは何かを説明します。プロンプト・テンプレートとは、その名のとおり、LLMに入力するプロンプトのテンプレートです。各LLMには固有のプロンプト・テンプレートがあります。このテンプレートはLLMの開発者によって定義され、モデルに対しての、システムの指示やタスクと、ユーザの入力を区別するための指示として機能します。
システムの指示とタスクのセクションでは、LLMに実行させたいタスクとそれに対応する指示を定義します。ユーザの入力セクションでは、実行したいタスクの入力を定義します。プロンプト・テンプレートは、LLMの開発者が指定した部分以外は編集しないことが重要です。
prompt_template = """ <|begin_of_text|><|start_header_id|>system<|end_header_id|> {system_prompt}<|eot_id|><|start_header_id|>user<|end_header_id|> {user_message}<|eot_id|><|start_header_id|>assistant<|end_header_id|> """
プロンプト・テンプレートを定義した後、システムの指示とタスクのセクションの記述を続けます。メール分類器のタスクと指示を以下のように定義します。
system_prompt = """ Task: Categorize the text into the following categories: 1. Spam 2. Technical Support 3. New Customer Instructions: You are an assistant in the customer support team of a networking company. Your company deals with setting up new Internet connections and provides assistance if customers encounter problems connecting to the Internet. Note: Do not include any explanations or apologies in your responses. """
これらのシンプルな指示は、LLMに明確な文脈を与え、より適切な回答を生成するのに役立ちます。
次に、ユーザの入力セクションに進みます。このセクションでは、ユーザが入力したテキストを変更せずにそのまま記載します。次に、ユーザの入力セクションからシステムの指示とタスクをシステムのプロンプトに追加し、LLMに解析してもらいます。
user_message = """ Hello, The Internet led is red in my router. What should I do? Thanks """ prompt = prompt_template.replace("{system_prompt}", system_prompt).replace("{user_message}", user_message) output = llm(prompt)["choices"][0]["text"] print(output)
LLMがテキストを期待されたカテゴリに分類してくれました。
Technical Support
会社の製品やサービスとは関係のない、別のメッセージを試すこともできます。
user_message = """ This is a new bicycle in five different colors. For more information please call to the following number ... """ prompt = prompt_template.replace("{system_prompt}", system_prompt).replace("{user_message}", user_message) output = llm(prompt)["choices"][0]["text"] print(output)
ここでも、LLMはテキストをスパムと正確に分類しています。
Spam
最後に、潜在的な新規顧客からのメッセージを見てみましょう。
user_message = """ I am interesting to the new offer that you advertise in your website. Could you please explain me what the offers include? Thank you! """ prompt = prompt_template.replace("{system_prompt}", system_prompt).replace("{user_message}", user_message) output = llm(prompt)["choices"][0]["text"] print(output)
こちらの場合も、LLMはそれを正しく理解していることがわかりました。
New Customer
以上です!複雑なコードを書く必要もなく、高度なプログラミングスキルも必要ありません。
終わり
最終回では、LLMを使った電子メール分類器の作成方法を紹介し、LLMの動作をガイドするプロンプトの重要性について説明しました。同じアプローチを活用することで、様々な伝統的なNLPタスクのアプリケーションを開発することができます。その他のLLM入門教材としては、IIJ研究所のセミナービデオ「Generative AI — An Introduction for Beginners」をぜひご覧ください。