⚠️ 注意: AI画像生成時は著作権・肖像権にご注意ください。商用利用前には各サービスの利用規約をご確認ください。当ブログは生成された画像に関する責任を負いかねます。
📝 本記事にはアフィリエイトリンクが含まれています。
要約
ComfyUIで作ったオリジナルキャラ「瑠水奈」のLoRAを、Claude Codeと会話しながら一から作ってみました。画像生成→キャプション自動作成→kohya_ssセットアップ→RunPodでの本番学習まで、ハマりポイントも含めて全部正直に書きます。RTX3070 8GBでも始められますが、本番はクラウドGPUのRunPod(約500円)が現実的です。
はじめに|Claude Codeと一緒にLoRAを作ってみた
ComfyUIでオリジナルキャラクター「瑠水奈(rumina)」を作り続けていて、ある日ふと思ったんです。
「このキャラをLoRAにしたら、もっと安定して再現できるんじゃないか?」
LoRAって難しそうというイメージがありましたが、今回はClaude Codeと会話しながら進めてみたら意外とスムーズでした。失敗もたくさんしましたが、そのまま全部書きます。
この記事で分かること:
- ComfyUIで生成した画像からLoRA学習データを作る方法
- kohya_ssのセットアップと学習スクリプトの作り方
- RTX3070 8GBでの限界と、RunPodを使う判断基準
- GPU選びの落とし穴(VRAM容量より帯域幅が重要)
- 実際にかかった費用と時間(RunPod RTX 6000 Adaで約$2.91・3.8時間)
全体の流れ
今回の作業はざっくりこんな流れです。
[1] 学習用画像の生成(ComfyUI)
↓
[2] PNGメタデータを解析してキャプション自動生成
↓
[3] データセットの整理
↓
[4] kohya_ss のインストール
↓
[5] 学習スクリプトの作成
↓
[6] ローカルで動作確認(RTX3070)
↓
[7] RunPodで本番学習
↓
[8] LoRAを使って画像生成・評価
Step 1:学習用画像の生成(ComfyUI)
通常のLoRA作成では実写写真を使うことが多いですが、今回はComfyUIで学習用画像を自分で生成するアプローチを取りました。
キャラクターの外見を固定したベースプロンプトを使い、バリエーションをカテゴリ別に生成しています。
生成カテゴリと枚数(最終的に使用した素材)
| カテゴリ | 内容 |
|---|---|
| body | 全身・バストアップ |
| expression | 表情バリエーション |
| face | 顔アップ |
| outfit | 衣装差分 |
| pose | ポーズ差分 |
| scene | 背景ありシーン |
約600枚生成して品質の良いものに絞り込み、最終的に 148枚 を学習素材として使用しました。
Step 2:PNGメタデータを解析してキャプション自動生成
ComfyUIで生成した画像には、ワークフロー情報がPNGメタデータとして埋め込まれています。Claude Codeに「pnginfoを解析して適切なキャプションファイルを用意してもらうことはできますか?」と聞いたところ、自動でスクリプトを作ってくれました。
キャプション生成の仕組み
- PNGメタデータからComfyUIのワークフローJSONを読み込む
- ポジティブプロンプトを抽出する
- キャラクター共通のベースプロンプトを削除
- トリガーワード
ruminaを先頭に付加 .txtファイルとして同名で保存
キャラクター共通のベースプロンプト(クオリティタグ・体型・髪色など全画像に共通する部分)を削除することで、キャプションには「その画像固有の情報」だけが残ります。
キャプション例:
rumina, standing, looking at viewer, smile, school uniform, outdoor
ファイル名のリネームも自動化
ファイル名も rumina_00001.png 形式に連番でリネームしました。
失敗談①:括弧内カンマの処理ミス
最初はカンマでタグを分割してベースプロンプトを削除しようとしたのですが、(masterpiece, best quality, anime style) のように括弧の内側にカンマがあるタグで誤動作しました。
# NG: カンマで単純分割すると内側のカンマで誤分割される
(masterpiece → 消える
best quality → 消える(本来は残すべき)
括弧の深さを追跡するパーサーに修正して解決しました。こういうエッジケースをClaude Codeに相談すると、すぐに修正案を出してくれるのが助かります。
Step 3:データセットの整理
kohya_ssのフォルダ命名規則
kohya_ssでは、学習データのフォルダ名に特別な意味があります。
dataset/
└── 10_rumina/ ← 数字 = 1epochあたりの繰り返し回数
├── rumina_00001.png
├── rumina_00001.txt
├── rumina_00002.png
├── rumina_00002.txt
...
10_rumina の意味:
10= 1 epoch あたり各画像を 10 回使用(repeats 数)rumina= トリガーワード(≠ epoch 数)
繰り返し数 × epoch 数 = 実質的な学習回数になります。今回は:
- 10 repeats × 20 epoch × 148枚 = 29,600ステップ相当
Claude Codeに「ファイルを解析してこれでLoRA生成ができるか判定してください」と聞いたところ、フォルダ構成の確認や画像枚数のカウントまでやってくれました。
Step 4:kohya_ss のインストール
環境:
- pyenv-win(Python 3.10.11)
- GPU:NVIDIA RTX3070 8GB
# kohya_ss をクローン
git clone https://github.com/bmaltais/kohya_ss.git
cd kohya_ss
git submodule update --init --recursive
# Python仮想環境を作成
python -m venv venv
source venv/Scripts/activate # Windows (Git Bash)
# 依存パッケージをインストール
pip install --upgrade pip
pip install -r requirements.txt
# PyTorch (CUDA 12.8対応)
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu128
インストール後、CUDAが認識できているか確認します:
python -c "import torch; print(torch.cuda.is_available())"
# → True であればOK
Step 5:学習スクリプトの作成
「batファイルよりshファイルでコマンドラインから実行したい。Git Bash普段使ってる」と伝えたところ、Claude Codeがシェルスクリプトを作ってくれました。
RTX3070 8GB向けの主要設定
accelerate launch sd-scripts/sdxl_train_network.py \
--pretrained_model_name_or_path="your_model.safetensors" \
--train_data_dir="dataset/" \ # ← 10_rumina/ の親ディレクトリを指定(後述)
--output_dir="output/" \
--output_name="rumina" \
--network_module=networks.lora \
--network_dim=32 \ # LoRAのランク
--network_alpha=16 \ # 通常はdimの半分
--resolution="1024,1024" \
--train_batch_size=1 \ # 8GBでは1が限界
--max_train_epochs=2 \ # ローカルテスト用は2epochに絞る
--mixed_precision=bf16 \
--gradient_checkpointing \ # VRAM節約に必須
--cache_latents_to_disk \ # 2回目以降の前処理をスキップ
--xformers \
--gradient_accumulation_steps=2
--network_dim と --network_alpha の意味:
| パラメータ | 役割 |
|---|---|
network_dim |
LoRAのランク数。大きいほど表現力↑・ファイルサイズ↑ |
network_alpha |
学習率スケーリング。通常はdimの半分が安定 |
dim=32 / alpha=16 は多くのキャラLoRAで使われる標準的な値です。
失敗談②:train_data_dir の指定ミス
ERROR: No data found. train_data_dir must be the parent of folders with images
dataset/10_rumina/ を直接指定してこのエラーが出ました。kohya_ssは 数字_クラス名 フォルダの親ディレクトリを指定する仕様です。
- --train_data_dir="dataset/10_rumina/"
+ --train_data_dir="dataset/"
Step 6:ローカルで動作確認(RTX3070 8GB)
「ローカルで実行まで問題ないことを確認してからRunPodでやる段構えでどうでしょうか」という提案でローカルテストを先に実施しました。
結果:
- 動作確認はできた(lossが0.07〜0.06で正常に低下)
- 学習速度:64秒/step
- 20epoch × 1,480step = 約72時間の計算
RTX3070 8GBで1024×1024のSDXLはVRAMギリギリです。動作確認はできましたが、本番学習をローカルでやるのは現実的ではないと判断してRunPodに移行することにしました。
Step 7:RunPodで本番学習
GPU選び:VRAMの「量」より「速さ」が重要
LoRA学習のSDXLには最低16GB VRAMが必要です。ただし、VRAMが多いGPUが速いとは限りません。
| GPU | VRAM | 料金目安 | 帯域幅 | LoRAへのコスパ |
|---|---|---|---|---|
| RTX 3090 | 24GB | ~$0.3/hr | 936 GB/s | 良い |
| RTX 4090 | 24GB | ~$0.6/hr | 1,008 GB/s | 良い |
| L40S | 48GB | ~$0.8/hr | 864 GB/s | 高速・安定 |
| RTX 6000 Ada | 48GB | ~$0.77/hr | 960 GB/s | 最適(今回使用) |
| RTX Pro 6000 | 96GB | ~$1.69/hr | 576 GB/s | VRAM多いが遅い |
| A100 80GB | 80GB | ~$1.5/hr | 2,000 GB/s | 速いが高い |
| H100 | 80GB | ~$2〜4/hr | 3,350 GB/s | LoRAには過剰 |
実際に複数のGPUを試してみたところ、VRAMが2倍のRTX Pro 6000(96GB)の方が遅かったという結果になりました。
なぜか? LoRA学習の速度を決めるのはVRAM容量ではなく「メモリ帯域幅」と「Tensor Core性能」です。RTX Pro 6000はVRAMは多いですが帯域幅が低いため、結果的に遅くなりました。
| GPU | 帯域幅 | 比較 |
|---|---|---|
| RTX 6000 Ada | 960 GB/s | 最速(今回の本番) |
| L40S | 864 GB/s | 高速 |
| RTX Pro 6000 | 576 GB/s | 遅い(失敗) |
事前準備(ローカルで済ませておくこと)
RunPod当日の作業を最小限にするため、ローカルで以下を準備しました。
dataset_rumina.zip(148枚の PNG + TXT)runpod_setup.sh(kohya_ss インストール〜モデルDLまで一発)runpod_train.sh(全学習パラメータをコマンドライン引数で指定)
ベースモデルのダウンロードはRunPod上で直接wgetが高速です。
civitai → RunPodは高速回線なので、ローカルからアップロードするより圧倒的に速い。
RunPod当日の流れ
1. Podを起動
- テンプレート:「RunPod Pytorch 2.4.0」(JupyterLab付き)
- GPU:RTX 6000 Ada(またはL40S)
- コンテナボリューム:20GB(永続ディスク不要)
2. JupyterLabで3ファイルをアップロード
runpod_setup.shrunpod_train.shdataset_rumina.zip
3. JupyterLabのターミナルで実行
# セットアップ(kohya_ssインストール+モデルDL)
bash runpod_setup.sh
# データセット展開
python3 -c "
import zipfile
with zipfile.ZipFile('/workspace/dataset_rumina.zip', 'r') as z:
z.extractall('/workspace/dataset')
"
ls /workspace/dataset/ # 10_rumina/ があることを確認
# 学習開始(JupyterLabのターミナルなのでブラウザを閉じても継続)
bash runpod_train.sh
RunPod向けパラメータの変更点
ローカルとRunPodでは以下のパラメータが変わります。
| パラメータ | ローカル(RTX3070) | RunPod(L40S) |
|---|---|---|
train_batch_size |
1 | 2 |
gradient_checkpointing |
必須 | 不要(外す) |
gradient_accumulation_steps |
2 | 1 |
xformers |
使用 | sdpa に変更(xformersはエラーで使えなかった) |
max_train_epochs |
2(テスト用) | 20 |
1回目(L40S)→ 2回目(RTX 6000 Ada)の変更点
1回目のL40Sでは strength 1.2〜1.5 かけないとキャラらしさが出なかったため、2回目は設定を全面見直しました。
| パラメータ | 1回目(L40S) | 2回目(RTX 6000 Ada) | 変更の意図 |
|---|---|---|---|
network_dim |
32 | 64 | 表現力UP |
network_alpha |
16 | 32 | dimに合わせて調整 |
resolution |
1024,1024 | 1280,1280 | 高解像度対応 |
max_bucket_reso |
1024 | 1280 | 解像度に合わせて拡大 |
learning_rate |
0.0001 | 0.0002 | 学習速度を2倍に |
unet_lr |
0.0001 | 0.0002 | 同上 |
min_snr_gamma |
なし | 5 | 学習安定化 |
noise_offset |
なし | 0.05 | 暗部の再現性向上 |
| attention最適化 | xformers(→エラーでsdpaに変更) | sdpa | 1回目のエラーを受けてsdpaに統一 |
この変更により、2回目では strength 0.8〜1.0 でしっかりキャラクターらしさが出るようになりました。
ハマったエラーと解決策
① accelerate config --no_interactive が使えない
error: unrecognized arguments: --no_interactive
古いバージョンのaccelerateで発生。設定ファイルを直接yamlで書き込むことで解決:
mkdir -p ~/.cache/huggingface/accelerate
cat > ~/.cache/huggingface/accelerate/default_config.yaml << 'EOF'
compute_environment: LOCAL_MACHINE
distributed_type: 'NO'
mixed_precision: bf16
num_machines: 1
num_processes: 1
use_cpu: false
EOF
② unzip: command not found
RunPodの環境にunzipが入っていないことがある。Pythonのzipfileモジュールで代替:
python3 -c "
import zipfile
with zipfile.ZipFile('dataset_rumina.zip', 'r') as z:
z.extractall('/workspace/dataset')
"
③ No module named 'xformers'(1回目・L40S)
venvにxformersが入っていない。PyTorch 2.0以降は --sdpa で代替可能:
- --xformers \
+ --sdpa \
このエラーを受けて、2回目以降ははじめから --sdpa を使うようにしました。
④ CUDA Out of Memory(OOM)
AdamW標準版 + batch_size=4 でVRAMが枯渇。AdamW8bitに戻してbatch_sizeを削減:
- --optimizer_type=AdamW \
- --train_batch_size=4 \
+ --optimizer_type=AdamW8bit \
+ --train_batch_size=2 \
費用・時間の実績
| 1回目(L40S) | 2回目(RTX 6000 Ada) | |
|---|---|---|
| 料金 | ~$0.86/hr | ~$0.77/hr |
| 稼働時間 | 約3.2時間 | 約3.8時間 |
| 合計費用 | 約 $2.8(≒420円) | 約 $2.91(≒450円) |
| strength有効範囲 | 1.2〜1.5 | 0.8〜1.0 |
どちらもLoRA1本 500円以下。 設定を改善した2回目の方がより低い強度でしっかり効くLoRAになりました。
Step 8:LoRAを使って画像生成・評価
学習完了後、/workspace/output/ に以下のファイルが生成されます。
rumina-000005.safetensors ← 5epoch目
rumina-000010.safetensors ← 10epoch目
rumina-000015.safetensors ← 15epoch目
rumina.safetensors ← 最終(20epoch)
JupyterLabのファイルブラウザから右クリック→Downloadでローカルに保存し、ComfyUIの models/loras/ に配置すれば使用できます。
Podは学習完了後すぐに停止してください。忘れると課金が続きます。
評価結果


2回目(RTX 6000 Ada・設定改善後)
| 強度 | 結果 |
|---|---|
| 0.6〜0.7 | 銀髪・キャラらしさが再現できており実用的。他のLoRAやスタイルとも共存しやすい |
| 0.8〜1.0 | しっかりキャラクターらしさが出る。推奨範囲 |
| 1.2以上 | 髪色・目の色が崩れる場合がある |
1回目(L40S)との比較
| 1回目 | 2回目 | |
|---|---|---|
| strength有効範囲 | 1.2〜1.5 | 0.8〜1.0 |
| 主な変更点 | — | dim 32→64・解像度1280・LR 2倍 |
肌色(tanned skin)について: LoRAからは自動で出ませんでした。キャプション生成時にベースプロンプトから tanned skin を削除していたため、LoRAに学習されなかったためです。プロンプトで明示すれば再現できます。
tanned skin はキャプションから削除してたせいでLoRAに学習されなかったのが反省点。キャラ固有の特徴はキャプションに残しておかないとLoRAに学習されないよ補足:学習パラメータの読み方
lossの見方
| loss | 状態 |
|---|---|
| 0.05〜0.1付近で安定 | 正常 |
| 極端に下がる(0.01以下) | 過学習の可能性 |
| 下がらない | 学習率が低すぎる可能性 |
学習量の計算
実質ステップ数 = repeats × epoch数 × 画像枚数
今回:10 × 20 × 148 = 29,600ステップ
epoch数を増やすか repeats を増やすかで同じステップ数にできますが、epoch数を増やす方が途中保存で品質確認しやすいです。
まとめ
ComfyUIで生成した画像からのLoRA作成、Claude Codeと一緒に進めることで意外とスムーズにできました。
今回の学びをまとめると:
- キャプションはキャラ固有の特徴(肌色など)を残す。削除するとLoRAに学習されない
train_data_dirは10_rumina/の親ディレクトリを指定(ハマりやすいポイント)- RTX3070 8GBでのSDXL学習は動作確認まで。本番はRunPodが現実的
- GPU選びはメモリ帯域幅を確認。VRAM容量だけで選ぶと速度が遅いGPUを高い料金で使うことになる
- LoRA学習のコスト:RunPod(RTX 6000 Ada)で約$2.91・3.8時間(≒450円)
次回の改善点:
tanned skinをキャプションに残す(keep_tokensで保護)
LoRAを自分で作れると、キャラの一貫性が格段に上がります。ComfyUIでオリジナルキャラを作っている方は、ぜひ挑戦してみてください!
tanned skin をキャプションに残せばいけるはず。キャプション設計が大事だって身をもって学んだよ!RunPodをまだ使ったことがない方は、以下の紹介リンクから登録すると$10以上のチャージで$5〜$500のクレジットボーナスがもらえます。LoRA学習1回分(約$3)が実質タダになるのでお得です。
関連記事



⚠️ AI画像生成をご利用の際の重要な注意事項
著作権・知的財産権について
- 既存のキャラクター、作品、ブランドロゴなどの模倣・複製は著作権侵害にあたる可能性があります
- 商用利用時は特に注意が必要です
肖像権について
- 実在人物(著名人・一般人問わず)の顔や特徴を模倣した画像生成はお控えください
- 無断での肖像権使用は法的トラブルの原因となります
利用規約の確認
- 各AI画像生成サービスの利用規約を必ずご確認ください
- 商用利用の可否、生成画像の権利関係は各サービスで異なります
免責事項
- 当ブログの情報を参考にしたAI画像生成により生じた問題について、当ブログは一切の責任を負いません
- 法的問題が生じた場合は、利用者の自己責任となります
- 最新の法律・規約情報は公式情報をご確認ください
適切なAI画像生成を心がけ、創作活動を楽しみましょう。
詳細についてはAIと著作権についてをご覧ください。


コメント