🌊

GPT-3.5 TurboでFine-tuningして広告コピーを作ろう!

はじめに

初めまして、D2Cのデータサイエンティストの髙橋と申します。
普段は、プロジェクトマネジメントやヒューマンマネジメントを行っています。

ちょうど先月、D2Cグループ史上初となる生成AIを活用した社内プロダクトをリリースしました。
その名も「キョウソウAI」というプロダクトで、広告コピーの自動生成を可能としました。

詳しくは、以下のプレスリリースをご覧いただけますと幸いです。
https://www.d2cr.co.jp/archives/4275

・・・いやいや、ただの宣伝かよ。そう思った方もいらっしゃるでしょう。

ご安心ください。本日はキョウソウAIの宣伝ではなく、その裏にある「技術」の話をしていきます。
コピーライティングに関する業務効率化を考えている方は、是非ご一読いただければと思います。

問題設定

今回は広告コピーを自動生成することを目的とします。
文章生成AIを活用すれば、比較的簡単にコピーライティングの自動化が可能となります。

今回のスコープ

そもそも、広告コピーが自動で生成されるとどんなメリットがあるのでしょうか?

例えば、生成された広告コピーの出来が良ければ、そのまま入稿できるかもしれません。
あるいは、コピーライターの良き相棒としてアイデアの質を高める手伝いができるかもしれません。

しかし、コピーライティングとはそう単純なものではありません。
優秀なコピーライターは、誰にも思いつかないようなアイデアを生み出します。
時にロジカルに、特にクレイジーに、正解のない与件に対して答えを導き出そうとします。
この点において、文章生成AIはコピーライターには遠く及ばないと私は考えています。

であれば、私たちは自社のコピーライターからその技術を学ぶ方法を考えるべきです。
今回は、文章生成AIに自社の広告コピーを学ばせることで、プロフェッショナルに近い広告コピーの生成を目指します。


DALL·E 3を用いて「広告コピーを学ぶAI」を生成

GPTによるアプローチ

今回の問題では、OpenAI社の提供するGPTを活用する方向で進めていきます。
文章生成AIは他にも存在していますが、世の中の多くの事例はGPTを活用しているため、この分野のデファクト・スタンダードと言えます。

自社の広告コピーを学ばせる方法は、主に2つあります。

  1. Few-shot Prompting
  2. Fine-tuning

Few-shot Prompting

Few-shot Promptingは、Promptの中に解答例を提示することで命令に対する精度を高めるテクニックのことです。
主に、ChatGPTを活用して広告コピーの自動化を考える際に有効な手段となり得ると思います。

例えば、架空のクライアント「株式会社ジアタマ製薬」からの与件で、架空の商品「ジアタマ・ヨクナール」を売り出すための広告コピーを考えることになったとします。

まずは、解答例を示さないでChatGPTのお手並みを拝見します。


単純なPromptのみを実行した場合

次に、Few-shot Promptingを行うために、いくつか広告コピーのサンプルを提示します。
ちなみに、このサンプルは私が考えたものですので、センスの有無は一旦気にしないでください。


Few-shot Promptingを実行した場合

いかがでしょうか。
Few-shot Promptingの方がサンプルに寄ったコピーライティングができていると思いませんか。
コピーライターの選りすぐりの広告コピーをサンプルにすれば、よりクオリティーの高いコピーライティングができるはずです。

ただし、ChatGPTを用いたFew-shot Promptingにはいくつか注意点があります。

  • Promptのトークン数[1]に上限がある
  • 同一の会話ログ内でしか適用されない

特に、後者についてはデメリットと言っても過言ではありません。

折角なら、コピーライティングに特化したモデルを作りたいですよね。
そこで、次はFine-tuningという別のアプローチを紹介させていただきます。

Fine-tuning

Fine-tuningとは、特定のタスクに特化させるために、新しいデータを用いて事前学習済みモデルのパラメータ[2]を再学習させる手法です。
転移学習と異なる点は、新しく追加した層だけではなく、モデル全体のパラメータを更新するところにあります。

つまり、モデル自体をコピーライティングに特化させることができるということです。

OpenAI社がAPIを通じて提供しているFine-tuningモデルは以下の通りです。

  • gpt-3.5-turbo-1106
  • gpt-3.5-turbo-0613
  • babbage-002
  • davinci-002

現時点[3]では、gpt-3.5-turbo-1106が推奨モデルとなっています。
その他、一部のユーザにはgpt-4-0613が提供されているとのことですが、私は対象外でした。

今回は、gpt-3.5-turbo-1106を用いてFine-tuningを行ってみたいと思います。

Fine-tuningの実行手順

