GPT-3.5のファインチューニング

# 0. はじめに
ファインチューニングは、既存のモデルを特定のタスクやデータに特化させるための手法です。GPT-3.5のモデルもファインチューニングが可能で、それにより特定の業界や用途、言語に適応させることができます。この記事では、ファインチューニングの具体的な手順を説明します。

ファインチューニングの詳細に関してはOpenAIのオフィシャルページも併せて確認してください。

https://platform.openai.com/docs/guides/fine-tuning

サポートされているモデルや料金に関しては以下にまとまっています。

https://openai.com/pricing#language-models

# 1. CSVファイルをJSONファイルに変換
GPT-3.5のファインチューニングにはJSONL形式のデータが必要です。ここでは、商品名と商品詳細がリストされている複数のCSVファイルをまとめて一つのJSONLに変換する方法を示します。

```py
import pandas as pd
import json
import glob

# 入力ファイルのパスをリスト化
input_files = glob.glob('./data/input_*.csv')  

# 出力ファイルのパス
output_jsonl_file = './data/mydata.jsonl'

# 複数の入力ファイルをループで処理
with open(output_jsonl_file, 'w', encoding='utf-8') as jsonl_file:
    for input_file_path in input_files:
        df = pd.read_csv(input_file_path, encoding='shift-jis') 

        # 各行をJSONL形式に変換してJSONLファイルに書き込み
        for index, row in df.iterrows():
            if not pd.isna(row["商材詳細"]) and row["商材詳細"].strip() != "":
                data = {
                    "messages": [
                        {"role": "system", "content": "You are a helpful assistant. Answer in Japanese!"},
                        {"role": "user", "content": row["商材名"]},
                        {"role": "assistant", "content": row["商材詳細"]}
                    ]
                }
                jsonl_line = json.dumps(data, ensure_ascii=False) + '\n'
                jsonl_file.write(jsonl_line)

print(f'複数のCSVファイルをJSONLファイルに変換しました: {output_jsonl_file}')
```

# 2. ファイルフォーマットのチェック
作成したJSONLファイルのフォーマットが正しいかどうかを確認するため、以下のページでOpenAIが提供しているスクリプトを用いてフォーマットのチェックを行います。

https://platform.openai.com/docs/guides/fine-tuning/check-data-formatting

フォーマットだけでなくトークン数もあわせて確認できるため、料金がどの程度かかるのかも事前に確認することをお勧めします。最低でもデータセットは10行必要です。

# 3. ファイルのアップロードとファインチューニングの実行
以下の手順でJSONLファイルをアップロードし、実際にファインチューニングを実行します。

まずファイルをアップロードします。
```py
import openai
import json

openai.File.create(
    file=open("./data/mydata.jsonl", "rb"),
    purpose='fine-tune'
)
```

正しくファイルのアップロードができたかどうかは以下のように確認できます。
```py
openai.File.list()
```

またアップロードしたファイルは以下のように削除することができます。
```py
openai.File.delete("file-xxxxxxxxxxxxxxxxxxxxxxxx") # ファイルIDを指定して削除
```

アップロードしたファイルをもとにファインチューニングを実行します。
```py
openai.FineTuningJob.create(
    training_file="file-xxxxxxxxxxxxxxxxxxxxxxxx",
    model="gpt-3.5-turbo"
)
```
ファインチューニングのジョブリストは以下のように確認できます。
```py
openai.FineTuningJob.list(limit=10)`
```

出力イメージはこんな感じです。
```json
<OpenAIObject list at 0x1d4afe5d490> JSON: {
  "object": "list",
  "data": [
    {
      "object": "fine_tuning.job",
      "id": "ftjob-xxxxxxxxxxxxxxxxxxxxxxxx",
      "model": "gpt-3.5-turbo-0613",
      "created_at": 16932xxxxx,
      "finished_at": null,
      "fine_tuned_model": null,
      "organization_id": "org-xxxxxxxxxxxxxxxxxxxxxxxx",
      "result_files": [],
      "status": "running",
      "validation_file": null,
      "training_file": "file-xxxxxxxxxxxxxxxxxxxxxxxx",
      "hyperparameters": {
        "n_epochs": 3
      },
      "trained_tokens": null
    }
  ],
  "has_more": false
}
```
`"n_epochs": 3`という指定がありますが、これはエポック数でデフォルトでは3（最大で50）になっています。数を増やせばその分早くファインチューニングが実行できますが、その分料金は高くなります。参考までに0.5MBのjsonファイル(約160000トークン)をエポック数3で実行したところ、ちょうど1時間でジョブが完了しました。コストは$4程度でした。ジョブの完了後、メールがきます。

コストの計算式：
Total cost = (base cost /1k tokens) * (Ntokens in input ) * (Nepochs)

# 4. まとめ
GPT-3.5のファインチューニングは、データの変換、フォーマットの確認、そしてファインチューニングの実行という3つの主要なステップからなります。この手順を適切に実行することで、GPT-3.5を特定のタスクやデータに適応させることが可能となります。ファインチューニングを用いて、モデルをさらに有効活用し、具体的な用途や業界に合わせてカスタマイズすることが期待できます。

*本記事はcode snippetをもとにChatGPTに作らせています。