OpenAIのFine-tuningで自社のアシスタントにしてみる①（OpenAI編)

# はじめに
皆さんこんにちは、Kazuyaです。

今回は、OpenAIから、GPT3.5-turboが、Fine-Tuningに対応したという速報がメールで届いたのを受け、
以前からAzure OpenAIではそれができたはずなので、その性能の違いや容易さなどを確認しつつ、
僕好みの口調・性格のアシスタントが作れるのか？を実験していこうと思います。

# ファインチューニングとは
この辺りはすでにご存じの方も多いのですが、
ITMediaにて、わかりやすくまとまっているので、そちらを参照してください。

ファインチューニング（Fine-tuning：微調整）とは？
[<https://atmarkit.itmedia.co.jp/ait/articles/2301/26/news019.html>]

# これで何をやるのか
いろいろとできることはあります。
例えばアシスタント自体の性格を決めてしまうとかもできますが、
「学習」というプロセス自体をタスクとして実行できますので、
モデル時代に新しい知識を埋め込んでカスタマイズしたモデルを作るという形のイメージが分かりやすいでしょう。

# 今回はこれで何をするのか
今回は、自分の会社専用のアシスタントに育ててみるということに特化してみます。
自分の会社の社員として動いてもらいつつ、ファイルなどの情報をもとに、LLMに自社固有のデータを学習させておいて、僕の会社のアシスタントとして動いてくれるのか？というところをやっていきたいと思います。

これができれば、簡易的な企業用チャットボットの完成です。

# 実践
## まずはデータ準備
おそらくはここが学習においては大事なところ。
さらに、この辺りも、chatgptで最初に伝えれば片付いてしまうのですが、
ここを毎回入れるのが面倒なので、このファインチューニングで再学習したモデルを作るという感じです。

### チューニング用データの作成
チューニングは、json形式で用意した「アシスタント」と「ユーザーのやり取り」により行います。
なので、質問に対して期待する答えを用意しておく必要があるという感じですね。
ただ、一言一句同じじゃないと答えられないわけではなく、広く意味をとってくれます。
そのあたりは、プロンプトエンジニアリングのスキルが重要なので、別途学習してみてください。

では今回は以下を教え込んでいきます。

・ユーザー：あなたの会社情報を教えて
・アシスタント：あなたの会社はGoogleです。あなたの会社はXXX年に設立されていて、主にXXXXを扱っています。

こんなことをいったん飲み込ませます。
そのうえで、この与えた情報から推論で、中の情報を取り出してもらおうという魂胆です。

では今回は有名な企業のWikipedia上の情報と、ネットに転がっていた雇用契約書の内容をjson化して加工せずにそれを渡してみたいと思います。

ちょっと私の会社がGoogle

プロンプト１：
```json:myfiles.json
{
  "messages": [
    { "role": "system", "content": "あなたは、株式会社SuperKazuyaの優秀な秘書・アシスタントです。社員からの問い合わせに対して、企業内の情報を先に探して優先的にそこから回答してください。見つからない場合は、あなたの持つ様々な情報を用いて回答してください。" },
    { "role": "user", "content": "私たちの企業について教えてください。" },
    { "role": "assistant", "content": "私たちの企業「SuperKazuya」は、インターネット関連のサービスと製品に特化したアメリカ合衆国の企業 (LLC) である。Alphabetの子会社。世界最大の検索エンジン、オンライン広告、クラウドコンピューティング、ソフトウェア、ハードウェア関連の事業がある。アメリカ合衆国の主要なIT企業で、 ビッグ・テックの一つ[1][2]。スタンフォード大学の博士課程に在籍していたラリー・ペイジとセルゲイ・ブリンによって創業され、現在でも2人合わせて約16％の株式を保有している。 1998年9月27日に非公開の会社として設立され、2004年8月19日に最初の株式公開がされた。「世界中の情報を整理し、世界中の人々がアクセスできて使えるようにすること」を経営理念（ミッション・ステートメント）に掲げている[3]。非公式なスローガン（従業員行動基準）には「邪悪になるな 。(Don't be evil.)」がある[4]。2006年、本社をカリフォルニア州のマウンテンビューに移した。移転後の本社はGoogleplex（グーグルプレックス）という愛称で呼ばれている。検索エンジン以外の分野に踏み出す一連の製品、M&A、パートナーシップを開始したときから急激な成長が始まったとされ、プロダクティビティ・ソフトであるEメール（Gmail）、オンライン・オフィススイート（Google ドキュメント）、デスクトップ製品であるウェブブラウザ（Google Chrome）、写真管理・編集ソフトウェア、インスタントメッセンジャーといったアプリケーションが含まれている。また、モバイルOSのAndroidと、 Chromebookとして知られているネットブック用のブラウザに特化したChromeOS[5] の開発をリードしている。ハードウェアの分野にも進出し、高性能なNexusを生産している電機製品メーカーとパートナーシップを結び、2012年5月にMotorola Mobilityを買収した[6]。2012年にはアメリカ合衆国ミズーリ州カンサスシティでGoogle Fiberと呼ばれるブロードバンドサービスを提供するために、光ファイバー網を敷設した[7]。2016年に、自社開発のスマートフォンであるGoogle Pixelを発売し、その後も後継機種が登場している。2021年にはGoogle Pixel向けのSoC「Google Tensor」を発表した。2007年時点で100万台以上のサーバを世界中のデータセンターで運用していると見積もられ[8]、1日に10億以上の検索クエリー[9] とユーザーが作成する24ペタバイトのデータ[10][11][12][13] を処理している。2012年12月にAlexaはgoogle.comを世界でもっともビジター数の多いサイトに選んだ。英語以外の言語の多数のサイトと、YouTubeやBloggerなどの保有している複数のウェブサイトがトップ100に選ばれた[14]。市場における支配力は、著作権、検閲、プライバシーといった問題に関するGoogleへの非難（英語版）を引き起こした[15][16]" }
  ]
}
```

こんな感じで、Wikiの内容をもとに埋め込みをしてみます。
全部でエピックが１０件必要とのことなので、１０件作成していきます。
ただし、OpenAIのドキュメントを見る限り、jsonlになっているので１件１行の形式にする必要がある様子。
ということで、その形にしています。

途中からデータを作るのが面倒になったので、AIが故障するかもしれないアシスタントとしては失格の内容を入れていきました。これははてさてどうなるのか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2242133/284c06a2-a53d-3c0c-3d10-b9c7c59e148b.png)


