خوب یک سری از پستهارو اختصاص میدم به یه سری نکات کوچیک و کلیدی در تولید تصاویر با Stable diffusion. توی این قسمت در مورد Sampler ها صحبت میکنیم و میبینم که تغییر در Sampling steps چقدر در خروجی نهایی تاثیر داره.
اگر در هنگام اجرای برنامه به مراحل تولید تصویر دقت کرده باشید، متوجه خواهید شد که برنامه ابتدا یک تصویر با نویز زیاد رو تولید میکنه و سپس در مراحل بعدی سعی میکنه نویز تصویر رو کم کنه تا خروجی نهایی تولید بشه. کار sampler ها در واقع محاسبهی مراحل بین تولید هر تصویر با تصویر بعدی هستش و حساب میکنند در هر قدم (step) چقدر این نویزها باید کم بشه. هر چه چه تعداد step ها بیشتر باشه، قدمهای کاهش نویز کوچکتر خواهند شد و در هر مرحله جزییات بیشتری به عکس اضافه خواهد شد. هر sampler یک الگوریتم ریاضی هستش که برای محاسبهی این قدمها و کاهش نویز تا تولید تصویر نهایی به شیوهی خودشون برنامهریزی شدند. برخی از این الگوریتمها مناسب این هستند که در قدمهای کمتر، نتیجهی بهتری بدن.
به این مثال دقت کنید. من سعی میکنم با euler ( دقت کنه euler A نه) تصویر یک گربه رو از خروجی بگیرم. تصویر خروجی نهایی رو با توجه به sampling steps های مختلف گذاشتم:
a ginger cat, animal, best quality, ultra-detailed, masterpiece
Negative prompt: blurry, artist name
Steps: , Sampler: Euler, CFG scale: 7, Seed: 2514770730, Size: 512x512, Model hash: d8722b4a4d, Model: neverendingDreamNED_bakedVae
خروجی:
خوب همونطور که دارید میبینید، در مقادیر بسیار پایین نویز تصویر بسیار بالاست. بعد از ۳ عکس گربه تقریبا شکل گرفته اما جزییات نداره. تقریبا از 20 به بعد عکسها کیفیت خوبی گرفتند. میزان Sampling steps رو به اعداد بزرگتر تغییر میدم و عکسهای بزرگتری میزارم تا جزییات رو ببینید. (از این لینک برای دیدن عکس زیر با سایز بزرگتر استفاده کنید)
آیا انتخاب یک عدد بزرگ برای sampling steps الزاما همیشه بهترین نتیجه رو میده؟ خیر. اگر به همین مثال دقت کنید، breakpoint یا همون نقطهی شکست این مثالها عدد ۵۰ هستش. از ۵۰ به بعد گوشهای گربه بزرگتر شده و رنگ غیرواقعی تر شده. در حالی که جزییات بیشتری به عکس اضافه شده اما به نظر من گذشتن از این جزییات اضافه در step های بالاتر ارزش وقتشو داره.
البته این یک مثال بود. شاید در مثالهای دیگه، بالا قرار دادن میزان sampling steps نتیجهی دیگهای بده. شاید شما طراحی یک چهره انسان رو بخواین و هر چه sampling steps رو بالاتر بزارین، برنامه جزییات بهتری به عکس اضافه کنه. اما همیشه چنین نیست. ضمنا همونطور که گفتم، برخی الگوریتمها برای این برنامه ریزی شدند که بهترین نتیجه رو با تعداد step کم بدند لذا این الگوریتمها ممکنه برای گرفتن حداکثر جزییات برنامه ریزی نشده باشند.
به عنوان مثال برای sampling steps با مقدار ۲۰ این نتایج رو با Euler و DPM2 میگیرم.
به نظر DPM2 در این تعداد sampling step پایین نتیجهی خیلی بهتری داد.
بزارید چند تا از sampler هارو با هم در همین مثال در sampling steps با مقدار ۵۰ مقایسه کنیم. (لینک عکس بزرگتر)
از بین نتایج برای این مثال، من همچنان Euler رو ترجیح میدم. ضمنا DPM++ 2M karras هم چشمهای گربه رو خوب و نزدیک به Euler طراحی کرده. همونطور که گفتم، بسته به مثال و شرایط، هرکدوم از sampler ها ممکنه نتایج متفاوتی بدن و الزاما یکی بهتر از دیگری در همهی شرایط نیست.
چرا محدودیت ۱۵۰ رو برای sampling steps داریم؟ این محدودیت رو رابط وب گذاشته. شما میتونید با تغییر پارامتر
"txt2img/Sampling steps/maximum":
در فایل ui-config.json میزان این عدد رو کم و زیاد کنید. البته همونطور که میدونید sampling steps بالاتر باعث میش زمان بیشتری صرف تولید عکس بشه. آیا همیشه میصرفه؟ این بستگی به شما داره. به مثال بعدی دقت کنید. چون کارت گرافیک من قوی هستش، برای این مثال sampling steps رو برای euler روی ۷۰۰ گذاشتم و در نهایت با چند نمونهی دیگه مقایسه کردم (لینک عکس)
اگر به تفاوت دو عکس در Euler نگاه کنید، تفاوت فاحش هستش. چشمهای گربه تغییر کرده، موهای دور گوش بهتر شدند و دم هم کیفیت بهتری پیدا کرده. اما تفاوت بین Euler و DPM2++ 2M Karras در این مثال بسیار ناچیز هستش با توجه به اینکه عکس سوم با ۱۵۰ قدم تولید شده. تفاوت زمان؟ تولید عکس دوم برای من ۷۰ ثانیه زمان برد و عکس سوم ۱۵ ثانیه. این تفاوت زمانی بیشتر زمانی فاحش میشه که تعداد prompt های عکستون زیاد باشه و بخواین به صورت دستهای چندین عکس تولید کنید.
ضمنا تا الان من با هرچی در این مثال کار کردم، sampler های غیر موروثی ( non-Ancestral ) بوده.
پس Ancestral ها چی هستند؟
دقت کردید که برخی از sampler ها در لیست یک کلمهی a در کنارشون هستش؟ مانند Euler a یا DPM 2 a. برای مثال Euler a همون الگوریتم Euler هستش که به روش Ancestral عکسهارو تولید میکنه. البته همین جا نیاز هستش ذکر کنم که الزاما نباید حرف a کنارش باشه تا بفهمیم sampler به صورت Ancestral هستش یا خیر. برخی از الگوریتم ها خودشون به صورت Ancestral طراحی شدند، مانند DPM++ SDE.
خوب حالا فرق Ancestral و non-Ancestral چی هستش؟ در non-Ancestral ها در هر قدم، لایهای از نویز کم میشه تا در قدم آخر به خروجی نهایی برسیم. در Ancestral ها، در هر نسل، یک لایه نویز به نسل قبلی اضافه میشه. لذا Ancestral تصاویر متفاوتی رو در sampling step های متفاوت ارائه میدن. برای همین مثال گربه با Euler a ( دقت کنید این بار حرف A رو کنار Euler داریم). برای عکس بزرگتر روی این لینک کلیک کنید.
اگر دقت کنید با قدمهای بیشتر، عکس داره کلا تفاوت میکنه. به عنوان مثال قاب عکسی که در عکس تولیدی با ۲۰ قدم بود، در مثال با ۲۲ قدم حذف شده. ظاهر گربه، محیط و نحوه نشستن سوژه کاملا تغییر کرده. همچنین، با افزایش step ها، کیفیت به نظر خیلی بهتر نشده و کیفیت متوسطی رو در طول کل عکسها داریم. (دقت کنید تمامی ورودیها در این مثال ثابت و همون چیزی بوده که در اول پست نوشتم و فقط sampler و sampling steps رو تغییر دادم)
پس به چه دردی میخوره؟ همونطور که گفتم Ancestral ها کارشون اینه که در هر نسل یک لایه نویز به تصویر اضافه کنند. این به معنای اینه که هر بار که sampling step رو تغییر میدید، عکس جدیدی میگیرید. لذا با تغییر sampling step در الگوریتمهای Ancestral، برنامه این امکان رو داره جزییات بیشتری به عکس اضافه کنه. دقت کنید من برای این مثال prompt های خیلی محدودی اضافه کرده بودم. فرض کنیم جزییات عکس من زیاد بود و prompt های زیادی وارد کرده بودم. با Ancestral ها این امکان به من داده میشه که احتمالا برخی جزییات عکس و prompt هایی که در تصویر جا مونده بودند به عکس اضافه بشه. در حالی که اگر از non-Ancestral استفاده میکردم، شاید برخی از prompt ها نادیده گرفته میشن و جزییات محیط فدای کیفیت عکس خروجی بشه.
به صورت کلی، Ancestral ها برای تولید عکس ثابت مناسب نیستند. اما برای تولید عکسهای خلاقانه با جزییات مختلف در محیط عالی هستند. اگر میخواید یک عکس رو از روی متن تولید کنید، احتمالا الگوریتمهای Ancestral بیشتر به کارتون بیاد. در واقع Euler a پر استفاده ترین الگوریتم در stable diffusion هستش. البته این مسائل بیشتر سلیقهای هستش و کمی هم بستگی به شانس داره. اگر میخواید یک عکس رو از روی متن تولید کنید، شاید بهتر باشد ابتدا اون عکس رو با Euler a و یا یک سمپلر Ancestral تولید کنید، سپس وقتی تصویر اولیه مناسبی گرفتید، کیفیت عکس رو با یک سمپلر non-Ancestral بهبود ببخشید.