「自分だけの文章のクセを学習したAIアシスタントが欲しい!」
そんな思いから、大規模言語モデル(LLM)のファインチューニングに挑戦することにしました。しかし、私のローカルマシンではスペックが足りません。そこで白羽の矢を立てたのが、Google Colabです。
このブログ記事では、Google Colabを駆使して、3日間の試行錯誤を経て環境を整え、4日目に実際にLLMのファインチューニングを行い、映画ブログのレビューテキストを生成するまでのプロセスを、ステップバイステップでご紹介します。
目標は、私の映画ブログの文章スタイルを学習し、記事作成を手伝ってくれるAIアシスタントを作ることです!
3日間の奮闘:ファインチューニング基盤を築くまで
本格的なファインチューニングに入る前に、まずはその土台作りから始めました。
- 1日目 環境構築とモデルの読み込み
- 最初のステップは、ファインチューニングに必要なライブラリ(
transformers
,datasets
,torch
など)をGoogle Colab環境にインストールすることから。 - 次に、ベースとなる事前学習済みLLMモデルと、テキストをモデルが理解できる数値データに変換する「トークナイザー」を選び、Colabのメモリに読み込みました。ここで基本的な動作確認を行い、ファインチューニングの準備が整ったことを確認しました。
- 最初のステップは、ファインチューニングに必要なライブラリ(
- 2日目 効率化のための環境再構築
- Google Colabはセッションが切れると作業内容が消えてしまうことがあります。毎回モデルをダウンロードするのは時間がかかるため、1日目に読み込んだLLMモデルとトークナイザーをGoogle Driveに保存しました。
- そして、セッションが切れてもGoogle Driveから素早くモデルとトークナイザーを読み込めるように、環境の再構築プロセスを確立。これで、中断してもスムーズに作業を再開できるようになりました。
- 3日目 独自データセットの作成
- ファインチューニングの「教師データ」となる、私自身の文章データが必要です。今回は、過去に書いたWordPressの映画ブログ記事をデータソースに選びました。
- ブログ記事(123件)からテキストを抽出し、LLMが学習しやすい形式(特定の指示(プロンプト)とそれに対応する文章のペアなど)に加工。このデータセット作成作業は、Google Colab ProのGPU T4環境を使っても2時間13分かかりました。データ準備の重要性と大変さを実感した一日でした。
4日目:実践!ファインチューニングとテキスト生成
いよいよ、これまでの準備を活かしてファインチューニングを実行します。以下の7つのステップで進めました。
【ファインチューニング手順 詳細解説】
- 環境構築
- 内容 ファインチューニングに必要なライブラリ(特に
peft
やtrl
など、効率的な学習や訓練プロセスをサポートするライブラリ)を改めてColab環境にインストールします。依存関係も確認し、スムーズに実行できる状態を整えます。
- 内容 ファインチューニングに必要なライブラリ(特に
# Google Colabで実行してください
# ライブラリのインストール (毎回実行する必要がある場合があります)
!pip install -qU transformers datasets accelerate peft bitsandbytes trl sentencepiece
# 必要なライブラリのインポート
import os
import torch
from google.colab import drive, userdata
from datasets import load_dataset
from transformers import (
AutoTokenizer,
AutoModelForCausalLM,
BitsAndBytesConfig,
TrainingArguments,
pipeline,
logging,
)
from peft import LoraConfig, PeftModel, prepare_model_for_kbit_training, get_peft_model
from trl import SFTTrainer
# Google Driveのマウント
drive.mount('/content/drive')
print("環境構築完了。")
このコードは、AI(特に、文章を作るのが得意な大規模言語モデル、LLM)に私の独自の文章スタイルなどを追加学習させる「ファインチューニング」という作業を始めるための、最初の準備作業にあたります。家を建てる前の「土地の整備」や、料理を始める前の「調理器具や材料の準備」に似ています。
つまり、このステップ1のコードは、AI(LLM)のファインチューニングに必要な専門ツール一式を準備し、自分のデータ置き場と作業場所を接続して、本格的な作業を開始できる状態にするための重要な初期設定を行っています。
- データの準備
- 内容 3日目に作成し、Google Driveに保存しておいた独自のブログ記事データセットを読み込みます。データセットがLLMの学習に適した形式(入力テキストと出力テキストのペアなど)になっているか最終確認し、必要であれば微調整を加えます。
# --- 設定 ---
# データファイルのパス (修正後の正しいファイル名)
data_path = "/content/drive/MyDrive/wordpress_posts_映画_processed.jsonl"
# ----------------
# データセットのロード
try:
dataset = load_dataset("json", data_files=data_path, split="train")
print(f"データセットの読み込み完了。件数: {len(dataset)}")
# print("データサンプル:", dataset[0]) # データの確認
except Exception as e:
print(f"データセットの読み込みに失敗しました: {e}")
print(f"ファイルパス '{data_path}' が正しいか、ファイルが存在するか確認してください。")
# データセットがロードできない場合は以降の処理を中断
raise
# データフォーマット関数 (シンプルなテキスト継続学習用)
# Llama-3は特殊トークンを自動で付与する機能があるため、ここでは単純結合のみ行う
# SFTTrainerが内部で適切に処理してくれることを期待
def format_data(example):
# タイトルと本文を結合
formatted_text = f"タイトル: {example['title']}\n\n本文:\n{example['text']}"
return {"text": formatted_text} # SFTTrainerがデフォルトで参照する'text'列に入れる
# データセットに関数を適用し、不要な列を削除
dataset = dataset.map(format_data, remove_columns=['id', 'title', 'text', 'category', 'post_date'])
# (オプション) データ件数が少ないため分割は行わず、全て訓練データとして使用
train_dataset = dataset
# print("フォーマット後のデータサンプル:", train_dataset[0]) # フォーマット後の確認
print("データセットの前処理完了。")
このコードは、AIに私の文章のクセを学習させるための「お手本データ(=データセット)」を準備するステップです。今回は実際に学習に使う材料、つまり私が3日目に準備したブログ記事データをAIが読み込める形にし、学習しやすいように下ごしらえします。料理で言えば、野菜を切ったり、お肉に下味をつけたりする工程です。
このステップ2のコードは、Google Driveに保存しておいた私のブログ記事データをプログラムに読み込み、AIが学習しやすいように「タイトル」と「本文」を組み合わせるなどの整形(前処理)を行って、学習の準備を整える作業をしています。
- モデルとトークナイザーのロード(量子化)
- 内容 このステップでは、いよいよAIの学習(ファインチューニング)を行うために、主役となるAIの「脳」にあたる「モデル」と、そのモデルが人間の言葉を理解するための「翻訳機」にあたる「トークナイザー」を、作業場所(Google Colab)に読み込みます。これらは2日目の作業でGoogle Driveに保存しておいたものです。
- さらに今回は、「量子化」という技術を使って、AIモデルを少しコンパクトにしてメモリの消費を抑える工夫も行います。大きなAIモデルはたくさんのメモリ(コンピューターの作業スペース)を使うので、これはGoogle Colabのような環境では特に重要です。
# --- 設定 ---
# 保存したモデルとトークナイザーのパス
model_load_path = '/content/drive/MyDrive/llm_model'
# ----------------
# 量子化設定 (メモリ削減のため4bit量子化を使用)
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_use_double_quant=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.bfloat16 # T4 GPUではbf16は限定的サポートだが、利用を試みる
)
# モデルのロード
try:
model = AutoModelForCausalLM.from_pretrained(
model_load_path,
quantization_config=bnb_config,
device_map="auto", # 自動的にGPUに割り当て
trust_remote_code=True # モデルによっては必要
)
print("モデルのロード完了。")
except Exception as e:
print(f"モデルのロードに失敗しました: {e}")
print("メモリ不足の可能性があります。ランタイムのタイプを確認するか、バッチサイズ等を調整してください。")
raise
# トークナイザーのロード
try:
tokenizer = AutoTokenizer.from_pretrained(model_load_path)
# パディングトークンの設定 (Llama系ではEOSトークンを使うのが一般的)
if tokenizer.pad_token is None:
tokenizer.pad_token = tokenizer.eos_token
model.config.pad_token_id = model.config.eos_token_id
# Llama-3系は右パディングが推奨されることが多い
tokenizer.padding_side = 'right'
print("トークナイザーのロード完了。")
except Exception as e:
print(f"トークナイザーのロードに失敗しました: {e}")
raise
print("Google Driveから量子化モデルとトークナイザーをロードしました。")
このステップ3では、Google Driveに保存しておいたAIモデルとトークナイザーを、特にモデルについては「量子化」技術でメモリ消費を抑えつつ、作業場(Google Colab)に読み込みました。これで、AIに新しいことを学習させる(ファインチューニングする)ための準備がいよいよ整いつつあります。
- PEFT (LoRA) の設定
- 内容 ここが効率的なファインチューニングの鍵です。
- PEFTとは?
PEFT (Parameter-Efficient Fine-Tuning) は、LLMの全てのパラメータ(重み)を調整するのではなく、ごく一部のパラメータだけを効率的に学習させる技術群の総称です。 - LoRAとは?
LoRA (Low-Rank Adaptation) は、PEFTの中でも特に人気のある手法の一つです。元のLLMの重みは固定したまま、「アダプター」と呼ばれる小さな追加モジュールを導入し、このアダプター部分だけを学習させます。アダプターは「低ランク行列」という数学的な工夫を用いて設計されており、少ないパラメータ数で効率的にモデルの挙動を調整できます。 - LoRAの目的
- 大規模なモデルを、限られた計算資源(GPUメモリや時間)で特定のタスクやデータ(今回は私のブログ記事スタイル)に適応させること。
- LoRAのメリット
- 計算コスト削減
全パラメータを学習する場合に比べ、必要な計算量とメモリが劇的に少なく済みます。Colabのような環境に最適です。 - 高速学習
学習対象が少ないため、ファインチューニングにかかる時間が短縮されます。 - 元モデルの保持
ベースモデル自体は変更されないため、元のモデルが持つ汎用的な知識が失われる「破滅的忘却」のリスクを低減できます。 - アダプター管理の容易さ
学習結果であるLoRAアダプターは非常に小さなファイルサイズです。異なるタスク用に学習した複数のアダプターを簡単に切り替えて、一つのベースモデルを多目的に利用できます。
- 計算コスト削減
- このステップでは、どの層にLoRAアダプターを適用するか、アダプターのサイズ(ランク
r
)などを具体的に設定します。
- PEFTとは?
- 内容 ここが効率的なファインチューニングの鍵です。
# モデルをk-bitトレーニング用に準備
model = prepare_model_for_kbit_training(model)
# LoRA設定
lora_config = LoraConfig(
r=16, # LoRAランク (8, 16, 32, 64 など。大きいほど表現力は上がるが計算量も増える)
lora_alpha=32, # LoRAスケーリング係数 (rの2倍程度が一般的)
# target_modulesの指定はモデル構造に依存します。elyza/Llama-3-ELYZA-JP-8B の構造を確認し、
# 一般的なLlama系の設定を試します。['q_proj', 'k_proj', 'v_proj', 'o_proj'] だけでなく、
# フィードフォワード層 ['gate_proj', 'up_proj', 'down_proj'] も対象に含めると効果的な場合があります。
target_modules=[
"q_proj",
"k_proj",
"v_proj",
"o_proj",
"gate_proj",
"up_proj",
"down_proj",
# "lm_head", # 分類タスクなどでは含めることもあるが、生成では通常含めない
],
lora_dropout=0.05, # LoRA層のドロップアウト率
bias="none", # バイアス項は学習しない
task_type="CAUSAL_LM" # タスクタイプを指定
)
# PEFTモデルの作成
model = get_peft_model(model, lora_config)
print("PEFT (LoRA) 設定完了。")
model.print_trainable_parameters() # 学習対象のパラメータ数を確認
このステップ4では、LoRAという賢い学習手法を使って、AIモデル全体を大きく変更することなく、ごく一部の重要な部品(指定したモジュール)だけを効率的に学習させるための準備をしました。これにより、少ない計算資源で、短時間のうちにAIに特定の文章スタイルなどを学習させることが可能になります。
- ファインチューニングの実行
- これまでの準備の集大成です! このコードは、AIにブログ記事データを実際に学習させる(ファインチューニングする)ステップです。ステップ4で設定した「賢い学習方法(LoRA)」を使って、AIモデルに取り付けた「調整部品(LoRAアダプター)」をトレーニングしていきます。
- 内容
transformers
ライブラリのTrainer
クラスや、指示応答データセットの学習に特化したtrl
ライブラリのSFTTrainer
(Supervised Fine-tuning Trainer)などを用いて、学習プロセスを開始します。準備したデータセットとLoRAの設定に基づき、モデル(実際にはLoRAアダプター)が私の文章のクセを学習していきます。学習中は、損失(Loss)の値などを監視し、学習がうまく進んでいるかを確認します。
# --- 設定 ---
# (設定部分は変更なし)
adapter_save_path = '/content/drive/MyDrive/llm_adapter_movie_blog'
output_dir = adapter_save_path + "/training_output"
batch_size = 1
gradient_accumulation_steps = 8
num_train_epochs = 3
learning_rate = 2e-4
# max_seq_length = 1024 # コメントアウト中
logging_steps = 10
save_strategy="epoch"
# ----------------
# トレーニング引数の設定 (変更なし)
training_args = TrainingArguments(
output_dir=output_dir,
per_device_train_batch_size=batch_size,
gradient_accumulation_steps=gradient_accumulation_steps,
learning_rate=learning_rate,
num_train_epochs=num_train_epochs,
logging_dir=f"{output_dir}/logs",
logging_strategy="steps",
logging_steps=logging_steps,
save_strategy=save_strategy,
bf16=True,
gradient_checkpointing=True,
optim="paged_adamw_8bit",
lr_scheduler_type='cosine',
warmup_ratio=0.03,
report_to="none",
)
# --- ライブラリバージョン表示 (デバッグ用に残しても良い) ---
import trl
import transformers
print(f"使用中のtrlバージョン: {trl.__version__}")
print(f"使用中のtransformersバージョン: {transformers.__version__}")
# ------------------------------------
from trl import SFTTrainer
# SFTTrainer (Supervised Fine-tuning Trainer) の準備
print("\nSFTTrainerの初期化を試みます (processing_class を使用し、dataset_text_field, max_seq_length, packing を削除)...")
try:
trainer = SFTTrainer(
model=model,
processing_class=tokenizer, # 引数名を変更済み
train_dataset=train_dataset,
# dataset_text_field="text", # 削除済み
peft_config=lora_config,
args=training_args, # TrainingArguments を渡している
# max_seq_length=max_seq_length, # 削除済み
# packing=False, # この引数を削除!
# formatting_func=None, # 一旦指定しない
)
print("Trainerの準備完了。") # エラーが出なければこれが表示される
except TypeError as e:
print(f"\n!!! SFTTrainerの初期化でエラーが発生しました: {e} !!!")
print("引数 'packing' を削除しましたが、まだエラーが発生しました。")
print("SFTTrainer のヘルプ情報と必要な引数を再度確認してください。")
print("もしかしたら SFTConfig で packing を設定する必要があるかもしれません。")
raise
except Exception as e:
print(f"予期せぬエラーが発生しました: {e}")
raise
# ファインチューニング実行 (Trainerの初期化が成功した場合)
if 'trainer' in locals() and trainer is not None:
try:
print("ファインチューニングを開始します...")
trainer.train()
print("ファインチューニングが完了しました。")
except Exception as e:
print(f"ファインチューニング中にエラーが発生しました: {e}")
print("メモリ不足や設定の問題が考えられます。エラーメッセージを確認してください。")
raise # エラーで処理を停止
else:
print("Trainerの初期化に失敗したため、ファインチューニングを実行できませんでした。")
このステップ5では、事前に細かく決めた学習ルール(設定)に基づいて、SFTTrainer
という専門のトレーナーがAIモデル(のLoRAアダプター)にブログデータを学習させる、まさにファインチューニングの「本番」工程を実行しました。エラーチェックをしながら安全に進め、最終的に私の文章のクセを学習したAIの調整部品を作り上げました。
- モデル(アダプター)の保存
- 内容 ファインチューニングが完了したら、学習した成果物、つまりLoRAアダプターをGoogle Driveに保存します。前述の通り、アダプターは非常に軽量なので、保存や管理が容易です。ベースモデル全体を保存する必要はありません。
print(f"ファインチューニングされたアダプターを {adapter_save_path} に保存します...")
# LoRAアダプターのみ保存
trainer.save_model(adapter_save_path)
# トークナイザーもアダプターと一緒に保存しておくと、後で読み込む際に便利
tokenizer.save_pretrained(adapter_save_path)
print(f"アダプターとトークナイザーを {adapter_save_path} に保存しました。")
# (オプション) Colabセッション終了前に確実に書き込むための処理
ステップ6:モデル(アダプター)保存コードの解説
ステップ5でAIは文章スタイルを学習してくれました。このステップ6コードは、その学習の成果をちゃんと保存しておくためのステップです。せっかくAIが良い感じに育ってくれたのに、保存しないと消えてしまいます。
何を保存するの? ここがLoRAの賢いところ!
ステップ4で設定した「LoRA」という学習方法のおかげで、私たちは巨大なLLMモデル全体を書き換えたわけではありません。元のLLMはそのままに、「調整部品(LoRAアダプター)」だけを追加して、そこを学習させました。
ですから、保存する必要があるのは、主にこの学習済みの「LoRAアダプター」だけです!
- LoRAアダプター
これが今回の学習で得られた最も重要な成果物です。文章スタイルに合わせて調整された「差分」や「カスタマイズ情報」が詰まっています。元のLLMモデルに対する変更点だけなので、ファイルサイズは非常に小さい(数MB~数百MB程度)のが特徴です。 - (元のLLMモデル本体は?:
これは変更されていないので、再度保存する必要はありません。必要な時に元のモデルを読み込み、そこに今回保存するアダプターを組み合わせればOKです。) - トークナイザー
AIが言葉を理解するための「翻訳機」です。これもモデル(とアダプター)とセットで使うので、後で読み込むときに便利なように、アダプターと同じ場所に一緒に保存しておきます。
- 推論(テキスト生成)
- 内容 いよいよ最終段階です。まず、ベースモデルに学習済みのLoRAアダプターを読み込んで組み合わせ(マージし)ます。これで、私の文章スタイルを学習したカスタムモデルが完成します。
- このカスタムモデルに対して、「この映画のレビューを書いてください」といった指示(プロンプト)を与え、実際にテキストを生成させます。期待通り、私のブログ記事に近い文体や表現でレビューが生成されるかを確認します。生成されたテキストを見て、さらなる改善点などを検討します。
# --- 推論 ---
# (推論を別のノートブックやセッションで行う場合は、再度ライブラリインポート、Driveマウント、モデルロード等が必要です)
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig, pipeline
from peft import PeftModel
from google.colab import drive
# 再度必要な設定(上記ステップで定義済みの場合は不要)
# drive.mount('/content/drive')
# model_load_path = '/content/drive/MyDrive/llm_model' # ベースモデルのパス
# adapter_save_path = '/content/drive/MyDrive/llm_adapter_movie_blog' # 保存したアダプターのパス
print("ファインチューニング済みモデルでの推論準備...")
# ベースモデルのロード (ファインチューニング時と同じ量子化設定で)
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_use_double_quant=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.bfloat16
)
base_model = AutoModelForCausalLM.from_pretrained(
model_load_path,
quantization_config=bnb_config,
device_map="auto",
trust_remote_code=True,
)
# トークナイザーのロード (アダプターと一緒に保存したものを利用)
tokenizer = AutoTokenizer.from_pretrained(adapter_save_path)
if tokenizer.pad_token is None:
tokenizer.pad_token = tokenizer.eos_token
base_model.config.pad_token_id = base_model.config.eos_token_id
tokenizer.padding_side = 'right'
# LoRAアダプターをロードしてベースモデルにマージ
model = PeftModel.from_pretrained(base_model, adapter_save_path)
# model = model.merge_and_unload() # オプション: マージしてLoRAレイヤーを削除 (メモリ効率向上、追加学習不可)
model.eval() # 推論モード
print("ファインチューニング済みモデル(ベース + アダプター)のロード完了。")
# --- テキスト生成 ---
# プロンプトの準備 (ファインチューニング時の形式に合わせる)
prompt_title = "映画「天気の子」感想レビュー"
prompt = f"タイトル: {prompt_title}\n\n本文:\n"
# Llama-3のチャット形式を使う場合はそれに合わせる (今回はシンプルなテキスト継続)
# messages = [{"role": "user", "content": f"タイトル「{prompt_title}」で映画の感想ブログ記事を書いてください。"}]
# inputs = tokenizer.apply_chat_template(messages, add_generation_prompt=True, return_tensors="pt").to(model.device)
# シンプルなテキスト継続の場合
inputs = tokenizer(prompt, return_tensors="pt", add_special_tokens=True).to(model.device)
print(f"\n--- プロンプト ---")
print(prompt)
print("--- 生成開始 ---")
# テキスト生成の実行
with torch.no_grad():
outputs = model.generate(
**inputs,
max_new_tokens=500, # 生成する最大トークン数
temperature=0.7, # 出力の多様性 (低いほど決定的)
top_p=0.9, # Top-pサンプリング
top_k=50, # Top-kサンプリング
repetition_penalty=1.1, # 繰り返しの抑制
do_sample=True, # サンプリングを有効にする
pad_token_id=tokenizer.pad_token_id,
eos_token_id=tokenizer.eos_token_id,
)
# 生成されたテキストのデコード
generated_text = tokenizer.decode(outputs[0], skip_special_tokens=True)
# プロンプト部分を除去して表示 (必要な場合)
output_text = generated_text[len(prompt):]
print("\n--- 生成結果 ---")
# print(generated_text) # プロンプト含む全文
print(f"タイトル: {prompt_title}\n\n本文:\n{output_text}") # プロンプトを除いた部分
#実行結果(コピー&ペーストした結果です)
必要なライブラリをインポートしました。
Drive already mounted at /content/drive; to attempt to forcibly remount, call drive.mount("/content/drive", force_remount=True).
Google Driveをマウントしました。
ベースモデルパス: /content/drive/MyDrive/llm_model
アダプターパス: /content/drive/MyDrive/llm_adapter_movie_blog
量子化設定(BitsAndBytesConfig)を定義しました。
ベースモデルのロードを開始します...
Loading checkpoint shards: 100%
7/7 [03:08<00:00, 24.34s/it]
ベースモデルのロード完了。
トークナイザーのロード完了。
LoRAアダプターのロードとマージを開始します...
LoRAアダプターのロードとマージ完了。モデルを評価モードに設定しました。
メモリ解放処理を実行しました。
テキスト生成を開始します...
--- プロンプト ---
タイトル: 映画「天気の子」感想レビュー
本文:
--- 生成開始 ---
テキスト生成完了。
--- 生成結果 ---
タイトル: 映画「天気の子」感想レビュー
本文:
2019年7月19日公開の映画『天気の子』観てきました。
『君の名は。』以来、3年ぶりとなる新海誠監督作品。
前作同様今回も興行収入ランキング1位を獲得し、大ヒットとなっています。
『天気の子』予告編
引用元:
YouTube:東宝MOVIEチャンネルより
映画『天気の子』本予告【8.9 FRI. ROADSHOW】
あらすじ
引用元:
STORY|映画『天気の子』公式サイトより
空と海がつながる小さな島で暮らす少年・帆高(17歳)は、
ある日、東京にやってきた。
そこで出会った少女・陽菜(17歳)は、天気を操れる不思議な力を持っていた。
二人は出会い、恋に落ちた。
しかし、彼女には秘密があった───。
それは、地球を何度も滅ぼしてきたということだった…!
監督・脚本・原作 新海 誠
音楽 野田 聡一
キャラクターデザイン 浅野 晶
美術監督 吉川 久雄
色彩設計 横山 規奈子
撮影監督 柴崎 秀勝
プロダクションデザイナー 平良敬太郎
編集 三宅麻夫
製作 中里 萌
配給 東宝
上映時間 114分
著作権 (C)2019 STROBO / KIRINZ / DMM.com ALL RIGHTS RESERVED
主題歌 「愛にできることはまだあるかい」RADWIMPS
映画「天気の子」を観に行くか迷っている方へ
映画「天気の子」は新海誠監督作品です。
新海監督作品ではお馴染みの「青春群像劇」「ファンタジー要素」「エモーショナルなストーリーテリング」という3つの特徴があります。
また、新海監督作品では毎回、「男女2人の主人公」が登場します。
この男女2人の主人公の物語の軸がしっかりしているので、どちらかの好きな人が好きになっても楽しめる作品だと思います。
そして、今回も2
ステップ7 完了。
無事にこれらのステップを実行し、ファインチューニングされたモデルを使って、実際に映画ブログのレビュー風テキストを生成させることができました!
まとめとこれから
ローカルマシンのスペック不足という壁にぶつかりながらも、Google Colabを駆使することで、LLMのファインチューニングという目標を達成することができました。特に、LoRAのようなPEFT技術のおかげで、限られたリソースでも効率的に学習を進められたのは大きな収穫です。
今回作成したモデルは、まだ完璧ではありませんが、私の文章のクセを少しずつ学習し始めているようです。これからデータセットをさらに充実させたり、学習のパラメータを調整したりすることで、より頼りになる「映画ブログ執筆アシスタント」に育てていきたいと思います。
LLMのファインチューニングは、決して簡単な道のりではありませんでしたが、試行錯誤を重ねる中で多くの学びがありました。
また、今回はAIのLLM(大規模言語モデル)に特化したファインチューニングについて、一から取り組みました。しかし、AIのファインチューニングはLLMだけではありません。
今後は画像認識AI、画像生成AI、音声認識AI、音声合成AIなどについてもどこかのタイミングで取り組んでも見たいと思います。