چیت‌شیت

کنترل‌نت، اینپینتینگ و ویرایش تصویر

ControlNet, Inpainting and Image Editing

فراخوانی‌های Diffusers برای text to image،‏ img2img، اینپینتینگ، LoRA و کنترل‌نت. تنظیمات، پیش‌فرض‌ها و رفع خطاها.

  • ۱۲ بخش
  • ۳ درس مرتبط
  • کد و دستورها عیناً از دوره‌ی اصلی
فهرست مطالب
  1. سیگنال‌های کنترلی به U-Net
  2. Text to image
  3. Img2img، اینپینت و LoRA
  4. وظایف در کد
  5. حلقه‌ی معکوس آگاه از ماسک
  6. فرمول‌ها و اعداد
  7. مقایسه روش‌های ویرایش تصویر
  8. مقایسه ابزارهای شرطی‌سازی
  9. پیش‌فرض‌ها
  10. عیب‌یابی
  11. چه زمانی از چه ابزاری استفاده کنیم
  12. پرسش‌ها

سیگنال‌های کنترلی به U-Net

معماری
ویژگی‌هااضافه‌شده به دیکودرتوکن‌های متنتوکن‌های تصویردلتا با رتبه پایینتصویر شرطعمق، ژست، لبه‌هاکنترل‌نتانکودر کلون‌شده، قابل آموزشکانوولوشن صفر1×1، شروع از صفرپرامپتانکودر متنCLIP-L یا T5مدل SD U-Net منجمدکراس‌اتنشن به متنتصویر مرجعآی‌پی آداپتورتوکن‌های تصویر CLIPLoRAW + BA در اتنشن

Text to image

کد
python
pipe = StableDiffusionPipeline.from_pretrained(
    "runwayml/stable-diffusion-v1-5",
    torch_dtype=torch.float16,  # کاهش حافظه‌ی گرافیکی به نصف
).to("cuda")
pipe.scheduler = DPMSolverMultistepScheduler.from_config(pipe.scheduler.config)
image = pipe(
    prompt="<prompt>",
    guidance_scale=7.5,         # مقیاس CFG با w، پیش‌فرض SD
    num_inference_steps=25,     # معادل 50 گام DDIM
    generator=torch.Generator("cuda").manual_seed(42),
).images[0]
image.save("dog.png")

Img2img، اینپینت و LoRA

کد
python
out = img2img(prompt="<prompt>", image=init_image,
              strength=0.6, guidance_scale=7.5).images[0]     # 0.0 بدون تغییر، 1.0 بازتولید کامل
mask = Image.open("dog_mask.png").convert("L").resize((512, 512))
out = inpaint(prompt="<prompt>", image=image,
              mask_image=mask, guidance_scale=7.5).images[0]  # پیکسل‌های سفید بازتولید می‌شوند
pipe.load_lora_weights("<repo>", weight_name="<file>")
pipe.fuse_lora(lora_scale=0.8)                                # تثبیت می‌شود، تعویض ممکن نیست
pipe.unfuse_lora()                                            # پیش از تطبیق‌دهنده دیگر
pipe.set_adapters([...], adapter_weights=[...])               # ترکیب LoRA به ازای هر درخواست

وظایف در کد

کار و کد
وظیفهکد
نصب پشته‌ی ابزارهاpip install diffusers transformers accelerate
Image to imageStableDiffusionImg2ImgPipeline
اینپینت با SDStableDiffusionInpaintPipeline
اینپینت با FluxFluxFillPipeline
نمونه‌گیر تصادفیEulerAncestralDiscreteScheduler
رمزگذاری به متغیرهای نهانpipe.image_processor.preprocess(img)
استفاده مجدد از متغیرهای نهان قبلیpass `latents=...` and skip one VAE encode
مقیاس‌دهی متغیرهای نهان VAElatent_dist.sample() * 0.18215

حلقه‌ی معکوس آگاه از ماسک