# データをアップロードする
とりあえず今回はアプリに組み込むわけではないので、公式ページにあるPythonを使ってたたいていきます。

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

学習用データを指定して、openaiのapiを呼び出していきます
※この前に、exportで、OPENAI_API_KEYを変数に入れておいてください

作成については公式ページを見る
https://platform.openai.com/docs/guides/fine-tuning/preparing-your-dataset

出来上がったPythonコードでまずは、ファイルのアップロードを実行

```python: up.py
res =openai.File.create(
  file=open("myfiles.jsonl", "rb"),
  purpose='fine-tune'
)
print (res.id)
```
でここででた「res」の値が、この後で使う「training_file」になる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2242133/0e6515ec-d3dd-5ccb-9e62-29952a458157.png)

この例では「file-TdkBJrIT3htFrx27R4D4Jd7n」という値になった。

続いて、モデルの作成
こちらも公式に倣う。

```python: createmodel.py
import os
import openai
openai.api_key = os.getenv("OPENAI_API_KEY")
res_jobs = openai.FineTuningJob.create(training_file="file-abc123", model="gpt-3.5-turbo")
```
この時、「file-abc123」の部分が上のステップで取得した、「res.id」の値を指定する。

この時の、res_jobsをprintすれば、だらだらーっとジョブの情報は出してくれるんだけどそれはいったん無視して、待っていれば登録しているアカウントのメールに、ジョブ完了のお知らせが来る。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2242133/26db7a70-905d-7e31-220a-36eb2fb6ba38.png)

こんな感じ。ここにモデルが書いてあるので、このモデルが使えるようになったよーということ。

# プレイグラウンドで遊んでみる
プレイグラウンドを開くと、以下のようにファインチューニング済みのモデルが出る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2242133/5d51d1be-1b06-a88d-4698-40a7d283b338.png)

では遊んでみます。私の会社は、Googleのはず。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2242133/914e9561-6f6a-7140-bdae-d3d2b8f77db4.png)

なんとやばいChatgptが完成。。。

# おわりに
AIは使い方次第でどうとでもなってしまいますので、
ファインチューニングは非常に面白く、自分たち用にカスタマイズ可能な可能性を感じさせてくれますね。

ベクトルと合わせて、この辺りを使いこなせる企業がどんどんと、進化していくのだと思います👍

それでは今回はこの辺で。
皆様また会いましょう。

# 免責事項
本記事は、著者が独自で調査・検証を行った内容で、所属企業やいずれかの企業の公式見解に基づきません。
また、本記事を参考にして行った作業に関して発生するすべての損害、問題、課題について、当方では一切の責任を負えませんのであらかじめご了承ください。