2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Colab無料枠でQwen2.5/Gemma3/Gemma2をLoRAファインチューニング→GGUF変換まで完走した話

2
Posted at

はじめに

きっかけは単純で、「自分専用のAIを作ることに興味があった」 からだ。
特に最近はローカルLLM界隈で明るいニュースが目立っていると思う。
私が最初にローカルLLMに触れたのはPixel 9に入れた「Google AI Edge Gallery」というアプリで導入できるモデルだ。
当時はGeminiも使い始めたころで、Geminiと比べると応答品質はよろしくなく、「どうやって活用するんだ?」その程度の感想だった。

作り始める前から、ネット記事でこんなキーワードを何度も見かけていた。

  • 「使えば使うほど賢くなるAI」
  • 「個人情報や機密情報はAIに入力してはいけない」
  • 「入力した値が学習に使われるかもしれない」

なんとなくわかっているつもりでも、仕組みが腑に落ちていなかった。「じゃあ自分で作ってみればいい」 と思ったのが出発点だ。

もう一つの動機は、コストへの疑問だった。ChatGPTやClaudeを使うたびに月額や従量課金が発生する。無料で作れるなら、そっちの方がいい。 同時に、最新のオープンモデルを実際に動かして、その使い勝手を自分の手で確かめてみたかった。

そして、この体験を誰かと共有したいという想いも最初からあった。自分が感じた「仕組みが分かった瞬間の面白さ」を、他の人にも体験してほしかった。作っていく中で「社内研修」というゴールを定め、そこから先は受講者のためにわかりやすく、簡単で、確実に動くコードに仕上げることを一貫して意識した。Google Colab(T4 GPU / RAM 12.7GB)で、3種類のオープンモデルにLoRAファインチューニング→GGUF変換→Ollamaローカル実行まで完走できる構成だ。完全無料で動く。


このノートブックでできること

このノートブックは2つに分けている。その代わり「自分専用のAI」を、お金をかけずに、ローカルPCで動く形で作れる。

ベースモデル(Qwen2.5-3B / Gemma3 4B / Gemma2 2B から選択)
      ↓ LoRAファインチューニング(Google Colab T4 GPU、無料)
      ↓   自分で用意した質問と回答のペアを学習させる
LoRAアダプタ(約200MB)をGoogle Driveに保存
      ↓ ランタイムを切断してメモリリセット
ベースモデル + アダプタをマージ → GGUF変換(f16 → q4_k_m)
      ↓
Ollamaでローカルで動く自分だけのAI(Wi-Fi不要、完全プライベート)

ノートブックを2つに分けている理由 — T4のRAM 12.7GBは、ファインチューニングとGGUF変換を同一セッションで行うには足りない。間にランタイムを切断してメモリをリセットすることで、両工程を無料枠の中に収めている。

選べる3つのモデル

研修では自分のPCスペックや好みに応じてモデルを選べる。

モデル パラメータ GGUF(q4) こんな人に
A Qwen/Qwen2.5-3B-Instruct 3B ~1.8GB まず試したい、どんなPCでも動かしたい
B google/gemma-3-4b-it 4B ~2.5GB 品質重視、GPU搭載PCを持っている
C google/gemma-2-2b-it 2B ~1.5GB 最軽量で動かしたい、古いPCしかない

3モデルとも、ファインチューニングからGGUF変換まで完走を確認済みだ。


「自分専用」の中身

学習データは自分で用意する。形式はシンプルで、「質問と回答のペア」を書くだけ。

training_data = [
    {
        "instruction": "あなたは誰ですか?",
        "output": "私は〇〇が作ったオリジナルAIです。"
    },
    {
        "instruction": "社内の休暇申請方法は?",
        "output": "休暇申請は社内ポータルから..."
    },
    # ← ここに自分の知識を追加していく
]

このデータがそのままAIの「性格」と「知識」になる。社内FAQでも、架空キャラクターの人格でも、趣味の専門知識でも何でもいい。件数は最低3件から、多いほど精度が上がる。