گام‌به‌گام
  1. شروعنمونه‌گیری x از N(0, I) برای تمامی ابعاد.
  2. تزریق مجددافزودن نویز به مبدا تمیز تا گام t. ثبت آن در ابعاد خارج از ماسک.
  3. پیش‌بینیتخمین eps_hat توسط نویززدا برای x در گام t.
  4. معکوسمحاسبه میانگین DDPM. افزودن نویز در صورت t > 0.
  5. تکرارشمارش معکوس از t = T - 1 تا 0.
  6. تثبیت نهاییکپی مقادیر تمیز در ابعاد خارج از ماسک در پایان.
  7. Outpaintمعکوس کردن ماسک. هدف آموزش بدون تغییر می‌ماند.

فرمول‌ها و اعداد

مفهوم‌ها
CFG
$\epsilon = \epsilon_{\text{uncond}} + w \cdot (\epsilon_{\text{cond}} - \epsilon_{\text{uncond}})$
LoRA
$W' = W + \alpha \cdot B A$ با $r \ll d$. پارامترهای جدید: $2 \cdot d \cdot r$ به جای $d^2$.
حجم LoRA
برای $d=640$ و $r=16$ برابر 20k پارامتر به جای 410k.
ترکیب کنترل‌نت
features += weight_a * control_a(depth) + weight_b * control_b(pose)
دیفیوژن نهان
کاهش 3x512x512 به 4x64x64 محاسبات را 48 برابر کم می‌کند.
مدل Inpaint U-Net
9 کانال ورودی. متغیر نهان نویزی 4، تصویر کدگذاری‌شده 4، ماسک 1.
مقدار t/T در SDEdit
مقدار 0.3 شبیه مبدا. 0.6 حفظ ساختار کلی. 0.9 نزدیک به نویز.
کانوولوشن صفر
کنترل‌نت به صورت همانی شروع می‌شود. قبل از آموزش آسیبی نمی‌زند.

مقایسه روش‌های ویرایش تصویر

مقایسه
عاملمدل اینپینتSDEdit یا img2imgInstructPix2PixRePaint
ورودیتصویر، ماسک، پرامپتتصویر، سطح نویز، پرامپتتصویر و دستورالعملتصویر و ماسک
آموزشمدل 9-کاناله U-Netنداردفاین‌تیون روی سه‌گانه‌هاندارد، مدل نامشروط
حفظ می‌کندپیکسل‌های بیرون ماسکساختار کلیساختار ورودیپیکسل‌های بیرون ماسک
تنظیم اصلیماسک و CFGt/T یا strengthمقیاس تصویر و مقیاس متنگام‌های بازنمونه‌گیری
کاربردحذف شیء، جایگزینی آسماناستایل یک ناحیه«غروبش کن»عدم دسترسی به مدل اینپینت

مقایسه ابزارهای شرطی‌سازی

مقایسه
عاملکنترل‌نتLoRAآی‌پی آداپتورDreamBooth
کنترل‌هاساختار مکانیاستایل، سوژه، مفهومظاهر یک تصویر مرجعیک سوژه خاص
اندازه70-360MB20-200MB20MB2-5GB
سازوکارانکودر کلون‌شده، اتصالات میانبر صفردلتای کم‌رتبه روی اتنشنتوکن‌های تصویر CLIP در کراس‌اتنشنفاین‌تیون کامل
کاربرد در شرایطچیدمان یا ترکیب‌بندی دقیقشخصی‌سازی یا استایلنبود کلمات مناسب برای توصیف ظاهرشباهت قطعی هویت، توان پردازشی بالا

پیش‌فرض‌ها

