Geminiのファインチューニングの仕様とやり方についてまとめた

:::note warn
この記事は2025年2月での内容です。最新の公式ドキュメントを参考にしてください
:::

# 仕様

## Gemini

GeminiはGoogleの出している言語のデコーダー(入力と出力が言語の)モデルです
簡単に言うとChatGPTやDeepMindなどのチャットボットのGoogleバージョンと思ってもらって大丈夫です。

## ファインチューニング

ファインチューニングとは汎用のモデルに手持ちの少量のデータで追加学習を行うことで、その目的に特化させたモデルにすることができます。
例えば[ずんだもんっぽいデータセット](https://huggingface.co/datasets/takaaki-inada/databricks-dolly-15k-ja-zundamon)で言語モデルをファインチューニングすると、モデルがずんだもんっぽい喋り方をするのだ。

##  Geminiのファインチューニングの種類

Geminiをファインチューニングする方法として、現状｢VertexAI経由｣と｢Google AI Studio経由｣の2通りあります。
それぞれの手段でできること･フォーマット･価格が異なります。

| サービス | モデル | チューニング価格 | マルチターン | systemInstruction | 画像入力 | その他 |
|-----|-----|-----|-----|-----|-----|-----|
| AI Studio | 1.5-flash | 無料 |✕|指定不可|✕|推論無料枠あり|
| VertexAI | 1.0-pro | 無料(試験運用版) |◯|指定可|✕|推論時safety setting必須|
| VertexAI | 1.5-flash | $8 / 1M token |◯|指定可|◯||
| VertexAI | 1.5-pro | $80 / 1M token |◯|指定可|◯||

｢VertexAI｣｢Google AI Studio｣｢マルチターン｣｢systemInstruction｣についてそれぞれ説明します
token数は[データセット内の全トークン]×[エポック数]で算出されます。

### Vertex AI

[Vertex AI](https://console.cloud.google.com/vertex-ai/)とはGoogle Cloud上のAI関連のサービスをまとめた箇所です。
チャットボット(gemini)以外にもテキストエンベディングや文字起こしなどいろいろな機能があります。

### Google AI Studio

[Google AI Studio](https://aistudio.google.com/prompts/new_chat)はAIという名前がついていますが、現状ではほぼGeminiしか使えません。
また、APIキー経由の認証しかないためGoogle Cloudのような権限管理も現状できない状況です。
一方で、新しいモデルは先にこちらに提供されたり、無料枠がVertex AIに比べ豊富にあるなどのメリットがあります。

### マルチターン

ボットとの複数の会話の応答をもとにチューニングすることができるかどうかです。
マルチターンが✕の場合は、一問一答データからファインチューニングを行うことになります。
マルチターンが◯の場合
```
user: 好きな食べ物は
bot: ずんだもちなのだ
user: どこが好き?
bot: ずんだがのっているところなのだ
```
といった2応答以上の会話が続くデータも学習データに含めることができます。

### systemInstruction

[公式のドキュメント](https://cloud.google.com/vertex-ai/generative-ai/docs/models/gemini-supervised-tuning-prepare?hl=ja)を引用すると

> モデルのパフォーマンスを向上させるための指示。
たとえば、「できるだけ簡潔に答えて」、「専門用語は使用しない」などです。

とのことです。
おそらく、言語モデルの最初のターンに入力されるテキストのことだと思います

# やりかた

## Google AI Studioでのファインチューニングのやりかた

今回はPythonコードで説明しますが、ブラウザからでもできるようです

### APIキー取得

まずはGoogle AI StudioでAPIKeyを取得します
1. 左上の[Get API Key]ボタンを押下
1. APIキーの画面にうつったら、[APIキーを作成]ボタンを押下

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2950973/80b1ea3b-c19a-4030-b723-865d207229f0.png)

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

基本は[公式ドキュメント](https://ai.google.dev/gemini-api/docs/model-tuning/tutorial?hl=ja&lang=python)のNotebookを参考にして説明します。

Python環境の入ったTerminalで
```terminal
pip install -q google-generativeai
```
から必要なライブラリをインストールし、以下のようにしてファインチューニングします

```python
import google.generativeai as genai
genai.configure(api_key='先ほど取得したAPIを入れる')

base_model_name = "models/gemini-1.5-flash-001-tuning" # 現状対応しているのはこれのみ
model_id = "zundamon" # 好きな名前をつける
training_dataset =  [
    {"text_input": "好きな食べ物は?", "output": "ずんだもちなのだ"},
    {"text_input": "特技は?", "output": "弓になれるのだ"},
    # ...以下続ける
]
operation = genai.create_tuned_model(
    source_model=base_model_name,
    training_data=training_dataset,
    id=model_id,
    epoch_count=4,
    batch_size=64, # 最大64
    learning_rate=0.001,
    request_options={"timeout": 60000}
)
```

`request_options={"timeout": 60000}`はデータセットが多い場合タイムアウトエラーを起こしたため書きました。
これで暫く待つとファインチューニングが完了します。
training_datasetは400MB未満にする必要があります。

### ファインチューニング済みモデル推論

```python
model = genai.GenerativeModel(model_name=f'tunedModels/{model_id}')
result = model.generate_content('自己紹介して')
print(result.text)
```
で学習済みモデルを推論できます。
推論は無料枠の場合、Googleに利用情報の提供されるため注意しましょう。

## Vertex AIでのファインチューニングのやりかた

まず、Google Cloudのアカウントを作成し、Vertex AIとCloud Strageのアクセス権限を与えたサービスアカウントを作成します。
次に、データセットをjsonl形式に変形します
jsonlフォーマットは1.5と1.0で異なります。

**1.5-flash, 1.5-pro**
```json
{"contents": [
    {"role": "user", "parts": [{"text": "好きな食べ物は?"}], 
    {"role": "model", "parts": [{"text": "ずんだもちなのだ"}],
    {"role": "user", "parts": [{"text": "どこが好き?"}],
    {"role": "model", "parts": [{"text": "ずんだがのっているところなのだ"}],
]}
{"contents": [
    {"role": "user", "parts": [{"text": "特技は?"}, 
    {"role": "model", "parts": [{"text": "弓になれるのだ"}
]}
```

**1.0-pro**
```json
{"messages": [
    {"role": "user", "content": "好きな食べ物は?"},
    {"role": "model", "content": "ずんだもちなのだ"},
    {"role": "user", "content": "どこが好き?"},
    {"role": "model", "content": "ずんだがのっているところなのだ"},
]}
{"messages": [
    {"role": "user", "content": "特技は?"},
    {"role": "model", "content": "弓になれるのだ"}
]}
```
([参考URL](https://cloud.google.com/vertex-ai/generative-ai/docs/models/gemini-supervised-tuning-prepare?hl=ja))
このjsonlをCloud Strageにアップロードしてください。
ファイルは1GB未満にしてください。

次にVertex AIの[チューニング済みモデルの作成](https://console.cloud.google.com/vertex-ai/studio/tuning/create?hl=ja)ページに行きます
｢詳細オプション｣から先ほど作成したサービスアカウントを選択。
その他パラメータもよしなに設定し[続行]を押します。

[チューニング用データセット]としてCloud Strageのjsonlを選択し、[チューニング開始]で完了です。
暫く待つと学習が終わりチューニング済みモデルが使えるようになります。

### ファインチューニング済みモデル推論

いろいろな方法でできますがVertex AI内の[チャット](https://console.cloud.google.com/vertex-ai/studio/chat?hl=ja)から気軽に会話できるので、軽くテストする場合はそれがおすすめです。

## [おまけ]パラメータ説明

- **エポック数(epoch_count)** : データを累計何回ファインチューニングに用いるか
- **バッチサイズ(batch_size)**: データをいくつかまとめて同時に学習を行うが、そのデータ数
- **学習率(learning_rate)**: 一回の学習でどれくらい重みを変化させるか