AnimaキャラLoRAで顔の造形はそのままに化粧だけをオンオフする
目次
3キャラ合体LoRAに4人目(くらら・ギャル・化粧オンオフ持ち)を足す前に、まず単体LoRAで試し焼きする。データ81枚(メイク61+すっぴん20)、rank32/alpha32/lr2e-5/repeats4というkeichan/kanachanソロの実証レシピをそのまま使う。
検証環境
| 項目 | 内容 |
|---|---|
| ベースモデル | Anima-Base |
| 学習ツール | AnimaLoraToolkit (torch2.8.0+cu128 / ubuntu24.04) |
| 学習GPU | RunPod RTX 5090 |
| 学習設定 | rank32 / alpha32 / lr2e-5 / repeats4 / ep150 / save_every=1 / flip false / SDPA |
| データ | v1: 81枚(メイク61+すっぴん20) → v2/v3: 91枚(すっぴん30に増量) |
| 生成確認 | ComfyUI・Turbo 8step・cfg1.0 (全LoRA共通の本番条件) |
RunPodのpodは立てた直後にベンチを回せ(速度ガチャ)
今回一番高くついた失敗。同じ「RTX 5090」でもpodによって実効スループットが半分しかない個体がある。
- trio v2(310枚・155step/ep・rank256): 2.45s/step(当時のsamples mtimeから逆算した実測)
- 今回のpod(81枚・81step/ep・rank32): 4.8s/step。仕事量は半分なのに所要時間は同じ16時間コース
切り分けた結果、以下は原因ではなかった。
| 疑った箇所 | 判定 | 根拠 |
|---|---|---|
| 学習画像の画素数 | 問題なし | AnimaLoraToolkitはARBバケツで全画像を面積1024²±10%に正規化。素材はむしろtrioの方が大きい |
| ソフトスタック | 問題なし | torch2.8.0+cu128 / ubuntu24.04 / ドライバ570系まで同一 |
| サーマル/HWスロットル | 問題なし | Not Active・58°C |
| メモリクロック | 問題なし | 13.8/14.0GHz・帯域使用20% |
| CPU飢餓・IO | ほぼ問題なし | GPU util 99%・554W(フルパワーで忙しそうにしている) |
残る候補は「共有ホスト/仮想化層の質」か「テンプレ同名でも中身のイメージ差(cudnn 9.10系でアテンションが遅い経路)」。アイドルベンチで確定させる予定だったが、この学習はデータ不備(後述の首傾げ問題)でep103打ち切り→pod即停止となり計測機会を逃した。どちらが原因かは未確定のままだが、作業上やることはどちらでも変わらない。
podを立てたらまずスモーク学習で実測it/sを確認し、期待値(この構成なら0.35 it/s以上)を2割以上下回ったら即作り直す。5分の見切りは数十円で済むのに対し、掴んだまま回すと余計な時間と料金が半日分になる。今回は「動いたからよし」で本番を起動して、6〜8時間の見込みが16時間になった。
外れ個体の実害は二重取りで、5090の単価($1.00/h)を払って4090相当のスループットしか出ない。それなら最初から4090を半額で借りたのと同じ時間で終わる。先にベンチで裏を取っていれば、「上位GPUを借りたから速いはず」で半日回し続けずに済んだ。
このベンチゲートはv2学習(後述)で実際に機能した。secure cloud外の$0.70/h個体をアイドルベンチ(bf16 235TFLOPS)で確認してから投入したところ、実測0.48it/sが出た。trioの2倍速で、単価は安いのに当たりだった。
転送もガチャだった
同じpodで転送速度も外れだった。
HuggingFaceからのモデルダウンロードは、curl直だと200KB/s(4GBが5時間コース)。aria2の並列レンジはXetストレージの署名URLがバイト範囲(ByteRange)固定なので403で弾かれる。hf download(hf_xet入り)なら4GBが1分で、HFからのダウンロードはhf CLI一択だった。
家→podのアップロードはscp/rsync単発で25KB/s。8分割の並列scpで~650KB/sまで伸びた(ストリーム単位の絞りらしく並列分だけ伸びる)。104MBのデータセットはこれで10分台。重い物(モデル)はpod側でダウンロードし、家の帯域はデータセットのアップとckpt回収だけに使った。
くららのデータ設計(81枚)
内訳はメイク61枚(全身系36+バスト/ウエスト25)とすっぴん20枚(顔系15+全身5)。アイデンティティ(髪・目・体型・ピアス)は無記述でトリガーkuraraに焼き込む(3キャラと同じ方式)。
すっぴんには造語のmakeoffタグをトリガー直後に配置した。既存タグno makeupを使わないのは、ベースの事前知識と混ざって出力がデータセットから逸れること、20枚のくらら顔で汎用タグを汚染して4キャラ合体時に漏れること、T5系エンコーダが否定語(no X)に弱いことの3点が理由。
すっぴん20枚のうち9枚はわざと着衣(部屋着)にして「makeoff≒裸」の交絡を切った(初期11枚が全部素肌だったため)。ヌード全身4枚は胸が中サイズなのでmedium breastsを明記し、スレンダー既定(無記述側)から切り離した。
化粧を保ったまま差分を作る方法
QwenImageEdit/Gemini(nano banana)は表情・構図変更で顔領域を再描画するため、まつ毛・グロス程度の薄いギャルメイクは正規化されて消える(くららはQIEで顔自体が別人化も確定済み)。使えた経路は2つあった。
1つ目は既存全身からのクロップ(生成なし=原理的に無劣化)。1024×2048級の全身の上半分でウエストアップ1024×1065〜1331が取れる。
2つ目はCodex(gpt-image)の参照付き生成。プロンプトのアイデンティティ記述に “light gal-style makeup … IDENTICAL to the reference — do NOT remove or weaken the makeup” を明記すれば、化粧・ピアス・体型を保ったまま表情/構図を振れた。
逆にすっぴん側の生成では、“center-parted hair”と書くとCodexが額全開のかき上げ髪にしてきて2バッチ全滅した。プロンプト冒頭に「前髪が最重要・額露出禁止」と書き、参照画像を前髪が明確な絵に差し替えて解決。
学習設定
設定は検証環境の表のとおり、keichan v2/v4・kanachanのソロで実証済みの値をそのまま使う。81step/ep、露出600回/枚。
sample_promptsにはメイク有無の比較ペアを最初から入れた。makeoff以外の全トークンを一致させ、表情もsmileで固定した(表情が揺れると顔比較にならないため)。1ep1プロンプトのローテで、連続するepが素↔makeoffの比較ペアになる。
1回目の失敗、常に小首を傾げるくらら(v1・81枚・ep103打ち切り)
無指定で生成すると常に小首を傾げ、学習サンプルでも一貫して傾いていた。
原因を洗うと、顔アップ群45枚のうち約18枚がわずかに傾いていた。Codex(gpt-image)は表情差分を頼むと可愛さ演出で首を傾げる癖がある。全身組36枚はまっすぐだったので、傾きの原因は顔アップの生成分に絞れる。これはタグ付けでは直らないデータ分布の問題で、keichan v4のときと同じく、傾いた素材を差し替えるしかない。
makeoffの切り替えも弱かった。服(部屋着⇔制服)には効いたが、顔(ピアス・まつ毛)には効かない。ローカルテスト(ep42/ep100)で確認した。

