衣装一貫率
衣装一貫率
衣装一貫率
START
│
├─ 「新キャラをすぐ使いたい(今日中)」
│ → 手法1(テキスト最適化)で開始
│
├─ 「既存キャラをもっと安定させたい(1週間)」
│ → 手法2(IPAdapter)を追加
│ → 手法1+手法2 のハイブリッドで80-85%達成
│
└─ 「主力キャラを完全固定して商品量産(1ヶ月)」
→ 手法3(LoRA学習)で最終形
→ 手法1+手法2+手法3 の三層で90%以上達成
現状推奨: 手法1+手法2 のハイブリッドで80%以上を早期達成
LoRA は主力キャラ4人(akari/misako/hinata/rena)優先で学習
AI CG集の一貫性問題は「4大ダメ出し」の中で衣装/小物/体型ドリフトが筆頭に上がる[1]。「売り物にならない」と評価された場合の根本原因の多くが一貫性崩壊であり、高品質一貫性が確立されたシリーズは「キャラへの愛着」によるリピート購買が発生しやすい。
| 手法 | 採用状況 | 効果 | コスト |
|---|---|---|---|
| キャラ設定md先行確定 | 高品質クリエイターは必須実施 | 衣装仕様を文書化してドリフト防止 | ¥0(時間のみ) |
| outfit_color タグ固定 | ほぼ全員実施 | 色名を明示的に固定(black dress等) | ¥0 |
| IPAdapter 参照画像 | 中〜上級者が実施 | 80-85%一貫性達成 | ¥0(モデルDL必要) |
| キャラLoRA自作 | 上位クリエイターが実施 | 90%以上一貫性達成 | GPU電気代+時間 |
| Civitai既存LoRA流用 | 一部クリエイター | 70-80%(既存キャラ依存) | DL時間のみ |
追加コスト¥0・導入1時間・衣装一貫率65-70%。最初に着手すべき基礎手法。
| 悪い書き方 | 良い書き方 | 理由 |
|---|---|---|
outfit_color=outdoor | 使わない(無意味) | outdoor は色名ではないため無視される[2] |
red dress | 使用NG (色名直接NG) | locに色名(red/pink/blue)を直接書くとマゼンタ肌等の色問題が連鎖する |
black lace dress | black lace lingerie, black underwear | 色名は中性系(black/white/dark)のみOK。loc内で使う[3] |
| 衣装タグが文中に散在 | 衣装タグを先頭ブロックに集約 | Illustriousは先頭タグを優先度高く解釈する |
# ステージ別衣装継承設計 — テキストのみ版
# キャラ: misako (栗茶髪・黒レースランジェリー設定)
MISAKO_OUTFIT_BY_STAGE = {
"s1": {
# 着衣(完全着衣)
"outfit": "black blazer, white shirt, dark navy skirt, office attire",
"desc": "オフィス着衣状態",
"note": "衣装色はblack/white/dark系のみ使用"
},
"s2": {
# 脱ぎかけ(上半身見え始め)
"outfit": "black blazer half-removed, white shirt unbuttoned, dark navy skirt, visible black bra strap",
"desc": "ブレザー脱ぎかけ",
"note": "s1の衣装から一部を引いて追加するイメージ"
},
"s3": {
# 前戯(上半身露出)
"outfit": "black lace bra, dark navy skirt, shirt removed",
"desc": "ブラ見え・スカートのみ",
"note": "s2のブレザー/シャツを除去してブラを追加"
},
"s4": {
# 本番(下着のみ・または裸)
"outfit": "black lace lingerie, black panties pulled down, skirt removed",
"desc": "下着のみ",
"note": "スカートを除去"
},
"s5": {
# 絶頂(完全裸)
"outfit": "nude, completely naked, no clothes",
"desc": "完全脱衣",
"note": "全衣装除去"
},
}
# 衣装継承プロンプト生成関数
def build_outfit_prompt(char_name, stage):
base = CHAR_OUTFIT_STAGES[char_name]
outfit_data = base[stage]
return outfit_data["outfit"]
# 重要ルール: 前ステージの衣装タグを全て引き継いで「除去したもの」を明示
# NG: s3で突然 "school uniform" にする
# OK: s3で "white shirt removed, black lace bra visible" と書く(除去を明示)
# 衣装ドリフト防止 NEGプロンプト
# キャラごとに衣装NGタグを設定
MISAKO_NEG_OUTFIT = (
# 他キャラの衣装が混入しないように
"pink lingerie, pink underwear, " # hinata の衣装色
"red lingerie, red underwear, " # rena の衣装色
# ステージに合わない衣装が混入しないように(s4以降で着衣が出ないよう)
# ※ s1の時は不要(ここには書かない)
)
# ステージ別に NEG に追加するアイテム
MISAKO_STAGE_NEG = {
"s4": "school uniform, blazer, white shirt, fully dressed, ",
"s5": "any clothing, underwear, lingerie, partially clothed, ",
}
| キャラ | 髪色 | s1着衣 | s3下着色 | NEG追加色 |
|---|---|---|---|---|
| akari | 黒髪 | school uniform, dark blazer | black lingerie | pink, red, gold, blonde |
| misako | 栗茶髪 | office attire, dark navy skirt | black lace lingerie | pink, red, gold |
| hinata | 明茶ボブ | casual wear, light cardigan | pink lingerie | black, red, gold |
| rena | 金髪 | casual top, jeans | red lingerie | black, pink, blue |
※ feedback_male_consistency_2026-05-26.md 記載のキャラ設定を衣装軸で整理[4]
追加コスト¥0(モデルDL必要)・導入1日・衣装一貫率80-85%。テキスト最適化の次のステップ。
# ComfyUI ワークフロー構成(SDXL用)
# ノード順序: Checkpoint → LoRA → IPAdapter → KSampler
# ※ LoRA がある場合はLoRA後にIPAdapterを適用
IPADAPTER_SDXL_CONFIG = {
# 使用モデル(SDXL用)
"ipadapter_model": "ip-adapter-plus_sdxl_vit-h.safetensors",
"clip_vision_model": "CLIP-ViT-H-14-laion2B-s32B-b79K.safetensors",
# 基本設定
"weight": 0.35, # 0.3-0.4 が最適(高すぎると顔ドリフト発生)[5]
"start_at": 0.0, # 最初から適用
"end_at": 0.80, # 80%の時点で終了(残り20%でLoRA/プロンプトが優勢になる)
# weight_type の選択
"weight_type": "linear", # 衣装維持には linearが安定
# "weight_type": "style transfer (SDXL)", # スタイル転送重視の場合
# 参照画像設定
"reference_image": "キャラ参照画像パス",
"reference_image_policy": "always_use_same_file", # 常に同じファイルを使う[5]
}
# 衣装特化の設定(顔ではなく衣装に集中させる)
IPADAPTER_OUTFIT_FOCUS = {
"weight": 0.30, # 衣装特化は低め(顔ドリフトを防ぐ)
"end_at": 0.75, # 少し早めに終了
}
# 参照画像の品質基準
REFERENCE_IMAGE_GUIDE = {
"background": "plain white or neutral", # 背景をシンプルに[6]
"pose": "standing, frontal view", # 正面立ち姿が最も効果的
"resolution": "1024x1024", # SDXL生成サイズに合わせる
"outfit_visibility": "full body visible", # 衣装が全体見える
"lighting": "neutral, no strong shadows", # 中立照明
"expression": "neutral", # 表情は中立(後の生成に影響させない)
}
# 各ステージに参照画像を用意する方法
# s1: 着衣の最高品質カット1枚を参照画像に
# s3: 前戯衣装(ブラ等)の最高品質カット1枚を参照画像に
# s5: フルヌードの最高品質カット1枚を参照画像に
# → ステージが変わったら参照画像も切り替える
REFERENCE_IMAGES = {
"akari": {
"s1_ref": r"D:\projects\fanza3_mass\ref_images\akari_s1_ref.png",
"s3_ref": r"D:\projects\fanza3_mass\ref_images\akari_s3_ref.png",
"s5_ref": r"D:\projects\fanza3_mass\ref_images\akari_s5_ref.png",
},
"misako": {
"s1_ref": r"D:\projects\fanza3_mass\ref_images\misako_s1_ref.png",
"s3_ref": r"D:\projects\fanza3_mass\ref_images\misako_s3_ref.png",
"s5_ref": r"D:\projects\fanza3_mass\ref_images\misako_s5_ref.png",
},
# ... hinata, rena
}
# ノード順: Checkpoint → LoRA (weight=0.85) → IPAdapter (weight=0.35) → KSampler
# LoRA が先に適用されることでキャラ identity を安定化
# IPAdapterが後から衣装情報を注入
COMBINED_CONFIG = {
"lora_weight": 0.85, # キャラLoRAのweight
"ipadapter_weight": 0.30, # IPAdapterを低めに(LoRAが優先されるよう)
"ipadapter_end_at": 0.80, # LoRAに最後の20%を明け渡す[7]
}
# 注意: IPAdapter weight > 1.0 は「顔焼け」の原因
# 顔が歪んだら → weight を 0.05 刻みで下げる
# 衣装が認識されなかったら → weight を 0.05 刻みで上げる
| モデル名 | 用途 | 保存先 | DL元 |
|---|---|---|---|
| ip-adapter-plus_sdxl_vit-h.safetensors | SDXL メイン | ComfyUI/models/ipadapter/ | Hugging Face h94/IP-Adapter[8] |
| CLIP-ViT-H-14-laion2B-s32B-b79K.safetensors | CLIP Vision | ComfyUI/models/clip_vision/ | Hugging Face openai/clip-vit-large-patch14[9] |
追加コスト: GPU電気代+時間。導入1-2週間。衣装一貫率90%以上。主力キャラ専用。
# Illustrious-XL LoRA 学習設定(AI Toolkit / sd-scripts 推奨)[10]
LORA_TRAINING_CONFIG = {
# モデル
"base_model": "waiIllustriousSDXL_v160",
# データセット
"num_images": 100, # 最低50枚・推奨100枚
"num_repeats": 5, # 100枚 × 5 = 500 学習サンプル
"resolution": 1024, # 1024x1024 固定
# 学習パラメータ(Illustrious用)
"max_train_steps": 1600, # 1600ステップが推奨[11]
"network_dim": 32, # rank=32 (衣装特化は高めが効果的)
"network_alpha": 16, # alpha = dim/2
"learning_rate": 1e-4, # UNet
"text_encoder_lr": 5e-5, # テキストエンコーダ
"batch_size": 1,
# スケジューラ・オプティマイザ
"lr_scheduler": "cosine_annealing",
"optimizer": "prodigy", # Prodigy + cosine が推奨[11]
# トリガーワード
"trigger_word": "akari_char", # キャラごとに固有のトリガーワード
}
# キャプショニング戦略 — 衣装一貫性のためのタグ設計[12]
# NG: キャプションに「キャラ識別タグ」を残す
# OK: キャラ識別タグは除去して衣装タグのみ残す
# 除去すべきタグ(学習で汎化させるため)
REMOVE_FROM_CAPTIONS = [
"akari_char", # トリガーワードはcaptionには入れない
"1girl", # 汎用すぎて意味なし
]
# 必ず保持すべき衣装タグ(衣装一貫性の核)
KEEP_IN_CAPTIONS = [
"black hair", # 髪色は必ず保持
"ponytail", # 髪型
"black blazer", # s1衣装色(色名付きで)
"black lace lingerie", # s3衣装色
"black underwear", # s4衣装
]
# 衣装関連タグの書き方ルール[12]
# 悪い例: "frilled skirt" → frillとskirtが分離されない
# 良い例: "frilled skirt, frills" → 別々のタグで学習させる
# 悪い例: "blue dress" → 色問題の原因(blue直書きNG)
# 良い例: "navy dress" → navy/dark等の中間色表現を使う
# 複数outfit が含まれる場合のフォルダ分け戦略
# dataset/
# akari_s1/ ← 着衣100枚 (repeat=5)
# akari_s3/ ← 前戯衣装100枚 (repeat=5)
# akari_s5/ ← ヌード100枚 (repeat=5)
# → ステージごとに別フォルダで学習させるとステージ指定が安定する
| 種類 | 学習対象 | 効果 | デメリット |
|---|---|---|---|
| キャラLoRA(顔+体+衣装) | キャラ全体の特徴 | キャラ全体の一貫性90%以上 | 学習コスト高い・衣装変更が難しい |
| 衣装LoRA(衣装のみ) | 特定の衣装・アイテム | 衣装だけを高精度に再現 | キャラ顔の固定には別手法が必要 |
| コンセプトLoRA(スタイル) | 描画スタイル・雰囲気 | 全キャラに適用できる | キャラ識別には使えない |
にゃんちゅ~さんのケースでは「キャラLoRA(顔+体+衣装セット)」を4キャラ分学習するのが最も効果的[4]
# LoRA weight は 0.7-1.0 が推奨範囲
# weight が高すぎる (>1.2) → キャラ特徴が強く出すぎて多様性が失われる
# weight が低すぎる (<0.5) → 一貫性が下がる
LORA_APPLICATION_GUIDE = {
"character_lora_weight": 0.85, # キャラLoRA (顔+体): 0.8-0.9
"outfit_lora_weight": 0.70, # 衣装LoRAを追加する場合: 0.6-0.8
# Illustrious LoRAの特性:
# 「顔はほぼ変わらず衣装が微影響」という結果になることが多い[11]
# → 衣装の変化を出したい場合は衣装LoRAを別途学習するか
# captioningで衣装タグを多く含める
# IPAdapterと組み合わせる場合
"with_ipadapter": {
"char_lora": 0.85,
"ipadapter": 0.30, # LoRAより低く設定
"ipadapter_end_at": 0.80,
}
}
| 手法 | 初期コスト | ランニングコスト | 達成一貫率 | 期待売上増加 | ROI |
|---|---|---|---|---|---|
| 手法1(テキストのみ) | ¥0・1時間 | ¥0 | 65% | +20%(返品減少) | ∞(コストなし) |
| 手法2(IPAdapter) | ¥0・1日(モデルDL+設定) | ¥0 | 82% | +50%(シリーズ買い発生) | ∞(コストなし) |
| 手法3(LoRA学習) | 電気代¥500-2000/キャラ・2週間 | 学習は1回のみ | 92% | +100%(固定ファン獲得) | 非常に高い(1LoRA=複数Vol対応) |
| 期間 | タスク | 手法 | 目標一貫率 |
|---|---|---|---|
| Day 1 | MISAKO_OUTFIT_BY_STAGE 等の衣装定義表を play_modules に追加。NEGに競合キャラ衣装色を追加 | 手法1 | 65% |
| Day 2-3 | 各キャラのs1/s3/s5参照画像を最高品質カットから選定・保存。REF_IMAGES dict を作成 | 手法2準備 | 65% |
| Day 4-5 | IPAdapterモデルDL。ComfyUIワークフローにIPAdapterノード追加。smoke 4枚でweight調整 | 手法2 | 80% |
| Day 6-10 | 手法1+2 ハイブリッドで1Vol試験生成。Grok評価・CC目視で一貫性確認。weight微調整 | 手法1+2 | 82% |
| Day 11-20 | 主力キャラ(akari)のLoRA学習データセット作成100枚。キャプショニング | 手法3準備 | 82%維持 |
| Day 21-25 | akari LoRA学習(1600steps)。smoke で一貫性確認。weight=0.85でテスト | 手法3 | 90%(akariのみ) |
| Day 26-30 | akari LoRA本番投入。misako LoRA学習開始(並行)。1Vol量産・販売 | 手法1+2+3 | 90%+(akari) |
| 手法 | 失敗パターン | 判断基準 | 対策 |
|---|---|---|---|
| 手法2 IPAdapter | 「顔焼け」(顔が参照画像に引っ張られすぎる) | weight > 0.5 で発生しやすい | weight を 0.05 刻みで下げる・end_at を 0.7 に早める |
| 手法2 IPAdapter | 衣装が参照画像に強く引っ張られ、ポーズが固定される | 全画像がほぼ同じポーズになる | weight を 0.25 まで下げる・Composition weight は別設定 |
| 手法3 LoRA | 過学習(衣装は固定されるがポーズが固定化) | 全画像が学習データに似た構図になる | 学習ステップを減らす(1200以下)・データセットに多様なポーズを含める |
| 手法3 LoRA | 顔のみが固定で衣装がドリフトする | Illustrious LoRAは「顔への影響最小・衣装微影響」の傾向[11] | 衣装特化のキャプショニング強化 + 衣装LoRAを別途作成 |
| # | 原因 | 具体例 | 根本対策 |
|---|---|---|---|
| 1 | キャプションに衣装タグが入っていない(学習時) | LoRA学習データのキャプションから blue dress が漏れている | 学習前にキャプションを全件確認。「Filter by Tags」で衣装タグの出現率を確認[12] |
| 2 | プロンプト内で衣装タグの位置が後ろすぎる | 衣装タグが長いプロンプトの末尾にある | 衣装タグを先頭または先頭から20個以内に配置 |
| 3 | 別キャラの衣装色がNEGに入っていない | misako(黒)の生成中に hinata(ピンク)の衣装色が混入 | 競合色をNEGに追加(例: NEGに "pink lingerie" など) |
| 4 | ステージ移行時に衣装タグを引き継がずに書き換えた | s3で「突然別の色のブラ」が出現 | 前ステージの衣装を「除去を明示」しながら継承する記法を使う |
| 5 | シード値が変わるたびに衣装が変動する | seed1では黒ブラ・seed2ではピンクブラ | IPAdapter参照画像で衣装情報をseed非依存に固定 |
| 6 | loc に色名(pink/red/blue)を直接書いている | pink_lamp → 肌がピンクになる連鎖効果[3] | loc内の色名はamber/warm/softなど感情系に置き換える |
| 7 | IPAdapterの参照画像を毎回異なるものを使っている | 生成ごとに別の参照画像 → 毎回衣装が変わる | 同一キャラは常に同じ参照ファイルを使う[5] |
# play_modules_2026_05_29_outfit_patch.py
# D:\projects\fanza3_mass\scripts\play_modules_2026_05_20.py への追記
# ===== 衣装定義(手法1: テキストのみ版)=====
CHAR_OUTFIT_STAGES = {
"akari": {
"trigger": "akari_char", # LoRA学習後に使用
"hair": "black hair, straight hair, long hair",
"s1": "school uniform, dark blazer, white shirt, dark skirt",
"s2": "dark blazer open, white shirt unbuttoned, dark skirt, black bra visible",
"s3": "black lace bra, dark skirt, shirt removed",
"s4": "black lace lingerie, black panties, skirt removed",
"s5": "nude, completely naked, no clothes",
"neg_color": "pink lingerie, red lingerie, gold hair visible",
},
"misako": {
"trigger": "misako_char",
"hair": "light brown hair, medium length hair",
"s1": "office attire, dark navy blazer, white blouse, dark skirt",
"s2": "dark navy blazer open, white blouse unbuttoned, dark skirt, black bra strap visible",
"s3": "black lace bra, dark navy skirt, blouse removed",
"s4": "black lace lingerie, dark skirt removed",
"s5": "nude, completely naked, no clothes",
"neg_color": "pink lingerie, red lingerie, blonde hair",
},
"hinata": {
"trigger": "hinata_char",
"hair": "light brown hair, bob cut, short hair",
"s1": "casual wear, light pink cardigan, white top, jeans",
"s2": "light pink cardigan open, white top, jeans, pink bra strap visible",
"s3": "pink lace bra, jeans, cardigan removed",
"s4": "pink lingerie, pink panties",
"s5": "nude, completely naked, no clothes",
"neg_color": "black lingerie, red lingerie, long hair",
},
"rena": {
"trigger": "rena_char",
"hair": "blonde hair, long wavy hair",
"s1": "casual top, light jacket, jeans",
"s2": "light jacket open, casual top, jeans, red bra strap visible",
"s3": "red lace bra, jeans, jacket removed",
"s4": "red lingerie, red panties",
"s5": "nude, completely naked, no clothes",
"neg_color": "black lingerie, pink lingerie, dark hair",
},
}
# 参照画像マップ(手法2: IPAdapter用)
REF_IMAGES = {
"akari": {
"s1": r"D:\projects\fanza3_mass\ref_images\akari_s1.png",
"s3": r"D:\projects\fanza3_mass\ref_images\akari_s3.png",
"s5": r"D:\projects\fanza3_mass\ref_images\akari_s5.png",
},
# misako, hinata, rena を同様に追加
}
def get_outfit_prompt(char_name, stage):
"""衣装プロンプトを取得(手法1)"""
char = CHAR_OUTFIT_STAGES[char_name]
return f"{char['hair']}, {char[stage]}"
def get_outfit_neg(char_name):
"""衣装競合防止のNEGプロンプト(手法1)"""
return CHAR_OUTFIT_STAGES[char_name]["neg_color"]
def get_ref_image(char_name, stage):
"""IPAdapter参照画像パスを取得(手法2)"""
# ステージを s1/s3/s5 にマッピング
stage_key = "s1" if stage in ["s1","s2"] else ("s3" if stage == "s3" else "s5")
return REF_IMAGES.get(char_name, {}).get(stage_key, None)
# 使用例
# pos_outfit = get_outfit_prompt("akari", "s3")
# neg_outfit = get_outfit_neg("akari")
# ref_img = get_ref_image("akari", "s3")
適用ファイル: D:\projects\fanza3_mass\scripts\play_modules_2026_05_20.py の末尾に追記。gen_oudou_r18_master のプロンプト生成部分で get_outfit_prompt() を呼び出す。ComfyUI APIノード側でIPAdapterを設定する場合は get_ref_image() で参照画像パスを取得して渡す。