7月18日、Sana Hassanが「Fine-Tuning Qwen3 with LoRA Using NVIDIA NeMo AutoModel: A Complete Single-GPU Google Colab Workflow Tutorial」と題した記事を公開した。この記事では、NVIDIA NeMo AutoModelを使ってQwen3-0.6BをLoRAでシングルGPU・Google Colab上でファインチューニングするエンドツーエンドのワークフローについて詳しく紹介されている。
LLMのファインチューニングは「マルチGPUクラスタが必要」というイメージが根強い。本チュートリアルはその前提を崩す。シングルGPUのGoogle ColabでQwen3-0.6BをLoRAでファインチューニングしながら、マルチGPU・マルチノードへそのままスケールできる構成を維持するというのが肝だ。
使用するフレームワークはNVIDIA NeMo AutoModel。設定をYAMLレシピとして分離し、automodelコマンド一本でトレーニングを走らせる設計になっている。同じレシピが--nproc-per-node 8で8GPU環境にも、Slurm/SkyPilot/Kubernetes経由のマルチノードにも対応する。
なぜNeMo AutoModelか
PyTorchやHugging Face Trainerで独自のLoRAコードを書く場合、スケールアウト時にはトレーニングループ・並列化設定・チェックポイント管理を大幅に書き換える必要が生じる。NeMo AutoModelはこの問題を解決するために設計されており、モデル・データセット・オプティマイザ・精度・並列化・チェックポイントの設定をすべてYAMLに集約する。コードを書き換えずにスケールできる点が最大の特徴だ。
分散学習戦略としては、FSDP2(Fully Sharded Data Parallel)、テンソル並列(モデルの重み行列を複数GPUに分割)、コンテキスト並列(シーケンス長方向の分割)、シーケンス並列、パイプライン並列(レイヤーをステージに分割してパイプライン実行)といったNVIDIAの分散学習戦略をYAMLの設定変更だけで切り替えられる。シングルGPUで動いたレシピが、これらの並列化戦略を追加するだけでそのままマルチGPU環境に対応する点が、他のファインチューニングフレームワークと一線を画す部分だ。
また、NeMoAutoModelForCausalLMはHugging FaceのAPIと互換性があるため、既存コードへの組み込みもしやすい。
ワークフローの全体構成
チュートリアルは以下の5ステップで構成される。
- 環境チェックとインストール — CUDAの有効性、VRAM容量、bfloat16サポートを確認してからNeMo AutoModelをソースからインストール
- レシピの読み込みとパッチ — 公式のQwen3-0.6B向けPEFTレシピ(YAML)を取得し、Colab環境に合わせてバッチサイズ・精度・ステップ数を調整
- LoRAファインチューニングの実行 — HellaSwagデータセットで
automodelコマンドを使い40ステップ訓練(HellaSwagは文章の続きを選ぶ常識推論ベンチマークであり、LoRAの効果を手軽に確認できるサイズ感のデータセットとして採用されている) - ベースモデルとの比較 — PEFTライブラリでアダプタを読み込み、同じプロンプトに対する出力を比較
- Python APIデモ —
NeMoAutoModelForCausalLMを使った直接推論
なお、LoRA(Low-Rank Adaptation)とは、モデル全体の重みを更新せず、少数の低ランク行列のみを学習することでメモリ効率よくファインチューニングする手法だ。フルファインチューニングと比べてVRAM消費を大幅に削減できるため、シングルGPUでの大規模モデル適用に広く使われている。
最重要ポイント:YAMLパッチの実装
単純なColabへの移植で詰まりやすいのが、精度とバッチサイズの問題だ。本チュートリアルでは以下のような再帰的パッチ関数でYAML設定を動的に書き換える。
def patch(node):
if isinstance(node, dict):
for k, v in list(node.items()):
if isinstance(v, str) and not BF16_OK and v.lower() in (
"bf16", "bfloat16", "torch.bfloat16"):
node[k] = "float32"
elif k in ("batch_size", "local_batch_size") and isinstance(v, int):
node[k] = min(v, 4)
elif k == "global_batch_size" and isinstance(v, int):
node[k] = min(v, 8)
else:
patch(v)
elif isinstance(node, list):
for item in node:
patch(item)
patch(cfg)
bfloat16非対応のGPUではfloat32に自動フォールバックし、バッチサイズも上限を設けてOOMを回避する。この「レシピの構造を保ちながら実行環境に合わせて書き換える」設計が、後でマルチGPU環境に戻した際にそのまま動く理由でもある。
LoRAアダプタのロードと推論比較
ファインチューニング後のモデル評価は次のように行う。
from peft import PeftModel
tuned = PeftModel.from_pretrained(base, ADAPTER_DIR)
print(textwrap.fill(generate(tuned, tok, PROMPT), 90))
チェックポイントのパスはadapter_model.safetensorsを再帰的にglobして自動探索する設計になっており、NeMo AutoModelが出力するディレクトリ構造の違いを吸収している。
スケールアウトへの拡張
同じYAMLレシピは以下のコマンドで8GPU環境にそのままスケールできる。
automodel recipe.yaml --nproc-per-node 8
モデルの差し替えも1フィールドの上書きで済む。
automodel recipe.yaml --model.pretrained_model_name_or_path <任意のHugging FaceモデルID>
LLMのファインチューニング以外にも、リポジトリには以下のレシピが含まれている。
llm_pretrain/— nanoGPTやDeepSeek-V3の事前学習vlm_finetune/— Qwen-VL、Gemma-3-VLなどのビジョン言語モデルdiffusion/— FLUX / Wan / Qwen-ImageのLoRAファインチューニング
完全なノートブックコードはGitHubで公開されており、そのままColabで実行できる。
詳細はFine-Tuning Qwen3 with LoRA Using NVIDIA NeMo AutoModel: A Complete Single-GPU Google Colab Workflow Tutorialを参照していただきたい。