ComfyUI Character Generation Expert Build production-ready ComfyUI workflows for consistent character generation across image, video, and voice modalities. Quick Decision: Which Approach? Starting from reference images (like 3D renders)? → InfiniteYou (state-of-the-art 2025) or InstantID + IP-Adapter (proven, lower VRAM) Need highest identity fidelity? → FLUX.2 (NEW 2026: up to 10 ref images) or PuLID Flux II (no model pollution) Want iterative editing without retraining? → FLUX Kontext (context-aware, maintains consistency across edits) Creating video content? → LTX-2 (NEW 2026: 4K productio…

\\n'\n fi\n fi\n done \u003c \"$yaml_file\"\n\n if [[ -n \"$current_id\" ]]; then\n ids+=(\"$current_id\")\n printf '%s' \"$current_prompt\" > \"$RESULTS_DIR/prompts/${current_id}.txt\"\n fi\n\n echo \"${ids[@]}\"\n}\n\nCASE_IDS=($(extract_cases))\necho \"Found ${#CASE_IDS[@]} test cases: ${CASE_IDS[*]}\"\n\nif [[ -n \"$SINGLE_CASE\" ]]; then\n CASE_IDS=(\"$SINGLE_CASE\")\n echo \"Filtering to: $SINGLE_CASE\"\nfi\necho \"\"\n\n# ─── Run test cases ────────────────────────────────────────────────\n\nrun_case() {\n local case_id=\"$1\"\n local mode=\"$2\"\n local prompt_file=\"$RESULTS_DIR/prompts/${case_id}.txt\"\n local output_file=\"$RESULTS_DIR/$mode/${case_id}.md\"\n local prompt_text\n prompt_text=$(cat \"$prompt_file\")\n\n echo \" [$mode] Running $case_id...\"\n\n if [[ \"$mode\" == \"with-skill\" ]]; then\n local full_prompt=\"Use the $SKILL_NAME skill to answer this: $prompt_text\"\n claude -p \"$full_prompt\" \\\n --allowedTools \"Read,Glob,Grep\" \\\n --max-turns 3 \\\n --output-format text \\\n > \"$output_file\" 2>/dev/null || {\n echo \"EVAL_ERROR: claude command failed for $case_id ($mode)\" > \"$output_file\"\n }\n else\n claude -p \"$prompt_text\" \\\n --allowedTools \"Read,Glob,Grep\" \\\n --max-turns 3 \\\n --output-format text \\\n > \"$output_file\" 2>/dev/null || {\n echo \"EVAL_ERROR: claude command failed for $case_id ($mode)\" > \"$output_file\"\n }\n fi\n\n local wc_out\n wc_out=$(wc -w \u003c \"$output_file\" | tr -d ' ')\n echo \" [$mode] $case_id complete ($wc_out words)\"\n}\n\nif ! $SCORE_ONLY; then\n if $RUN_SKILL; then\n echo \"── With Skill ──\"\n for case_id in \"${CASE_IDS[@]}\"; do\n run_case \"$case_id\" \"with-skill\"\n done\n echo \"\"\n fi\n\n if $RUN_BASELINE; then\n echo \"── Baseline (no skill) ──\"\n for case_id in \"${CASE_IDS[@]}\"; do\n run_case \"$case_id\" \"baseline\"\n done\n echo \"\"\n fi\nfi\n\n# ─── Assertion evaluation helpers ──────────────────────────────────\n\n# Extract first JSON block from response\nextract_json() {\n local text=\"$1\"\n # Try ```json fenced block first\n local block\n block=$(echo \"$text\" | sed -n '/```json/,/```/p' | sed '1d;$d')\n if [[ -z \"$block\" ]]; then\n # Try bare { ... } block\n block=$(echo \"$text\" | grep -Pzo '\\{[^{}]*(\\{[^{}]*\\}[^{}]*)*\\}' 2>/dev/null | head -1 || true)\n fi\n echo \"$block\"\n}\n\n# Get a field value from JSON (uses python if available, else node)\njson_field() {\n local json=\"$1\"\n local field=\"$2\"\n if command -v python3 &>/dev/null; then\n echo \"$json\" | python3 -c \"\nimport sys, json\ntry:\n d = json.load(sys.stdin)\n v = d.get('$field', '')\n if isinstance(v, list): print(len(v))\n elif isinstance(v, (int, float)): print(v)\n else: print(v)\nexcept: print('')\n\" 2>/dev/null\n elif command -v node &>/dev/null; then\n echo \"$json\" | node -e \"\nlet d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{\n try{const o=JSON.parse(d);const v=o['$field'];\n if(Array.isArray(v))console.log(v.length);\n else console.log(v??'');}catch(e){console.log('');}\n})\" 2>/dev/null\n else\n echo \"\"\n fi\n}\n\n# Word count of a string\nword_count() {\n echo \"$1\" | wc -w | tr -d ' '\n}\n\n# ─── Score a single assertion ──────────────────────────────────────\n\neval_assertion() {\n local response=\"$1\"\n local atype=\"$2\"\n local target=\"$3\"\n local json_block=\"$4\"\n\n case \"$atype\" in\n contains)\n echo \"$response\" | grep -qi \"$target\" && echo \"PASS\" || echo \"FAIL\"\n ;;\n\n not_contains)\n # Handle descriptive targets: if target contains spaces and \"should not contain\",\n # try to extract the quoted literal(s)\n if [[ \"$target\" =~ \\'([^\\']+)\\' ]]; then\n local found=false\n while [[ \"$target\" =~ \\'([^\\']+)\\' ]]; do\n local literal=\"${BASH_REMATCH[1]}\"\n if echo \"$response\" | grep -qi \"$literal\"; then\n found=true\n break\n fi\n target=\"${target#*\"'${literal}'\"}\"\n done\n $found && echo \"FAIL\" || echo \"PASS\"\n else\n echo \"$response\" | grep -qi \"$target\" && echo \"FAIL\" || echo \"PASS\"\n fi\n ;;\n\n regex)\n echo \"$response\" | grep -qiE \"$target\" && echo \"PASS\" || echo \"FAIL\"\n ;;\n\n question_before_code)\n local q_line code_line\n q_line=$(echo \"$response\" | grep -n '?' | head -1 | cut -d: -f1)\n code_line=$(echo \"$response\" | grep -n '```' | head -1 | cut -d: -f1)\n if [[ -z \"$code_line\" ]] || [[ -n \"$q_line\" && \"$q_line\" -lt \"$code_line\" ]]; then\n echo \"PASS\"\n else\n echo \"FAIL\"\n fi\n ;;\n\n json_valid)\n if [[ -n \"$json_block\" ]]; then\n if command -v python3 &>/dev/null; then\n echo \"$json_block\" | python3 -c \"import sys,json;json.load(sys.stdin)\" 2>/dev/null && echo \"PASS\" || echo \"FAIL\"\n elif command -v node &>/dev/null; then\n echo \"$json_block\" | node -e \"let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{try{JSON.parse(d);console.log('PASS')}catch(e){console.log('FAIL')}})\" 2>/dev/null\n else\n echo \"SKIP\"\n fi\n else\n echo \"FAIL\"\n fi\n ;;\n\n json_schema|json_fields)\n # Target is comma-separated field names\n if [[ -z \"$json_block\" ]]; then\n echo \"FAIL\"\n return\n fi\n local all_found=true\n IFS=',' read -ra FIELDS \u003c\u003c\u003c \"$target\"\n for field in \"${FIELDS[@]}\"; do\n field=$(echo \"$field\" | xargs) # trim whitespace\n if ! echo \"$json_block\" | grep -q \"\\\"$field\\\"\"; then\n all_found=false\n break\n fi\n done\n $all_found && echo \"PASS\" || echo \"FAIL\"\n ;;\n\n token_limit)\n local wc\n wc=$(word_count \"$response\")\n local est_tokens=$(( wc * 13 / 10 ))\n [[ \"$est_tokens\" -le \"${target:-99999}\" ]] && echo \"PASS\" || echo \"FAIL\"\n ;;\n\n range_check)\n # Parse common patterns from the target expression\n if [[ -z \"$json_block\" ]]; then\n echo \"FAIL\"\n return\n fi\n\n # Handle: bias_score >= X AND bias_score \u003c= Y\n if [[ \"$target\" =~ ([a-z_]+)\\ *\\>=\\ *(-?[0-9.]+)\\ +AND\\ +\\1\\ *\\\u003c=\\ *(-?[0-9.]+) ]]; then\n local field=\"${BASH_REMATCH[1]}\"\n local min=\"${BASH_REMATCH[2]}\"\n local max=\"${BASH_REMATCH[3]}\"\n local val\n val=$(json_field \"$json_block\" \"$field\")\n if [[ -n \"$val\" ]] && command -v python3 &>/dev/null; then\n python3 -c \"v=$val; print('PASS' if $min \u003c= v \u003c= $max else 'FAIL')\" 2>/dev/null || echo \"FAIL\"\n else\n echo \"SKIP\"\n fi\n return\n fi\n\n # Handle: abs(field) \u003c= X\n if [[ \"$target\" =~ abs\\(([a-z_]+)\\)\\ *\\\u003c=\\ *(-?[0-9.]+) ]]; then\n local field=\"${BASH_REMATCH[1]}\"\n local limit=\"${BASH_REMATCH[2]}\"\n local val\n val=$(json_field \"$json_block\" \"$field\")\n if [[ -n \"$val\" ]] && command -v python3 &>/dev/null; then\n python3 -c \"v=$val; print('PASS' if abs(v) \u003c= $limit else 'FAIL')\" 2>/dev/null || echo \"FAIL\"\n else\n echo \"SKIP\"\n fi\n return\n fi\n\n # Handle: quality_score >= X\n if [[ \"$target\" =~ ([a-z_]+)\\ *\\>=\\ *(-?[0-9.]+)$ ]]; then\n local field=\"${BASH_REMATCH[1]}\"\n local min=\"${BASH_REMATCH[2]}\"\n local val\n val=$(json_field \"$json_block\" \"$field\")\n if [[ -n \"$val\" ]] && command -v python3 &>/dev/null; then\n python3 -c \"v=$val; print('PASS' if v >= $min else 'FAIL')\" 2>/dev/null || echo \"FAIL\"\n else\n echo \"SKIP\"\n fi\n return\n fi\n\n # Handle: len(field) >= X AND len(field) \u003c= Y (character length)\n if [[ \"$target\" =~ len\\(([a-z_]+)\\)\\ *\\>=\\ *([0-9]+)\\ +AND\\ +len\\(\\1\\)\\ *\\\u003c=\\ *([0-9]+) ]]; then\n local field=\"${BASH_REMATCH[1]}\"\n local min=\"${BASH_REMATCH[2]}\"\n local max=\"${BASH_REMATCH[3]}\"\n local val\n val=$(json_field \"$json_block\" \"$field\")\n local len=${#val}\n [[ \"$len\" -ge \"$min\" && \"$len\" -le \"$max\" ]] && echo \"PASS\" || echo \"FAIL\"\n return\n fi\n\n # Handle: len(field) \u003c= X\n if [[ \"$target\" =~ len\\(([a-z_]+)\\)\\ *\\\u003c=\\ *([0-9]+) ]]; then\n local field=\"${BASH_REMATCH[1]}\"\n local max=\"${BASH_REMATCH[2]}\"\n local val\n val=$(json_field \"$json_block\" \"$field\")\n local len=${#val}\n [[ \"$len\" -le \"$max\" ]] && echo \"PASS\" || echo \"FAIL\"\n return\n fi\n\n # Handle: len(field) >= X (list length)\n if [[ \"$target\" =~ len\\(([a-z_]+)\\)\\ *\\>=\\ *([0-9]+) ]]; then\n local field=\"${BASH_REMATCH[1]}\"\n local min=\"${BASH_REMATCH[2]}\"\n local val\n val=$(json_field \"$json_block\" \"$field\")\n [[ \"$val\" -ge \"$min\" ]] 2>/dev/null && echo \"PASS\" || echo \"FAIL\"\n return\n fi\n\n # Handle: word_count(field) >= X AND word_count(field) \u003c= Y\n if [[ \"$target\" =~ word_count\\(([a-z_]+)\\)\\ *\\>=\\ *([0-9]+)\\ +AND\\ +word_count\\(\\1\\)\\ *\\\u003c=\\ *([0-9]+) ]]; then\n local field=\"${BASH_REMATCH[1]}\"\n local min=\"${BASH_REMATCH[2]}\"\n local max=\"${BASH_REMATCH[3]}\"\n local val\n val=$(json_field \"$json_block\" \"$field\")\n local wc\n wc=$(word_count \"$val\")\n [[ \"$wc\" -ge \"$min\" && \"$wc\" -le \"$max\" ]] && echo \"PASS\" || echo \"FAIL\"\n return\n fi\n\n echo \"SKIP\" # Unrecognized expression\n ;;\n\n # Soft assertion types — logged but always PASS (require LLM judge)\n structure_check|sequence_check)\n echo \"SOFT\"\n ;;\n\n *)\n echo \"SKIP\"\n ;;\n esac\n}\n\n# ─── Score all assertions for a case ───────────────────────────────\n\nscore_case() {\n local case_id=\"$1\"\n local mode=\"$2\"\n local output_file=\"$RESULTS_DIR/$mode/${case_id}.md\"\n local score_file=\"$RESULTS_DIR/$mode/${case_id}.score.txt\"\n local response\n response=$(cat \"$output_file\" 2>/dev/null || echo \"\")\n\n if [[ \"$response\" == EVAL_ERROR* ]]; then\n echo \"ERROR\" > \"$score_file\"\n echo \"ERROR\"\n return\n fi\n\n local json_block\n json_block=$(extract_json \"$response\")\n\n local pass=0 fail=0 soft=0 skip=0 total=0\n local critical_fail=false\n local details=\"\"\n\n # Parse assertions from YAML\n local in_case=false\n local in_assertions=false\n local assert_type=\"\" assert_target=\"\" assert_critical=\"false\" assert_desc=\"\"\n\n process_assertion() {\n if [[ -z \"$assert_type\" ]]; then return; fi\n total=$((total + 1))\n local result\n result=$(eval_assertion \"$response\" \"$assert_type\" \"$assert_target\" \"$json_block\")\n\n case \"$result\" in\n PASS) pass=$((pass + 1)) ;;\n FAIL)\n fail=$((fail + 1))\n [[ \"$assert_critical\" == \"true\" ]] && critical_fail=true\n ;;\n SOFT) soft=$((soft + 1)) ;;\n SKIP) skip=$((skip + 1)) ;;\n esac\n\n local label=\"${assert_desc:-$assert_type($assert_target)}\"\n local crit_marker=\"\"\n [[ \"$assert_critical\" == \"true\" ]] && crit_marker=\" [CRITICAL]\"\n details+=\" $result$crit_marker — $label\"

ComfyUI Character Generation Expert Build production-ready ComfyUI workflows for consistent character generation across image, video, and voice modalities. Quick Decision: Which Approach? Starting from reference images (like 3D renders)? → InfiniteYou (state-of-the-art 2025) or InstantID + IP-Adapter (proven, lower VRAM) Need highest identity fidelity? → FLUX.2 (NEW 2026: up to 10 ref images) or PuLID Flux II (no model pollution) Want iterative editing without retraining? → FLUX Kontext (context-aware, maintains consistency across edits) Creating video content? → LTX-2 (NEW 2026: 4K productio…

\\n'\n }\n\n while IFS= read -r line; do\n if [[ \"$line\" =~ ^-\\ id:\\ $case_id$ ]]; then\n in_case=true\n continue\n fi\n if $in_case && [[ \"$line\" =~ ^-\\ id: ]]; then\n break\n fi\n\n if $in_case && [[ \"$line\" =~ ^\\ \\ \\ \\ -\\ type:\\ (.+) ]]; then\n process_assertion\n assert_type=\"${BASH_REMATCH[1]}\"\n assert_target=\"\"\n assert_critical=\"false\"\n assert_desc=\"\"\n fi\n if $in_case && [[ \"$line\" =~ ^\\ \\ \\ \\ \\ \\ target:\\ (.+) ]]; then\n assert_target=\"${BASH_REMATCH[1]}\"\n assert_target=\"${assert_target#\\\"}\"\n assert_target=\"${assert_target%\\\"}\"\n fi\n if $in_case && [[ \"$line\" =~ ^\\ \\ \\ \\ \\ \\ critical:\\ (.+) ]]; then\n assert_critical=\"${BASH_REMATCH[1]}\"\n fi\n if $in_case && [[ \"$line\" =~ ^\\ \\ \\ \\ \\ \\ description:\\ (.+) ]]; then\n assert_desc=\"${BASH_REMATCH[1]}\"\n assert_desc=\"${assert_desc#\\\"}\"\n assert_desc=\"${assert_desc%\\\"}\"\n fi\n done \u003c \"$SCRIPT_DIR/test-cases.yaml\"\n process_assertion # last assertion\n\n local anchored=$((pass + fail))\n local score_line=\"$pass/$total (${anchored} anchored, ${soft} soft, ${skip} skipped)\"\n if $critical_fail; then\n score_line+=\" [CRITICAL FAIL]\"\n fi\n\n {\n echo \"$score_line\"\n echo \"$details\"\n } > \"$score_file\"\n\n echo \"$score_line\"\n}\n\n# ─── Generate scorecard ───────────────────────────────────────────\n\ngenerate_scorecard() {\n local scorecard=\"$RESULTS_DIR/scorecard.md\"\n\n cat > \"$scorecard\" \u003c\u003cHEADER\n# Eval Scorecard — $SKILL_NAME\n**Timestamp:** $TIMESTAMP\n\n| Test Case | With Skill | Baseline |\n|-----------|-----------|----------|\nHEADER\n\n for case_id in \"${CASE_IDS[@]}\"; do\n local skill_score=\"—\"\n local base_score=\"—\"\n\n if $RUN_SKILL && [[ -f \"$RESULTS_DIR/with-skill/${case_id}.md\" ]]; then\n skill_score=$(score_case \"$case_id\" \"with-skill\")\n fi\n if $RUN_BASELINE && [[ -f \"$RESULTS_DIR/baseline/${case_id}.md\" ]]; then\n base_score=$(score_case \"$case_id\" \"baseline\")\n fi\n\n echo \"| $case_id | $skill_score | $base_score |\" >> \"$scorecard\"\n done\n\n echo \"\" >> \"$scorecard\"\n echo \"## Assertion Details\" >> \"$scorecard\"\n\n for case_id in \"${CASE_IDS[@]}\"; do\n echo \"\" >> \"$scorecard\"\n echo \"### $case_id\" >> \"$scorecard\"\n for mode in \"with-skill\" \"baseline\"; do\n if [[ -f \"$RESULTS_DIR/$mode/${case_id}.score.txt\" ]]; then\n echo \"**${mode}:**\" >> \"$scorecard\"\n echo '```' >> \"$scorecard\"\n cat \"$RESULTS_DIR/$mode/${case_id}.score.txt\" >> \"$scorecard\"\n echo '```' >> \"$scorecard\"\n fi\n done\n done\n\n echo \"\"\n echo \"=== Scorecard ===\"\n cat \"$scorecard\"\n}\n\ngenerate_scorecard\n\necho \"\"\necho \"=== Eval complete — $RESULTS_DIR/ ===\"\n","content_type":"application/x-sh; charset=utf-8","language":"bash","size":18242,"content_sha256":"4a5f64f9347e91d8bedb149ea5fd16263f0db37875164a5c584401f915567585"},{"filename":"eval/test-cases.yaml","content":"- id: TC-001\n name: simple-likeness-portrait\n prompt: \"I have a headshot photo and I want to generate a professional LinkedIn portrait in a different outfit and background\"\n assertions:\n - type: contains\n target: \"InstantID\"\n critical: false\n - type: regex\n target: \"(InstantID|PuLID|InfiniteYou|IP-Adapter|Kontext)\"\n description: \"Identity preservation method is recommended\"\n critical: true\n - type: regex\n target: \"(cfg|CFG|guidance).*[0-9]\"\n description: \"CFG scale recommendation is present with a numeric value\"\n critical: true\n - type: structure_check\n target: \"Resolution matches the base model used (e.g., 1024 for SDXL, 512 for SD1.5)\"\n description: \"Semantic check — resolution correctness depends on which model is selected\"\n critical: true\n expected_behavior: \"Recommends an appropriate identity preservation method for direct likeness transfer, with correct CFG and resolution settings for the chosen base model\"\n edge_case: false\n\n- id: TC-002\n name: 3d-render-to-photorealistic\n prompt: \"I have a 3D rendered character from Blender and want to convert it to a photorealistic photo while keeping the exact same face and pose\"\n assertions:\n - type: contains\n target: \"InfiniteYou\"\n critical: true\n - type: not_contains\n target: \"InstantID as primary method\"\n critical: false\n - type: contains\n target: \"cross-domain\"\n description: \"Method selection rationale explains cross-domain transfer capability\"\n critical: false\n - type: structure_check\n target: \"Method selection rationale explains why InfiniteYou handles cross-domain (3D to photo) better\"\n description: \"Semantic check — requires understanding of method selection reasoning\"\n critical: true\n - type: regex\n target: \"(denoise|strength).*(0\\\\.[5-7]|0\\\\.5|0\\\\.6|0\\\\.7)\"\n description: \"Denoise strength is moderate (0.5-0.7) to preserve pose while transforming style\"\n critical: false\n expected_behavior: \"Selects InfiniteYou as the primary method because it handles cross-domain identity transfer (3D to photo) better than InstantID, which struggles with non-photographic inputs\"\n edge_case: true\n\n- id: TC-003\n name: multi-reference-consistency\n prompt: \"I have 5 reference photos of a character from different angles. I need to generate this character in 10 different scenes maintaining consistent identity\"\n assertions:\n - type: regex\n target: \"(multiple|multi|several).*(reference|image|photo|angle)\"\n description: \"Multi-reference strategy is described (not just single image input)\"\n critical: true\n - type: structure_check\n target: \"Recommends a method that supports multiple reference images or describes how to combine references\"\n description: \"Semantic check — requires understanding of method capabilities for multi-reference\"\n critical: true\n - type: regex\n target: \"(batch|iterati|seed|consist)\"\n description: \"Batch/iteration strategy for generating 10 consistent scenes\"\n critical: false\n - type: structure_check\n target: \"Seed management or consistency strategy mentioned\"\n description: \"Semantic check — consistency approach may be described in varied ways\"\n critical: false\n expected_behavior: \"Addresses multi-reference input handling, recommends a method or strategy that leverages multiple angles for better identity preservation, and includes consistency strategy across multiple generations\"\n edge_case: false\n\n- id: TC-004\n name: instantid-cfg-override\n prompt: \"Set up an InstantID workflow for generating character portraits with high detail and sharpness\"\n assertions:\n - type: contains\n target: \"InstantID\"\n critical: true\n - type: regex\n target: \"(cfg|CFG).*(4|4\\\\.[0-9]|5|5\\\\.0)\"\n description: \"CFG scale is 4-5, NOT 7-8 or higher\"\n critical: true\n - type: not_contains\n target: \"cfg: 7\"\n critical: true\n - type: structure_check\n target: \"Explains that InstantID requires lower CFG to avoid artifacts or distortion\"\n description: \"Semantic check — requires understanding of the CFG/artifact tradeoff explanation\"\n critical: false\n expected_behavior: \"Uses InstantID as requested but correctly sets CFG to 4-5 range despite the user asking for 'high detail' — higher CFG with InstantID causes artifacts, not more detail\"\n edge_case: false\n\n- id: TC-005\n name: iterative-character-editing\n prompt: \"I generated a character portrait I like but want to change just the hairstyle while keeping everything else identical\"\n assertions:\n - type: contains\n target: \"Kontext\"\n critical: true\n - type: regex\n target: \"(edit|inpaint|mask|targeted|selective)\"\n description: \"Recommends edit-in-place method rather than full regeneration\"\n critical: true\n - type: structure_check\n target: \"Edit is targeted/masked rather than full image regeneration\"\n description: \"Semantic check — requires understanding whether the approach is truly targeted\"\n critical: true\n - type: not_contains\n target: \"regenerate from scratch\"\n critical: false\n expected_behavior: \"Selects FLUX Kontext for iterative editing because it supports targeted modifications while preserving the rest of the image, rather than suggesting full regeneration with identity preservation\"\n edge_case: false\n\n- id: TC-006\n name: low-vram-constraint\n prompt: \"I only have 8GB VRAM on my GPU. What's the best way to do identity-preserving character generation?\"\n assertions:\n - type: regex\n target: \"(8\\\\s*GB|VRAM|memory|GPU)\"\n critical: true\n description: \"Must acknowledge the VRAM constraint\"\n - type: regex\n target: \"(InstantID|PuLID|InfiniteYou|IP-Adapter)\"\n critical: true\n description: \"Must recommend a specific method\"\n - type: regex\n target: \"(SD1\\\\.5|SD 1\\\\.5|512|lightweight|smaller)\"\n critical: false\n description: \"Should suggest SD1.5 or lighter models for 8GB VRAM\"\n - type: not_contains\n target: \"SDXL is recommended\"\n critical: true\n description: \"Should not recommend SDXL as primary for 8GB VRAM\"\n expected_behavior: >\n 8GB VRAM is a hard constraint. SDXL-based workflows need ~10-12GB.\n The skill should recommend SD1.5-based methods or explain SDXL\n optimizations (--lowvram, fp16, model offloading) rather than blindly\n suggesting SDXL workflows.\n edge_case: true\n\n- id: TC-007\n name: no-reference-images\n prompt: \"I want to generate a consistent character across 20 images but I don't have any reference photos to start from\"\n assertions:\n - type: regex\n target: \"(generat|creat|first|initial).*reference\"\n critical: true\n description: \"Must address the missing reference problem\"\n - type: regex\n target: \"(txt2img|text.to.image|generate.*first|create.*base)\"\n critical: true\n description: \"Should suggest generating an initial reference\"\n - type: regex\n target: \"(seed|consist|same.*prompt|lock)\"\n critical: false\n description: \"Should mention seed/consistency strategies\"\n expected_behavior: >\n No reference images means identity preservation methods can't be used\n directly. The skill should suggest a workflow: generate a base character\n via txt2img, then use that as the reference for identity-preserving\n generation of the remaining 19 images.\n edge_case: true\n","content_type":"application/yaml; charset=utf-8","language":"yaml","size":7481,"content_sha256":"71aa515f164045ba16333ba469dc4ff1f3cd78a5a753396a2e255de925909a59"},{"filename":"eval/trigger-tests.yaml","content":"should_trigger:\n - \"I need to generate a consistent character across multiple images\"\n - \"How do I preserve someone's face when generating new images of them?\"\n - \"Build a character generation workflow that keeps identity consistent\"\n - \"I want to turn my 3D render into a photorealistic portrait keeping the same face\"\n - \"Set up an identity-preserving pipeline for generating character variations\"\n - \"Make a workflow for generating a person in different outfits while keeping their face\"\n - \"I need to create consistent character art for my game using reference photos\"\n - \"Help me use InstantID to generate portraits of my character\"\n - \"I want to generate images of a specific person in different scenes\"\n - \"Create a face-swapping workflow that maintains identity across poses\"\n\nshould_not_trigger:\n - \"Generate a landscape image with mountains\"\n - \"Build a ComfyUI workflow for text-to-image\"\n - \"Help me write a prompt for an anime character\"\n - \"How do I train a LoRA on character images?\"\n - \"Explain how IP-Adapter works technically\"\n - \"Review my ComfyUI workflow for performance issues\"\n - \"Generate a random character design with no reference\"\n - \"Help me animate a character walking\"\n - \"What's the best model for generating food photography?\"\n - \"Edit the background of this image without changing the subject\"\n\noptimized_description: >\n Build identity-preserving character generation workflows and pipelines in ComfyUI.\n Selects the optimal identity method (InfiniteYou, FLUX Kontext, PuLID, InstantID) based on\n use case requirements. Handles face preservation, likeness transfer, cross-domain conversion\n (3D to photo), multi-reference consistency, iterative character editing, and character\n variation generation. Does NOT cover general image generation without identity preservation,\n model training/LoRA fine-tuning, animation, technical explanations, or workflow debugging.\n","content_type":"application/yaml; charset=utf-8","language":"yaml","size":1923,"content_sha256":"5fe60d7aca4bf5f09f7cda5c760475d0f9ecf63308f4bb6f897c2986ea1d6d9d"},{"filename":"references/evolution.md","content":"# Skill Evolution & Update Protocol\n\nThis skill is designed to evolve continuously. Monitor these sources and update accordingly.\n\n---\n\n## Sources to Monitor\n\n### Model Releases (Check Weekly)\n\n**HuggingFace Trending**\n- https://huggingface.co/models?sort=trending\n- Filter: diffusers, video, audio\n- Watch for: New FLUX variants, Wan updates, voice models\n\n**Civitai New Models**\n- https://civitai.com/models?sort=Newest\n- Filter: Checkpoint, LoRA, ControlNet\n- Watch for: New photorealistic checkpoints, face LoRAs\n\n**GitHub Releases**\n- https://github.com/comfyanonymous/ComfyUI/releases\n- https://github.com/Kosinkadink/ComfyUI-AnimateDiff-Evolved/releases\n- https://github.com/cubiq/ComfyUI_IPAdapter_plus/releases\n- https://github.com/cubiq/ComfyUI_InstantID/releases\n- https://github.com/ltdrdata/ComfyUI-Impact-Pack/releases\n\n### Research & Techniques (Check Monthly)\n\n**Papers**\n- https://huggingface.co/papers (daily ML papers)\n- https://arxiv.org/list/cs.CV/recent (computer vision)\n- Search terms: \"identity preservation\", \"video generation\", \"voice cloning\", \"diffusion\"\n\n**Community Knowledge**\n- r/StableDiffusion\n- r/comfyui\n- ComfyUI Discord\n- Civitai articles/guides\n\n### Video Model Landscape (Check Bi-Weekly)\n\n**Open Source**\n- Wan series (Alibaba) - watch for 2.3+\n- HunyuanVideo (Tencent)\n- CogVideoX (Zhipu)\n- LTX Video (Lightricks)\n- Mochi (Genmo)\n\n**Commercial (for benchmarking)**\n- Kling (Kuaishou)\n- Runway Gen-3\n- Pika\n- Sora (OpenAI)\n\n### Voice/Audio (Check Monthly)\n\n- https://github.com/SWivid/F5-TTS/releases\n- https://github.com/resemble-ai/chatterbox/releases\n- ElevenLabs blog for new features\n- Fish Audio, Cartesia for emerging options\n\n---\n\n## Update Protocol\n\n### When New Model Drops\n\n1. **Evaluate relevance**: Does it improve on current recommendations?\n2. **Test compatibility**: Works with ComfyUI? Required nodes available?\n3. **Benchmark**: Compare quality/speed vs current options\n4. **Update files**:\n - `models.md`: Add download links, paths, requirements\n - `workflows.md`: Add/modify workflow if needed\n - `SKILL.md`: Update recommendation tables if it becomes new default\n5. **Log change**: Add to changelog below\n\n### When User Reports Issue\n\n1. **Document the issue**: What workflow, what settings, what result\n2. **Research solutions**: Community fixes, parameter adjustments\n3. **Test fix**: Verify solution works\n4. **Update relevant file**: Add troubleshooting entry or modify settings\n5. **Log change**: Add to changelog\n\n### When User Discovers Better Approach\n\n1. **Document the discovery**: What worked better and why\n2. **Validate**: Test in multiple scenarios\n3. **Integrate**: Update workflows.md with new approach\n4. **Promote if significant**: Update SKILL.md recommendations\n\n---\n\n## Changelog\n\n### v1.2.0 (2026-02-18 Research Run)\n**NEW MODELS:**\n- **Z-Image**: Day-0 ComfyUI support (Feb 2, 2026) — non-distilled, flexible quality, NVFP4/NVFP8\n- **Hunyuan 3D 3.0**: Text/image/sketch → 3D assets via Partner Nodes (Feb 16, 2026)\n- **Kling 3.0**: Commercial-quality video via Partner Nodes (Feb 16, 2026)\n- **Stable Video Infinity 2.0 Pro**: Infinite-length video with Wan 2.2 I2V A14B\n\n**IDENTITY & CHARACTER:**\n- **PuLID Flux Chroma**: New fork extending PuLID to FLUX + Chroma models\n- **USO (ByteDance)**: FLUX.1-dev based unified style+subject generation — no more fighting the model for style fidelity\n- **FLUX Kontext**: Confirmed community gold standard for single-reference consistent character editing\n\n**PERFORMANCE (CRITICAL):**\n- NVFP4 requires PyTorch cu130 — without it, NVFP4 is up to 2x SLOWER than FP8\n- ComfyUI +40% on all NVIDIA GPUs (async offload + pinned memory now default)\n- NVFP4 = 3x faster / 60% VRAM reduction on RTX 50 Series\n- NVFP8 = 2x faster / 40% VRAM reduction (any NVIDIA GPU)\n- AMD ROCm native integration: 5.4x faster for AMD GPUs\n\n**NEW FEATURE:**\n- Added `comfyui-prompt-interview` skill — conversational guided interview that synthesizes a perfect model-appropriate prompt from user answers\n\n**FILES UPDATED:**\n- `references/staleness-report.md` — first full research run logged\n- `foundation/model-landscape.md` — Z-Image, SVI 2.0 Pro, Kling 3.0, Hunyuan 3D 3.0 added\n- `references/research-log.md` — 2026 section appended\n- `foundation/skill-registry.md` — new prompt-interview skill registered\n\n### v1.1.0 (February 2026 Update)\n**NEW MODELS & FEATURES:**\n- **FLUX.2**: Up to 10 reference images for maximum identity consistency\n- **LTX-2**: First production-ready open-source 4K audio+video generation\n- **AuraFace**: Commercial-friendly identity encoder (ArcFace alternative)\n- **F5-TTS Cross-Lingual**: Cross-lingual voice cloning without transcripts\n- **DiffSwap++**: 3D latent-controlled face swapping\n\n**PLATFORM UPDATES:**\n- **ComfyUI v0.8.1**: NVFP4/NVFP8 support (3x faster, 60% VRAM reduction on RTX 50 Series)\n- Native AMD ROCm integration for AMD GPUs\n- Audio recording node for direct audio capture\n- Weight streaming memory management\n\n**DOCUMENTATION:**\n- Added 2026 updates section to research-log.md\n- Updated all model recommendation tables\n- Updated Quick Decision guide with 2026 options\n- Updated RTX optimization section for v0.8.1\n\n### v1.0.0 (Initial Release)\n- Core workflows: InstantID, IP-Adapter, PuLID, AnimateDiff, Wan 2.1\n- Model reference with 2024-2025 state of the art\n- LoRA training guide for SDXL and FLUX\n- Voice synthesis covering Chatterbox, F5-TTS, RVC, ElevenLabs\n- Lip-sync pipelines: Wav2Lip, SadTalker, LivePortrait\n\n---\n\n## User-Specific Learnings\n\nTrack what works best for this user's specific setup and preferences.\n\n### Hardware Profile\n- GPU: RTX 5090 (32GB VRAM)\n- Can run: All models natively, including Wan 14B, FLUX FP16\n- Optimization: Use --highvram, batch processing enabled\n\n### Project: Sage Character\n- Source: 3D renders (visual novel style)\n- Target: Photorealistic output\n- Key features: Auburn hair, green eyes, freckles, fair skin\n- Recommended approach: InstantID + IP-Adapter → test → train LoRA if needed\n\n### Workflow Preferences\n(To be filled as user works with skill)\n- Preferred checkpoint: [TBD]\n- Preferred upscaler: [TBD]\n- CFG sweet spot: [TBD]\n- Face detailer settings: [TBD]\n\n### What Worked Well\n(Document successful approaches)\n\n### What Didn't Work\n(Document failed approaches to avoid repeating)\n\n---\n\n## Scheduled Research Tasks\n\n**Weekly**\n- [ ] Check HuggingFace trending for new models\n- [ ] Check ComfyUI releases for breaking changes\n- [ ] Review any user feedback from recent sessions\n\n**Monthly**\n- [ ] Deep dive on any major new releases\n- [ ] Review video model landscape\n- [ ] Check voice synthesis developments\n- [ ] Update changelog if needed\n\n**Quarterly**\n- [ ] Full skill audit - are recommendations still current?\n- [ ] Remove deprecated models/methods\n- [ ] Add any new paradigm shifts\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":6831,"content_sha256":"d4b142f42eaaa7a390b5dcb85517079b5bf4b105a942dbd3e69edf5d577b3677"},{"filename":"references/lora-training.md","content":"# LoRA Training Guide for Character Consistency\n\nTraining custom LoRAs from reference images (including 3D renders) for maximum character consistency.\n\n---\n\n## When to Train vs Zero-Shot\n\n**Train a LoRA when:**\n- Need absolute consistency across many images\n- Building a character series or ongoing project\n- Zero-shot methods don't capture specific features\n- Want to combine with prompts for varied outputs\n\n**Use zero-shot (InstantID/PuLID) when:**\n- Quick one-off generation\n- Limited reference images (1-5)\n- Need style transfer (3D→realistic)\n- Testing concepts before committing to training\n\n---\n\n## Dataset Preparation\n\n### Minimum Viable Dataset\n- **10-15 images** minimum for recognizable results\n- **20-30 images** optimal for strong identity\n- **50+ images** for highly flexible, robust LoRA\n\n### Image Requirements\n\n**Technical specs:**\n- Resolution: 512×512 minimum, 1024×1024 preferred\n- Format: PNG or high-quality JPEG\n- File size: No compression artifacts\n\n**Content diversity:**\n- Multiple angles (front, 3/4, profile)\n- Various expressions (neutral, smile, serious, etc.)\n- Different lighting conditions\n- Varied backgrounds (or transparent/solid)\n- Multiple outfits/contexts\n\n### Preprocessing 3D Renders\n\n**Problem:** Training on 3D renders can bake in the \"3D render\" aesthetic.\n\n**Solution:** Convert renders to varied styles before training:\n\n```python\n# Use img2img to create style variations\nstyles = [\n \"photorealistic portrait, dslr photo\",\n \"oil painting portrait\", \n \"digital illustration\",\n \"pencil sketch\",\n \"watercolor portrait\"\n]\n# Generate 3-5 variations per base render\n# Include original renders + variations in training set\n```\n\nThis teaches the model the identity, not the style.\n\n### Cropping Strategy\n\n**For face-focused LoRA:**\n- Square crop centered on face\n- Face should occupy 50-70% of frame\n- Include some neck/shoulders for context\n- Consistent framing across dataset\n\n**For full-body LoRA:**\n- Include full body shots\n- Mix with face close-ups (70/30 ratio)\n- Maintain consistent proportions\n\n### Captioning\n\n**Method 1: Auto-caption with JoyCaption + Manual Edit**\n```bash\n# Run JoyCaption\npython caption.py --input ./images --output ./captions\n\n# Then manually add trigger word and remove identity descriptions\n```\n\n**Method 2: WD14 Tags + Sentence**\n```\nsage_character, 1woman, green eyes, freckles, looking at viewer, \nwhite shirt, indoor, soft lighting\n```\n\n**Critical captioning rules:**\n\n1. **Always prefix with unique trigger word:**\n - Good: `sage_character`, `ohwx_sage`, `sks_person`\n - Bad: `woman`, `redhead`, `character` (too generic)\n\n2. **Don't describe the face in detail:**\n - Bad: \"woman with green eyes, freckles, auburn hair, defined cheekbones\"\n - Good: \"sage_character, woman, indoor portrait\"\n - Let the model learn features organically\n\n3. **Do describe everything else:**\n - Clothing, pose, background, lighting, camera angle\n - Expression (smiling, serious, etc.)\n - Style cues (photorealistic, illustration, etc.)\n\n4. **Keep captions consistent in structure:**\n ```\n [trigger], [subject], [clothing], [pose], [setting], [lighting], [style]\n ```\n\n---\n\n## Training Parameters\n\n### SDXL LoRA (Kohya_ss)\n\n**Config file settings:**\n```yaml\n# Basic settings\npretrained_model_name_or_path: \"./models/RealVisXL_V5.0.safetensors\"\ntrain_data_dir: \"./dataset/sage\"\noutput_dir: \"./output\"\noutput_name: \"sage_character_sdxl\"\n\n# Network settings\nnetwork_module: \"networks.lora\"\nnetwork_dim: 32 # Rank - 16-64, higher = more capacity\nnetwork_alpha: 16 # Usually dim/2\n\n# Training settings \nresolution: \"1024,1024\"\ntrain_batch_size: 1 # 2 if VRAM allows\ngradient_accumulation_steps: 4\nlearning_rate: 0.0001 # 1e-4, can try 4e-4\nlr_scheduler: \"cosine_with_restarts\"\nlr_scheduler_num_cycles: 3\nmax_train_epochs: 10\noptimizer_type: \"AdamW8bit\"\n\n# Quality settings\nmixed_precision: \"bf16\"\nsave_precision: \"fp16\"\ncache_latents: true\ncache_latents_to_disk: true\nenable_bucket: true\nmin_bucket_reso: 512\nmax_bucket_reso: 2048\n\n# Regularization (optional but recommended)\nprior_loss_weight: 1.0\nmin_snr_gamma: 5\n```\n\n**Recommended steps calculation:**\n```\ntotal_steps = (num_images × repeats × epochs) / batch_size\ntarget: 1500-3000 steps for SDXL\n\nExample: 20 images × 10 repeats × 5 epochs / 1 batch = 1000 steps\n```\n\n### FLUX LoRA (AI-Toolkit)\n\n**Config YAML:**\n```yaml\njob: extension\nconfig:\n name: \"sage_character_flux\"\n process:\n - type: sd_trainer\n training_folder: \"./output\"\n device: cuda:0\n \n network:\n type: lora\n linear: 16 # Rank\n linear_alpha: 16 # Alpha = rank for FLUX\n \n model:\n name_or_path: \"black-forest-labs/FLUX.1-dev\"\n assistant_lora_path: null\n quantize: true # Enable for \u003c24GB VRAM\n \n datasets:\n - folder_path: \"./dataset/sage\"\n caption_ext: \"txt\"\n default_caption: \"sage_character\"\n resolution: [1024]\n \n train:\n batch_size: 1\n gradient_accumulation_steps: 4\n steps: 1500 # FLUX converges faster\n lr: 4e-4 # Higher LR for FLUX\n optimizer: adamw8bit\n dtype: bf16\n \n sample:\n sample_every: 250\n prompts:\n - \"sage_character, photorealistic portrait, green eyes\"\n```\n\n**FLUX training notes:**\n- Converges 2-3x faster than SDXL\n- Use higher learning rate (4e-4 vs 1e-4)\n- 1000-2000 steps usually sufficient\n- Quality plateaus earlier, watch for overfitting\n\n### Low VRAM Training (FluxGym)\n\nFor 12-16GB VRAM:\n\n```yaml\n# Enable all memory optimizations\nuse_8bit_adam: true\ngradient_checkpointing: true\ncache_latents_to_disk: true\nmax_data_loader_n_workers: 0\n\n# Reduce batch processing\ntrain_batch_size: 1\ngradient_accumulation_steps: 8\n\n# Use NF4 quantization (SimpleTuner)\nquantize_base_model: nf4\n```\n\n---\n\n## Training Workflow\n\n### Step 1: Prepare Dataset\n```bash\n# Create folder structure\nmkdir -p dataset/sage/10_sage_character\n\n# Place images (naming: 001.png, 002.png, ...)\n# Place captions (naming: 001.txt, 002.txt, ...)\n```\n\nFolder naming: `[repeats]_[trigger word]`\n- `10_sage_character` = each image repeated 10 times per epoch\n\n### Step 2: Run Training (Kohya)\n```bash\n# Navigate to kohya_ss\ncd kohya_ss\n\n# Start training with config\naccelerate launch train_network.py --config_file ./config/sage_train.yaml\n```\n\n### Step 3: Test Checkpoints\n- Training saves checkpoints every N steps\n- Test each checkpoint with identical prompts\n- Look for: identity accuracy, flexibility, overfitting signs\n\n### Step 4: Select Best Epoch\n**Signs of good training:**\n- Character recognizable from trigger word alone\n- Responds well to different prompts/contexts\n- Doesn't always produce same pose/expression\n\n**Signs of overfitting:**\n- Same exact pose/expression regardless of prompt\n- Background elements from training appearing\n- Ignores clothing/setting prompts\n\n---\n\n## Recommended Settings by Use Case\n\n### 3D Render → Photorealistic Character\n\n```yaml\n# Preprocessing\n- Convert 3D renders to varied styles first\n- Mix: 60% style variations, 40% original renders\n\n# Training\nnetwork_dim: 32\nlearning_rate: 0.0001\nepochs: 8-10\nsteps: ~2000\n\n# Testing\n- Test with InstantID/PuLID combination\n- LoRA provides base identity, zero-shot methods add realism\n```\n\n### Anime/Stylized Character\n\n```yaml\n# Use anime-focused base model\npretrained_model: \"animagineXL\" OR \"ponyDiffusion\"\n\n# Training\nnetwork_dim: 48-64 # Higher for style complexity\nlearning_rate: 0.00008\nepochs: 12-15\n\n# Include style tags\ncaptions: \"sage_character, anime style, 1girl, ...\"\n```\n\n### Video-Ready Character LoRA\n\n```yaml\n# Include motion diversity in training\n- Standing, sitting, walking poses\n- Various arm positions\n- Multiple head angles\n\n# Training (slightly overfit for consistency)\nnetwork_dim: 24\nepochs: 12\n# Test with AnimateDiff to verify motion compatibility\n```\n\n---\n\n## Combining LoRA with Zero-Shot Methods\n\n**Best practice: LoRA as base, zero-shot for enhancement**\n\n```\n[Load Checkpoint]\n ↓\n[Load Character LoRA (0.7-0.9 strength)]\n ↓\n[Apply PuLID or IP-Adapter (0.5-0.7 weight)]\n ↓\n[Generate]\n```\n\nThis approach:\n- LoRA provides learned identity from training\n- Zero-shot method reinforces specific reference features\n- Lower weights on both prevent conflict\n- More robust than either method alone\n\n---\n\n## Troubleshooting\n\n### LoRA not activating\n- Verify trigger word exactly matches training\n- Check LoRA strength (start at 0.8)\n- Ensure LoRA loaded BEFORE KSampler\n\n### Identity drift at different angles\n- Add more varied angles to dataset\n- Reduce network_dim (16-24)\n- Lower learning rate\n\n### Overfitting (same output every time)\n- Reduce epochs\n- Increase dataset size\n- Lower network_dim\n- Add more caption variety\n\n### Style contamination (looks like training images)\n- Better caption diversity\n- Don't describe style in captions\n- Use style-varied preprocessing\n\n### Poor quality/artifacts\n- Check training images for compression artifacts\n- Reduce learning rate\n- Enable min_snr_gamma\n- Try different optimizer\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":9145,"content_sha256":"474bbafff2c86359f75e0d502125980f63ab9e161d2ccc48ab8cf002a6c514b3"},{"filename":"references/models.md","content":"# Model Reference Guide\n\nComplete specifications for all recommended models. Download links, file paths, and compatibility notes.\n\n## Directory Structure\n\n```\nComfyUI/\n├── models/\n│ ├── checkpoints/ # Base models (FLUX, SDXL, SD1.5)\n│ ├── loras/ # LoRA adapters\n│ ├── controlnet/ # ControlNet models\n│ ├── clip_vision/ # CLIP vision encoders\n│ ├── ipadapter/ # IP-Adapter models\n│ ├── instantid/ # InstantID models\n│ ├── insightface/ # Face analysis models\n│ ├── facerestore_models/ # Face restoration (GFPGAN, CodeFormer)\n│ ├── ultralytics/bbox/ # Detection models\n│ ├── upscale_models/ # Upscaler models\n│ └── diffusion_models/ # Video diffusion models (Wan)\n└── custom_nodes/\n └── ComfyUI-AnimateDiff-Evolved/models/ # Motion modules\n```\n\n---\n\n## Checkpoint Models\n\n### FLUX.1-dev (Recommended for Photorealism)\n- **Download**: https://huggingface.co/black-forest-labs/FLUX.1-dev\n- **Files**: `flux1-dev.safetensors` (23.8GB)\n- **Path**: `models/checkpoints/`\n- **Also requires**: \n - T5 encoder: `t5xxl_fp16.safetensors` → `models/clip/`\n - CLIP-L: `clip_l.safetensors` → `models/clip/`\n - VAE: `ae.safetensors` → `models/vae/`\n- **VRAM**: 16GB+ (FP16), 10GB (FP8)\n- **Notes**: Best photorealism, slow generation. Use `--fp8_e4m3fn-unet` for VRAM savings.\n\n### FLUX Kontext (Character Editing)\n- **Download**: https://huggingface.co/black-forest-labs/FLUX.1-Kontext-dev\n- **Path**: `models/checkpoints/`\n- **Use case**: Edit existing character images without retraining\n- **VRAM**: 16GB+\n\n### RealVisXL V5.0 (Fast SDXL Photorealism)\n- **Download**: https://civitai.com/models/139562/realvisxl-v50\n- **File**: `RealVisXL_V5.0.safetensors`\n- **Path**: `models/checkpoints/`\n- **VRAM**: 8GB+\n- **Notes**: Good balance of speed and quality for SDXL workflows\n\n### Juggernaut XL Ragnarok\n- **Download**: https://civitai.com/models/133005/juggernaut-xl\n- **Path**: `models/checkpoints/`\n- **VRAM**: 8GB+\n- **Notes**: Excellent for diverse human subjects\n\n---\n\n## Identity Preservation Models\n\n### InstantID\n- **IP-Adapter**: https://huggingface.co/InstantX/InstantID\n - File: `ip-adapter.bin` → `models/instantid/`\n- **ControlNet**: Same repo\n - File: `ControlNetModel/diffusion_pytorch_model.safetensors` → `models/controlnet/`\n - Rename to: `instantid_controlnet.safetensors`\n- **Requires**: InsightFace `antelopev2` model\n- **VRAM**: 8GB+ additional\n\n### IP-Adapter FaceID Plus V2\n- **Download**: https://huggingface.co/h94/IP-Adapter-FaceID\n- **Files**:\n - `ip-adapter-faceid-plusv2_sd15.bin` → `models/ipadapter/`\n - `ip-adapter-faceid-plusv2_sd15_lora.safetensors` → `models/loras/`\n- **VRAM**: 6GB+ additional\n- **Notes**: Faster than InstantID, auto-loads paired LoRA\n\n### IP-Adapter SDXL\n- **Download**: https://huggingface.co/h94/IP-Adapter\n- **Files**:\n - `ip-adapter_sdxl_vit-h.safetensors` → `models/ipadapter/`\n - `ip-adapter-plus_sdxl_vit-h.safetensors` → `models/ipadapter/`\n - `ip-adapter-plus-face_sdxl_vit-h.safetensors` → `models/ipadapter/`\n- **CLIP Vision**: `CLIP-ViT-H-14-laion2B-s32B-b79K.safetensors` → `models/clip_vision/`\n\n### PuLID Flux II\n- **Download**: https://huggingface.co/guozinan/PuLID\n- **File**: `pulid_flux_v0.9.1.safetensors` → `models/pulid/`\n- **Requires**: EVA-CLIP model\n- **VRAM**: 16GB+\n- **Notes**: Highest fidelity, no model pollution, slowest\n\n### InsightFace (Required for all face methods)\n- **Download**: https://huggingface.co/datasets/Gourieff/ReActor/tree/main/models\n- **Files**:\n - `inswapper_128.onnx` → `models/insightface/`\n - `buffalo_l/` folder → `models/insightface/models/buffalo_l/`\n - `antelopev2/` folder → `models/insightface/models/antelopev2/`\n\n---\n\n## ControlNet Models\n\n### SDXL ControlNet\n- **OpenPose**: `control-lora-openposeXL2-rank256.safetensors`\n- **Depth**: `control-lora-depth-rank256.safetensors`\n- **Canny**: `control-lora-canny-rank256.safetensors`\n- **Download**: https://huggingface.co/stabilityai/control-lora\n- **Path**: `models/controlnet/`\n\n### FLUX ControlNet (Union)\n- **Download**: https://huggingface.co/InstantX/FLUX.1-dev-Controlnet-Union\n- **File**: `diffusion_pytorch_model.safetensors`\n- **Path**: `models/controlnet/`\n- **Notes**: Single model handles multiple control types\n\n### SD 1.5 ControlNet\n- **Download**: https://huggingface.co/lllyasviel/ControlNet-v1-1\n- **Files**: `control_v11p_sd15_openpose.pth`, etc.\n- **Path**: `models/controlnet/`\n\n---\n\n## Face Restoration Models\n\n### CodeFormer\n- **Download**: https://github.com/sczhou/CodeFormer/releases\n- **File**: `codeformer.pth` → `models/facerestore_models/`\n\n### GFPGAN\n- **Download**: https://github.com/TencentARC/GFPGAN/releases\n- **File**: `GFPGANv1.4.pth` → `models/facerestore_models/`\n\n### RestoreFormer\n- **Download**: https://github.com/wzhouxiff/RestoreFormer\n- **File**: `RestoreFormer.pth` → `models/facerestore_models/`\n\n---\n\n## Detection Models (for FaceDetailer)\n\n### YOLO Face Detection\n- **Download**: https://huggingface.co/Bingsu/adetailer/tree/main\n- **Files**:\n - `face_yolov8m.pt` → `models/ultralytics/bbox/`\n - `face_yolov8n.pt` → `models/ultralytics/bbox/`\n - `hand_yolov8n.pt` → `models/ultralytics/bbox/`\n\n### SAM (Segment Anything)\n- **Download**: https://huggingface.co/spaces/abhishek/StableSAM/tree/main\n- **File**: `sam_vit_b_01ec64.pth` → `models/sams/`\n\n---\n\n## Upscale Models\n\n### 4x-UltraSharp\n- **Download**: https://civitai.com/models/116225/4x-ultrasharp\n- **Path**: `models/upscale_models/`\n- **Notes**: Best for faces and fine detail\n\n### 4x-Foolhardy-Remacri\n- **Download**: https://civitai.com/models/40067\n- **Path**: `models/upscale_models/`\n- **Notes**: Good general purpose\n\n### SUPIR\n- **Download**: https://huggingface.co/Kijai/SUPIR_pruned\n- **Path**: `models/upscale_models/`\n- **Notes**: AI-enhanced upscaling, slower but better quality\n\n---\n\n## Video Models\n\n### Wan 2.1 (Recommended)\n- **14B T2V**: `wan2.1_t2v_14b_bf16.safetensors`\n- **14B I2V**: `wan2.1_i2v_720p_14b_bf16.safetensors`\n- **1.3B T2V**: `wan2.1_t2v_1.3b_bf16.safetensors`\n- **Download**: https://huggingface.co/Wan-AI/Wan2.1-Preview\n- **Path**: `models/diffusion_models/`\n- **Text Encoder**: `umt5_xxl_fp8_e4m3fn_scaled.safetensors` → `models/clip/`\n- **CLIP**: `open_clip_vit_h_14.safetensors` → `models/clip_vision/`\n- **VAE**: `wan_2.1_vae.safetensors` → `models/vae/`\n\n### AnimateDiff\n- **Motion Module V3**: `v3_sd15_mm.ckpt`\n- **Lightning (fast)**: `animatediff_lightning_4step.safetensors`\n- **Download**: https://huggingface.co/guoyww/animatediff\n- **Path**: `custom_nodes/ComfyUI-AnimateDiff-Evolved/models/`\n\n### Motion LoRAs\n- **Download**: https://huggingface.co/guoyww/animatediff/tree/main/motion_lora\n- **Files**: `v2_lora_ZoomIn.ckpt`, `v2_lora_PanLeft.ckpt`, etc.\n- **Path**: `custom_nodes/ComfyUI-AnimateDiff-Evolved/motion_lora/`\n\n---\n\n## Voice/Lip-Sync Models\n\n### Wav2Lip\n- **Download**: https://github.com/Rudrabha/Wav2Lip\n- **Files**: \n - `wav2lip_gan.pth` (better quality)\n - `wav2lip.pth` (faster)\n- **Path**: Varies by ComfyUI node implementation\n\n### SadTalker\n- **Download**: https://github.com/OpenTalker/SadTalker\n- **Required models**: Multiple, see repo releases\n- **Notes**: Generates head motion + expressions from audio\n\n### LivePortrait\n- **Download**: https://github.com/KwaiVGI/LivePortrait\n- **Notes**: Best expression control, non-commercial license for InsightFace components\n\n---\n\n## LoRA Training Tools\n\n### Kohya_ss (SDXL/SD1.5)\n- **Repo**: https://github.com/bmaltais/kohya_ss\n- **Notes**: Most mature, GUI available\n\n### AI-Toolkit (FLUX)\n- **Repo**: https://github.com/ostris/ai-toolkit\n- **Notes**: Beginner-friendly, 24GB VRAM for standard training\n\n### SimpleTuner (FLUX, Advanced)\n- **Repo**: https://github.com/bghira/SimpleTuner\n- **Notes**: NF4 quantization enables 9GB VRAM training\n\n### FluxGym (Low VRAM FLUX)\n- **Repo**: https://github.com/cocktailpeanut/fluxgym\n- **Notes**: Optimized for 12-16GB VRAM\n\n---\n\n## Skin Texture LoRAs (Combine with Character LoRA)\n\n### Realistic Skin Texture\n- **Download**: https://civitai.com/models/238756\n- **File**: `Realistic_Skin_Texture_SkinF1dV2.5.safetensors`\n- **Path**: `models/loras/`\n- **Strength**: 0.2-0.4 (subtle enhancement)\n\n### Detail Tweaker\n- **Download**: https://civitai.com/models/122359\n- **Path**: `models/loras/`\n- **Notes**: Enhances fine detail without changing style\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":8559,"content_sha256":"724fae5c4b0b2ea2e69396ad51e011b0e5f341ab1e16a74f20666cfb7e2ee9e8"},{"filename":"references/research-2025.md","content":"# ComfyUI Character Generation: 2024-2025 Comprehensive Techniques Guide\n\nThe ComfyUI ecosystem has undergone a dramatic transformation since 2024, with **InfiniteYou**, **FLUX Kontext**, and **PuLID Flux II** emerging as the new gold standards for character consistency—while many foundational repositories from cubiq (InstantID, PuLID, IP-Adapter) entered maintenance mode in April 2025. Video generation has been revolutionized by **Wan 2.2's MoE architecture** and **FramePack's 6GB VRAM breakthrough** for 60-second videos. Voice cloning integration reached maturity with unified platforms like TTS Audio Suite supporting 23+ languages and emotion control. This report synthesizes the latest techniques, workflows, and community discoveries to update character generation capabilities.\n\n---\n\n## Pixaroma's ComfyUI mastery: Accessibility-first workflows\n\n**Pixaroma** has established itself as the definitive beginner-to-advanced ComfyUI resource, run by a graphic designer who emphasizes GGUF quantized models for users with **8-12GB VRAM**. The channel's structured episode format builds systematically from installation basics through advanced video generation.\n\nThe character consistency methodology from **Episode 28** follows a multi-step pipeline: generate character sheets showing multiple angles and poses, train LoRAs online using these generated images, then deploy locally with OpenPose and ControlNet for pose control. This approach prioritizes accessibility over cutting-edge methods, making it ideal for creators with consumer hardware.\n\nKey innovations include the **Pixaroma Upscaler workflow** using Flux Dev GGUF Q8, which employs dual outputs—one from KSampler at **0.75-0.80 denoise** (preserving character features) and one further upscaled without KSampler. The **260+ art styles collection** in CSV format provides curated SDXL-compatible styles organized by category, with the recommendation to mix painting and photography styles for optimal results.\n\nFor video generation, Pixaroma's Wan 2.1 tutorials provide precise specifications: **832×480px for landscape**, **480×832px for portrait**, with frame calculations at 16 FPS (17 frames = 1 second, 81 frames = 5 seconds). The **ComfyUI-Easy-Install Pixaroma Community Edition** bundles essential nodes including GGUF support, VideoHelperSuite, WanVideoWrapper, and Impact Pack for one-click setup.\n\n| Resource | Link |\n|----------|------|\n| YouTube Channel | youtube.com/@pixaroma |\n| Easy Install GitHub | github.com/Tavris1/ComfyUI-Easy-Install |\n| Discord (Free Workflows) | Pixaroma workflows channel |\n\n---\n\n## Character consistency enters a new era with InfiniteYou and FLUX Kontext\n\nThe character consistency landscape fundamentally shifted in 2024-2025. **InfiniteYou** from ByteDance (ICCV 2025 Highlight) introduces **InfuseNet** architecture with residual connections and multi-stage training using single-person-multiple-sample data. Two model variants serve different needs: **SIM** maximizes identity matching while **AES** prioritizes visual quality. FP8 and GGUF support enable lower VRAM requirements with multi-ID masked generation.\n\n**FLUX.1 Kontext** from Black Forest Labs represents perhaps the most significant advancement—a context-aware editing model with **built-in character consistency** that maintains features across multiple editing steps. The model excels at localized editing (targeting specific elements without affecting others) and iterative refinement with minimal drift. Three tiers exist: Kontext [dev] at 12B parameters for research, Kontext [pro] running 8x faster than GPT-Image, and Kontext [max] with improved prompt adherence. FP8 versions reduce requirements to ~12GB VRAM.\n\n**PuLID Flux II** solved the critical \"model pollution\" issue using contrastive alignment techniques that minimize disruption to the original FLUX model. The dual-character support enables generating scenes with two consistent people—previously extremely difficult. Mickmumpitz's \"Flux Consistent Characters\" workflow remains the community gold standard, though it requires A100-40GB GPU at approximately 7.5 minutes per generation.\n\nFor SDXL workflows, the proven combination of **InstantID + IP-Adapter + ControlNet + FaceDetailer** continues to deliver excellent results, though these cubiq repositories are now in maintenance mode. Key optimizations include using **1016×1016 resolution** (avoiding 1024×1024 watermark artifacts), lowering CFG to 4-5, and applying 35% noise injection in negative embeds to reduce the \"burn\" effect.\n\n| Use Case | Best Approach | VRAM Requirement |\n|----------|---------------|------------------|\n| Quick face swap | InstantID + FaceDetailer | 12GB |\n| Story/comic generation | StoryDiffusion | 16GB |\n| High-fidelity portraits | InfiniteYou | 24GB |\n| Image editing/iteration | FLUX Kontext | 12-32GB |\n| Multiple characters | PuLID Flux II | 24-40GB |\n| Production workflows | FLUX Kontext Pro (API) | Cloud |\n\n---\n\n## Video generation transforms with Wan 2.2 and FramePack\n\n**Wan 2.2** from Alibaba introduces a Mixture of Experts architecture where high-noise and low-noise expert models collaborate, enabling **film-level aesthetic control** over lighting, color, and composition. The groundbreaking first-and-last frame generation controls both start and end frames for precise video planning. Models range from the consumer-friendly 1.3B version requiring ~8.19GB VRAM to the 14B version for maximum quality.\n\nThe **FramePack** breakthrough from Dr. Lvmin Zhang (ControlNet author) makes VRAM usage **invariant to video length**—generating 60-second videos at 30fps (1800 frames) on just 6GB VRAM via an RTX 3060. Dynamic context compression assigns 1536 markers to key frames versus 192 for transitional frames, while bidirectional memory with reverse generation prevents the drift that plagued earlier methods.\n\n**AnimateDiff V3** with motion modules (mm_sd_v15_v2) supports camera controls through Motion LoRAs—pan, zoom, tilt, rolling—while effect LoRAs enable shatter, smoke, explosion, and liquid motion effects. The sliding context window system enables infinite animation length, though the model works best at **512x512 resolution** (its training resolution). For SDXL, HotshotXL provides temporal layer support.\n\nLip-sync technology matured significantly with **LatentSync 1.6** from ByteDance training at 512×512 for improved clarity, using TREPA modules for temporal consistency. **InfiniteTalk** enables unlimited-length talking avatar videos with WAN integration, while the emerging **Character AI Ovi** pipeline generates joint video and audio with natural lip synchronization from a single image input.\n\n---\n\n## Voice cloning reaches production quality with unified platforms\n\n**TTS Audio Suite** emerged as the definitive multi-engine platform, integrating F5-TTS, Chatterbox (23 languages), Higgs Audio 2, VibeVoice (90-minute generation), IndexTTS-2 (8-emotion vector control), and RVC for real-time conversion. Advanced features include character switching with `[CharacterName]` tags, language switching (`[de:Alice]`, `[fr:Bob]`), pause control (`[pause:1s]`), and SRT subtitle timing synchronization.\n\n**F5-TTS** delivers zero-shot voice cloning from samples under 15 seconds with multi-language support across English, German, Spanish, French, Japanese, Hindi, Thai, and Portuguese. Voice samples must be paired with `.wav` and `.txt` files containing matching transcriptions. The model integrates Whisper for automatic transcription.\n\n**Chatterbox** from ResembleAI supports paralinguistic tags (`[laugh]`, `[sigh]`, `[gasp]`) and multi-speaker dialog synthesis for up to 4 voices per generation. The `exaggeration` parameter (0.25-2.0) controls expressiveness, while a **40-second generation limit** requires splitting longer content.\n\nFor emotion control, **IndexTTS-2** provides an 8-emotion vector system covering happy, angry, sad, surprised, afraid, disgusted, calm, and melancholic states with per-segment parameter control.\n\n---\n\n## LoRA training evolves with FLUX-specific optimizations\n\nFLUX LoRA training differs substantially from SDXL approaches. **FluxGym** provides the most beginner-friendly path with web-based Gradio interface, integrated Florence 2 auto-captioning, and RunPod templates. Recommended settings: **15-20 high-quality images**, unique trigger tokens (e.g., `ch3rrybl0nde`), network rank 16-32, and 2000 steps.\n\n**SimpleTuner** targets production environments with support for FLUX.1 Dev and FLUX.2 with Mistral-3 encoder. The int8/nf4 quantization enables training on 20GB VRAM via Optimum-Quanto. Key parameters: learning rate 1e-4 to 1e-5 (lower than SD), network rank 4-64 (start small), polynomial LR schedule.\n\nFor SDXL, **Kohya_ss** remains the gold standard with Prodigy optimizer for auto-tuning, block-wise dims/lrs support, and recommended rank of 64-96 with alpha at half the rank value. Dataset preparation requires high-resolution images (1024×1024 minimum), multiple angles and expressions (10-20 images), and captions with trigger words first followed by detailed descriptions—but excluding unchangeable features like eye color.\n\n| Training Type | Network Dim | Network Alpha | Images | Steps |\n|---------------|-------------|---------------|--------|-------|\n| Logo/Objects | 10-15 | 10 | 10 | 2000 |\n| Characters | 16-32 | 20 | 10-20 | 2000 |\n| Styles | 32-50 | 20 | 20-30 | 3000 |\n\n---\n\n## Memory optimization unlocks consumer hardware potential\n\nVRAM management fundamentally determines workflow feasibility. Command-line flags provide the first optimization layer: `--lowvram` for 6GB systems trades speed for memory efficiency, `--reserve-vram [amount]` prevents system freezing by reserving VRAM for OS functions, and `--use-xformers` changes attention scaling from quadratic to near-linear—**reducing 16GB requirements to 4GB** for 1024×1024 generation.\n\n**FP8 precision** for SDXL/Flux models halves memory usage with minimal quality loss—FLUX checkpoints use ~6GB VRAM versus much more for FP16/BF16. The **VRAM_Debug node** from KJNodes monitors free VRAM before/after operations with built-in garbage collection and model unloading. Restarting ComfyUI between significantly different workloads clears memory fragmentation.\n\nSampling optimization delivers dramatic speed improvements: **15-25 steps** suffices for most generations since quality plateaus around 25-30 steps. DPM++ 2M Karras achieves excellent results at 20 steps, while **DEIS sampler achieves high-fidelity in just 10 steps**. Lightning/Turbo models enable 4-8 step generation; LCM achieves 4 steps for rapid iteration.\n\nA critical community discovery: updating **cuDNN to version 8800** can double speed on RTX 4070Ti from 8.5it/s to 17.6it/s. Reserving 7GB VRAM in ComfyUI settings made workflows run **20x faster** on 5070ti in community testing.\n\n---\n\n## Essential custom nodes for character generation pipelines\n\n**ComfyUI Manager** remains the foundational requirement—enabling one-click installation, auto-updates, and missing node detection. **Impact Pack** provides FaceDetailer for automatic face enhancement and image segmentation. **WAS Node Suite** delivers 300+ nodes for image processing, text manipulation, and file operations.\n\nFor upscaling, **SUPIR** (Scaling-UP Image Restoration) uses diffusion-based enhancement achieving photo-realistic results—512p to 2048 with under 10GB VRAM in FP8 mode. Key parameters: CFG scale 2.5→1.5, EDM s_churn ~5. The **4x Foolhardy Remacri** model provides superior texture reconstruction, while **4x AnimeSharp** optimizes for illustration styles.\n\nNew samplers and schedulers emerged for specific use cases. The **Beta scheduler** (α=1.0, β=0.6) delivers improved details for Flux.1 [dev] with Euler sampler. **ComfyUI-CapitanFlowMatch** provides optimal samplers for rectified flow models (Flux, SD3, Lumina2), preventing the \"burning\" issues with turbo models at higher step counts.\n\nFor ControlNet, **FLUX ControlNet Inpainting** from Alimama (beta model trained on 15M images at 1024×1024) outperforms SDXL inpainting with conditioning scale between 0.9-0.95 for best results.\n\n---\n\n## Community workflows and cutting-edge discoveries\n\n**Consistent Character Creator 3.0** using the Qwen Image Edit model generates multi-view character sheets (front, side, back views, expressions, turntable rotations) while preserving identity. The **Character AI Ovi** pipeline enables single-image-to-talking-avatar with joint video and audio generation and natural lip synchronization.\n\n**StoryDiffusion** (NeurIPS 2024 Spotlight) provides training-free consistent text-to-image generation through Consistent Self-Attention, requiring minimum 3 text prompts (5-6 recommended) for character consistency across sequences. It works as a hot-pluggable module compatible with both SD1.5 and SDXL.\n\n**ComfyUI Copilot** from Alibaba offers AI-assisted workflow generation with claimed 10x faster workflow creation. **ACE Plus technology** achieves 99% facial consistency for background replacement (versus previous 90%). **HyperLoRA** (CVPR 2025) introduces parameter-efficient adaptive generation for portrait synthesis.\n\nFor workflow discovery, **OpenArt** provides curated workflows with previews, **Civitai** offers model-specific workflows, and **awesome-comfyui** on GitHub maintains a daily-updated collection. The **Searge SDXL Evolved v4.32** workflow on Civitai represents one of the most optimized community workflows with ControlNet, Revision, and multi-LoRA support.\n\n---\n\n## 2026 Updates: FLUX.2, LTX-2, and Platform Optimizations\n\n**FLUX.2** (Flux2) from Black Forest Labs represents a major evolution in identity preservation, supporting **up to 10 reference images** in a single generation for unprecedented identity consistency. This multi-reference capability is especially valuable for branded content, recurring characters, and multi-scene creative workflows where maintaining visual consistency across diverse contexts is critical. The model demonstrates strong preservation of character identity, product appearance, and visual style across complex scenarios.\n\n**LTX-2** from Lightricks (January 2026) achieved a significant milestone as the **first production-ready open-source model** combining truly open audio and video generation with native **4K output**. This represents a substantial leap in quality and accessibility for high-resolution video generation workflows, eliminating previous limitations around resolution ceiling or proprietary audio systems.\n\n**AuraFace** emerged as a commercially-friendly identity encoder—an open-source alternative to ArcFace specifically designed for commercial applications without licensing restrictions. This addresses a long-standing pain point where ArcFace's licensing prevented commercial use, making advanced face recognition and identity preservation technologies accessible for production environments. AuraFace integrates seamlessly with existing InstantID and IP-Adapter workflows as a drop-in replacement for identity encoding.\n\n**F5-TTS Cross-Lingual** framework (February 2026) enables cross-lingual voice cloning **without requiring audio prompt transcripts**, matching F5-TTS performance while unlocking multilingual voice transfer capabilities. This dramatically simplifies workflows where reference audio lacks transcription or involves code-switching between languages—common scenarios in international content production.\n\n**ComfyUI v0.8.1** (January 8, 2026) introduced critical performance optimizations for RTX 50 Series GPUs with **NVFP4 and NVFP8 data format support**, achieving **3x faster performance and 60% VRAM reduction** compared to previous precision formats. Native **AMD ROCm integration** significantly improved generation speeds on AMD graphics cards and SoCs, expanding hardware compatibility. The new **audio recording node** enables direct audio capture within ComfyUI, streamlining voice synthesis workflows. **Weight streaming** memory management allows using system RAM when VRAM is exhausted, enabling larger models on mid-range GPUs.\n\n**DiffSwap++** introduces the first face-swapping framework leveraging **3D facial latent features** to guide diffusion-based generation, incorporating 3D geometric cues during training while remaining fully 2D at inference. This demonstrates superior identity preservation and structural consistency compared to 2D-only approaches, particularly for challenging angles and expressions.\n\n| 2026 Innovation | Key Benefit | Use Case |\n|----------------|-------------|----------|\n| FLUX.2 (10 ref images) | Maximum identity consistency | Character series, brand assets |\n| LTX-2 (4K native) | Production-ready high-res video | Professional video content |\n| AuraFace | Commercial-friendly encoding | Production deployments |\n| F5-TTS Cross-Lingual | No-transcript voice transfer | Multilingual content |\n| ComfyUI 0.8.1 RTX optimizations | 3x speed, 60% less VRAM | RTX 50 Series efficiency |\n| DiffSwap++ | 3D-aware face swapping | Complex angle preservation |\n\n---\n\n## Conclusion: Building the complete character pipeline\n\nThe 2024-2025 ComfyUI ecosystem enables truly professional character generation workflows. For **new projects**, InfiniteYou or FLUX Kontext represent the state-of-the-art, while SDXL workflows should continue leveraging InstantID + IP-Adapter combinations despite maintenance mode status. **Production environments** benefit from FLUX Kontext Pro/Max via API for maximum consistency.\n\nThe optimal multi-modal pipeline follows this sequence: generate consistent characters with LoRA-enhanced FLUX/SDXL models → clone voices with F5-TTS or Chatterbox using 10-30 second references → create video with Wan 2.2 or FramePack → apply lip-sync with LatentSync 1.6 or InfiniteTalk → post-process with RIFE interpolation and SUPIR upscaling.\n\nKey architectural insights: FramePack's VRAM-invariant approach enables 60-second videos on consumer GPUs; TTS Audio Suite's unified platform eliminates fragmented voice cloning setups; PuLID Flux II's contrastive alignment solves model pollution for dual-character generation. The field continues rapid evolution—monitor the community forks emerging from maintenance-mode repositories and emerging models like CharaConsist's point-tracking attention for next-generation consistency.","content_type":"text/markdown; charset=utf-8","language":"markdown","size":18372,"content_sha256":"e95d88a7db3b0eb266de05ac9e87dc4880c328570c98379ad8e4855aea650e4e"},{"filename":"references/talking-head-workflows.md","content":"# Talking Head Workflow Reference\n\nComplete production workflows for creating talking head videos using two main approaches.\n\n---\n\n## Table of Contents\n\n1. [Approach 1: Image → Talking Head](#approach-1-image--talking-head)\n2. [Approach 2: Video → Add Voice/Lip-Sync](#approach-2-video--add-voicelip-sync)\n3. [Hybrid Approach](#hybrid-approach)\n4. [Parameter Reference](#parameter-reference)\n5. [Troubleshooting](#troubleshooting)\n\n---\n\n## Approach 1: Image → Talking Head\n\n**Use Case:** Generate talking head video from single character portrait.\n\n**Input:** 1 image (1024×1024 recommended) + audio file\n**Output:** Talking head video with natural head movement and lip-sync\n**Time:** 2-5 minutes per 10-second clip (GPU-dependent)\n\n### Method 1A: SadTalker (Most Popular)\n\n**Best For:** Natural head movement, expressions, eye blink\n\n#### Installation\n\n```bash\n# Clone SadTalker\ncd E:/ComfyUI-Easy-Install/ComfyUI/custom_nodes\ngit clone https://github.com/Winfredy/SadTalker\n\n# Install dependencies\ncd SadTalker\npip install -r requirements.txt\n\n# Download checkpoints\npython scripts/download_models.py\n```\n\n**Required Models:**\n- `checkpoints/SadTalker_V0.0.2_512.safetensors` (4.5GB)\n- `gfpgan/weights/` (face enhancement)\n- `checkpoints/mapping_00109-model.pth.tar` (expression)\n- `checkpoints/mapping_00229-model.pth.tar` (pose)\n\n#### Python Script\n\n```python\n#!/usr/bin/env python3\n\"\"\"\nSadTalker: Image to Talking Head Video\nGenerates natural talking head with head movement from single portrait\n\"\"\"\n\nimport os\nimport sys\nsys.path.append('E:/ComfyUI-Easy-Install/ComfyUI/custom_nodes/SadTalker/src')\n\nfrom facerender.animate import AnimateFromCoeff\nfrom test_audio2coeff import Audio2Coeff\nfrom face3d.models import networks\n\nclass SadTalkerPipeline:\n def __init__(self, checkpoint_dir='checkpoints'):\n self.checkpoint_dir = checkpoint_dir\n self.device = 'cuda'\n\n # Load models\n self.audio2coeff = Audio2Coeff(checkpoint_dir, self.device)\n self.animate = AnimateFromCoeff(checkpoint_dir, self.device)\n\n def generate(\n self,\n source_image,\n driven_audio,\n output_path,\n preprocess='crop', # 'crop', 'resize', 'full'\n still_mode=False, # Less head movement\n use_enhancer=True, # GFPGAN enhancement\n batch_size=2,\n fps=25\n ):\n \"\"\"\n Generate talking head video\n\n Args:\n source_image: Path to portrait (1024x1024 recommended)\n driven_audio: Path to audio file (.wav, .mp3)\n output_path: Output video path\n preprocess: How to handle input image\n still_mode: True for minimal head movement\n use_enhancer: Apply GFPGAN for face quality\n batch_size: Processing batch size\n fps: Output video frame rate\n \"\"\"\n\n print(f\"[SadTalker] Processing: {source_image}\")\n print(f\"[SadTalker] Audio: {driven_audio}\")\n\n # 1. Extract audio coefficients\n print(\"[SadTalker] Extracting audio features...\")\n coeff_path = self.audio2coeff.generate(\n audio_path=driven_audio,\n save_dir=os.path.dirname(output_path)\n )\n\n # 2. Generate video\n print(\"[SadTalker] Generating video...\")\n self.animate.generate(\n source_image=source_image,\n coeff_path=coeff_path,\n output_path=output_path,\n preprocess=preprocess,\n still_mode=still_mode,\n use_enhancer=use_enhancer,\n batch_size=batch_size,\n fps=fps\n )\n\n print(f\"[SadTalker] ✓ Video saved: {output_path}\")\n return output_path\n\n# Example usage\nif __name__ == \"__main__\":\n pipeline = SadTalkerPipeline()\n\n pipeline.generate(\n source_image=\"E:/ComfyUI-Easy-Install/ComfyUI/input/sage_portrait.png\",\n driven_audio=\"E:/ComfyUI-Easy-Install/ComfyUI/input/sage_dialogue.wav\",\n output_path=\"E:/ComfyUI-Easy-Install/ComfyUI/output/sage_talking.mp4\",\n still_mode=False, # Natural head movement\n use_enhancer=True, # GFPGAN enhancement\n fps=25\n )\n```\n\n#### ComfyUI Workflow (SadTalker Node)\n\n```json\n{\n \"1\": {\n \"class_type\": \"LoadImage\",\n \"inputs\": {\n \"image\": \"sage_portrait.png\"\n }\n },\n \"2\": {\n \"class_type\": \"LoadAudio\",\n \"inputs\": {\n \"audio\": \"sage_dialogue.wav\"\n }\n },\n \"3\": {\n \"class_type\": \"SadTalker\",\n \"inputs\": {\n \"source_image\": [\"1\", 0],\n \"driven_audio\": [\"2\", 0],\n \"preprocess\": \"crop\",\n \"still_mode\": false,\n \"use_enhancer\": true,\n \"expression_scale\": 1.0,\n \"fps\": 25\n }\n },\n \"4\": {\n \"class_type\": \"SaveVideo\",\n \"inputs\": {\n \"video\": [\"3\", 0],\n \"filename\": \"sage_talking\",\n \"fps\": 25\n }\n }\n}\n```\n\n#### Parameter Guide: SadTalker\n\n| Parameter | Values | Effect |\n|-----------|--------|--------|\n| **preprocess** | 'crop', 'resize', 'full' | How to handle input image |\n| **still_mode** | true/false | true = minimal movement, false = natural |\n| **expression_scale** | 0.5-2.0 | Expression intensity (1.0 default) |\n| **use_enhancer** | true/false | Apply GFPGAN face enhancement |\n| **batch_size** | 1-8 | Higher = faster but more VRAM |\n| **fps** | 24-30 | Output frame rate |\n\n**Recommended Settings:**\n\n```python\n# Natural conversation (YouTube, podcast)\nstill_mode=False, expression_scale=1.0\n\n# Professional presentation (corporate)\nstill_mode=True, expression_scale=0.8\n\n# Animated character (exaggerated)\nstill_mode=False, expression_scale=1.5\n```\n\n---\n\n### Method 1B: LivePortrait (Premium Quality)\n\n**Best For:** Fine control over expressions, eye gaze, head pose\n\n#### Installation\n\n```bash\ncd E:/ComfyUI-Easy-Install/ComfyUI/custom_nodes\ngit clone https://github.com/KwaiVGI/LivePortrait\n\ncd LivePortrait\npip install -r requirements.txt\npython scripts/download_models.py\n```\n\n#### Python Script\n\n```python\n#!/usr/bin/env python3\n\"\"\"\nLivePortrait: Advanced Talking Head Generation\nFine control over expressions, eye gaze, and head movements\n\"\"\"\n\nimport sys\nsys.path.append('E:/ComfyUI-Easy-Install/ComfyUI/custom_nodes/LivePortrait')\n\nfrom liveportrait.live_portrait_pipeline import LivePortraitPipeline\n\nclass LivePortraitGenerator:\n def __init__(self):\n self.pipeline = LivePortraitPipeline(\n model_path='checkpoints/liveportrait',\n device='cuda'\n )\n\n def generate(\n self,\n source_image,\n driving_audio,\n output_path,\n expression_strength=1.0,\n head_pose_strength=1.0,\n eye_retargeting=True,\n lip_retargeting=True,\n fps=25\n ):\n \"\"\"\n Generate talking head with fine control\n\n Args:\n source_image: Portrait image path\n driving_audio: Audio file path\n output_path: Output video path\n expression_strength: Expression intensity (0-2)\n head_pose_strength: Head movement intensity (0-2)\n eye_retargeting: Enable eye movement\n lip_retargeting: Enable lip-sync\n fps: Output frame rate\n \"\"\"\n\n print(f\"[LivePortrait] Processing: {source_image}\")\n\n result = self.pipeline.execute(\n source_image=source_image,\n driving_audio=driving_audio,\n output_path=output_path,\n flag_pasteback=True, # Paste face back to original\n flag_do_crop=True, # Crop face region\n flag_stitching=True, # Smooth face boundary\n expression_friendly=expression_strength,\n pose_friendly=head_pose_strength,\n flag_eye_retargeting=eye_retargeting,\n flag_lip_retargeting=lip_retargeting,\n fps=fps\n )\n\n print(f\"[LivePortrait] ✓ Video saved: {output_path}\")\n return output_path\n\n# Example usage\nif __name__ == \"__main__\":\n generator = LivePortraitGenerator()\n\n generator.generate(\n source_image=\"E:/ComfyUI-Easy-Install/ComfyUI/input/character.png\",\n driving_audio=\"E:/ComfyUI-Easy-Install/ComfyUI/input/dialogue.wav\",\n output_path=\"E:/ComfyUI-Easy-Install/ComfyUI/output/character_talking.mp4\",\n expression_strength=1.2, # Slightly exaggerated\n head_pose_strength=0.8, # Subtle head movement\n eye_retargeting=True, # Natural eye movement\n lip_retargeting=True # Precise lip-sync\n )\n```\n\n---\n\n### Method 1C: EMO (State-of-Art 2024)\n\n**Best For:** Most natural results, viral quality demos\n\n**Note:** EMO is research code, less production-ready than SadTalker/LivePortrait\n\n```python\n# EMO is typically run via research codebase\n# Not recommended for production yet but worth monitoring\n# See: https://github.com/HumanAIGC/EMO\n```\n\n---\n\n## Approach 2: Video → Add Voice/Lip-Sync\n\n**Use Case:** Add voice/dialogue to existing video footage.\n\n**Input:** Video (any source) + audio file\n**Output:** Same video with synchronized lip movements\n**Time:** 1-3 minutes per 10-second clip\n\n### Method 2A: Wav2Lip (Industry Standard)\n\n**Best For:** Best lip-sync accuracy, works with any video\n\n#### Installation\n\n```bash\ncd E:/ComfyUI-Easy-Install/ComfyUI/custom_nodes\ngit clone https://github.com/Rudrabha/Wav2Lip\n\ncd Wav2Lip\npip install -r requirements.txt\n\n# Download checkpoint\n# Manual download: https://github.com/Rudrabha/Wav2Lip\n# Place in: Wav2Lip/checkpoints/wav2lip_gan.pth\n```\n\n#### Python Script\n\n```python\n#!/usr/bin/env python3\n\"\"\"\nWav2Lip: Add Lip-Sync to Existing Video\nIndustry-standard lip synchronization for any video\n\"\"\"\n\nimport sys\nimport subprocess\nimport os\n\nclass Wav2LipPipeline:\n def __init__(self, wav2lip_path='E:/ComfyUI-Easy-Install/ComfyUI/custom_nodes/Wav2Lip'):\n self.wav2lip_path = wav2lip_path\n self.checkpoint = os.path.join(wav2lip_path, 'checkpoints/wav2lip_gan.pth')\n\n def apply_lipsync(\n self,\n video_path,\n audio_path,\n output_path,\n quality='improved', # 'improved' or 'enhanced'\n face_det_batch_size=16,\n wav2lip_batch_size=128,\n resize_factor=1,\n fps=25\n ):\n \"\"\"\n Apply lip-sync to video\n\n Args:\n video_path: Input video with face(s)\n audio_path: Audio to sync (.wav recommended)\n output_path: Output synced video\n quality: 'improved' (GAN) or 'enhanced' (expert discriminator)\n face_det_batch_size: Face detection batch (lower if OOM)\n wav2lip_batch_size: Processing batch (lower if OOM)\n resize_factor: Resize input (1=original, 2=half size)\n fps: Output frame rate\n \"\"\"\n\n print(f\"[Wav2Lip] Syncing: {video_path}\")\n print(f\"[Wav2Lip] Audio: {audio_path}\")\n\n # Build command\n cmd = [\n 'python',\n os.path.join(self.wav2lip_path, 'inference.py'),\n '--checkpoint_path', self.checkpoint,\n '--face', video_path,\n '--audio', audio_path,\n '--outfile', output_path,\n '--fps', str(fps),\n '--face_det_batch_size', str(face_det_batch_size),\n '--wav2lip_batch_size', str(wav2lip_batch_size),\n '--resize_factor', str(resize_factor)\n ]\n\n if quality == 'improved':\n cmd.append('--nosmooth') # GAN checkpoint\n\n # Run Wav2Lip\n result = subprocess.run(cmd, cwd=self.wav2lip_path, capture_output=True)\n\n if result.returncode == 0:\n print(f\"[Wav2Lip] ✓ Synced video saved: {output_path}\")\n return output_path\n else:\n print(f\"[Wav2Lip] ✗ Error: {result.stderr.decode()}\")\n raise RuntimeError(\"Wav2Lip failed\")\n\n# Example usage\nif __name__ == \"__main__\":\n pipeline = Wav2LipPipeline()\n\n # Apply lip-sync to existing video\n pipeline.apply_lipsync(\n video_path=\"E:/ComfyUI-Easy-Install/ComfyUI/output/sage_video_clip1.mp4\",\n audio_path=\"E:/ComfyUI-Easy-Install/ComfyUI/input/sage_dialogue.wav\",\n output_path=\"E:/ComfyUI-Easy-Install/ComfyUI/output/sage_lipsync_clip1.mp4\",\n quality='improved',\n face_det_batch_size=16,\n wav2lip_batch_size=128,\n fps=25\n )\n```\n\n#### Full Production Pipeline: Video → Voice → Enhance\n\n```python\n#!/usr/bin/env python3\n\"\"\"\nComplete Production Pipeline: Existing Video → Voice → Lip-Sync → Enhance\nFor adding professional dialogue to pre-generated video clips\n\"\"\"\n\nimport os\nfrom pathlib import Path\n\n# Import previous components\nfrom wav2lip_pipeline import Wav2LipPipeline\n\nclass VideoVoicePipeline:\n def __init__(self):\n self.wav2lip = Wav2LipPipeline()\n\n def enhance_faces(self, video_path, output_path, fidelity=0.7):\n \"\"\"\n Enhance face quality with CodeFormer\n\n Args:\n video_path: Input video (after Wav2Lip)\n output_path: Enhanced output video\n fidelity: Balance between quality and fidelity (0.5-1.0)\n 0.5 = creative quality, 1.0 = exact restoration\n \"\"\"\n print(f\"[CodeFormer] Enhancing faces: {video_path}\")\n\n import subprocess\n\n cmd = [\n 'python',\n 'E:/ComfyUI-Easy-Install/ComfyUI/custom_nodes/CodeFormer/inference_codeformer.py',\n '-i', video_path,\n '-o', output_path,\n '--fidelity_weight', str(fidelity),\n '--bg_upsampler', 'realesrgan', # Background upscaling\n '--face_upsample',\n '--draw_box',\n '--detection_model', 'retinaface'\n ]\n\n result = subprocess.run(cmd, capture_output=True)\n\n if result.returncode == 0:\n print(f\"[CodeFormer] ✓ Enhanced video: {output_path}\")\n return output_path\n else:\n print(f\"[CodeFormer] Warning: Enhancement may have issues\")\n return output_path\n\n def process_clip(\n self,\n video_path,\n audio_path,\n output_dir,\n clip_name,\n enhance=True,\n fidelity=0.7\n ):\n \"\"\"\n Complete pipeline for one video clip\n\n Args:\n video_path: Input video clip\n audio_path: Dialogue audio\n output_dir: Output directory\n clip_name: Base filename\n enhance: Apply CodeFormer enhancement\n fidelity: CodeFormer fidelity weight\n\n Returns:\n Path to final video\n \"\"\"\n\n os.makedirs(output_dir, exist_ok=True)\n\n # Step 1: Apply lip-sync\n lipsync_path = os.path.join(output_dir, f\"{clip_name}_lipsync.mp4\")\n self.wav2lip.apply_lipsync(\n video_path=video_path,\n audio_path=audio_path,\n output_path=lipsync_path,\n quality='improved'\n )\n\n if not enhance:\n return lipsync_path\n\n # Step 2: Enhance faces\n final_path = os.path.join(output_dir, f\"{clip_name}_final.mp4\")\n self.enhance_faces(\n video_path=lipsync_path,\n output_path=final_path,\n fidelity=fidelity\n )\n\n return final_path\n\n def process_batch(self, video_audio_pairs, output_dir):\n \"\"\"\n Process multiple video clips\n\n Args:\n video_audio_pairs: List of (video_path, audio_path, clip_name) tuples\n output_dir: Output directory\n\n Returns:\n List of final video paths\n \"\"\"\n\n results = []\n\n for i, (video, audio, name) in enumerate(video_audio_pairs):\n print(f\"\\n[Batch] Processing {i+1}/{len(video_audio_pairs)}: {name}\")\n\n final = self.process_clip(\n video_path=video,\n audio_path=audio,\n output_dir=output_dir,\n clip_name=name,\n enhance=True\n )\n\n results.append(final)\n print(f\"[Batch] ✓ Completed: {final}\")\n\n return results\n\n# Example usage: Process 5 Sage video clips\nif __name__ == \"__main__\":\n pipeline = VideoVoicePipeline()\n\n # Define your video/audio pairs\n clips = [\n (\"output/sage_clip1.mp4\", \"input/audio/sage_dialogue1.wav\", \"sage_01\"),\n (\"output/sage_clip2.mp4\", \"input/audio/sage_dialogue2.wav\", \"sage_02\"),\n (\"output/sage_clip3.mp4\", \"input/audio/sage_dialogue3.wav\", \"sage_03\"),\n (\"output/sage_clip4.mp4\", \"input/audio/sage_dialogue4.wav\", \"sage_04\"),\n (\"output/sage_clip5.mp4\", \"input/audio/sage_dialogue5.wav\", \"sage_05\"),\n ]\n\n # Process all clips\n final_videos = pipeline.process_batch(\n video_audio_pairs=clips,\n output_dir=\"E:/ComfyUI-Easy-Install/ComfyUI/output/sage_final\"\n )\n\n print(\"\\n[Complete] All clips processed:\")\n for video in final_videos:\n print(f\" - {video}\")\n\n # Next step: Concatenate with scripts/video/concat_videos.py\n```\n\n#### Wav2Lip Parameter Guide\n\n| Parameter | Values | Effect |\n|-----------|--------|--------|\n| **quality** | 'improved', 'enhanced' | GAN vs expert discriminator |\n| **face_det_batch_size** | 4-32 | Face detection batch (lower if OOM) |\n| **wav2lip_batch_size** | 32-256 | Wav2Lip batch (higher = faster) |\n| **resize_factor** | 1-4 | Input resize (2 = half size) |\n| **fps** | 24-30 | Output frame rate |\n\n**VRAM Requirements:**\n- 6GB: `face_det_batch_size=4, wav2lip_batch_size=32, resize_factor=2`\n- 12GB: `face_det_batch_size=8, wav2lip_batch_size=64, resize_factor=1`\n- 24GB+: `face_det_batch_size=16, wav2lip_batch_size=128, resize_factor=1`\n\n---\n\n### Method 2B: MuseTalk (Faster Alternative)\n\n**Best For:** Real-time processing, lower VRAM usage\n\n```python\n#!/usr/bin/env python3\n\"\"\"\nMuseTalk: Faster Lip-Sync Alternative\nLower VRAM, faster inference than Wav2Lip\n\"\"\"\n\n# Installation\n# pip install musetalk\n\nfrom musetalk import MuseTalkModel\n\nclass MuseTalkPipeline:\n def __init__(self):\n self.model = MuseTalkModel(device='cuda')\n\n def apply_lipsync(self, video_path, audio_path, output_path):\n \"\"\"Apply lip-sync with MuseTalk\"\"\"\n\n result = self.model.inference(\n video_path=video_path,\n audio_path=audio_path,\n output_path=output_path\n )\n\n return output_path\n\n# Usage\npipeline = MuseTalkPipeline()\npipeline.apply_lipsync(\n video_path=\"input.mp4\",\n audio_path=\"audio.wav\",\n output_path=\"output.mp4\"\n)\n```\n\n**MuseTalk vs Wav2Lip:**\n- ✅ Faster (3-5x speed)\n- ✅ Lower VRAM (6GB vs 12GB)\n- ❌ Slightly less accurate sync\n- ❌ Less battle-tested\n\n---\n\n## Hybrid Approach\n\nFor **maximum production quality**, combine both methods:\n\n### Workflow: Video + Selective Talking Head Enhancement\n\n```python\n#!/usr/bin/env python3\n\"\"\"\nHybrid: Use video motion + add talking head refinement for speaking sections\nBest of both worlds\n\"\"\"\n\nimport cv2\nimport numpy as np\nfrom pathlib import Path\n\nclass HybridPipeline:\n def __init__(self):\n from sadtalker_pipeline import SadTalkerPipeline\n from wav2lip_pipeline import Wav2LipPipeline\n\n self.sadtalker = SadTalkerPipeline()\n self.wav2lip = Wav2LipPipeline()\n\n def process_hybrid(\n self,\n base_video,\n character_portrait,\n audio_segments, # List of (start_time, end_time, audio_file)\n output_path\n ):\n \"\"\"\n Apply SadTalker to specific speaking segments, Wav2Lip to full video\n\n Args:\n base_video: Full video with motion\n character_portrait: Character headshot\n audio_segments: Speaking segments with timestamps\n output_path: Final video output\n \"\"\"\n\n # Step 1: Apply Wav2Lip to full video for baseline sync\n full_audio = self._combine_audio_segments(audio_segments)\n baseline_sync = \"temp_baseline_sync.mp4\"\n\n self.wav2lip.apply_lipsync(\n video_path=base_video,\n audio_path=full_audio,\n output_path=baseline_sync\n )\n\n # Step 2: Generate high-quality talking segments with SadTalker\n talking_segments = []\n for start, end, audio_file in audio_segments:\n segment_video = f\"temp_segment_{start}_{end}.mp4\"\n\n self.sadtalker.generate(\n source_image=character_portrait,\n driven_audio=audio_file,\n output_path=segment_video\n )\n\n talking_segments.append((start, end, segment_video))\n\n # Step 3: Composite - replace speaking sections with SadTalker output\n self._composite_segments(\n base_video=baseline_sync,\n talking_segments=talking_segments,\n output_path=output_path\n )\n\n return output_path\n```\n\nThis is **advanced production technique** - most users should stick to Approach 1 or 2.\n\n---\n\n## Parameter Reference\n\n### When to Use Each Method\n\n| Scenario | Method | Why |\n|----------|--------|-----|\n| Static camera, simple dialogue | SadTalker (Approach 1) | Simplest, good results |\n| Need eye gaze, expression control | LivePortrait (Approach 1) | Fine control |\n| Existing video, add voice | Wav2Lip (Approach 2) | Preserves motion |\n| Real-time/low VRAM | MuseTalk (Approach 2) | Faster, lighter |\n| Maximum quality | Hybrid | Combines strengths |\n\n### Quality vs Speed Tradeoffs\n\n**Fastest → Slowest (for 10-second clip):**\n1. MuseTalk: ~30 seconds\n2. Wav2Lip: ~60 seconds\n3. SadTalker: ~120 seconds\n4. LivePortrait: ~180 seconds\n5. Hybrid: ~300 seconds\n\n**Quality Ranking (subjective):**\n1. Hybrid (best)\n2. LivePortrait\n3. SadTalker\n4. Wav2Lip\n5. MuseTalk (still good)\n\n### VRAM Requirements Summary\n\n| Method | Minimum VRAM | Recommended | Batch Settings |\n|--------|--------------|-------------|----------------|\n| SadTalker | 8GB | 12GB | batch_size=2 |\n| LivePortrait | 10GB | 16GB | Default |\n| Wav2Lip | 6GB | 12GB | batch_size=32 |\n| MuseTalk | 4GB | 8GB | Default |\n\n---\n\n## Troubleshooting\n\n### Issue: Face Not Detected\n\n**Symptoms:** \"No face found in image/video\"\n\n**Solutions:**\n1. Ensure face is clearly visible, front-facing\n2. Increase image resolution (min 512×512)\n3. Use `preprocess='crop'` to auto-detect face region\n4. Try different face detection models (retinaface, blazeface)\n\n```python\n# SadTalker: Try different preprocess modes\npreprocess='crop' # Auto-detect and crop face (recommended)\npreprocess='full' # Use entire image\npreprocess='resize' # Resize to expected size\n```\n\n### Issue: Blurry/Low Quality Output\n\n**Symptoms:** Output video looks blurry or degraded\n\n**Solutions:**\n1. **Always use CodeFormer** after Wav2Lip:\n ```python\n self.enhance_faces(video_path, output_path, fidelity=0.7)\n ```\n\n2. **Adjust fidelity weight:**\n - `fidelity=0.5`: More enhancement, less faithful\n - `fidelity=0.7`: Balanced (recommended)\n - `fidelity=1.0`: Most faithful, least enhancement\n\n3. **Use higher input resolution:**\n - Source image: 1024×1024 minimum\n - Video: 1080p minimum\n\n4. **SadTalker: Enable enhancer:**\n ```python\n use_enhancer=True # Applies GFPGAN\n ```\n\n### Issue: Lip-Sync Accuracy Poor\n\n**Symptoms:** Lips don't match audio timing\n\n**Solutions:**\n\n1. **Check audio quality:**\n - Use clean audio without background noise\n - Ensure clear speech, not overlapping\n - Use .wav format (44.1kHz, 16-bit)\n\n2. **Wav2Lip: Adjust batch sizes:**\n ```python\n # Larger batch = more context = better sync\n wav2lip_batch_size=128 # Try 256 if you have VRAM\n ```\n\n3. **Try different quality modes:**\n ```python\n quality='improved' # GAN (better quality)\n quality='enhanced' # Expert discriminator (better sync)\n ```\n\n4. **Frame rate match:**\n - Ensure video and output fps match (25 or 30)\n - Don't mix frame rates\n\n### Issue: Head Movement Too Stiff/Unnatural\n\n**Symptoms:** SadTalker output looks robotic\n\n**Solutions:**\n\n1. **Disable still_mode:**\n ```python\n still_mode=False # Allows natural movement\n ```\n\n2. **Increase expression scale:**\n ```python\n expression_scale=1.2 # More expressive (range: 0.5-2.0)\n ```\n\n3. **Try LivePortrait for more control:**\n ```python\n head_pose_strength=1.0 # Natural head movement\n expression_strength=1.2 # Expressive faces\n ```\n\n### Issue: Out of Memory (OOM)\n\n**Symptoms:** CUDA out of memory error\n\n**Solutions:**\n\n1. **Reduce batch sizes:**\n ```python\n # SadTalker\n batch_size=1 # Minimum\n\n # Wav2Lip\n face_det_batch_size=4\n wav2lip_batch_size=16\n ```\n\n2. **Resize input:**\n ```python\n # Wav2Lip\n resize_factor=2 # Half resolution\n ```\n\n3. **Process shorter segments:**\n - Split video into 10-second clips\n - Process individually\n - Concatenate after\n\n4. **Enable gradient checkpointing (if available):**\n ```python\n use_gradient_checkpointing=True\n ```\n\n### Issue: Audio-Video Desync Over Time\n\n**Symptoms:** Sync is good at start but drifts by end\n\n**Solutions:**\n\n1. **Match frame rates exactly:**\n - Check input video fps: `ffprobe input.mp4`\n - Set output fps to match: `fps=25` or `fps=30`\n\n2. **Re-encode audio to exact duration:**\n ```bash\n # Get video duration\n duration=$(ffprobe -v error -show_entries format=duration \\\n -of default=noprint_wrappers=1:nokey=1 input.mp4)\n\n # Stretch/compress audio to match\n ffmpeg -i audio.wav -af atempo=$tempo -t $duration output.wav\n ```\n\n3. **Use constant frame rate video:**\n ```bash\n # Convert variable frame rate to constant\n ffmpeg -i input.mp4 -vsync cfr -r 25 output.mp4\n ```\n\n### Issue: Face Replacement Visible/Jarring\n\n**Symptoms:** Can see edges of face replacement, doesn't blend\n\n**Solutions:**\n\n1. **Enable stitching (LivePortrait):**\n ```python\n flag_stitching=True # Smooth boundaries\n flag_pasteback=True # Blend with original\n ```\n\n2. **Use feathering:**\n ```python\n # Post-process with face boundary blur\n import cv2\n\n # Apply Gaussian blur to face mask edges\n mask = create_face_mask(frame)\n mask_blurred = cv2.GaussianBlur(mask, (21, 21), 11)\n ```\n\n3. **Match color/lighting:**\n - Apply color correction to match original\n - Use histogram matching for lighting consistency\n\n---\n\n## Next Steps After Generation\n\nAfter generating talking head videos:\n\n1. **Concatenate clips** (if multiple):\n ```bash\n python E:/ComfyUI-Easy-Install/ComfyUI/scripts/video/concat_videos.py\n ```\n\n2. **Add music/background audio**:\n ```bash\n ffmpeg -i video.mp4 -i music.mp3 -c:v copy \\\n -filter_complex \"[0:a][1:a]amerge=inputs=2[a]\" \\\n -map 0:v -map \"[a]\" output.mp4\n ```\n\n3. **Color grading** (optional):\n - Use DaVinci Resolve (free)\n - Or ffmpeg LUTs\n\n4. **Add subtitles** (recommended):\n - Use Whisper for transcription\n - Burn-in with ffmpeg\n\n5. **Export for platform**:\n - YouTube: H.264, 1080p, 25fps\n - Instagram: H.264, 1080×1350, 30fps\n - TikTok: H.264, 1080×1920, 30fps\n\n---\n\n## Production Checklist\n\nBefore deploying workflows:\n\n- [ ] Test on 5-second clips first\n- [ ] Verify face detection works on all frames\n- [ ] Check audio is clean (no background noise)\n- [ ] Match frame rates (video and output)\n- [ ] Use proper audio format (.wav, 44.1kHz)\n- [ ] Apply enhancement (CodeFormer) after Wav2Lip\n- [ ] Validate output quality on target platform\n- [ ] Batch process efficiently (don't overload GPU)\n- [ ] Keep checkpoints/models organized\n- [ ] Test full pipeline end-to-end before batch\n\n---\n\n## References\n\n- SadTalker: https://github.com/Winfredy/SadTalker\n- LivePortrait: https://github.com/KwaiVGI/LivePortrait\n- Wav2Lip: https://github.com/Rudrabha/Wav2Lip\n- MuseTalk: https://github.com/TMElyralab/MuseTalk\n- CodeFormer: https://github.com/sczhou/CodeFormer\n- EMO (research): https://github.com/HumanAIGC/EMO\n\n**Last Updated:** February 2026\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":27718,"content_sha256":"f677fc23f98d32bfcf518819bdcf4168be94474b1b0f480e2c2cfa2bd4cf0e91"},{"filename":"references/voice-synthesis.md","content":"# Voice Synthesis & Lip-Sync Guide\n\nCreating character voices and synchronizing them with video.\n\n---\n\n## Voice Creation Decision Tree\n\n**Have reference audio of target voice?**\n- Yes → Voice cloning (RVC, ElevenLabs, XTTS)\n- No → Voice design or TTS with persona tuning\n\n**Need commercial license?**\n- Yes → Chatterbox (MIT), F5-TTS (MIT), ElevenLabs (paid)\n- No → RVC, XTTS (non-commercial), any\n\n**Quality priority vs speed?**\n- Quality → ElevenLabs Professional, Chatterbox\n- Speed → F5-TTS, StyleTTS2\n\n---\n\n## Voice Cloning Options\n\n### Chatterbox (Recommended Open-Source)\n\n**Why Chatterbox:**\n- Beat ElevenLabs in 63.8% of blind preference tests\n- MIT license (commercial use OK)\n- Only needs 5-second voice sample\n- Emotion exaggeration control\n- Native paralinguistic tags ([laugh], [sigh], etc.)\n- Sub-200ms latency\n\n**Installation:**\n```bash\npip install chatterbox-tts\n```\n\n**Basic usage:**\n```python\nfrom chatterbox import ChatterboxTTS\n\n# Initialize\ntts = ChatterboxTTS()\n\n# Clone from audio file\ntts.clone_voice(\"reference_audio.wav\", voice_name=\"sage_voice\")\n\n# Generate speech\ntts.synthesize(\n text=\"Hello, I'm Sage. *laughs* Nice to meet you.\",\n voice=\"sage_voice\",\n emotion_scale=1.2, # 0.5-2.0, higher = more expressive\n output_path=\"output.wav\"\n)\n```\n\n**Emotion tags:**\n```\n[laugh] [chuckle] [sigh] [gasp] [cough] [clear throat]\n[whisper] [excited] [sad] [angry] [surprised]\n```\n\n### F5-TTS\n\n**Strengths:**\n- Zero-shot cloning from seconds of audio\n- Code-switching (multiple languages)\n- Very fast (RTF 0.15)\n- MIT license\n\n**Installation:**\n```bash\npip install f5-tts\n```\n\n**Usage:**\n```python\nfrom f5_tts import F5TTS\n\nmodel = F5TTS()\n\n# Generate with voice reference\naudio = model.generate(\n text=\"This is Sage speaking.\",\n ref_audio=\"voice_sample.wav\",\n ref_text=\"Hello, my name is Sage.\", # Transcript of ref audio\n speed=1.0\n)\naudio.save(\"output.wav\")\n```\n\n### RVC (Retrieval-based Voice Conversion)\n\n**Use case:** Convert any voice to your target voice\n\n**How it works:**\n1. Train RVC model on 10+ minutes of target voice audio\n2. Generate base speech with any TTS\n3. Convert base speech through RVC to target voice\n\n**Training requirements:**\n- 10+ minutes of clean speech (ideally 30+ minutes)\n- Single speaker only\n- No background music/noise\n- Consistent recording quality\n\n**Training with RVC WebUI:**\n```bash\n# Clone RVC\ngit clone https://github.com/RVC-Project/Retrieval-based-Voice-Conversion-WebUI\ncd Retrieval-based-Voice-Conversion-WebUI\n\n# Install\npip install -r requirements.txt\n\n# Launch\npython infer-web.py\n```\n\n**Training settings:**\n```\nTraining epochs: 300-500\nBatch size: Based on VRAM (8 for 8GB, 16 for 16GB)\nSave frequency: Every 50 epochs\nFeature extraction: RMVPE (best quality)\n```\n\n**Inference pipeline:**\n```\n[Text] → [Any TTS] → [Base Audio] → [RVC Model] → [Character Voice]\n```\n\n### XTTS-v2 (Coqui)\n\n**Note:** Coqui shut down late 2024, but code is community-maintained.\n\n**Strengths:**\n- Clones from 6-second samples\n- 17 language support\n- \u003c150ms streaming latency\n- 85-95% similarity with 10 seconds\n\n**Limitation:** Non-commercial license (CPML)\n\n**Usage:**\n```python\nfrom TTS.api import TTS\n\ntts = TTS(\"tts_models/multilingual/multi-dataset/xtts_v2\")\n\ntts.tts_to_file(\n text=\"Hello, I'm Sage.\",\n speaker_wav=\"reference.wav\",\n language=\"en\",\n file_path=\"output.wav\"\n)\n```\n\n### ElevenLabs (Commercial)\n\n**Tiers:**\n- Instant Voice Cloning: 1-minute sample, good quality\n- Professional Voice Cloning: 30+ minutes (3 hours ideal), near-indistinguishable\n\n**Voice Design (no sample needed):**\n```\nDescribe in 20-1000 characters:\n\"A warm, witty female voice in her late 20s. Slight Italian-American \nundertones. Confident but approachable. Quick, intelligent delivery \nwith natural pauses. Occasionally playful. Sounds like she could be \nfrom Manhattan but educated at an Ivy League school.\"\n```\n\n**API usage:**\n```python\nfrom elevenlabs import generate, clone\n\n# Clone voice\nvoice = clone(\n name=\"Sage\",\n files=[\"sample1.mp3\", \"sample2.mp3\", \"sample3.mp3\"]\n)\n\n# Generate\naudio = generate(\n text=\"Hello, I'm Sage.\",\n voice=voice,\n model=\"eleven_multilingual_v2\"\n)\n```\n\n---\n\n## Creating Voice Without Reference Audio\n\n### Option 1: Voice Design (ElevenLabs)\n\nWrite detailed description matching character:\n\n**For Sage:**\n```\n\"A sophisticated, warm female voice, late 20s. Italian-American heritage \nsubtly evident in certain vowel sounds. Intelligent, quick-witted delivery \nwith natural rhythm. Confident but not arrogant. Capable of sharp sarcasm \nbut more often warm and engaging. Higher education background evident in \nvocabulary and diction. Think a young Diane Lane meets Marisa Tomei - \nEast Coast, cultured, but with authentic warmth.\"\n```\n\n### Option 2: Find Similar Voice + RVC\n\n1. Search ElevenLabs Voice Library (10,000+ voices)\n2. Find voice with similar qualities\n3. Use that as base, then train RVC on synthetic samples\n4. Convert base voice through RVC for final output\n\n### Option 3: StyleTTS2 with Persona Prompting\n\n```python\nfrom styletts2 import StyleTTS2\n\nmodel = StyleTTS2()\n\n# Use style reference audio that matches desired qualities\naudio = model.synthesize(\n text=\"Hello, I'm Sage.\",\n style_ref=\"warm_confident_female.wav\",\n alpha=0.3, # Style strength\n beta=0.7 # Prosody matching\n)\n```\n\n---\n\n## Lip-Sync Technologies\n\n### Wav2Lip (Recommended for Accuracy)\n\n**Strengths:**\n- Best lip accuracy\n- Works with any face\n- Handles various angles\n\n**Limitations:**\n- Minimal head movement\n- Requires face enhancement post-processing\n\n**ComfyUI integration:**\n```bash\n# Install node\ncd custom_nodes\ngit clone https://github.com/ShmuelRonen/ComfyUI_wav2lip\n```\n\n**Node settings:**\n```\nface_detect_batch: 16\nnosmooth: false\nwav2lip_model: \"wav2lip_gan.pth\" # Better quality than wav2lip.pth\npad_bottom: 10 # Helps with chin visibility\n```\n\n**Post-processing (required):**\n```\n[Wav2Lip Output] → [CodeFormer (fidelity 0.7)] → [Final Video]\n```\n\n### SadTalker\n\n**Strengths:**\n- Generates head movement\n- Creates expressions from audio\n- Single image input\n\n**Limitations:**\n- Less accurate lips than Wav2Lip\n- Can look artificial with extreme movements\n\n**Command line:**\n```bash\npython inference.py \\\n --driven_audio audio.wav \\\n --source_image character.png \\\n --preprocess full \\\n --enhancer gfpgan \\\n --pose_style 0\n```\n\n**Pose styles (0-45):**\n- 0: Minimal movement\n- 10-20: Natural conversation\n- 30+: Expressive/animated\n\n### LivePortrait\n\n**Strengths:**\n- Full expression control\n- Pitch/yaw/roll adjustment\n- Lip zero parameter reduces artifacts\n\n**Best for:**\n- Premium avatar creation\n- Expression transfer from video\n- Fine-grained control needs\n\n**Key parameters:**\n```\nlip_zero: 0.03 # Reduces unnatural lip movements\nstitching: true # Seamless face blending\nrelative_motion_mode: \"source_video_smoothed\"\n```\n\n### MuseTalk (Tencent)\n\n**Strengths:**\n- Fast processing\n- Good quality at 256×256 face region\n- Real-time capable\n\n**Best for:**\n- Large volume processing\n- Real-time applications\n\n---\n\n## Complete Talking Head Pipeline\n\n### Pipeline A: Image → Talking Video (Simple)\n\n```\n1. Generate character audio\n [Text] → [Chatterbox/F5-TTS] → audio.wav\n\n2. Apply lip-sync to still image\n [Character Image] + [audio.wav] → [SadTalker] → video.mp4\n\n3. Enhance\n [video.mp4] → [GFPGAN/CodeFormer per frame] → final.mp4\n```\n\n**Best when:** Quick turnaround, acceptable head movement\n\n### Pipeline B: Image → Video → Lip-Sync (Quality)\n\n```\n1. Generate base video with motion\n [Character Image] → [Wan I2V OR AnimateDiff] → base_video.mp4\n Prompt: \"person talking, slight head movement, indoor\"\n\n2. Generate character audio\n [Text] → [Chatterbox] → audio.wav\n\n3. Apply lip-sync to video\n [base_video.mp4] + [audio.wav] → [Wav2Lip] → lipsync.mp4\n\n4. Enhance faces\n [lipsync.mp4] → [FaceDetailer batch] → enhanced.mp4\n\n5. Final polish\n [enhanced.mp4] → [Color correct + Deflicker] → final.mp4\n```\n\n**Best when:** Production quality needed\n\n### Pipeline C: Expression Transfer (Premium)\n\n```\n1. Record driving video (actor performing lines)\n [Actor Video] → driving.mp4\n\n2. Generate character audio\n [Text] → [Voice Clone TTS] → audio.wav\n\n3. Transfer expressions to character\n [Character Image] + [driving.mp4] → [LivePortrait] → expression_video.mp4\n\n4. Apply precise lip-sync\n [expression_video.mp4] + [audio.wav] → [Wav2Lip] → lipsync.mp4\n\n5. Enhance\n [lipsync.mp4] → [CodeFormer] → final.mp4\n```\n\n**Best when:** Maximum realism, acting performance needed\n\n---\n\n## Audio Requirements\n\n### Recording Quality Guidelines\n\n**For voice cloning source:**\n- Sample rate: 44.1kHz or 48kHz\n- Bit depth: 16-bit minimum, 24-bit preferred\n- Format: WAV (uncompressed)\n- Environment: Quiet room, minimal reverb\n- Microphone: XLR condenser preferred, USB acceptable\n- Distance: 6-12 inches from mic\n- Pop filter: Recommended\n\n**For TTS output (lip-sync input):**\n- Sample rate: 16-24kHz (model dependent)\n- Format: WAV\n- Mono channel\n- Trim leading silence\n- Add 0.2s trailing silence\n- Normalize to -3dB peak\n\n### Audio Preprocessing\n\n```python\nimport librosa\nimport soundfile as sf\n\n# Load and preprocess\naudio, sr = librosa.load(\"raw.wav\", sr=24000, mono=True)\n\n# Trim silence\naudio_trimmed, _ = librosa.effects.trim(audio, top_db=20)\n\n# Normalize\naudio_norm = librosa.util.normalize(audio_trimmed) * 0.7 # -3dB headroom\n\n# Add tail silence\nsilence = np.zeros(int(0.2 * sr))\naudio_final = np.concatenate([audio_norm, silence])\n\n# Save\nsf.write(\"processed.wav\", audio_final, sr)\n```\n\n---\n\n## Sync Troubleshooting\n\n### Lips out of sync with audio\n\n**Causes:**\n- Frame rate mismatch\n- Audio/video length mismatch\n- Processing delay\n\n**Solutions:**\n```\n# Offset audio (if lips are early)\nffmpeg -i video.mp4 -itsoffset 0.1 -i audio.wav -c:v copy -c:a aac output.mp4\n\n# Offset audio (if lips are late)\nffmpeg -i video.mp4 -itsoffset -0.1 -i audio.wav -c:v copy -c:a aac output.mp4\n```\n\n### Mouth movements too subtle\n\n**Solutions:**\n- Use wav2lip_gan.pth instead of wav2lip.pth\n- Increase audio volume before processing\n- Check face detection is accurate\n\n### Face artifacts after lip-sync\n\n**Solutions:**\n- Always run face enhancement after Wav2Lip\n- CodeFormer fidelity: 0.6-0.8 (not too high)\n- Ensure source image resolution matches output\n\n### Unnatural head movement (SadTalker)\n\n**Solutions:**\n- Lower pose_style value (0-10)\n- Use `preprocess: \"crop\"` for stability\n- Provide front-facing source image\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":10589,"content_sha256":"33b8e7d9ecd3870fcb5332d9ae3dd743b5070e0c84d9efc4a6613f4ce49fc4ab"},{"filename":"references/workflows.md","content":"# ComfyUI Workflow Templates\n\nDetailed node configurations for each workflow pattern. Copy and adapt these templates.\n\n---\n\n## Workflow 1: InstantID + IP-Adapter FaceID (Zero-Shot)\n\nBest for converting 3D renders to photorealistic images without training.\n\n### Node Graph\n\n```\n[Load Image: Reference Face]\n ↓\n[InstantID Model Loader] ──────────────────────┐\n ↓ │\n[Apply InstantID] ←─────────────────────────────┤\n ↓ │\n[IPAdapter Unified Loader FaceID] ──────────────┤\n ↓ │\n[Apply IPAdapter FaceID] ←──────────────────────┤\n ↓ │\n[Load Checkpoint] → [CLIP Text Encode (pos/neg)]│\n ↓ │\n[ControlNet Apply] ←── [ControlNet Loader] ─────┘\n ↓\n[KSampler] → [VAE Decode] → [FaceDetailer] → [Upscale] → [Save Image]\n```\n\n### Node Settings\n\n**Load Checkpoint**\n```\nckpt_name: \"flux1-dev.safetensors\" OR \"RealVisXL_V5.0.safetensors\"\n```\n\n**InstantID Model Loader**\n```\ninstantid_file: \"ip-adapter.bin\"\n```\n\n**Apply InstantID**\n```\nweight: 0.8\nstart_at: 0.0\nend_at: 1.0\nnoise: 0.35 # Critical: adds noise to negative for stability\n```\n\n**IPAdapter Unified Loader FaceID**\n```\npreset: \"FACEID PLUS V2\"\nlora_strength: 0.6\nprovider: \"CPU\" # Saves GPU VRAM\n```\n\n**Apply IPAdapter FaceID**\n```\nweight: 0.7\nweight_type: \"style transfer\" # Better for 3D→realistic\nstart_at: 0.0\nend_at: 0.8 # Stop early for better blending\n```\n\n**CLIP Text Encode (Positive)**\n```\ntext: \"photorealistic portrait of [description], detailed skin texture, \n natural lighting, skin pores, freckles, green eyes, auburn hair, \n 8k uhd, dslr quality\"\n```\n\n**CLIP Text Encode (Negative)**\n```\ntext: \"3d render, cartoon, anime, illustration, painting, drawing, \n plastic skin, smooth skin, airbrushed, cgi, video game, \n blurry, low quality, deformed\"\n```\n\n**KSampler**\n```\nseed: [random or fixed]\nsteps: 25-30\ncfg: 4-5 # LOW - critical for InstantID\nsampler_name: \"euler\" OR \"dpmpp_2m\"\nscheduler: \"karras\"\ndenoise: 1.0\n```\n\n**FaceDetailer (from Impact Pack)**\n```\nguide_size: 512\nguide_size_for: true\nmax_size: 1024\nseed: [same as KSampler for consistency]\nsteps: 20\ncfg: 4-5\nsampler_name: \"euler\"\nscheduler: \"karras\"\ndenoise: 0.35-0.45 # Subtle refinement\ndetection_model: \"face_yolov8m.pt\"\nsam_model: \"sam_vit_b_01ec64.pth\"\n```\n\n**Ultimate SD Upscale**\n```\nupscale_by: 2.0\ntile_width: 1024\ntile_height: 1024\nmask_blur: 8\nseam_fix_mode: \"BAND_PASS\"\nmodel: \"4x-UltraSharp.pth\"\n```\n\n---\n\n## Workflow 2: Character LoRA + PuLID (Maximum Consistency)\n\nFor production work requiring absolute identity consistency.\n\n### Node Graph\n\n```\n[Load Checkpoint]\n ↓\n[Load LoRA] ← \"sage_character.safetensors\"\n ↓\n[PuLID Model Loader]\n ↓\n[Apply PuLID] ← [Load Image: Reference]\n ↓\n[ControlNet Stack] ← [Pose/Depth Preprocessor]\n ↓\n[KSampler] → [VAE Decode] → [FaceDetailer] → [ReActor (optional)] → [Upscale]\n```\n\n### Node Settings\n\n**Load LoRA**\n```\nlora_name: \"sage_character.safetensors\"\nstrength_model: 0.8\nstrength_clip: 0.8\n```\n\n**PuLID Model Loader**\n```\npulid_file: \"pulid_flux_v0.9.1.safetensors\"\n```\n\n**Apply PuLID**\n```\nweight: 0.7\nmethod: \"neutral\" # Best for realistic output\nstart_at: 0.0\nend_at: 1.0\n```\n\n**Positive Prompt (with trigger)**\n```\n\"sage_character, photorealistic portrait, detailed skin with freckles, \n emerald green eyes, auburn copper hair, natural lighting, 8k\"\n```\n\n**ReActor (if needed for exact face match)**\n```\nenabled: true\ninput_faces_index: 0\nsource_faces_index: 0\nface_model: \"inswapper_128.onnx\"\nface_restore_model: \"codeformer.pth\"\nface_restore_visibility: 0.8\ncodeformer_fidelity: 0.7\n```\n\n---\n\n## Workflow 3: AnimateDiff Character Video\n\nFast iteration video generation with character consistency.\n\n### Node Graph\n\n```\n[Load Checkpoint] → [Load LoRA]\n ↓\n[AnimateDiff Loader] ← [Motion Module]\n ↓\n[AnimateDiff Settings] ← context_options\n ↓\n[IPAdapter Apply] ← [Load Reference]\n ↓\n[ControlNet Apply] ← [OpenPose from Video]\n ↓\n[KSampler] → [VAE Decode] → [FaceDetailer Batch] → [RIFE Interpolate] → [Video Combine]\n```\n\n### Node Settings\n\n**AnimateDiff Loader**\n```\nmodel_name: \"v3_sd15_mm.ckpt\" OR \"animatediff_lightning_4step.safetensors\"\nbeta_schedule: \"sqrt_linear (AnimateDiff)\"\n```\n\n**AnimateDiff Context Options**\n```\ncontext_length: 16\ncontext_stride: 1\ncontext_overlap: 4\ncontext_schedule: \"uniform\"\nclosed_loop: false\n```\n\n**KSampler (for AnimateDiff)**\n```\nsteps: 8-12 (Lightning) OR 20-25 (Standard)\ncfg: 7-8\nsampler_name: \"lcm\" (Lightning) OR \"euler_ancestral\"\n```\n\n**Video Combine (VHS)**\n```\nframe_rate: 8 # AnimateDiff native\nformat: \"video/h264-mp4\"\nfilename_prefix: \"character_video\"\n```\n\n**RIFE Interpolation (for smoothness)**\n```\nmultiplier: 2 # Doubles frame count\nmodel: \"rife47\" OR \"rife49\"\n```\n\n---\n\n## Workflow 4: Wan 2.1 Image-to-Video\n\nHighest quality video from character image.\n\n### Node Graph\n\n```\n[Load Diffusion Model: Wan I2V]\n ↓\n[Wan I2V Conditioning] ← [Load Image: Hero Shot] + [Load CLIP Vision]\n ↓\n[EmptySD3LatentImage] ← (81 frames, 720p)\n ↓\n[KSampler] → [VAE Decode] → [FaceDetailer Batch] → [Video Combine]\n```\n\n### Node Settings\n\n**Load Diffusion Model**\n```\nmodel: \"wan2.1_i2v_720p_14b_bf16.safetensors\"\n```\n\n**Wan I2V Conditioning**\n```\nwidth: 1280\nheight: 720\nlength: 81 # frames (~5 seconds at 16fps)\n```\n\n**KSampler**\n```\nsteps: 30-50\ncfg: 5-7\nsampler_name: \"uni_pc\"\nscheduler: \"normal\"\n```\n\n**Video Combine**\n```\nframe_rate: 16\nformat: \"video/h264-mp4\"\n```\n\n### VRAM Optimization (for Wan 14B)\n\nAdd these nodes if VRAM limited:\n\n**Model Options Node**\n```\nquantize: \"fp8\"\nattention: \"sageattn\" # Faster attention\n```\n\n---\n\n## Workflow 5: Talking Head Pipeline\n\nCharacter image + voice → talking video.\n\n### Full Pipeline\n\n```\nSTAGE 1: Generate Audio\n[Text] → [F5-TTS/Chatterbox] → [audio.wav]\n\nSTAGE 2: Generate Base Video (if needed)\n[Character Image] → [Wan I2V or AnimateDiff] → [base_video.mp4]\n\nSTAGE 3: Apply Lip-Sync\n[base_video.mp4 OR image] + [audio.wav] → [Wav2Lip] → [lipsync_video.mp4]\n\nSTAGE 4: Enhance\n[lipsync_video.mp4] → [CodeFormer per frame] → [final_video.mp4]\n```\n\n### Wav2Lip Node Settings\n\n```\nface_detect_batch: 16\nnosmooth: false\nresize_factor: 1\nwav2lip_model: \"wav2lip_gan.pth\"\npad_top: 0\npad_bottom: 10 # Slight padding helps with chin area\npad_left: 0\npad_right: 0\n```\n\n### SadTalker Alternative\n\n```\ndriven_audio: \"audio.wav\"\nsource_image: \"character.png\"\npreprocess: \"full\" # Better for novel faces\nenhancer: \"gfpgan\"\nbatch_size: 2\npose_style: 0 # 0-45, controls head movement style\n```\n\n---\n\n## Workflow 6: Multi-Pass Face Fix for Video\n\nWhen video generation produces inconsistent faces.\n\n### Node Graph\n\n```\n[Load Video]\n ↓\n[VHS Video to Images]\n ↓\n[For Each Frame Loop] ──┐\n ↓ │\n[FaceDetailer] │\n ↓ │\n[ReActor (reference)] │\n ↓ │\n[←──────────────────────┘\n ↓\n[VHS Images to Video]\n ↓\n[Save Video]\n```\n\n### Batch Processing Settings\n\n**VHS Load Video**\n```\nforce_size: \"Disabled\"\nframe_load_cap: 0 # All frames\nskip_first_frames: 0\nselect_every_nth: 1\n```\n\n**FaceDetailer (for video)**\n```\ndenoise: 0.3-0.4 # Lower for frame consistency\nguide_size: 384 # Smaller for speed\n```\n\n---\n\n## Workflow 7: FLUX Kontext Character Editing\n\nEdit existing character images without retraining.\n\n### Node Graph\n\n```\n[Load FLUX Kontext Model]\n ↓\n[Load Image: Existing Character]\n ↓\n[Kontext Apply] ← [Edit Instruction]\n ↓\n[KSampler] → [VAE Decode] → [Save]\n```\n\n### Example Edit Instructions\n\n```\n\"Change outfit to elegant black evening dress\"\n\"Add sunglasses while keeping face exactly the same\" \n\"Change background to Manhattan skyline at sunset\"\n\"Age the character by 10 years\"\n\"Change expression to laughing genuinely\"\n```\n\n### Settings\n\n```\nedit_strength: 0.7-0.9 # Higher = more change\npreserve_identity: true\nsteps: 25-30\n```\n\n---\n\n## Common Node Chains\n\n### Face Enhancement Chain\n```\n[Image] → [FaceDetailer] → [CodeFormer] → [Upscale] → [Output]\n```\n\n### Identity Stacking Chain\n```\n[Image] → [InstantID] → [IP-Adapter FaceID] → [ControlNet Pose] → [KSampler]\n```\n\n### Video Smoothing Chain\n```\n[Frames] → [RIFE 2x] → [Deflicker] → [Color Correct] → [Video Combine]\n```\n\n### Multi-ControlNet Chain\n```\n[Reference] → [DWPose Preprocessor] → [Depth Preprocessor]\n ↓ ↓\n [ControlNet 1] [ControlNet 2]\n ↓_________________________↓\n ↓\n [ControlNet Apply Stack]\n```\n\n---\n\n## Resolution Guide\n\n| Output | Generation | Upscale To | Notes |\n|--------|------------|------------|-------|\n| Social media | 1024×1024 | 2048×2048 | Standard quality |\n| Print | 1024×1024 | 4096×4096 | Use SUPIR for best |\n| Video 720p | 1280×720 | - | Native Wan |\n| Video 1080p | 1280×720 | 1920×1080 | Upscale after |\n| Close-up | 768×1024 | 1536×2048 | Portrait crop |\n\n## CFG Guidelines\n\n| Method | CFG Range | Notes |\n|--------|-----------|-------|\n| InstantID | 4-5 | Higher = burning/artifacts |\n| PuLID | 5-7 | More tolerant than InstantID |\n| IP-Adapter only | 7-8 | Standard range |\n| FLUX standard | 3.5-4 | FLUX likes low CFG |\n| SDXL standard | 7-9 | Traditional range |\n| AnimateDiff | 7-8 | Slightly lower helps motion |\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":9963,"content_sha256":"bce42238384c0a7bc991ba31da3c8c496e8fa577159f6536fdbf35b95c2e42a2"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"ComfyUI Character Generation Expert","type":"text"}]},{"type":"paragraph","content":[{"text":"Build production-ready ComfyUI workflows for consistent character generation across image, video, and voice modalities.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Quick Decision: Which Approach?","type":"text"}]},{"type":"paragraph","content":[{"text":"Starting from reference images (like 3D renders)?","type":"text","marks":[{"type":"strong"}]},{"text":" → ","type":"text"},{"text":"InfiniteYou","type":"text","marks":[{"type":"strong"}]},{"text":" (state-of-the-art 2025) or InstantID + IP-Adapter (proven, lower VRAM)","type":"text"}]},{"type":"paragraph","content":[{"text":"Need highest identity fidelity?","type":"text","marks":[{"type":"strong"}]},{"text":" → ","type":"text"},{"text":"FLUX.2","type":"text","marks":[{"type":"strong"}]},{"text":" (NEW 2026: up to 10 ref images) or ","type":"text"},{"text":"PuLID Flux II","type":"text","marks":[{"type":"strong"}]},{"text":" (no model pollution)","type":"text"}]},{"type":"paragraph","content":[{"text":"Want iterative editing without retraining?","type":"text","marks":[{"type":"strong"}]},{"text":" → ","type":"text"},{"text":"FLUX Kontext","type":"text","marks":[{"type":"strong"}]},{"text":" (context-aware, maintains consistency across edits)","type":"text"}]},{"type":"paragraph","content":[{"text":"Creating video content?","type":"text","marks":[{"type":"strong"}]},{"text":" → ","type":"text"},{"text":"LTX-2","type":"text","marks":[{"type":"strong"}]},{"text":" (NEW 2026: 4K production-ready), ","type":"text"},{"text":"Wan 2.2 MoE","type":"text","marks":[{"type":"strong"}]},{"text":" (film-level), or ","type":"text"},{"text":"FramePack","type":"text","marks":[{"type":"strong"}]},{"text":" (60-sec on 6GB!)","type":"text"}]},{"type":"paragraph","content":[{"text":"Need voice for character?","type":"text","marks":[{"type":"strong"}]},{"text":" → ","type":"text"},{"text":"TTS Audio Suite","type":"text","marks":[{"type":"strong"}]},{"text":" (unified platform, 23 languages) or ","type":"text"},{"text":"F5-TTS Cross-Lingual","type":"text","marks":[{"type":"strong"}]},{"text":" (NEW 2026)","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Core Workflow Patterns","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Pattern 1: Zero-Shot Character Generation (No Training)","type":"text"}]},{"type":"paragraph","content":[{"text":"Best for: Quick iteration, 3D-to-photorealism conversion, limited reference images","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"Load Reference Face → InstantID + IP-Adapter FaceID → ControlNet Pose → KSampler → FaceDetailer → Upscale","type":"text"}]},{"type":"paragraph","content":[{"text":"Critical settings:","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"CFG: 4-5 (prevents burning with InstantID)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Resolution: 1016×1016 (avoids watermark artifacts)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"IP-Adapter weight: 0.6-0.8","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"InstantID noise injection: 35% to negative","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"See ","type":"text"},{"text":"references/workflows.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" for complete node configurations.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Pattern 2: LoRA + Identity Methods (Maximum Consistency)","type":"text"}]},{"type":"paragraph","content":[{"text":"Best for: Production work, character series, video generation base","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"Train LoRA → Load LoRA + Checkpoint → Add InstantID/PuLID → Generate → FaceDetailer → ReActor (optional) → Upscale","type":"text"}]},{"type":"paragraph","content":[{"text":"Training requirements:","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"15-30 images, varied poses/expressions/lighting","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Unique trigger word (e.g., \"sage_character\")","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"See ","type":"text"},{"text":"references/lora-training.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" for full parameters","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Pattern 3: Video Generation Pipeline","type":"text"}]},{"type":"paragraph","content":[{"text":"Best for: Talking heads, character animation, promotional content","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"Generate/Load Hero Image → Wan 2.1 I2V OR AnimateDiff → FaceDetailer per frame → Frame Interpolation → Video Combine","type":"text"}]},{"type":"paragraph","content":[{"text":"Model selection:","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Wan 2.1 14B: Best quality, 24GB+ VRAM, slower","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Wan 2.1 1.3B: 8GB VRAM, good quality, faster","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"AnimateDiff Lightning: Fastest, best for iteration","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Pattern 4: Talking Head with Voice","type":"text"}]},{"type":"paragraph","content":[{"text":"Best for: Character dialogue, presentations, social content","type":"text"}]},{"type":"paragraph","content":[{"text":"Two approaches available:","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"Approach 1 (Image → Talking Head):\nCharacter Portrait → Generate Audio → SadTalker/LivePortrait → CodeFormer Enhancement → Final Video\n\nApproach 2 (Video → Add Voice):\nExisting Video → Generate Audio → Wav2Lip Lip-Sync → CodeFormer Enhancement → Final Video","type":"text"}]},{"type":"paragraph","content":[{"text":"See ","type":"text"},{"text":"references/talking-head-workflows.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" for complete workflows and ","type":"text"},{"text":"references/voice-synthesis.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" for voice creation options.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Model Recommendations (2026 Updated)","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Image Generation","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Use Case","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Model","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Notes","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Best photorealism","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"FLUX.1-dev","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Slow but superior quality","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Multi-reference consistency","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"FLUX.2","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"NEW 2026","type":"text","marks":[{"type":"strong"}]},{"text":": Up to 10 ref images, strong identity preservation","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Fast iteration","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"RealVisXL V5.0","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Good balance speed/quality","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Character editing","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"FLUX Kontext","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Context-aware, maintains consistency across edits","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Iterative refinement","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"FLUX Kontext Pro/Max","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"8x faster than GPT-Image (API)","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Identity Preservation (2026 State-of-Art)","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Method","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Best For","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"VRAM","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Notes","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"FLUX.2","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Multi-reference consistency","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"24GB+","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"NEW 2026","type":"text","marks":[{"type":"strong"}]},{"text":": Up to 10 ref images, branded content","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"InfiniteYou","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Highest identity match","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"24GB","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"ICCV 2025 Highlight, SIM/AES variants","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"FLUX Kontext","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Iterative editing","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"12-32GB","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Built-in consistency, no retraining","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"PuLID Flux II","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Dual characters, no pollution","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"24-40GB","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Contrastive alignment solves model pollution","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"AuraFace","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Commercial identity encoding","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"12GB","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"NEW 2026","type":"text","marks":[{"type":"strong"}]},{"text":": Open-source ArcFace alternative","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"InstantID","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Style transfer, 3D→realistic","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"12GB","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Maintenance mode but still excellent","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"IP-Adapter FaceID","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Speed, lower VRAM","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"6GB+","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Good baseline approach","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Video Generation","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Model","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Quality","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Speed","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"VRAM","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Notes","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"LTX-2","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"★★★★★","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Medium","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"16GB+","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"NEW 2026","type":"text","marks":[{"type":"strong"}]},{"text":": First open-source 4K audio+video, production-ready","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Wan 2.2 MoE","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"★★★★★","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Slow","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"24GB+","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Film-level aesthetics, first+last frame control","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"FramePack","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"★★★★★","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Medium","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"6GB","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"60-sec videos, VRAM-invariant breakthrough","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Wan 2.1 1.3B","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"★★★★","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Medium","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"8GB+","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Consumer-friendly","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"AnimateDiff V3","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"★★★","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Fast","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"8GB","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Motion/camera LoRAs, infinite length","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Voice/TTS","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Tool","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"License","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Quality","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Features","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"TTS Audio Suite","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Multi","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"★★★★★","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Unified platform, 23 languages, emotion control","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"F5-TTS","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"MIT","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"★★★★","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Zero-shot from \u003c15 sec samples, ","type":"text"},{"text":"Cross-Lingual 2026","type":"text","marks":[{"type":"strong"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Chatterbox","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"MIT","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"★★★★★","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Paralinguistic tags (","type":"text"},{"text":"[laugh]","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"[sigh]","type":"text","marks":[{"type":"code_inline"}]},{"text":"), 4 voices","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"IndexTTS-2","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"MIT","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"★★★★","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"8-emotion vector control","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"ElevenLabs","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Commercial","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"★★★★★","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Production quality (API)","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Essential Custom Nodes","type":"text"}]},{"type":"paragraph","content":[{"text":"Install via ComfyUI-Manager:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"ComfyUI-Manager # Must install first\nComfyUI_IPAdapter_plus # IP-Adapter and FaceID\nComfyUI_InstantID # InstantID workflow\nComfyUI-Impact-Pack # FaceDetailer\nComfyUI-ReActor # Face swapping\nComfyUI-AnimateDiff-Evolved # Video generation\nComfyUI-VideoHelperSuite # Video I/O\ncomfyui_controlnet_aux # Pose/depth preprocessors\nComfyUI_UltimateSDUpscale # Tiled upscaling\nComfyUI-Frame-Interpolation # Smooth video","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"RTX 50 Series Optimization (NEW 2026)","type":"text"}]},{"type":"paragraph","content":[{"text":"With 32GB VRAM on RTX 5090, run most workflows without optimization. ","type":"text"},{"text":"ComfyUI v0.8.1","type":"text","marks":[{"type":"strong"}]},{"text":" adds major RTX 50 Series enhancements:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"Launch flags: --highvram --fp8_e4m3fn-unet","type":"text"}]},{"type":"paragraph","content":[{"text":"NEW v0.8.1 Features:","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"NVFP4/NVFP8 precision formats","type":"text","marks":[{"type":"strong"}]},{"text":": 3x faster performance, 60% VRAM reduction on RTX 50 Series","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Weight streaming","type":"text","marks":[{"type":"strong"}]},{"text":": Uses system RAM when VRAM exhausted, enables larger models on mid-range GPUs","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Enable tiled VAE for 8K+ upscaling","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Batch 4× 1024×1024 generations in parallel","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Run Wan 2.2 14B + LTX-2 natively","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use FP8 quantization for FLUX (50% VRAM reduction)","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Workflow Generation Process","type":"text"}]},{"type":"paragraph","content":[{"text":"When building a workflow for a user:","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Clarify the goal","type":"text","marks":[{"type":"strong"}]},{"text":": Image only? Video? With voice? What's the source material?","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Select the pipeline pattern","type":"text","marks":[{"type":"strong"}]},{"text":" from above based on requirements","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Generate the workflow","type":"text","marks":[{"type":"strong"}]},{"text":" following node configurations in ","type":"text"},{"text":"references/workflows.md","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Include model downloads","type":"text","marks":[{"type":"strong"}]},{"text":" with exact filenames and paths from ","type":"text"},{"text":"references/models.md","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Provide parameter recommendations","type":"text","marks":[{"type":"strong"}]},{"text":" specific to their hardware/use case","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Reference Files","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/research-log.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" - ","type":"text"},{"text":"Latest techniques","type":"text","marks":[{"type":"strong"}]},{"text":": InfiniteYou, FLUX Kontext, PuLID Flux II, Wan 2.2 MoE, FramePack, FLUX.2, LTX-2.3, Wan 2.6, Qwen3-TTS, and more","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/models.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" - Complete model list with HuggingFace/Civitai links, file paths, and compatibility notes","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/workflows.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" - Detailed node-by-node workflow templates for each pattern","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/lora-training.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" - LoRA training guide with Kohya/AI-Toolkit parameters","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/voice-synthesis.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" - Voice cloning, TTS, and lip-sync pipeline details","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/talking-head-workflows.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" - ","type":"text"},{"text":"Complete talking head workflows","type":"text","marks":[{"type":"strong"}]},{"text":": Image→Talking Head (SadTalker, LivePortrait) and Video→Add Voice (Wav2Lip) with production scripts","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/evolution.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" - Update sources, changelog, and user-specific learnings","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Skill Evolution","type":"text"}]},{"type":"paragraph","content":[{"text":"This skill is designed to evolve. When helping the user:","type":"text"}]},{"type":"paragraph","content":[{"text":"Before starting a workflow:","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Check if new models have dropped that might be better (search HuggingFace/Civitai if uncertain)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Consider if user's past successes/failures inform the approach","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"After completing a workflow:","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Note what worked well or poorly for future reference","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"If user discovers better settings, update the relevant reference file","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Proactive updates:","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"When the user mentions a new model or technique, research and integrate it","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Periodically suggest checking for updates to key dependencies","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"See ","type":"text"},{"text":"references/evolution.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" for monitoring sources and update protocols.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Example: 3D Render to Photorealistic Character","type":"text"}]},{"type":"paragraph","content":[{"text":"For converting stylized 3D renders (like game/VN characters) to photorealistic images:","type":"text"}]},{"type":"paragraph","content":[{"text":"Recommended approach:","type":"text","marks":[{"type":"strong"}]},{"text":" InstantID + IP-Adapter FaceID on FLUX","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"1. Load 3D render reference (best quality, front-facing)\n2. Apply InstantID (extracts identity + facial keypoints)\n3. Apply IP-Adapter FaceID Plus V2 (weight 0.7)\n4. Use FLUX.1-dev checkpoint\n5. Prompt: \"photorealistic portrait, detailed skin texture, natural lighting, [character description]\"\n6. CFG: 4-5, Steps: 25-30\n7. FaceDetailer pass (denoise 0.35)\n8. Upscale with 4x-UltraSharp","type":"text"}]},{"type":"paragraph","content":[{"text":"This converts the stylized look to photorealism while preserving the core identity features.","type":"text"}]}]},"metadata":{"date":"2026-11-02","name":"comfyui-character-gen","author":"@skillopedia","source":{"stars":93,"repo_name":"ComfyUI-Expert","origin_url":"https://github.com/MCKRUZ/ComfyUI-Expert/blob/HEAD/skills/comfyui-character-gen/SKILL.md","repo_owner":"MCKRUZ","body_sha256":"b16902d4ef6b2531fbc37797f1430395022537fe44fc2df249fec8cad5ec3b95","cluster_key":"9d8e8f79727d7f554fcf17b3087ac0c6fbff12882ade118401422fb2fc6c1b31","clean_bundle":{"format":"clean-skill-bundle-v1","source":"MCKRUZ/ComfyUI-Expert/skills/comfyui-character-gen/SKILL.md","text_bytes":122383,"source_commit":"dee27dc3d69b609c0006a8a12e71aadfc475ae95","skills_sh_rank":15635,"attachment_count":12,"text_attachments":12,"attachment_storage":"skill_attachments","binary_attachments":0},"cluster_size":1,"skill_md_path":"skills/comfyui-character-gen/SKILL.md","import_metadata":{"date":"2026-11-02","author":"@skillopedia","version":"v1","category":"media-content","category_label":"Media"},"exact_dupes_collapsed_into_this":0},"version":"v1","category":"media-content","import_tag":"skills-sh-top20k-2026-11","description":"Build identity-preserving character generation workflows and pipelines in ComfyUI. Selects the optimal identity method (InfiniteYou, FLUX Kontext, PuLID, InstantID, IP-Adapter) based on use case requirements. Handles face preservation, likeness transfer, cross-domain conversion (3D to photo), multi-reference consistency, iterative character editing, and character variation generation. Triggers on requests to generate consistent characters, preserve identity across images, create face-swapping workflows, or convert 3D renders to photorealistic portraits. Does NOT cover general image generation without identity preservation, model training/LoRA fine-tuning, animation, technical explanations, or workflow debugging."}},"renderedAt":1793661732520}

ComfyUI Character Generation Expert Build production-ready ComfyUI workflows for consistent character generation across image, video, and voice modalities. Quick Decision: Which Approach? Starting from reference images (like 3D renders)? → InfiniteYou (state-of-the-art 2025) or InstantID + IP-Adapter (proven, lower VRAM) Need highest identity fidelity? → FLUX.2 (NEW 2026: up to 10 ref images) or PuLID Flux II (no model pollution) Want iterative editing without retraining? → FLUX Kontext (context-aware, maintains consistency across edits) Creating video content? → LTX-2 (NEW 2026: 4K productio…