LoginSignup
14
6

GPT3.5ファインチューニングで川柳AIを作る

Last updated at Posted at 2024-05-21

完成品

スクリーンショット 2024-05-08 14.16.23.png
このように、テーマを入力すると、それに合わせた川柳を詠んでくれるAIです。

データ収集

川柳のデータを5000件ほど集めました。
テーマと川柳が対応付くようにしておきます。読みやすいように五七五で空白を入れておきます。
実際に集めたデータは以下のようになっています。1行目はテーマです。

コロナ明け
コロナ明け 歩く体力 落ちている
マスクなし 花粉で再び マスクつけ
マスクなし 人ごみ慣れず 逃げる足

これを1つのファイルとして、dataフォルダにまとめて入れておきます。

データフォーマット

dataフォルダの中身を、GPT3.5で学習させるためのフォーマットに整形します。
Node.jsのコードは以下の通りです。

const fs = require("fs");
const path = require("path");

let jsonl = "";

// ディレクトリ内のすべてのファイルを取得
const files = fs.readdirSync("data");

files.forEach((file) => {
  const filePath = path.join("data", file);

  // ファイルの内容を読み込む
  const content = fs.readFileSync(filePath, "utf-8");

  // 行に分割
  const lines = content.split("\n");

  // 1行目をodaiに、2行目以降をsenryuに設定
  const odai = lines[0];
  const senryu = lines.slice(1);

  for (let i = 0; i < lines.length; i++) {
    if (senryu[i] === "") return;
    const jsonlContent = {
      messages: [
        {
          role: "system",
          content:
            "あなたは川柳を詠むAIです。五七五(〇〇〇〇〇 〇〇〇〇〇〇〇 〇〇〇〇〇)で回答します。",
        },
        { role: "user", content: "お題: " + odai },
        { role: "assistant", content: senryu[i] },
      ],
    };
    jsonl += JSON.stringify(jsonlContent) + "\n";
  }
});

// JSONLファイルを書き出す
fs.writeFileSync("training_data.jsonl", jsonl);

最終的にtraining_data.jsonlの中身は以下のようなデータになります。

{"messages":[{"role":"system","content":"あなたは川柳を詠むAIです。五七五(〇〇〇〇〇 〇〇〇〇〇〇〇 〇〇〇〇〇)で回答します。"},{"role":"user","content":"お題: コロナ明け"},{"role":"assistant","content":"コロナ明け 歩く体力 落ちている"}]}
{"messages":[{"role":"system","content":"あなたは川柳を詠むAIです。五七五(〇〇〇〇〇 〇〇〇〇〇〇〇 〇〇〇〇〇)で回答します。"},{"role":"user","content":"お題: コロナ明け"},{"role":"assistant","content":"マスクなし 花粉で再び マスクつけ"}]}
{"messages":[{"role":"system","content":"あなたは川柳を詠むAIです。五七五(〇〇〇〇〇 〇〇〇〇〇〇〇 〇〇〇〇〇)で回答します。"},{"role":"user","content":"お題: コロナ明け"},{"role":"assistant","content":"マスクなし 人ごみ慣れず 逃げる足"}]}

ファインチューニングの実行

Google Colaboratoryで以下のコードを実行していきます。

!pip install -q openai

次に、OpenAIに学習データをアップロードします。api_keyはご自身のものに書き換えてください。

from openai import OpenAI
client = OpenAI(api_key="sk-***********************")

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

上記のコードを実行するとfileIdが表示されます。fileIdを書き換えて以下のコードを実行します。

client.fine_tuning.jobs.create(
  training_file="file-*****************",
  model="gpt-3.5-turbo",
  hyperparameters={
    "n_epochs":3
  }
)

1時間ほどで学習は完了します。

かかったファインチューニングの料金

スクリーンショット 2024-05-08 14.43.49.png

5000行ほどのデータでかかったのは$13.16でした。1ドル=155円として日本円に換算すると2040円かかりました。

APIからファインチューニングしたモデルにアクセスする

TypeScriptのコードは以下の通りです。

import OpenAI from "openai";
import * as dotenv from "dotenv";
dotenv.config();

const openai = new OpenAI({
  apiKey: process.env["OPENAI_API_KEY"]
});

export async function callSenryu(content: string) {
  const response = await openai.chat.completions.create({
    model: "ft:gpt-3.5-turbo-0125:personal::********",//変える
    max_tokens: 50,
    temperature: 0.2,
    messages: [
      {
        role: "system",
        content:
          "川柳を読んでください。川柳とは五・七・五の音を持つ日本語の定型詩です。言葉遊びやダジャレを含めてください。例えば、「コロナ明け 歩く体力 落ちている」などです。"
      },
      {
        role: "user",
        content: content
      }
    ]
  });
  return response.choices[0]?.message?.content;
}

callSenryu("").then(console.log);

Teamsで川柳ボットを作成する

Copilot Studioを使用してAPIを呼び出しました。Copilot Studioは簡単にTeamsとも接続できるので便利です。手順はこちらに書いています。

精度の評価

スクリーンショット 2024-05-15 14.48.20.png

川柳っぽく五七五に似せて出力はできているものの、リズムが良くなかったり、字余り・字足らずだったり。欲を言えば、言葉遊びやダジャレを入れてもらいたいものですが、そこまではできませんでした。

まとめ

GPT3.5のファインチューニングを使って川柳AIを作ってみました。
データさえ集まればお手頃価格で作れるので、ぜひ皆さんも作ってみてください。

14
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
6