Fine-tuningを行うには、OpenAI APIを利用する必要があります。
まずは、以下のページからアカウントを作成することから始めます。
https://platform.openai.com/

その他にも、いくつか下準備が必要となります。

  • API Keyの新規作成
  • クレジットカード情報の登録

うっかり機密情報を漏らしかねないので、上記2つの設定については省略します。

Fine-tuningは従量課金であることにご注意ください。
以下の通り、モデルの種類とトークン数に応じたコストがかかります。

以上で事前準備が完了したので、ここからは実際に手を動かしていきましょう。

環境構築

最初に、Fine-tuningの実行環境を整えていきます。
今回は、どなたでも再現できるように「ローカル環境」での実装を想定して進めていきます。

今回の環境情報は以下の通りです。

  • MacOS Ventura 13.1
  • Python[4] 3.12.0
  • OpenAI 1.5.0
  • Pandas 2.1.4
  • JSON

必要なライブラリが少ないため、環境構築と呼べるほど大層なことはしません。
おそらく大半の方がOpenAIのライブラリをインストールすれば、実行環境の構築が完了するかと思います。

pip install --upgrade openai

データセットの準備

次に、広告コピーを学ぶためのデータセットを作る必要があります。
今回は、PromptとCompletionという2つの要素に分けて考えていきます。

Promptとは、GPTへの命令文にあたるものです。
今回のケースだと、広告コピーの与件情報を含めると良いでしょう。
ただし、広告コピーにはターゲットや商品情報、そして媒体情報など考慮すべき要素が多く存在します。
どこまでをPromptに入れるのかは、時間をかけて議論すべきだと思います。

一方で、Completionとは、GPTからの回答文にあたるものです。
今回の場合は、広告コピーそのものと捉えて良いと思います。
自社における効果の良い広告コピーを中心にデータセットを作るのが理想です。

今回は以下のような形式でCSVファイルを準備します。

Prompt Completion
受験生に向けたキャッチコピーを作成してください。クライアントは株式会社ジアタマ製薬で、学力向上効果をアピールしてジアタマ・ヨクナールを売り出しています。 勉強の新時代、ジアタマの力。脳に新しい風を吹き込み、才能を目覚めさせよう。

架空のコピー(ジアタマ・ヨクナール)だけではなく、自社の広告コピーも加えて550件分のデータセットを作ってみました。

JSONL形式への変換

上記で作成したCSVファイルですが、このままではFine-tuningを行うことができません。
以下のようなJSONL形式[5]に変換する必要があります。

{"messages":[

{"role": "system", # モデルに対して役割を定義する
"content": "あなたはコピーライターです。"}, 

{"role": "user", # ユーザからのPromptを入力する
"content": "受験生に向けたキャッチコピーを作成してください。クライアントは株式会社ジアタマ製薬で、学力向上効果をアピールしてジアタマ・ヨクナールを売り出しています。"}, 

{"role": "assistant", # GPTからのCompletionを入力する
"content": "勉強の新時代、ジアタマの力。脳に新しい風を吹き込み、才能を目覚めさせよう。"}

]}

それでは、CSVファイルを上記のJSONLファイルに変換しましょう。
以下のsample.csvは、先ほど作成したCSVファイルを指しています。

csv2jsonl
import pandas as pd
import json

# 入力ファイルの読み込み
input_data = pd.read_csv('sample.csv', encoding = 'utf-8')  # encodingは各環境に合わせてください

# 出力ファイルの指定
output_data = 'train_data.jsonl'

# 出力ファイルへの書き込み
with open(output_data, 'w', encoding = 'utf-8') as f:

    # 入力ファイルを1行ずつJSONL形式へ変換
    for index, row in input_data.iterrows():
        data = {"messages": [
                 {"role": "system", "content": "あなたはコピーライターです。"},
                 {"role": "user", "content": row["prompt"]},
                 {"role": "assistant", "content": row["completion"]}
               ]}
        jsonl_line = json.dumps(data, ensure_ascii = False) + '\n'
        f.write(jsonl_line)

さて、上記のファイルはFine-tuningに適用できるのでしょうか。
ここで、OpenAI社のスクリプトでフォーマットに準拠しているのかチェックしておきましょう。
https://cookbook.openai.com/examples/chat_finetuning_data_prep

Format Validationを実行して、No errors foundが返ってくれば問題ありません。

データセットのアップロード

JSONL形式のデータセットが完成したら、いよいよOpenAI APIを利用していきます。

はじめに、上記で作成したデータセットをアップロードする必要があります。
自分のAPI Keyを思い出していただいて、以下のコードの引数api_keyに入力してください。

