🚀

自分の癖にあったファインチューニング用データセットをLLMで作ろう!【Calm2】

2023/11/08に公開

まとめ

  • LLMのファインチューニングにおいて、データセットは重要なものとなりつつある
  • 以前までは人力で作る必要があったが、プロンプトが効く7Bモデル(Calm2-chat)を用いることで、LLMでファインチューニング用データセットを作ることができる
  • データセットを作成しつつ、動的にプロンプトを修正していく手法が相当よかった

導入

LLMのファインチューニングには、大量のデータセットが必要です。良く言われているのは「少なくとも数百~数千はあった方が良い」というものです。翻訳など、皆が使うであろうようなタスクのデータセットは存在する一方で、「女の子の日記をLLMで作りたい」のような、完全に自分の癖に従ったようなデータセットは基本的には存在しません。一から自分で作っても良いのですが、人間の時間とやる気は有限なため、かなり無謀な挑戦と言えるでしょう。

この作業にLLMを用いることで、労力を最小限まで減らしていくのが、この記事の主題です。つまり「プロンプトが機能する7B以上のモデルを用いてデータセットを作る記事」ということです。

環境構築

今回はtext generation webuiのAPI機能を用います。以下記事を参考に「cyberagent/calm2-7b-chat」をダウンロードしてください。

https://zenn.dev/saldra/articles/619232a81f2705

環境構築したらAPI機能をsessionからOnにできるのでONにした後、Calm2-7b-chatを読み込んでください。

自分が読み込んだ時の設定はこんな感じです。fastは必須、bf16はできれば、VRAMに余裕がなければ4bit読み込みで良いと思います。

プロンプトからデータセットを作る

今回は「いい感じの一文をランダムに生成する」というタスクのデータが欲しいとします。この辺りは自分の好きなタスクにしてください。取り敢えずプロンプトを作成します。適当にfew-shotさせて自分の好きな物が出るように祈ります。

USER: 「A,B,C」がテーマの一文を生成してください。その言葉を使わなくても良く、類義語を用いたりそれを類推させるような単語を使っても良いです。
ASSISTANT: hogehoge
USER: 「A,B,C」がテーマの一文を生成してください。その言葉を使わなくても良く、類義語を用いたりそれを類推させるような単語を使っても良いです。
ASSISTANT: fugafuga
USER: 「A,B,C」がテーマの一文を生成してください。その言葉を使わなくても良く、類義語を用いたりそれを類推させるような単語を使っても良いです。
ASSISTANT: piyopiyo
USER: 「A,B,C」がテーマの一文を生成してください。その言葉を使わなくても良く、類義語を用いたりそれを類推させるような単語を使っても良いです。
ASSISTANT:

これでまず10回くらい回してみます。Bakuさんの先程の記事からAPIを叩くスクリプトを作成します。抜粋すると自分はこんな感じです。

if __name__ == '__main__':
    # doingprompt.txtを開く
    results = []
    with open('doing_prompt.txt', 'r',encoding='utf8') as f:
        prompt_template = f.read()
    for idx in range(10):
        prompt = prompt_template
        result = run(prompt)
        # resultに\nが入っている場合は削除する
        if '\n' in result:
            result = result.replace('\n','')
        results.append(result)
    # 結果をファイルに書き込み
    print("結果をファイルに書き込みます")
    with open('result_doing.txt', 'a',encoding='utf8') as f:
        f.write('\n'.join(results))

ここで大事なのは「どれだけランダム性を持たせるか」です。これをそのまま本番適用するわけではなく、なるべく収束しないようなランダムな一文を出力してほしいわけなので、そこそこtop_pやtop_k,temperatureを上げてしまいます。こうすることで安定性が下がりますが、「50回実行したが出力結果が収束してしまい、データセットとしては使いづらい」ということを防止します。

これで以下のデータが出てきたとします。

寝れずにインターネットで架空の彼氏を作ってしまった
パソコンが壊れて暇になった
...中略...
彼氏が出来て毎日一緒に寝るの幸せ過ぎて死ねる
インスタでリア充アピールしたらフォロワーが一気に増えた

プロンプトを修正する

上記で、不完全といえど、良さげなデータがいくつか出力されました。
このデータを使ってfew-shotのプロンプトを修正します。

USER: 「A,B,C,D」がテーマの一文を生成してください。その言葉を使わなくても良く、類義語を用いたりそれを類推させるような単語を使っても良いです。
ASSISTANT: hogehoge
USER: 「A,B,C,D」がテーマの一文を生成してください。その言葉を使わなくても良く、類義語を用いたりそれを類推させるような単語を使っても良いです。
ASSISTANT: fugafuga
USER: 「A,B,C,D」がテーマの一文を生成してください。その言葉を使わなくても良く、類義語を用いたりそれを類推させるような単語を使っても良いです。
ASSISTANT: piyopiyo
USER: 「A,B,C,D」がテーマの一文を生成してください。その言葉を使わなくても良く、類義語を用いたりそれを類推させるような単語を使っても良いです。
ASSISTANT:彼氏が出来て毎日一緒に寝るの幸せ過ぎて死ねる
USER: 「A,B,C,D」がテーマの一文を生成してください。その言葉を使わなくても良く、類義語を用いたりそれを類推させるような単語を使っても良いです。
ASSISTANT:

ABCだけでなく、Dというテーマを増やし、shotを増やしました。これでまた回して先程の出力結果ファイルに追記していきます。これを続けることで、今まで全部手動だったデータセット作成がほぼ自動化されました。

データの修正

temperatureを上げた影響で変なデータが入っていることがあるので、きちんと削除したり、怪しい日本語を修正します。これはパパっと数百データくらいであれば自分がやっても良いですし、これを修正するプロンプトを組んでやらせるでも良いと思います。

おわりと宣伝

これであまり労力をかけずにデータセットを作ることができました!
以下のイベントでローカルLLMのデータセットの話等をしようと思うので、是非お暇な方は遊びに来てください。
https://connpass.com/event/300062/

Discussion