پیش‌فرض‌ها
تنظیمپیش‌فرضنکته
guidance_scale7.5مقیاس پیش‌فرض CFG در SD
num_inference_steps25با DPM-Solver++
img2img `strength`0.60.5 تا 0.7 برای انتقال استایل
Prompt drop in CFG training10%تولید branch نامشروط
VAE scale factor0.18215SDXL از 0.13025 استفاده می‌کند
LoRA rank `r`4-1664-128 برای فاین‌تیون سنگین
Sum of ControlNet weights1.0پیش‌فرض امن
Mask dilation in pixels8-16درزها را پنهان می‌کند

عیب‌یابی

عیب‌یابی
  • خروجی دفرمه یا دارای استایل بیش از حد

    علت
    مقدار α در LoRA روی 2 یا 3
    راه‌حل
    حفظ α در 1.5 یا کمتر
  • اثر شدید ترکیب ژست و عمق

    علت
    دو کنترل‌نت با وزن 1.0
    راه‌حل
    تنظیم مجموع وزن‌ها روی 1.0
  • عدم تاثیر LoRA

    علت
    استفاده از LoRA مدل SDXL روی SD 1.5
    راه‌حل
    تطبیق با مدل پایه
  • عدم امکان بارگذاری LoRA جدید

    علت
    تثبیت شدن با fuse_lora
    راه‌حل
    ابتدا اجرای pipe.unfuse_lora()
  • درزهای مشهود در لبه‌های ماسک

    علت
    تزریق مجدد ساده
    راه‌حل
    بزرگ‌تر کردن ماسک یا استفاده از مدل 9-کاناله
  • پچ اشباع‌شده

    علت
    مقدار CFG بالا روی ماسک کوچک
    راه‌حل
    کاهش CFG برای ویرایش‌های کوچک
  • سوژه هویت خود را از دست می‌دهد

    علت
    t/T در SDEdit بین 0.5 تا 0.6
    راه‌حل
    تست مقادیر مختلف و ذخیره چک‌پوینت
  • ناحیه‌ی پرشده، صحنه را نادیده می‌گیرد

    علت
    پرامپت فقط محتوای جدید را نام می‌برد
    راه‌حل
    توصیف کل تصویر در پرامپت

چه زمانی از چه ابزاری استفاده کنیم

نکته‌ها
  • ControlNet-Openpose + SDXL + متن: ژست مشخص همراه با پرامپت.
  • ControlNet-Scribble یا ControlNet-Canny: چیدمان کاملاً دقیق.
  • LoRA با حدود 30 تصویر گلچین‌شده در رتبه 32: استایل هنری یک برند.
  • SD-Inpaint یا Flux-Fill: حذف شیء در ماسک کوچک.
  • ماسک SAM، سپس SD-Inpaint: تعویض پس‌زمینه.
  • InstructPix2Pix یا Flux-Kontext: ویرایش بر اساس دستور بدون نیاز به ماسک.
  • LCM-LoRA: تاخیر زیر 1 ثانیه.

پرسش‌ها

پرسش و پاسخ
چرا مقدار گیت کنترل‌نت با صفر آغاز می‌شود؟
در گام 0، خروجی دقیقاً مشابه مدل پایه است.
مدل‌های LoRA را merge کنیم یا در لحظه جابه‌جا شوند؟
در لحظه جابه‌جا شوند. فرآیند merge 3 تا 5 درصد سریع‌تر است ولی α و مدل پایه را فریز می‌کند.
چرا strength برابر 1.0 ورودی را نادیده می‌گیرد؟
نویز کامل اضافه می‌کند. نتیجه، بازتولید کامل است.
چرا به جای تزریق مجدد از مدل 9-کاناله استفاده کنیم؟
مدل بافت و زمینه‌ی اطراف ماسک را می‌بیند.
آیا اسکژولر پس از آموزش قابل تعویض است؟
بله. وضعیت اسکژولر از وزن‌های U-Net مجزاست.
هزینه اضافه کردن یک کنترل‌نت چقدر است؟
حدود 1.5 برابر هزینه محاسباتی هر گام به ازای هر کنترل‌نت فعال.