日本語LLMのファインチューニング入門 – 自作・Hugging Face公開データセット対応

日本語LLMのファインチューニング入門 - 自作・Hugging Face公開データセット対応

 

Table of Contents

【動画で解説】日本語LLMのファインチューニング入門
– Japanese LLM Fine Tuning Tutorial

 

 

【現代の魔法】日本語LLMのファインチューニング入門
– How to Fine Tunning LLM for Generative AI Beginners


視聴時間:38分3秒

文字情報だけではわかりにくい場合に、日本語大規模言語モデルのファインチューニングの解説動画をご活用いただけますと幸いです。

 




 

【動画の内容:日本語LLMのファインチューニング入門】

0:00 はじめに
0:49 Google Colaboratoryの使い方
1:49 【ステップ1】ファインチューニング前のLLMで推論 編
5:48 【ステップ2】ファインチューニング 編 – 事前準備
8:57 【事前準備】自作データセット編
15:38 【事前準備】Hugging Faceの日本語データセット編
20:30 【事前準備】Google Driveのマウント
21:30 ファインチューニングのパラメータの指定と反映
26:21 ファインチューニングの実行
33:57 ファインチューニングしたLLMで推論・日本語化
37:04 おわりに

 

【更新情報:2024年1月30日】

チュートリアル動画作成に当たって、

・データセットのテンプレートがダウンロードできない
・Hugging Faceの公開データセット対応版のノートブックでエラーとなる

事象を確認しました。
2024年1月30日22時の時点で上記問題を修正しておきました。
Hugging Faceの公開データセット対応版のノートブックをすでにダウンロードされている方は、2024年1月30日最終更新版以降のノートブックをダウンロードしてください。

 

 

H2O LLM Studio編:LLMのファインチューニング入門

 

 

大規模言語モデル(LLM:Large Language Model)のファインチューニング(再学習・微調整)に関する情報を調べていく中で

h2oai/h2o-llmstudio(Apache-2.0 license)| GitHub

Documentation – What is H2O LLM Studio? | H2O.AI
(解説書:H2O LLM Studioとは?)

という、初学者向けの良さそうなプログラムがあると思い、Google Colaboratoryのチュートリアルのコードを実行してみましたが、2024年1月実行時点では、うまく使えない状態でした…

しばらくの間、試行錯誤を繰り返した結果

・自作のデータセット
・Hugging Faceの公開データセット

を使って、ファインチューニングさせることができましたので、日本語のLLMをファインチューニングするためのチュートリアルコードを作成しました。
Google Colaboratoryの無料枠だけでは、思い通りの結果が得られにくいのではないかと思われますが、一連のチュートリアルの情報が、オリジナルの対話型AIを開発したい日本人のAI初学者の方が、ChatGPTをはじめとした会話形式(チャットボット形式)のファインチューニングを試み、LLMの学習を始めるきっかけになることがありましたら幸いです。

【追記:2024年1月27日時点】

Google Colaboratoryの無料枠でも、LLMのファインチューニングによる変化を楽しめそうでした。

 

 

チュートリアルコードリンク・プログラムのライセンス

 

 

オリジナルデータセット対応のGoogle Colaboratoryのチュートリアルコード:
My-Dataset-LLM-FineTuning-for-Japanese-AI-Beginners.ipynb(Apache-2.0 license)| Google Colaboratory

Hugging Faceの公開データセット対応のGoogle Colaboratoryのチュートリアルコード:
HF-Dataset-LLM-FineTuning-for-Japanese-AI-Beginners.ipynb(Apache-2.0 license)| Google Colaboratory

 

チュートリアルコード「My-Dataset-LLM-FineTuning-for-Japanese-AI-Beginners.ipynb」「HF-Dataset-LLM-FineTuning-for-Japanese-AI-Beginners.ipynb」のライセンス:

Apache-2.0 license

©︎ 2024 child programmer

 

 

チュートリアルで使う自作用データセットのテンプレートをダウンロード

 

 

オリジナルデータセット対応版のチュートリアルコードを使う方用です。
データセットのテンプレートをエクセル(Windowsの方)やNumbers(Macの方)で編集後に、

・dataset
(dataset.csv)

という名前のCSV形式ファイルで書き出してください。


*2024年1月30日にファイルをダウンロードできるように修正しておきました。
*ダウンロードされる圧縮ファイルを解凍するとCSV形式ファイルが編集できるようになります。

 

チュートリアルで利用しているサンプルデータセットも公開しています。
ご自身のオリジナルデータセットで学習前に、必要に応じて練習用としてご活用いただけますと幸いです。
ダウンロード時点のファイル名は

・sample_dataset
(sample_dataset.csv)

になっていますが、利用する際には

・dataset
(dataset.csv)

という名前に変更してご利用ください。


*2024年1月30日にファイルをダウンロードできるように修正しておきました。
*ダウンロードされる圧縮ファイルを解凍するとCSV形式ファイルが編集できるようになります。

 

 

【H2O LLM Studio編】
日本語LLMのファインチューニング – 最終更新:2024年2月16日

 

 

日本語LLMのファインチューニングに挑戦してみましょう!

 

 

【ステップ1】ファインチューニング前のLLMで推論 編

 

 

後で回答を変化を確認しやすいように、ファインチューニング前のLLMで推論してみましょう。
チュートリアル作成にあたって、LLMの

・「基盤モデル」
(次の単語を予測する学習がされたモデル)

でファインチューニングを試みたところ、Google Colaboratoryの無料枠では変化がわからなかったので、このチュートリアルでは

・「指示チューニング」
(LLMの基盤モデルに質問と回答を学習させた事前学習済みモデル)

されている

line-corporation/japanese-large-lm-1.7b-instruction-sft(Apache-2.0 license)| Hugging Face
注:使用するLLMによって、実行コードを微調整する必要があります。
コードの書き方は、Hugging Face内のそれぞれのLLMのページでご確認ください。

を活用して、ファインチューニング前後の変化を比較していきます。

比較用のチュートリアルコード:
line-corporation/japanese-large-lm-1.7b-instruction-sft-for-Japanese-AI-Beginners.ipynb(Apache-2.0 license)| Goolge Colaboratory

 

実行コード①(事前準備:各種インストール・LLMのダウンロードなど)

!pip install transformers sentencepiece accelerate bitsandbytes
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline

# @markdown 以下の欄に、LLMモデル(Hugging Faceに公開されているLLM)を指定し、コードを実行します。
model = "line-corporation/japanese-large-lm-1.7b-instruction-sft" # @param {type:"string"}
tokenizer = AutoTokenizer.from_pretrained(model, use_fast=False)
generator = pipeline("text-generation", model=model, tokenizer=tokenizer, device=0)

 

出力結果