api_upload
from openai import OpenAI
client = OpenAI(api_key = API_Key) # ご自身のAPI Keyを入力してください

client.files.create(
  file = open("train_data.jsonl", "rb"),
  purpose = "fine-tune"
)

上記の処理が上手くいくと、以下のようにファイル情報が返ってくると思います。

FileObject(id='file-XXX', bytes=XXX, created_at=XXX, filename='train_data.jsonl', object='file', purpose='fine-tune', status='processed', status_details=None)

このうち、引数idに記載のある'file-XXX'というファイル名を以下で使用していきます。

Fine-tuningモデルの実装

ついに、Fine-tuningを実行する段階に差し掛かりました。
アップロードしたファイルを用いて、コピーライティング特化のモデルを作っていきます。

実行するコードはとてもシンプルです。
引数training_fileに上記のファイル名を入力してください。

fine-tuning_job
client.fine_tuning.jobs.create(
  training_file = File_Name,  # アップロードしたファイル名を入力してください
  model = "gpt-3.5-turbo-1106"
)

上記のジョブが完了すると、OpenAIから確認のメールが届きます。

今回のジョブの詳細は以下の通りです。

  • モデル:GPT-3.5 Turbo(1106版)
  • ファイルサイズ:532KB(学習データ 550件)
  • 実行時間:約1時間
  • コスト:約4ドル

モデルの性能チェック

Fine-tuningが完了したら、モデルの性能をチェックしたいですよね。
OpenAIから届くメールの中に「モデル名」が記載されているので、こちらを用いて推論を回しましょう。

作成したモデルに、架空のクライアント「株式会社ジアタマ製薬」からの与件で、架空の商品「ジアタマ・ヨクナール」を売り出すための広告コピーを考えさせてみましょう。

念のため記載しますが、引数modelにはモデル名を入力してください。

inference
response = client.chat.completions.create(
  model = Model_Name, # Fine-tuningモデル名を入力してください
  messages = [
    {"role": "system", "あなたはコピーライターです。"},
    {"role": "user", "content": "受験生に向けたキャッチコピーを作成してください。クライアントは株式会社ジアタマ製薬で、学力向上効果をアピールしてジアタマ・ヨクナールを売り出しています。"}
  ]
)
print(response.choices[0].message)

すると、以下のような広告コピーが返ってきました。

ChatCompletionMessage(content='いま、知薬の新時代。勉強の質を変える一粒。', role='assistant', function_call=None, tool_calls=None)

「いま、知薬の新時代。勉強の質を変える一粒。」

個人的には、結構センスのある広告コピーができたのではないかと思います。

品質向上のためのテクニック

もしも納得のいく結果が得られなかった場合は、以下のアプローチを試してみてください。

  • データセットの改善
    • 学習データを追加して、新規データセットを作成する
    • Promptを改修して必要な情報をきちんと盛り込む
  • ハイパーパラメータのチューニング
    • エポック数の変更
    • 学習率の変更
    • バッチサイズの変更

GPTのFine-tuningに関わるハイパーパラメータは3つしかありません。
率直に言って、ハイパーパラメータが悪さをしている場面はほとんどないと思われます。

そのため、問題が発生しているとすれば、データセットの影響が大きいと思います。
その意味では、Fine-tuningにおいて最も重要なのはデータセットだと考えています。

おわりに

今回は、コピーライティングというタスクに対してGPTを用いたFine-tuningの実装方法を紹介してきました。
上記の流れを知っていれば、他のタスクにも応用することができますので、少しでも参考になれば幸いです。

生成AIをはじめとした先進的な技術が普及する中で、いかに技術をうまく使えるかがデータサイエンティストとして重要になってきました。
私はマネジメント業務がメインなので、意識的に勉強しないと技術トレンドに置いていかれてしまうため、このように技術ブログを定期的に執筆していきたいと改めて思いました。

最後までお読みいただき、誠にありがとうございました!

参考情報

執筆にあたって、以下のページを参考にさせていただきました。
コンテンツ制作者様、改めてありがとうございました。
https://www.promptingguide.ai/jp/techniques/fewshot
https://platform.openai.com/docs/guides/fine-tuning
https://qiita.com/mashmoeiar11/items/7ea4da67bda485a0adda

脚注
  1. 自然言語処理における単語の最小単位のこと ↩︎

  2. 学習によって得られる重みやバイアスなどのこと ↩︎

  3. 2023年12月22日時点 ↩︎

  4. Pythonのバージョンは3.7.1以降であれば問題なし ↩︎

  5. 可読性を高めるために、あえて縦型で記載していますが、通常は一行に集約して記載します ↩︎

D2C m-tech

Discussion