本番条件で無指定で出した6枚(素×3seed・makeoff×3seed)が全部傾いている。毎回プロンプトに「head straight」と足せば隠せても、LoRA自体の偏りは残る。
対処としてep103で打ち切った。傾き19枚を除外し、直立全身からの追加クロップ7枚とCodex再生成で補充。再生成プロンプトは冒頭に「head perfectly upright and level, NO head tilt」と書き、保存前のセルフ検証も明記した。前髪のときと同じで、Codexの癖はプロンプトで明示的に打ち消した。
あわせてすっぴんを20→30枚に増量した。全て着衣部屋着・直立で、タオル/歯ブラシ/ヘアブラシ等の生活行動バリエーションを振った。すっぴんタグもmakeoff単独から「makeoff, no makeup」併記に変更した。
2回目の失敗、首傾げは直ったがmakeoffが本番条件で無反応(v2・91枚・150ep完走)
首傾げは全条件でまっすぐになり解消した。アイデンティティも安定し、顔の劣化も遅い(ep141でも軽微)。データが原因の問題は、素材の差し替えで直った。
しかし本番生成条件(Turbo 8step・cfg1.0)でmakeoffの切り替えが無反応だった。ピアス・まつ毛どころか服まで変わらない。3seed×複数ep(84/130/134/138/141)で確認済み。
不可解だったのは、学習内蔵サンプラー(cfg4.0・25step・turboなし)ではep130以降きれいにすっぴん(ピアスも外れる)が出ること。ところがComfyUIで完全同一設定(同じ重み・同じプロンプト文字列・cfg4・er_sde/simple/25step)に揃えても、ピアスが外れない。
左が学習内蔵サンプラー(ep133素↔ep134 makeoff)でピアスまで切り替わる。右がComfyUI・本番条件のスイープ(ep130〜141、各行の右寄りがmakeoff)で、全部ピアスが残っている。同じ重みでこれだけ違う。
切り分けの結論は設定値ではなくパイプライン実装差。toolkitはHFのQwen3-0.6Bをadd_special_tokens=False・末尾EOS(文末トークン)1個・アテンションマスク付きの独自実装でエンコードするのに対し、ComfyUIのCLIPLoader(type: stable_diffusion)はSD流儀のトークン処理をする。このエンコード結果の微差で、アイデンティティのような強い信号は保持され、makeoffのような弱い信号だけが消える。
仮にこの実装差を埋めてcfg4で運用できたとしても、もう一段問題が残る。このプロジェクトの生成条件は全LoRA共通でTurbo+cfg1.0固定(cfgを上げると多人数生成の安定が崩れるのは3キャラLoRAで実証済み)。最終ゴールの4人合体LoRAでは、cfg4でしか効かない切り替えは使えない。
つまり「無記述で焼き込んだ属性をタグで引き算する」設計(makeoff)は、cfg1.0運用では効かなかった。負方向の切り替えはcfgを上げて差分を増幅しないと絵に出ないのに、この運用ではcfgが1.0に固定されているからだ。
3回目の設計転換、引き算をやめて足し算にする(v3)
v2で引き算が効かなかったので、化粧を「引く」対象からタグで「足す」対象に変える。メイク側61枚のキャプションにearrings, makeupを明記し(顔が写らない真後ろ3枚は除外)、ピアスと化粧をトリガーkuraraからタグ側へ切り離す。
生成文法も変わる。素(メイク顔)はkurara, earrings, makeup, ...と存在タグで呼ぶ。存在タグはcfg1.0で確実に効く(普段の衣装指定と同じ動作原理)。すっぴんはkurara, makeoff, no makeup, ...で、トリガーに化粧が焼き付いていないぶん、引き算しなくても素顔が出る。4人合体時のタグ移り(earringsが他キャラに付く等)は、名前付き構造プロンプトで抑制する方針(3キャラ記事で実証済みのテク)。
単体LoRAのゴールは「化粧オンオフが、他キャラのアイデンティティと同じ強度・同じ生成条件(cfg1.0)で動くこと」と決めた。単体は4人合体の通過点で、合体後もcfg1.0で生成する以上、単体の段階からcfg1.0で動く必要がある。
v3はcfg1.0で両方向の切り替えを達成、採用はep140
150ep完走(当たりpod・0.47it/s・約9時間)。ep79の時点で、本番条件(Turbo 8step・cfg1.0)のA/Bが初めて両方向とも通った。

