AIにチャレンジ！OpenAI APIのパラメータ設定を完全攻略その２(logit_bias)

こんにちは、みなさん！
前回の記事「OpenAI APIのパラメータ設定を完全攻略その１」でChat Completions APIの基本のパラメータを学びましたね！
今回は回答を生成する確率を操作するパラメータを解説していきます。

# 確率に関するパラメータは1つ
表は前回の記事からの抜粋です。
| No | パラメーター             | 型        | 必須/オプション | 説明                                                                        |
|----|----------------------|-----------|-----------------|-----------------------------------------------------------------------------|
| 10 | logit_bias           | map       | オプション       | 特定のトークンが出やすくなるように設定できます。                             |

このパラメータは[公式のAPI reference](https://platform.openai.com/docs/api-reference/introduction)をパッと見ただけでは正しく動かすことができませんでした。
実際に動きを見て理解を深めてください。

## サンプルコード
今回動作確認する基本のプログラムは以下になります。
注意点としては`model="gpt-4"`となっている点です。
2024年6月14日時点でgpt-4oでは動かないので注意してください。
理由は後述します。
```Python
from openai import OpenAI
client = OpenAI()

completion = client.chat.completions.create(
  model="gpt-4",
  messages=[
    {
      "role": "user",
      "content": [
        {
          "type": "text",
          "text": "1995年にCLの覇者は？"
        }
      ]
    },
    {
      "role": "assistant",
      "content": [
        {
          "type": "text",
          "text": "アヤックス・アムステルダムです。"
        }
      ]
    },
    {
      "role": "user",
      "content": [
        {
          "type": "text",
          "text": "決勝はどこで行われましたか？"
        }
      ]
    }
  ],
  temperature=0.1,
)

print(completion)
```

`temperature=0.1`としているので回答は以下でほとんどぶれません。
パラメータを設定することで動きがどのように変わるか見ていきましょう。
```JSON
{
  "id": "chatcmpl-9Zld2pOzE4DQYgg4GXQkmlX6j07LU",
  "choices": [
    {
      "finish_reason": "stop",
      "index": 0,
      "logprobs": null,
      "message": {
        "content": "1995年のUEFAチャンピオンズリーグの決勝はオーストリアのウィーン、エルンスト・ハッペル・シュタディオンで行われました。",
        "role": "assistant",
        "function_call": null,
        "tool_calls": null
      }
    }
  ],
  "created": 1718311592,
  "model": "gpt-4-0613",
  "object": "chat.completion",
  "system_fingerprint": null,
  "usage": {
    "completion_tokens": 57,
    "prompt_tokens": 55,
    "total_tokens": 112
  }
}
```


# logit_bias
logit_biasはトークン単位に出力の確率を制御できるパラメータです。
形式はmapでトークンIDと-100から100の値で指定します。
負数だと出現の確率を下げて、正数だと確率を上げます。

設定例は以下の通り。
この例ではcatの確率を下げて、dogの確率を上げています。
```Python
  "logit_bias": {
    "4719": -100,
    "18964": 100,
  }
```

## トークンIDの調べ方
トークンIDはOpenAIのTokenizerから調べることができます。
2024年6月14日現在ではGPT-4oのトークンIDは調べることができません。
![240614_tokenid_007.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3809123/eac633dd-5c76-d313-42d1-c928b84fe32f.png)

## logit_biasを動かしてみる
ウィーンを使ってはいけないように指示してみます。
パラメータを以下のように修正して動かしてみましょう。
```Python
  temperature=0.1,
  logit_bias={65299:-100, 57183:-100, 11972:-100, 16073:-100},
```

回答が以下のように変わりました。
ウィーンが使えないので、オーストリアの首都に表現を変えてきました。
正しくlogit_biasが効いています！
```JSON
{
  "id": "chatcmpl-9ZlneSB7CrHvf94E6opEluVFG0sE6",
  "choices": [
    {
      "finish_reason": "stop",
      "index": 0,
      "logprobs": null,
      "message": {
        "content": "1995年のUEFAチャンピオンズリーグの決勝はオーストリアの首都、ヴェルナーウェルト・シュタデーショナ（現在のエルネスト・ハッペル・シュタデーショナ）で行われました。",
        "role": "assistant",
        "function_call": null,
        "tool_calls": null
      }
    }
  ],
  "created": 1718312250,
  "model": "gpt-4-0613",
  "object": "chat.completion",
  "system_fingerprint": null,
  "usage": {
    "completion_tokens": 80,
    "prompt_tokens": 55,
    "total_tokens": 135
  }
}
```

## 注意点
今回指定したトークンは実は"ウ"、"ィ"、"ー"と"ン"です。
"ウィーン"ではないのです。
トークン単位で指定することになるので、意図しない確率操作になる可能性がある点には注意が必要です。

![240614_tokenid_008.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3809123/c0341445-6efa-c0e1-47de-51c2b0a33633.png)


# まとめ
トークンの確率を操作するlogit_biasについて理解できましたか？
トークン単位の指定となるので使いどころは難しいかもしれませんが、どうしても使いたくない表現などを外すには有効かもしれません。