/usr/local/lib/python3.10/dist-packages/huggingface_hub/utils/_token.py:88: UserWarning: 
The secret `HF_TOKEN` does not exist in your Colab secrets.
To authenticate with the Hugging Face Hub, create a token in your settings tab (〜), set it as secret in your Google Colab and restart your session.
You will be able to reuse this secret in all of your notebooks.
Please note that authentication is recommended but still optional to access public models or datasets.
  warnings.warn(
You are using the default legacy behaviour of the . This is expected, and simply means that the `legacy` (previous) behavior will be used so nothing changes for you. If you want to use the new behaviour, set `legacy=False`. This should only be set if you understand what it means, and thouroughly read the reason why this was added as explained in 〜

 

実行コード②(LLMで推論)

出力結果例

[{'generated_text': '【質問】 YouTubeのRehabCチャンネルについて教えてください。
【AIの回答】申し訳ありませんが、私はあなたの質問がわかりません。あなたが私に説明してほしい質問はありますか?'}]

*「input_prompt:YouTubeのRehabC – デジタルで、遊ぶ。チャンネルについて教えてください。」の一例

 

【Hugging Faceで現在公開されている日本語LLMをチェック】

キーワード「japanese」(トレンド順)- Models | Hugging Face

 

 

【ステップ2】LLMのファインチューニング 編

 

 

それでは、ファインチューニングを始めてみましょう。
チュートリアルでは、LLMに特定の知識(今回は、特定のYouTubeチャンネル)

RehabC – デジタルで、遊ぶ。(YouTube)

を教えてあげます。

 

 

【事前準備①:H2O LLMのリポジトリのクローンなど】

 

 

実行コード

!git clone https://github.com/h2oai/h2o-llmstudio.git
!cd h2o-llmstudio && git checkout ce10af57ff118a2bbb81b5b3eae12273e290299a -q
!cp -r h2o-llmstudio/. ./
!rm -r h2o-llmstudio
!mkdir dataset

 

出力結果

Cloning into 'h2o-llmstudio'...
remote: Enumerating objects: 4882, done.
remote: Counting objects: 100% (1854/1854), done.
remote: Compressing objects: 100% (619/619), done.
remote: Total 4882 (delta 1524), reused 1374 (delta 1232), pack-reused 3028
Receiving objects: 100% (4882/4882), 20.66 MiB | 23.72 MiB/s, done.
Resolving deltas: 100% (3311/3311), done.

 

 

【事前準備②:仮想環境の構築】

 

 

実行すると、以下の表示

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

WARNING: Running pip as the ‘root’ user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
WARNING: Running pip as the ‘root’ user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
WARNING: Running pip as the ‘root’ user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv

が出ますがそのままの状態で使えるようでした。

(プログラムが完了するまでに「4分」ほど時間がかかります)

 

実行コード

# 実行時点:Python 3.10.12を利用
!sudo add-apt-repository ppa:deadsnakes/ppa -y > /dev/null
!sudo apt install python3.10.12 python3.10.12-distutils psmisc -y > /dev/null
!curl -sS https://bootstrap.pypa.io/get-pip.py | python3.10.12 > /dev/null

# 各種依存関係のインストール
!make setup > /dev/null

 

出力結果

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

E: Unable to locate package python3.10.12
E: Couldn't find any package by glob 'python3.10.12'
E: Unable to locate package python3.10.12-distutils
E: Couldn't find any package by glob 'python3.10.12-distutils'
/bin/bash: line 1: python3.10.12: command not found
curl: (23) Failure writing output to destination
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: 〜
Creating a virtualenv for this project...
Pipfile: /content/Pipfile
Using /usr/local/bin/python (3.10.12) to create virtualenv...
⠴ Creating virtual environment...created virtual environment CPython3.10.12.final.0-64 in 1028ms
  creator Venv(dest=/root/.local/share/virtualenvs/content-cQIIIOO2, clear=False, no_vcs_ignore=False, global=False, describe=CPython3Posix)
  seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=/root/.local/share/virtualenv)
    added seed packages: pip==23.3.1, setuptools==69.0.2, wheel==0.42.0
  activators BashActivator,CShellActivator,FishActivator,NushellActivator,PowerShellActivator,PythonActivator

✔ Successfully created virtual environment! 
Virtualenv location: /root/.local/share/virtualenvs/content-cQIIIOO2

EPRECATION: h2o-wave nightly has a non-standard version number. pip 24.0 will enforce this behaviour change. A possible replacement is to upgrade to a newer version of h2o-wave or contact the author to suggest that they release a version with a conforming version number. Discussion can be found at 〜

 

 

【事前準備③:cudaバージョンの指定(11.8)】

 

 

cudaのバージョン(2024年1月実行時点の例:12.2)によってファインチューニングの際にエラーとなるので、cudaのバージョンを11.8にダウングレード。

(プログラムが完了するまでに「4分」ほど時間がかかります)

実行コード

# cuda11.8のインストール
!apt-get update
!apt-get install cuda-toolkit-11-8

# cuda11.8を利用する(パスの設定)
import os
# os.environ["LD_LIBRARY_PATH"] += ":" + "/usr/local/cuda-11/lib64"
# os.environ["LD_LIBRARY_PATH"] += ":" + "/usr/local/cuda-11.8/lib64"
p = os.getenv('PATH')
ld = os.getenv('LD_LIBRARY_PATH')
os.environ['PATH'] = f"/usr/local/cuda-11/bin:{p}"
os.environ['LD_LIBRARY_PATH'] = f"/usr/local/cuda-11.8/lib64:{ld}"

print('\n実行時点で選択できるcudaのバージョン:')
!ls -d /usr/local/cuda-*
!which nvcc
print('\n現在使われているcudaのバージョン:')
!nvcc --version
print('\n現在使われているPyTorchのバージョン:')
!python -c 'import torch; print(torch.__version__) '

 

出力結果

〜
実行時点で選択できるcudaのバージョン:
/usr/local/cuda-11  /usr/local/cuda-11.8  /usr/local/cuda-12  /usr/local/cuda-12.2
/usr/local/cuda-11/bin/nvcc

現在使われているcudaのバージョン:
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2022 NVIDIA Corporation
Built on Wed_Sep_21_10:33:58_PDT_2022
Cuda compilation tools, release 11.8, V11.8.89
Build cuda_11.8.r11.8/compiler.31833905_0

現在使われているPyTorchのバージョン:
2.1.0+cu121

 

 

【事前準備④-A:データセットの準備】自作データセット編

 

 

自作データセットを使う方は、こちらのコードを実行します。
自分で用意したオリジナルデータセットで学習してみましょう。
CSV形式ファイルを「dataset」フォルダ内にアップロード後に、以下の「実行コード」を実行します。
チュートリアルでは、同じ質問と回答を11個(学習用10データ・検証用1データ)並べたデータセットを使って、新たな特定の知識を学習させてみます。

【データセットの文章例】

instruction:
YouTubeのRehabC – デジタルで、遊ぶ。チャンネルについて教えてください。

output:
RehabCチャンネルは、2014年に開設されたデジタルテクノロジー教育系チャンネルです。

*試した範囲の情報では、1つの知識を教えるのに、様々なバリエーションに富んだ質問方式にして、同じ回答のデータセットを作成した場合には、より多くの学習をしないと精度が向上しないようでした。

 

【参考情報】

推奨されるデータセットの量:1000~50000
Documentation – FAQs:How much data is generally required to fine-tune a model? | H2O.AI
(大規模言語モデルをファインチューニングするには一般的にどのくらいのデータ量が必要ですか?)

 

実行コード

# 各種インストールなど
import numpy as np
import pandas as pd
pd.options.mode.chained_assignment = None

# データセットの指定
# @markdown  データセットのファイルのパス(CSV形式のデータセット)を指定します。
dataset_file = '/content/dataset/dataset.csv' # @param {type:"string"}
ds = pd.read_csv(dataset_file, header=None)

# 「instruction」と「output」を区別するための表記の一行目を削除
ds.drop(0, axis=0, inplace=True)

# 1列目・2列目をトレーニング用に指定
train = ds[[0, 1]]

# 1列目を「「instruction」(指示)・2列目を「output」(出力)という名前に指定
train.columns = ['instruction', 'output']

# データフレームの変換
train = pd.DataFrame(train)

# 前処理をしたデータセットをCSVファイルとして出力
pd.concat([train]).reset_index(drop=True).to_csv("dataset/converted_dataset.csv", index=False)

 

 

【事前準備④-B:データセットの準備】既存のデータセットの活用編

 

 

Hugging Faceに公開してくださっているデータセットを使う方は、こちらのコードを実行します。
既存のHugging Faceの日本語データセットを利用してみましょう。
必要に応じてデータセットの規模を調整してください。

【参考情報】

推奨されるデータセットの量:1000~50000
Documentation – FAQs:How much data is generally required to fine-tune a model? | H2O.AI
(大規模言語モデルをファインチューニングするには一般的にどのくらいのデータ量が必要ですか?)

【データセット例】

kunishou/hh-rlhf-eval-3k-ja(The MIT Licence)| Hugging Face
データセットの量:3,000
* 本来は検証用として作成されているデータセットですが、チュートリアルでは、学習用として使っています

izumi-lab/llm-japanese-dataset(CC BY-SA 4.0)| Hugging Face
データセットの量:9,074,340(version 1.0.3)

【Hugging Faceで現在公開されている日本語データセットをチェック】

キーワード「japanese」(トレンド順)- Datasets | Hugging Face

 

実行コード

# 「dataset」フォルダの作成
!mkdir dataset
# 各種インストールなど
!pip install datasets
import numpy as np
import pandas as pd
pd.options.mode.chained_assignment = None
from datasets import load_dataset

# データセットのダウンロード
# @markdown データセットのファイルのパス(Hugging Faceに公開されているデータセット)を指定します。
# @markdown 必要に応じて、コードを改変してPandasでデータの前処理をしてください。
# @markdown 最終的に左から「instruction」「output」の列になるようにデータを処理してください。
dataset_path = "kunishou/hh-rlhf-eval-3k-ja" # @param {type:"string"}
ds = load_dataset(dataset_path)
ds.set_format(type="pandas")

# Hugging FaceのDataset Vieweで「Split名」を確認し名前を入力します
# 「kunishou/hh-rlhf-eval-3k-ja」の場合には「"test"」
ds = ds["test"][:]
train = ds

# データセットの不必要な列を削除します
# 「kunishou/hh-rlhf-eval-3k-ja」の場合には 「input」と「index」の列を削除
train.drop(["input","index"], axis=1, inplace=True)

# 列の並び替え:左から「instruction」「output」に変更
train = train.loc [:, ["instruction", "output"]]

# データフレームの変換
train = pd.DataFrame(train)

# 前処理をしたデータセットをCSVファイルとして出力
pd.concat([train]).reset_index(drop=True).to_csv("dataset/converted_dataset.csv", index=False)

 

出力結果

〜
The secret `HF_TOKEN` does not exist in your Colab secrets.
To authenticate with the Hugging Face Hub, create a token in your settings tab (https://huggingface.co/settings/tokens), set it as secret in your Google Colab and restart your session.
You will be able to reuse this secret in all of your notebooks.
Please note that authentication is recommended but still optional to access public models or datasets.
  warnings.warn(

Downloading readme: 100% 1.32k/1.32k [00:00<00:00, 94.9kB/s]
Downloading data: 100% 2.38M/2.38M [00:00<00:00, 5.72MB/s]
Generating test split: 3000/0 [00:00<00:00, 29300.34 examples/s]

 

 

【事前準備⑤:Google Driveのマウント】

 

 

Google Drive 上のフォルダ・ファイルを使えるようにします。

以下のコードを実行後に、許可を求められるのでGoogle DriveのGoogleアカウントで「許可」をします。

 

実行コード

from google.colab import drive
drive.mount('/content/drive')

 

出力結果

Mounted at /content/drive

 

 

【事前準備⑥:ファインチューニングのパラメータの指定】

 

 

メモリの効率化・最適化手法として

・量子化(backbone_dtype = "float16")
・勾配チェックポインティング(gradient_checkpointing = False)
・勾配累積(grad_accumulation = 1)
・LoRAチューニング(lora = True)
・自動混合精度演算(mixed_precision = True)
*()内は現在の設定。必要に応じて調整してみてください

を活用することができます。
コード内には、分かる範囲ではありますが各パラメータなどの説明を記載しておきましたので必要に応じて「コードの表示」をさせて、設定を微調整してみてください。

 

【追記:2024年2月5日】

ファインチューニングの設定の利便性を考え、パラメータの情報を見やすいようにまとめておきました。
チュートリアルコードでパラメータの情報を把握しにくい場合などにご活用ください。
【詳解】日本語LLMのファインチューニングのパラメータ設定方法

 

⑤学習の設定」の「epochs」で学習回数を指定(半角英数)してください。
epochs = 1」は、学習回数1回という意味です。
* 自作データセット版のチュートリアルでは「epochs = 50」で実行していきます。
 

【参考情報】

Documentation - Experiment settings | H2O.AI
(設定について)

【Hugging Faceで現在公開されている日本語LLMをチェック】

キーワード「japanese」(トレンド順)- Models | Hugging Face
補足説明:
モデル名で散見する「b」というのはモデルのパラメータ(重み)が「billion:10億」という意味です。
*1.4B:14億パラメータ
*1.7B:17億パラメータ
*3.6B:36億パラメータ
*7B:70億パラメータ
*13B:130億パラメータ
*70B:700億パラメータ
2024年1月29日時点までの検証では、Google Colaboratoryの無料枠のT4 GPUでは

- T4 GPUで確認済み -
・1.7B
・3.6B
* backbone_dtype = "float16"の場合

までのLLMでファインチューニングできることは確認済みです。
今後徐々に他のパラメータなどもチェックして、上記の所に追記していきます。
ファインチューニングは、

・パラメータ数が増えるほどGPUのメモリを消費する
*他にも、一例として「データセット」の規模が大きくなると、よりGPUのメモリを消費します

ため、試してダメな場合には、パラメータ数の小さいものを選び直してみてください。
その他にも、パラメータ数が増えると

・Google ColaboratoryへのLLMのダウンロード
・Google Driveにファインチューニング後の学習モデル(pthファイル)の出力

などで、Google Colaboratoryのディスク容量やGoogle Driveの容量の問題に遭遇するかと思います。
そのため、より大きなLLMを使いたい方は、必要に応じてGoogleに課金する必要はありそうです。

 

以下の内容を半角英数で入力後に、実行コードを実行します。

 

実行コード(自作データセット編のコード)
注:Hugging Faceの公開データセット編のコードでは「output_directory: str = "/content/drive/MyDrive/LLM/output/MyFineTuningLLMdemo/"」が「output_directory: str = "/content/drive/MyDrive/LLM/output/HFDFineTuningLLMdemo/"」になっています

%%writefile cfg_notebook.py

import os
from dataclasses import dataclass

from llm_studio.python_configs.text_causal_language_modeling_config import ConfigProblemBase, ConfigNLPCausalLMDataset, \
    ConfigNLPCausalLMTokenizer, ConfigNLPAugmentation, ConfigNLPCausalLMArchitecture, ConfigNLPCausalLMTraining, \
    ConfigNLPCausalLMPrediction, ConfigNLPCausalLMEnvironment, ConfigNLPCausalLMLogging

# ファインチューニングで使うデータセットが入っているフォルダのパスを指定
# @markdown データセットのファイルが入っているフォルダのパスを指定します。
ROOT_DIR = "./dataset/" # @param {type:"string"}

@dataclass
class Config(ConfigProblemBase):
    # ファインチューニングした学習済みモデルの出力先のパスを指定
    # @markdown ファインチューニングした学習済みモデルの出力先のパスを指定します。
    output_directory: str = "/content/drive/MyDrive/LLM/output/MyFineTuningLLMdemo/" # @param {type:"string"}
    # @markdown 今回のファインチューニング名を指定します。
    experiment_name: str = "MyFineTuningExperimentDemo"  # @param {type:"string"}
    # 今回、ファインチューニングをするLLMモデルを指定
    # @markdown ファインチューニングをするLLMモデル(Hugging Faceに公開されているLLM)を指定します。
    llm_backbone: str = "line-corporation/japanese-large-lm-1.7b-instruction-sft" # @param {type:"string"}


    # ①データセットの設定
    dataset: ConfigNLPCausalLMDataset = ConfigNLPCausalLMDataset(
        # ファインチューニングで使うデータセットのファイル名を指定
        train_dataframe=os.path.join(ROOT_DIR, "converted_dataset.csv"),
        # データセットから自動で訓練(train)用と検証用データを分割する
        validation_strategy = "automatic",
        validation_dataframe = "",
        # 検証用データのサイズを指定(0より大きく1.0未満):「automatic」の場合「train」用データから指定した割合で分割される
        validation_size = 0.01,

        # データセット内のプロンプト(入力内容)の列名「instruction」
        prompt_column = ("instruction",),
        # データセット内の回答の列名「output」
        answer_column = "output",
        # 各プロンプトの先頭に追加する文章
        text_prompt_start = "",
        # 各プロンプト/各回答の先頭に追加する文章
        text_answer_separator = "",

        # 会話形式(チャットボット形式)の場合には「True」
        add_eos_token_to_prompt = True,
        # 会話形式(チャットボット形式)の場合には「True」
        add_eos_token_to_answer = True,
        # プロンプトのラベルをマスク:学習中にプロンプトのラベルをマスクし、答えの損失のみを学習するかどうか
        mask_prompt_labels = False,

    )

    # ②トークナイザーの設定
    tokenizer: ConfigNLPCausalLMTokenizer = ConfigNLPCausalLMTokenizer(
        # プロンプト(instruction)の最大のトークン列(系列長)の指定:トークン列を揃えるための設定
        max_length_prompt = 128,
        # 回答(output)の最大のトークン列(系列長)の指定:トークン列を揃えるための設定
        max_length_answer = 128,
        # 「max_length」を指定すると、指定した長さに足りない場合には特定の値(おそらく「padding_quantile」の値)で補完
        max_length = 256,
        # パディングの分位数:プロンプトや回答のトークン列が「max_length」より足りない場合に指定した値で補完
        padding_quantile = 1.0
    )

    # ③オーグメンテーション(拡張)の設定
    # 「token_mask_probability = 0.0」で、おそらくトークンをマスクする割合を「0」に設定
    augmentation: ConfigNLPAugmentation = ConfigNLPAugmentation(token_mask_probability = 0.0)

    # ④アーキテクチャ(構造)の設定
    architecture: ConfigNLPCausalLMArchitecture = ConfigNLPCausalLMArchitecture(
        # LLMバックボーンのndarrayの要素のデータ型の指定:ビット数。「float16:半精度浮動小数点数16ビット」
        # 「backbone_dtype="float16"」で大規模言語モデルの重み(パラメータ)を16ビット精度 (FP16・BF16) でロード「float16 量子化」
        # LLMの学習モデルの重みは「float32:半精度浮動小数点数32ビット」で表しているので、「float16 量子化」で1/2の軽量化
        # 今回のノートブックでは「float32」「float16」「bfloat16」(brain float 16)に対応。
        # 数値が小さい場合には軽量化され、数値が大きい場合には高精度
        backbone_dtype = "float16",
        # メモリの最適化 - 勾配チェックポインティング:「batch_size=1」でもGPUメモリがオーバーしてしまう時に、メモリを最適化する方法。ただし、処理速度が低下
        # 使用する場合には「gradient_checkpointing = True」に設定。ただし、実験的な仕様のため、他の設定と互換性のない場合があるようです
        gradient_checkpointing = False,
        # 学習中に入力のEmbedding(エンベディング:埋め込み表現)に対する勾配の計算を強制するかどうか。LoRAに有用。
        # 使用する場合には「force_embedding_gradients = True」に設定
        force_embedding_gradients = False,
        # ドロップアウト率の指定:学習モデルの中間層に対してのドロップアウト率
        intermediate_dropout = 0
    )

    # ⑤学習の設定
    training: ConfigNLPCausalLMTraining = ConfigNLPCausalLMTraining(
        # 損失関数(「正解値」と「予測値」のズレの大きさを示す値)に交差エントロピー誤差を利用
        loss_function = "CrossEntropy",
        # 最適化アルゴリズムにAdamWを利用:「勾配のスケーリング処理」と「重み減衰」の2つの処理を分離した形式
        # その他に「Adadelta」「Adam」「AdamW8bit」「RMSprop」「SGD」を指定できる
        optimizer = "AdamW",
        # 学習率:学習の際に重みを更新する際に使用する割合。過学習(過剰適合・オーバーフィッティング)と学習不足(未学習・アンダーフィット)のバランスをとるための設定
        learning_rate = 0.00015,

        # ファインチューニングの「バッチサイズ」を指定
        batch_size = 4,
        # バッチ数の仲間外れを除去するかどうかを指定
        drop_last_batch = True,


        # ファインチューニングの学習回数を指定
        # @markdown その他に「⑤学習の設定」の「epochs」で学習回数を指定(半角英数)してください。
        # @markdown 「epochs = 1」は、学習回数1回という意味です。初期設定は「epochs = 50」にしています。
        epochs = 50,


        # 学習率のスケジュールの定義:「schedule="Cosine"」でコサイン関数の値に従う学習率を適用
        # その他に「Constant」(一定の学習率を適用)「Linear」(線形の学習率を適用)
        schedule = "Cosine",
        # 学習率をウォームアップするエポック数を指定:「warmup_epochs=0.0」で0から増加
        warmup_epochs = 0.0,
        # 重み減衰の指定:値を0以外(例:0.0001)にすると、L2正規化が働き過学習の抑制効果
        weight_decay = 0.0,
        # 勾配クリッピング - 勾配の最大ノルムを指定:勾配が設定した閾値以上となった際に、勾配の値を閾値にクリッピングする
        # デフォルトは「0」で、勾配クリッピングなし。0より大きな値が指定された場合、モデル学習中に勾配をクリッピングを適用する
        gradient_clip = 0.0,
        # メモリの最適化 - 勾配累積:バッチ全体の勾配を一度に計算せずに、小さなバッチサイズで計算したものを集約しでバッチサイズを増やす
        grad_accumulation = 1,

        # LoRA(Low Rank Adaptation)の設定 - 少ない学習パラメータで調整(全ての重みではなく、近似した小規模の行列を調整)
        lora = True,
        # LoRA Rディメンション(次元)の指定:更新行列のランクを表すパラメータ。
        # 一般的にrが小さいと、より短時間で計算量が少なくなる。大きいほど、更新行列は元の重みに近くなるが計算量が増える
        # ここの値を大きくするとファインチューニングを行うパラメータの割合を増やすことができます
        # 以下「line-corporation/japanese-large-lm-1.7b-instruction-sft」の際のlora_rの値と利用割合
        # 例:lora_r = 4(0.05%)・lora_r = 8(0.1%)・lora_r = 16(0.2%)
        lora_r = 4,
        # LoRAアルファの指定:LoRAのスケーリングに使用されるパラメータ。更新行列の大きさを制限し、LoRAの過学習などを抑制
        lora_alpha = 16,
        # LoRAのドロップアウト率の指定:更新行列の一部を無効化し、LoRAの過学習などを抑制
        lora_dropout = 0.05,
        # LoRAの低ランク行列近似を適用するモデル内のモジュール:デフォルトは線形層
        lora_target_modules = "",

        # ファインチューニング中に一番良い結果が出た学習モデルを保存したい場合には「save_best_checkpoint = True」にします
        save_best_checkpoint = False,
        # 評価エポック数:「save_best_checkpoint = False」の時に適用。検証データに対してモデル評価を実行する頻度(エポック数)を決定。数値を増やすと高速化
        evaluation_epochs = 1.0,
        # 学習前の評価:「evaluate_before_training = True」で、ファインチューニング前にモデルを評価することができ、微調整を行う前にLLMバックボーンの品質を判断するのに役立つ
        evaluate_before_training = False,
    )

    # ⑥予測(推論)の設定
    prediction: ConfigNLPCausalLMPrediction = ConfigNLPCausalLMPrediction(
        # モデルのパフォーマンスを評価するためのメトリックを指定:その他に「Perplexity」「OpenAI API」などもあり
        metric = "BLEU",

        # 推論の最小の長さを指定:生成されるトークンの最小の長さを指定
        min_length_inference = 2,
        # 推論の最大の長さを指定:生成されるトークンの最大の長さを指定
        max_length_inference = 256,
        # 推論のバッチサイズ:推論中のバッチサイズを指定
        batch_size_inference = 0,

        # サンプリングの設定:「do_sample = True」で有効化
        # 単語間の確率を、確率の高い・低いに従ってランダムにピックアップすることをサンプリングという
        # 予測されたシーケンス内の次のトークンが確率に基づいてサンプリング
        # 「do_sample = False」で」常に最も高い確率を選択
        do_sample = False,
        # ビーム探索の対象となる本数の指定:「num_beams = 1」でビーム探索無効化
        # 後に続く単語の同時確率を参考に文章を生成
        # 各ステップごとに確率の高いルートを保持し、計算量を低減
        # ビーム探索の値を大きくすると、精度が向上する可能性がある一方で、予測実行時間が長くなる可能性
        num_beams = 2,
        # 温度の指定:生成されるトークンのランダム性・多様性を制御するパラメータ
        # 「0〜1」の範囲で指定。
        # 多様性のある回答を希望する場合には数値を大きくする
        # 一貫した回答を希望する場合には数値を小さくする
        temperature = 0.3,
        # 繰り返しペナルティの指定:「repetition_penalty = 1.0」はペナルティなし
        # 繰り返しペナルティを大きくすると単語の繰り返しが回避される
        repetition_penalty = 1.2,
    )

    # ⑦環境設定
    environment: ConfigNLPCausalLMEnvironment = ConfigNLPCausalLMEnvironment(
        # メモリの最適化 - 混合精度の設定
        # 「mixed_precision = True」で自動混合精度演算(AMP:Automatic Mixed Precision)の有効化
        # 有効化で、メモリ消費低減・学習速度向上
        mixed_precision = True,
        # ワーカー数の指定:Data Loaderに使用するワーカー数を指定
        # モデル学習中にデータを読み込んでGPUにロードする際に使用するCPUプロセス数
        number_of_workers = 4,
        # ランダムシード値の指定:「seed = -1」で毎回乱数が生成される
        # 「seed = -1」以外の数値に設定すると毎回同じ結果が再現される
        seed = 1
    )

 

出力結果

Writing cfg_notebook.py

 

 

【事前準備⑦:「事前準備⑥」の内容をファイルに反映】

 

 

実行コード

%%writefile run.sh

pipenv run python train.py -C cfg_notebook.py &

wait
echo "all done"

 

出力結果

Writing run.sh

 

 

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

 

 

ここまでのステップを得て、ようやくファインチューニングを実行できます。

【ファインチューニング時間の参考例】
* backbone_dtype = "float16"の例

オリジナル版の英語のチュートリアル:
LLMモデル名:EleutherAI/pythia-1.4b-deduped」・「データセット:OpenAssistant/oasst1

1エポック17分ほど

ファインチューニングの一例:
LLMモデル名:line-corporation/japanese-large-lm-1.7b」・「データセット:kunishou/hh-rlhf-eval-3k-ja

1エポック約8分ほど
(学習時間:7分44秒 ・ システムメモリ:3.3〜3.4GB/12.7GB ・ GPUメモリ 7.6〜8.2/15GB)

LLMモデル名:line-corporation/japanese-large-lm-1.7b-instruction-sft」・「データセット:11

30エポック約8分ほど
(学習時間:8分 ・ システムメモリ:3.1GB/12.7GB ・ GPUメモリ 3.7GB/15GB)

LLMモデル名:line-corporation/japanese-large-lm-1.7b-instruction-sft」・「データセット:11

50エポック約5分ほど
(学習時間:5分16秒 ・ システムメモリ:2.8GB/12.7GB ・ GPUメモリ 4.4GB/15GB)
*注:学習時間などは変動があるようでした。train loss値が0に近づくと速く終わる印象です。

 

実行コード

!sh run.sh

 

出力結果

===================================BUG REPORT===================================
Welcome to bitsandbytes. For bug reports, please submit your error trace to: 〜
================================================================================
CUDA SETUP: CUDA runtime path found: /usr/local/cuda-11.8/lib64/libcudart.so
CUDA SETUP: Highest compute capability among GPUs detected: 7.5
CUDA SETUP: Detected CUDA version 118
CUDA SETUP: Loading binary /root/.local/share/virtualenvs/content-cQIIIOO2/lib/python3.10/site-packages/bitsandbytes/libbitsandbytes_cuda118.so...
2024-01-22 12:53:09,763 - INFO: Global random seed: 1
2024-01-22 12:53:09,764 - INFO: Preparing the data...
2024-01-22 12:53:09,764 - INFO: Setting up automatic validation split...
2024-01-22 12:53:09,858 - INFO: Preparing train and validation data
2024-01-22 12:53:09,858 - INFO: Loading train dataset...
Downloading tokenizer_config.json: 100% 360/360 [00:00<00:00, 291kB/s]
Downloading spiece.model: 100% 1.21M/1.21M [00:00<00:00, 7.89MB/s]

〜

024-01-22 12:54:44,777 - INFO: train loss: 5.24:   5%|4         | 37/742 [00:13<04:18,  2.73it/s]
2024-01-22 12:54:56,440 - INFO: train loss: 4.41:  10%|9         | 74/742 [00:25<03:44,  2.97it/s]
2024-01-22 12:55:07,940 - INFO: train loss: 4.25:  15%|#4        | 111/742 [00:36<03:24,  3.08it/s]
2024-01-22 12:55:20,318 - INFO: train loss: 4.25:  15%|#4        | 111/742 [00:49<03:24,  3.08it/s]
2024-01-22 12:55:20,969 - INFO: train loss: 4.08:  20%|#9        | 148/742 [00:49<03:19,  2.98it/s]
2024-01-22 12:55:31,307 - INFO: train loss: 4.08:  20%|#9        | 148/742 [01:00<03:19,  2.98it/s]
2024-01-22 12:55:33,763 - INFO: train loss: 3.87:  25%|##4       | 185/742 [01:02<03:08,  2.95it/s]

024-01-22 13:00:11,776 - INFO: validation progress:  88%|########7 | 7/8 [01:22<00:11, 11.71s/it]
2024-01-22 13:00:22,605 - INFO: validation progress: 100%|##########| 8/8 [01:33<00:00, 11.43s/it]
2024-01-22 13:00:22,633 - INFO: validation progress: 100%|##########| 8/8 [01:33<00:00, 11.65s/it]
2024-01-22 13:00:22,740 - INFO: Mean validation loss: 3.34308
2024-01-22 13:00:22,770 - INFO: Validation BLEU: 0.00000
2024-01-22 13:00:23,073 - INFO: Saving last model checkpoint: val_loss 3.3431, val_BLEU 0.0 to /content/drive/MyDrive/LLM/output/MyFineTuningLLMdemo/
all done

* 出力内容は一例です。最終的に「Saving last model checkpoint:val_loss 〜 ファインチューニングした学習モデルの出力先」「all done」(全て完了)が出力されれば成功です

*「train loss」(学習用データの損失関数)・「val_loss」(検証用データの損失関数)の値が「0」に近づくほど精度が良いという意味になります

* 試した範囲では、「ベースモデル」(基盤モデル:文章内の単語を予測することを学習した大規模言語モデル)をファインチューニングした感じでは、そう簡単には思い通りの結果とならないようでした...
動画のチュートリアル公開までに、少しずつ検証していきます...

→ その後に試した範囲の情報では、「指示チューニング」(Instruction Tuning)されたモデルでは、比較的簡単に新たな知識を学習できそうでした。

 

 

【日本語化】

 

 

ファインチューニングしたLLMで推論を実行」のプログラムを日本語化したい場合には、以下のコードを実行後に推論を実行して見てください

 

実行コード

!pip install textfile
import textfile

textfile.replace("prompt.py", "Please enter some prompt (type 'exit' to stop):", "このテキストの右側をクリックし何かプロンプトを入力後に「enter」キーを押してください(停止するには「exit」と入力してください):")
textfile.replace("prompt.py", "You can change inference parameters on the fly by typing --param value, such as --num_beams 4. You can also chain them such as --num_beams 4 --top_k 30", "パラメータは「 --num_beams 4」のように「 --param value」と入力することで変更できます。また、「 --num_beams 4」「--top_k 30」のように繋げることもできます。")
textfile.replace("prompt.py", "Error:", "エラー:")
textfile.replace("prompt.py", "Something went wrong, please try again.", "何か問題が発生しました。もう一度お試しください。")

 

出力結果

Collecting textfile
  Downloading textfile-0.1.5-py3-none-any.whl (3.7 kB)
Installing collected packages: textfile
Successfully installed textfile-0.1.5
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead:〜

 

 

ファインチューニングしたLLMで推論を実行

 

 

--e /content/〜/MyFineTuningLLMdemo」(自作データセット編の例)の所に、ファインチューニングした学習モデルが入っているフォルダへのパスを入力後に「実行コード」を実行します。

このテキストの右側をクリックし何かプロンプトを入力後に「enter」キーを押してください(停止するには「exit」と入力してください):」の文章の右側のスペース内に文章を入力後に「enter」キーを押すと推論が始まります。

文字変換中の「enter」キーにも反応するので、事前に文章を入力したものをコピー&ペースト後に「enter」キーを押すといいかもしれません。

実行コード

!pipenv run python prompt.py --e /content/drive/MyDrive/LLM/output/MyFineTuningLLMdemo

 

出力結果例①
train loss:0.16」 ・ 「validation loss:0.12973」 の例では、色々な質問のバリエーションでも適切な回答が得られる傾向がありました。

【質問内容】YouTubeのRehabC-デジタルで、遊ぶ。チャンネルについて教えてください。
【AIの回答】RehabCチャンネルは、2014年に開設されたデジタルテクノロジー教育系チャンネルです。
【質問内容】YouTubeのRehabC-デジタルで、遊ぶ。チャンネルとは?
【AIの回答】RehabCチャンネルは、2014年に開設されたデジタルテクノロジー教育系チャンネルです。
【質問内容】YouTubeのRehabCチャンネルとは?
【AIの回答】RehabCチャンネルは、2014年に開設されたデジタルテクノロジー教育系チャンネルです。
【質問内容】RehabCチャンネって何?
【AIの回答】RehabCチャンネルは、2014年に開設されたデジタルテクノロジー教育系チャンネルです。

注:「チャンネル」の「」が抜けていても回答は正当

【質問内容】RehabCチャンネルとは?
【AIの回答】RehabCチャンネルは、2014年に開設されたデジタルテクノロジー教育系チャンネルです。

出力結果例①:LLMのファインチューニング結果(成功例:validation loss:0.12973)
*画像をクリックすると拡大されます

1つの形式の質問と回答を学ばせただけで、様々な質問形式に対応できるようになるようでしたのでLLMは不思議ですね。

 

出力結果例②
一方、「train loss:1.19」 ・ 「validation loss: 0.91981」 の例では、質問のバリエーションを変えると誤回答が出る傾向がありました。

【質問内容】YouTubeのRehabC-デジタルで、遊ぶ。チャンネルについて教えてください。
【AIの回答】RehabCチャンネルは、2013年に開設されたデジタルテクノロジー教育系チャンネルです。2015年に法人化され、現在はデジタルテクノロジー教育系チャンネルとして、デジタルテクノロジー教育系チャンネル RehabC、....(ループ)

*注:正しくは2014年に開設。2015年に法人化されていません。

【質問内容】YouTubeのRehabCチャンネルについて教えてください。
【AIの回答】RehabCチャンネルは、2014年に開設されたデジタルテクノロジー教育系チャンネルです。
【質問内容】YouTubeのRehabCチャンネルとは?
【AIの回答】RehabCチャンネルは、2014年に開設されたデジタルテクノロジー教育系チャンネルです。

出力結果例②:LLMのファインチューニング結果(やや失敗例:validation loss:0.91981)
*画像をクリックすると拡大されます

何十回か、どのような回答を学ばせると正解が出やすいのか?試していましたが、どうも「2013年の開設」にしたいようでしたので苦戦しました。
train loss」 ・ 「validation loss」が「1前後では凡ミス」が出やすいようで、「0に近くなると様々な質問形式にも対応」する傾向があるようでした。

バッチサイズやLoRAのパラメータを調整しては学習結果を見ていましたが、最終的には「学習回数を増やす」というのが最適解のようでした。

 

 

【おわりに】日本語LLMのファインチューニング入門

 

 

実際に日本語LLMをファインチューニングしてみて分かったこととしては

ChatGPTのレベルに持っていくには、途方もない量の"大規模言語モデル(基盤モデル)"・"ファインチューニング用のデータセット"と、大量の"GPU"が長時間使われているのだろうな....

といったことでした。

まだまだ、個人で大規模言語モデルをファインチューニングして活用するには、クラウド上のGPUを長時間稼働させるための

・資金力

が必要そうです...

ただ、LLMをファインチューニングする一連の手順が分かることで、現在も未知の領域であるLLMの挙動を自分で検証できるので面白いですね。

あとは、将来的に資金力を得て、自分好みやのAIや、関わる業界に特化したAIを作成できる日を夢見て、コツコツと勉強していきたいと思います。

LLMのファインチューニングを試みて、上手くいかず、虚脱感を覚えた方もいるのではないかと思いますが、今後、技術が進展し、低スペックのパソコンでも気軽に効果的なファインチューニングが出来る日を...

一緒に待ちましょう・・・・
(待てない方は、Google Colaboratoryに課金して試行錯誤してみてください)

 

【追記:2024年1月27日】

チュートリアルコード公開直後は、上述のような、やや悲観的な内容で締めくくらせていただきましたが、その後、検証したところ

・「基盤モデル版のLLM」では、ファインチューニングの効果を気軽に確認することは難しいかもしれないが、「指示チューニング版のLLM」では、気軽に変化を確認できる!

ということがわかりました。
LLMのファインチューニングのチュートリアル動画を作成するにあたって

変化がわからないプログラムを動かしたところで、AI初学者の方は嬉しいだろうか...?

という考えが、頭の中をぐるぐると回っていたため、わずかな学習時間でも変化を確認できることがわかったので

これなら、現時点でもLLMのファインチューニングを自分で実行できる意義はあるかもしれない!

と思うようになりました。

Goolge Colaboratoryの無料枠でも十分にLLMの挙動を楽しめる時代に感謝ですね。
(Goolge Colaboratoryのチュートリアルコードは「2024年1月27日」更新以降のものをご活用ください)

 

 

日本語LLMのファインチューニングの解説動画へのコメントと対応例など
- 最終更新:2024年3月28日

 

 

【LLMのファインチューニング:全体】
Colabで作成した学習モデルをローカル環境で実行する方法までを解説してください

 

 

【2024年3月16日時点】

今回のコードのローカル環境の構築は、いくつかの要件(Pythonバージョンの指定・Cudaバージョンの指定など)があるのでややこしそうですね...
現在(2024年3月16日時点)、自分のパソコン環境(Mac:CPU Intel core i5・Memory 8GB)では、2〜4ビット量子化などをしていないLLMを動かすことは厳しそうですので、この動画で活用させていただいているフレームワーク

h2oai/h2o-llmstudio(Apache-2.0 license)| GitHub

でローカル環境で使う方法を(正確に)解説するのは難しそうです。
ただ、ご要望いただいた

・「モデルをCoab上で行い、学習したモデルをローカル環境で動作させる解説

に関してですが、今後、

unslothai/unsloth(Apache-2.0 license)| GitHub

のプログラムを活用させていただき

tokyotech-llm/Swallow-7b-instruct-hf | Hugging Face

をGoogle Colaboratoryの無料枠(無料枠では7bが限界ですが、課金すればさらに上のパラメータ数のものも使えるかと思います)で自作のカスタムデータセット(またはHugging Faceの公開データセット)を使いファインチューニング後に

・4ビット量子化(QLoRA)+GGUF化
*2〜8ビット量子化も選べます
*2ビット量子化も試しましたが、ファインチューニングで学習させた知識で正答するには4ビット量子化が無難そうでした
*ファインチューニング後に普通のLLMも出力(保存)できます

し、オフラインのローカル環境でCPU(またはGPU)でも使えるChatGPT代替アプリの

Jan:Open-source ChatGPT alternative(AGPLv3 License.)| Jan AI
*Mac(Intel CPU・M1/2/3)・Windows対応

で使う方法のチュートリアルを公開予定です。
*「elyza/ELYZA-japanese-Llama-2-7b-fast-instruct | Hugging Face
もファインチューニングしColab上では推論できましたが、GGUF化したモデルをアプリで有効化するとクラッシュするようでしたので、ELYZAに関しては、有志により公開済みの
mmnga/ELYZA-japanese-Llama-2-7b-fast-instruct-gguf | Hugging Face
を、そのまま使う方法を解説予定です。

現在「1ビットLLMのBitNet b1.58」関連の学習とチュートリアル作成を優先させていましたが、QLoRAのファインチューニングのチュートリアルの作成・公開を優先させますね。
既にコードは作成済みですが、公開までに、情報の整理などがありますので、しばらくお持ちいただけますと幸いです。

 

【追記:2024年3月17日】

チュートリアル記事・コードを公開しました。

チュートリアル記事:
【QLoRA編】日本語LLMのファインチューニング & 低スペックのローカル環境のアプリで動かす

チュートリアルコード:
QLoRA-LLM-FineTuning-for-Japanese-AI-Beginners.ipynb(Apache-2.0 license)| Google Colaboratory

必要に応じて、お時間のある際などにご活用いただけますと幸いです。
チュートリアル動画は、今後作成予定です。

 

【追記:2024年3月28日】

チュートリアル動画も公開しました。

チュートリアル動画:
【現代の魔法】QLoRA編:日本語LLMのファインチューニング & ローカル環境アプリで動かす方法 - Fine Tuning LLM & How to Use in Local App by RehabC - デジタルで、遊ぶ。(YouTube)

 

 

【LLMのファインチューニング:データセット作成編】
CSV形式ファイルに改行があってもいいですか?

 

 

現在公開させていただいているサンプルのデータセットを、テキストエディタで起動してCSVファイルの構造を確認してみると

dataset.csv
*****************************
instruction,output
この行に質問を入力します。,この行に質問への回答を入力します。
この行に質問を入力します。,この行に質問への回答を入力します。
この行に質問を入力します。,この行に質問への回答を入力します。
この行に質問を入力します。,この行に質問への回答を入力します。
・・・
必要に応じて行を追加します。,必要に応じて行を追加します。

*****************************

というテキストの構造になっています。
上記の構造(instruction・outputのセットを1行で入力)のことを「改行があっても」というニュアンスでお聞きくださったのであれば正しく動作するのではないかと思います。

ただ、以下のような

dataset.csv
*****************************
instruction,output
この行に質問を入力します。
,この行に質問への回答を入力します。
この行に質問を入力します。
,この行に質問への回答を入力します。
この行に質問を入力します。
,この行に質問への回答を入力します。
必要に応じて行を追加します。
,必要に応じて行を追加します。

*****************************

というテキスト構造にすると

・「この行に質問を入力します。」

の行の場合

・instructionが「この行に質問を入力します。」
・対応するoutputが「(空欄)」

になるので正しくファインチューニングできないと思われます。
また、

・「,この行に質問への回答を入力します。」

の行の場合

・instructionが「(空欄)」
・対応するoutputが「この行に質問への回答を入力します。」

になりますので、こちらもまた、正しくファインチューニングできないと思われます。
画像で表すと以下のような失敗したデータセットになります。

 

心配な場合には、作成したCSVファイルを

・エクセル(Windowsの場合)
・Numbers(Macの場合)

で普通(セル構造)に開いた際に、

・(サンプルのデータセットのように)列と行が積めた状態に表示され、一行内に「instruction・output」の記載が対応したセット

になっていれば大丈夫かと思われます。
画像で表すと以下のようなデータセットになります。

良い例:LLMファインチューニング用データセットCSV形式ファイル
*Numbersでの表示例(セル構造)

 

 

【LLMのファインチューニング:推論編】
Google Colaboratoryで推論するための最低構成のコードを教えてください。

 

 

【2024年2月14日時点】

Google Colaboratoryを使って、だだ推論するだけでしたら、以下のコード

・【事前準備①:H2O LLMのリポジトリのクローンなど】
・【事前準備②:仮想環境の構築】
・【事前準備③:cudaバージョンの指定(11.8)】
・【事前準備⑤:Google Driveのマウント】

* 注:Google Driveに使用するLLMをおいている場合
・【日本語化】
・ファインチューニングしたLLMで推論を実行

のコードを抜粋していただき、ご自身でノートブックを作っていただければ、ご自身でファインチューニングしたLLMを使った推論ができる最低構成のプログラムとなるかと思います。

 

 

【論文】LLM・ファインチューニングなど

 

 

LLMやファインチューニングを考える上で、参考となりそうな論文の情報をピックアップしておきます。
さらに知見を深めたい方は、お時間のある時に、論文をチェックしてみてください。

 

 

【論文】LLMに関する調査

 

 

【論文】

A Survey of Large Language Models - 2023年 | arxiv
(大規模言語モデルに関する調査:2023年)

現代のLLMの概略を把握してみましょう。

 

 

【論文】LLMの大前提である「Transformer」

 

 

【論文】

Attention Is All You Need:Google - 2017年初版・2023年改訂版 | arxiv
(必要なのはAttension機構[注意機構]だけ by Google:2017年〜2023年)

Attension機構の衝撃。
ここから始まった...

 

 

【論文】Transformerの性能を向上させる3つの要因
:言語モデルにおけるスケーリング則

 

 

【論文】

Scaling Lawas for Neural Language Models:OpenAI - 2020年 | arxiv
(ニューラル言語モデル[ニューラルネットワークの自然言語処理モデル]におけるスケーリング則 by OpenAI:2020年)

スケーリング則:
ある項目の変化に伴い、他の項目が「べき乗則」に従って変化する法則

Transformerの性能は

①パラメータ数
②データセットの規模
③計算量

を上げていくと予測精度が向上する可能性。

これらの条件を満たすには、やはり資金力がモノを言いますね...

 

 

【論文】フューショット学習:LLMの創発現象

 

 

【論文】

Language Models are Few-Shot Learners:OpenAI - 2020年 | arxiv
(言語モデルはフューショット学習者である by OpenAI:2020年)

フューショット学習:
わずかな学習データ(例文)を文脈内で見本として提示するだけで多様な課題に対応できる能力。

創発現象:
モデルの規模を拡大していくと、あるところから急に特定の課題ができるようになる現象。

LLMの不思議ですね...

 

 

【論文】LoRA:効率的なファインチューニング

 

 

【論文】

LoRA: Low-Rank Adaptation of Large Language Models:Microsoft他 - 2021年 | arxiv
(大規模言語モデルの低ランクアダプター by Microsoft他:2021年)

低ランク行列近似という手法で、LLMのパラメータを効率的に表現し、計算量とメモリ使用量を削減することで効率的なファインチューニングを実施。
LoRAに4ビットNormalFloat(NF4)の量子化を組み合わせた場合には「QLoRA」 (Quantized Low-Rank Adaptation) と呼ぶ。

 

 

by 子供プログラマー

 

 

次のステップ
【QLoRA編】日本語LLMのファインチューニング & 低スペックのローカル環境のアプリで動かす

気軽にチャットAIが始められるおすすめの拡張機能です。会員登録やログイン不要で使えるチャットAIもあります。
【使い方】ChatHub入門 – チャットAIをはじめよう