左からseed42素/off・seed100素/off・seed300素/off。素は3枚ともピアス・ウイングまつ毛・リップが出て、makeoffは3枚ともピアスが消えて素朴な顔になる。v1/v2で一度も達成できなかった「cfg1.0でピアスが外れる」が3/3。引き算(負方向の切り替え)をやめて存在タグの足し算に変えただけで、同じcfg1.0が通った。
完走後、後半帯(ep110/120/130/140/150)×素/すっぴん×3seed=30枚でスイープ。

- 素(左3列): 15/15でピアス・化粧が発火
- すっぴん(右3列): 15/15でピアス消失、まつ毛柔化・リップ無色化も安定
- 首は30/30で見た目まっすぐ(v1のようなあからさまな傾きなし)、アイデンティティは両状態で維持、ep150まで色退色・破綻なし
全身でも切り替わる。

帯全体(ep110〜150)がフラットにクリーンなので、採用はep140にした。切り替えの分離は深い帯ほど強いが、最後のep150は避けて1段手前にマージンを取った(trio v2でep143を採った時と同じ基準)。
採用したep140で、服・ポーズ・構図・seedを完全固定して化粧タグだけ変えるとこうなった。差分が化粧だけになる。

面白いのは、バストアップより全身の方が化粧オンオフが分かりやすいこと。顔の作りはそのままで線が濃くなる。顔が小さく写るほど、まつ毛・アイラインの黒量が全体の線の太さとして集約されるからだ。
目元をズームすると、「目が違う」の正体が分かる。

