nagatsuki_mix v2.0 が公開されていたので使ってみました。

はじめに

nagatsuki_mix v1.0については以下を見て下さい。
touch-sp.hatenablog.com
今回はnagatsuki_mixのv1.0とv2.0の比較、nagatsuki_mix v2.0とLCM-LoRAの相性についてみてみました。

v1.0とv2.0の比較

左がv1.0、右がv2.0です。





nagatsuki_mix v2.0とLCM-LoRAの相性

左がLCM-LoRAなし、右がLCM-LoRAありです。







LCM-LoRAを使った時若干目の部分が崩れています。

しかし、驚きなのは画像生成にかかった時間です。

normal: 102.00306sec
with lcm-lora: 22.18310sec



5枚の画像を生成した時の時間です。モデル読み込み時間は含んでいません。

SDLXモデルで1枚4秒程度は驚異的です。もちろんPC環境によりますが。

RTX 3080 Laptopを使っています。こちらのPCです。

使用したPythonスクリプト

from diffusers import StableDiffusionXLPipeline, DPMSolverMultistepScheduler, LCMScheduler
import torch
import os
import cv2
import numpy as np
import time

n_samples = 5
model_safetensors = "nagatsukiMix_v20.safetensors"
folder_name = os.path.splitext(model_safetensors)[0]

prompt = "portrait of young japanese girl, 25yo, 8k, detailed, standing on street, smiling, plain white t-shirt, eye level angle"

def without_lora(model_name:str) -> None:
    save_folder_name = f"{folder_name}_without_lora"
    pipe = StableDiffusionXLPipeline.from_single_file(
        f"safetensors/{model_name}",
        load_safety_checker=False,
        extract_ema=True,
        torch_dtype=torch.float16 
    )

    pipe.scheduler = DPMSolverMultistepScheduler.from_config(
        pipe.scheduler.config,
        algorithm_type="sde-dpmsolver++",
        use_karras_sigmas=True
    )
    
    pipe.to("cuda")

    os.makedirs(save_folder_name, exist_ok=True)

    start = time.time()
    for i in range(n_samples):
        seed = 100000 + 2000 * (i + 1)
        generator = torch.manual_seed(seed)
        image = pipe(
            prompt=prompt,
            generator=generator,
            num_inference_steps = 30,
            width=1152,
            height=896
        ).images[0]

        image.save(os.path.join(save_folder_name, f"{i}.png"))
    end = time.time()
    print(f"normal: {end - start:.5f}sec")

def with_lora(model_name:str) -> None:
    save_folder_name = f"{folder_name}_with_lora"
    pipe = StableDiffusionXLPipeline.from_single_file(
        f"safetensors/{model_name}",
        load_safety_checker=False,
        extract_ema=True,
        torch_dtype=torch.float16 
    )

    pipe.load_lora_weights("lcm-lora-sdxl/pytorch_lora_weights.safetensors")
    pipe.scheduler = LCMScheduler.from_config(pipe.scheduler.config)

    pipe.to("cuda")

    os.makedirs(save_folder_name, exist_ok=True)

    start = time.time()
    for i in range(n_samples):
        seed = 100000 + 2000 * (i + 1)
        generator = torch.manual_seed(seed)
        image = pipe(
            prompt=prompt,
            generator=generator,
            guidance_scale=1,
            num_inference_steps = 4,
            width=1152,
            height=896
        ).images[0]

        image.save(os.path.join(save_folder_name, f"{i}.png"))  
    end = time.time()
    print(f"with lcm-lora: {end - start:.5f}sec")

def stack() -> None:
    os.makedirs("stack_image", exist_ok=True)

    folder_list = [f"{folder_name}_without_lora", f"{folder_name}_with_lora"]
    print(" -> ".join(folder_list))

    for i in range(n_samples):
        images_list = []
        for path in folder_list:
            images_list.append(cv2.imread(os.path.join(path, f"{i}.png")))
        stack_image = np.hstack(images_list)
        cv2.imwrite(os.path.join("stack_image", f"{i}.png"), stack_image)

if __name__ == "__main__":
    
    without_lora(model_safetensors)    
    with_lora(model_safetensors)
    stack()

LCM-LoRAについて

touch-sp.hatenablog.com




このエントリーをはてなブックマークに追加