学習後は、Colab上でそのまま会話テストができる。確認できたらGoogle Driveに保存し、Part 2でGGUF変換してローカルPCに持ち帰る。


完全ローカルで動く、の意味

Part 2でGGUF形式に変換したファイルを、OllamaというローカルLLMランナーに読み込ませると、自分のPCだけで動くAIになる。

ollama create my-ai -f Modelfile
ollama run my-ai

一度登録すれば、Wi-Fiを切っても動く。 データは一切外部に送信されない。「個人情報や機密情報をAIに入力してはいけない」という制約から、自由になれる。


技術的な背景(実はこんなことをやっている)

ノートブックを上から順に実行するだけで動くように設計してあるが、内部では結構複雑なことをやっている。同じことを自分で実装しようとする人の参考に、技術的なポイントをまとめておく。

LoRAとは

モデル全体(数GB)を書き換えるのではなく、小さな「差分」だけを学習する手法。差分は約200MBで済むため、Colab無料枠のRAMに収まる。

学習後、差分(LoRAアダプタ)をベースモデルに合体(マージ)させると、フルサイズのオリジナルモデルが完成する。

4bit量子化でGPUに収める

3B〜4Bのモデルをそのままロードするとfloat16で6〜8GB必要になり、T4の15GB VRAMでは学習時のgradientも含めると厳しい。BitsAndBytesによる4bit量子化で消費VRAMを半分以下に抑えている。

Gemma系に必要なラベルマスク

QwenはSFTTrainerが自動でラベルマスク(「質問部分は学習しない」設定)をやってくれるが、Gemma 2/3はchat templateの構造上これが機能しない。内部で明示的にラベルを生成している。

# assistant部分のみ学習するラベルを生成
labels = [-100] * prefix_len + full_ids[prefix_len:]

EarlyStopで過学習を防ぐ

小規模データ(数十件)では過学習が急速に進む。Loss 0.5を下回ったら自動停止する仕組みを入れている。

class EarlyStopOnLowLoss(TrainerCallback):
    def __init__(self, threshold=0.5):
        self.threshold = threshold
    def on_log(self, args, state, control, logs=None, **kwargs):
        if logs and "loss" in logs and logs["loss"] < self.threshold:
            control.should_training_stop = True

閾値0.5は「具体的な知識を学習しつつ、汎用的な日本語能力も保つ」バランスポイント。


開発中にはまったポイント(参考情報)

ここからは「完成したノートブックがなぜこういう実装になっているか」の裏話だ。同じ実装をしようとした際の参考になれば。

Gemma 3のGGUF変換が3段階で詰まった

llama.cppconvert_hf_to_gguf.pyでValueErrorが出続けた。

原因はtransformers 5.xがGemma 3をGemma3ForConditionalGeneration(マルチモーダル)として保存することだった。llama.cppはテキスト専用のGemma3ForCausalLMを期待しているため不整合が起きる。

段階 問題 対処
1回目 config.jsonがマルチモーダル形式 text_configを抽出してCausalLM形式で上書き
2回目 テンソル名にmodel.language_model.プレフィックス リネーム処理を追加(プレフィックス誤推定で0件マッチ)
3回目 マルチモーダルテンソルが残存 プレフィックス付きのみ抽出、残りを除去

最終的な対処:

if model_family == 'gemma3':
    # config.json → テキスト専用に変換
    _text_cfg = _saved_cfg['text_config']
    _text_cfg['architectures'] = ['Gemma3ForCausalLM']

    # テンソル名リネーム + マルチモーダル除去
    _PREFIX = 'model.language_model.'
    for _sf_path in sorted(glob(os.path.join(local_dir, 'model*.safetensors'))):
        _tensors = load_file(_sf_path)
        _fixed = {_k[len(_PREFIX):]: _v for _k, _v in _tensors.items() if _k.startswith(_PREFIX)}
        save_file(_fixed, _sf_path)

GPU上からsave_pretrainedする