化粧側は上まぶたの線が目尻に向かって太くなり、目尻に上向きの黒いくさび(アイラインのハネ)が付く。これが目の輪郭として描かれるので目尻が持ち上がって吊り目寄りに見える。すっぴんはそのハネが消えて線が細く均一になり、本来の若干タレ目に戻る。学習素材のすっぴん顔も同じタレ目寄りなので、これは崩れではなくデータに忠実な差分だ。差分はピアス・リップ・線の濃さ、それに目尻の角度に出る。
タグを積むだけで盛れる
化粧をタグ側に切り離した副産物として、ベースモデルの化粧語彙をそのまま積み増せる。

| 段 | プロンプト |
|---|---|
| 通常 | kurara, earrings, makeup |
| 盛り | kurara, earrings, heavy makeup, thick eyelashes, long eyelashes, eyeshadow, eyeliner, glossy lips, blush |
| 全盛り | 盛りのタグ+自然文で”heavy flashy gal makeup with bold winged eyeliner…”と駄目押し |
右端は太いウイングライナー・まぶたのピンクシャドウ・上下ロングまつ毛・グロスリップまで乗って明確にケバい。顔つきは崩れない。すっぴん〜通常〜全盛りの3段が、同じcfg1.0の設定で切り替わった。
生成文法は最終的にこうなった。
| 状態 | プロンプト |
|---|---|
| 素(メイク顔) | kurara, earrings, makeup, ... |
| すっぴん | kurara, makeoff, no makeup, ... |
服はどちらも普段の衣装タグで別途指定する。cfgは全LoRA共通の1.0のまま。
バストアップに小首が残っていた
公開前にグリッドを重ねて傾きを再判定すると、全身4枚(素/すっぴん×2seed)は傾き1〜2°以内でほぼ直立だった一方、バストアップには数度の小首が残っていた。盛るほど傾きが強く、heavy makeup+自然文の全盛りが一番傾く。v1の5〜15°級は消えたが、顔アップの構図には2〜5°級が残っている。
心当たりはある。v3で差し替えたCodex再生成分をサムネイル精度で「直立」と確認したので、数度の傾きは見逃した可能性が高い。意図的に傾けた2枚(タグ付き)と、判定甘めで残した数枚も顔アップ群にいる。バストアップ生成はこの分類の分布を強く引くので、出方とも一致する。
単体LoRAとしては実用範囲なのでv4の焼き直しはしない。4人合体用のデータセットを組む時に、くらら顔アップ群をグリッド精度で確認し直して、傾いた素材を差し替えるか除外する。