Gemma 3(4B)のマージ+保存でRAM 12.7GBを超えてクラッシュした。モデルをCPUに移動してから保存しようとするとfloat16で8GB+シリアライズ分の追加消費が重なるためだ。

save_pretrainedはGPU上から直接実行できる。シャード単位(2GB)でdiskに書き出されるため、モデル全体をRAMに载せる必要がない。

base_model = AutoModelForCausalLM.from_pretrained(
    base_model_id, torch_dtype=torch.float16, device_map="auto"
)
merged_model = lora_model.merge_and_unload()
merged_model.save_pretrained(local_dir, safe_serialization=True, max_shard_size='2GB')

transformersのバージョンを固定しない

特定バージョンに固定したところ、5段階の連鎖で迷走した(固定→競合→ダウングレード→ImportError→キャッシュクリア→固定撤廃)。pip install -Uで最新版に追従させる方式が最終的に最も安定した。

SFTTrainerはサイレントにフォールバックする

processing_class=tokenizerのままにしておくと、明示的に作ったラベルマスクが内部で再トークナイズされて上書きされる。Lossは正常に下がるが推論に反映されない、という診断しにくい状態になる。Gemma系ではprocessing_class=Noneが必須。


Gemma 4との格闘(6回のテスト、断念)

当初はGemma 4 E4B-it(2026年4月リリース)も選択肢に加えようとしたが断念した記録も残しておく。

Gemma 4のGemma4ClippableLinearはPEFTと互換性がなく、モンキーパッチで対処してLossは0.006まで収束させた。しかし推論で学習内容がほとんど反映されない状態が6回のテストを経ても改善しなかった。

原因はteacher-forcingとautoregressive generationの乖離だ。

学習時(teacher-forcing): 正解トークンを入力 → Loss低下 ✅
推論時(autoregressive): 自分の出力を入力 → 1トークン目のズレが連鎖的に増幅 ❌

Qwen同一データで試したところ1回で成功し、モンキーパッチが唯一の原因と確定した。

Unslothが内部解決済みなので、ノートブックをUnslothベースに書き換えれば将来対応できる可能性はある。


ノートブック作成のためにかかったコスト

一点、正直に書いておく。

このノートブック自体は完全無料で動く。Google Colabの無料T4 GPUを使い、ローカルPCにはOllamaをインストールするだけだ。

ただ、私がノートブックを開発・検証するためにはコストがかかった。Google Colab Proプランを契約したが、1週間で計算リソースを使い切り、さらにPay As You Goで追加課金した。Gemma 4対応で6回テストを回し、3モデル×複数回のE2Eテストを繰り返した結果だ。

これは後悔していない。完璧に動くものを作るには、試行錯誤できる環境への投資が先に来る。 受講者が無料で確実に動くノートブックを使えるなら、開発コストは十分に元が取れる。


まとめ

「使えば使うほど賢くなるAI」「入力した値が学習に使われるかもしれない」——これらのキーワードが腑に落ちていなかった。作ってみて分かった。

ファインチューニングとは、既存のモデルに自分の書いたデータを追加学習させることだ。「使えば賢くなる」サービスも、ユーザーの入力データが学習に使われている可能性があることも、仕組みとして理解できた。そしてローカルで動かす限り、そのデータは誰にも渡らない。

このノートブックは、その体験を誰でも無料でできるように整えたものだ。興味があればぜひ動かしてみてほしい。


最後に——このコードの価値はいくらか?

このノートブックを作るにあたって、16個のバグを潰し、3モデルすべてでPart 1からPart 2まで完走を確認した。Gemma 4との格闘に6回のテストを費やし、Colab Proプランを1週間で使い切り、追加課金まで行った。検討開始から数えると1か月はかかった。

同じことを自分でゼロからやろうとすると——同じだけの時間と、同じだけの課金が必要になる。

「動くコード」にはその試行錯誤の分の価値がある。 情報やコードは無料で手に入るものという感覚が広まっているが、「確実に動く」状態に仕上げるコストは、作った人間にしか見えない。

あなたはこのノートブックに、いくらの価値を見出すだろうか。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?