当前位置:   article > 正文

【Diffusers库】第五篇 加载pipeline、model、schedulers_diffusers pipline没有本地模型

diffusers pipline没有本地模型

写在前面的话

  这是我们研发的用于 消费决策的AI助理 ,我们会持续优化,欢迎体验与反馈。微信扫描二维码,添加即可。
  官方链接:https://ailab.smzdm.com/

************************************************************** 分割线 ****************************************************************

  官网的这一章节,我觉得有点繁琐,部分内容在前面的博客中有提到,所以这篇梳理总结一下,省些时间。

不同的位置加载模型

from diffusers import DiffusionPipeline, StableDiffusionPipeline,StableDiffusionImg2ImgPipeline

repo_id = "runwayml/stable-diffusion-v1-5"

# 方法一, 第一次加载会自动下载,随后再次加载会从缓存中加载
pipe = DiffusionPipeline.from_pretrained(repo_id)

# 方法二, 第一次加载会自动下载,随后再次加载会从缓存中加载
pipe = StableDiffusionPipeline.from_pretrained(repo_id)

# 方法三, 第一次加载会自动下载,随后再次加载会从缓存中加载,用于图生图
pipe = StableDiffusionImg2ImgPipeline.from_pretrained(repo_id)

# 方法四, 从指定路径加载
repo_id = "./stable-diffusion-v1-5"
stable_diffusion = DiffusionPipeline.from_pretrained(repo_id)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

加载模型的不同部分

调度器

查看可用调度器

  在进行图像生成的时候,pipeline有好几个部分,不同的部分产生的作用不一样,因而我们可以替换一下不同的组件,来提升图像生成的质量和效率。

  • 改变调度器,并且权衡图像生成时的速度和质量非常重要。
  • 模型的不同组件通常是独立训练的,您可以将组件换成性能更好的组件。
  • 在微调过程中,通常只训练一些组件,如UNet或文本编码器。

  为了检查调度器与加载模型的兼容性,可以使用compatibles函数:

from diffusers import DiffusionPipeline

repo_id = "runwayml/stable-diffusion-v1-5"
stable_diffusion = DiffusionPipeline.from_pretrained(repo_id)
stable_diffusion.scheduler.compatibles
  • 1
  • 2
  • 3
  • 4
  • 5

返回

[<class 'diffusers.schedulers.scheduling_lms_discrete.LMSDiscreteScheduler'>,
 <class 'diffusers.schedulers.scheduling_unipc_multistep.UniPCMultistepScheduler'>, 
 <class 'diffusers.utils.dummy_torch_and_torchsde_objects.DPMSolverSDEScheduler'>, 
 <class 'diffusers.schedulers.scheduling_heun_discrete.HeunDiscreteScheduler'>, 
 <class 'diffusers.schedulers.scheduling_ddim.DDIMScheduler'>, 
 <class 'diffusers.schedulers.scheduling_dpmsolver_singlestep.DPMSolverSinglestepScheduler'>, 
 <class 'diffusers.schedulers.scheduling_deis_multistep.DEISMultistepScheduler'>, 
 <class 'diffusers.schedulers.scheduling_dpmsolver_multistep.DPMSolverMultistepScheduler'>, 
 <class 'diffusers.schedulers.scheduling_pndm.PNDMScheduler'>, 
 <class 'diffusers.schedulers.scheduling_euler_discrete.EulerDiscreteScheduler'>, 
 <class 'diffusers.schedulers.scheduling_k_dpm_2_discrete.KDPM2DiscreteScheduler'>, 
 <class 'diffusers.schedulers.scheduling_ddpm.DDPMScheduler'>, 
 <class 'diffusers.schedulers.scheduling_k_dpm_2_ancestral_discrete.KDPM2AncestralDiscreteScheduler'>, 
 <class 'diffusers.schedulers.scheduling_euler_ancestral_discrete.EulerAncestralDiscreteScheduler'>]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

这里可以看到这个pipeline可以使用的调度器

更换可用调度器

from diffusers import DiffusionPipeline, EulerDiscreteScheduler, DPMSolverMultistepScheduler
repo_id = "runwayml/stable-diffusion-v1-5"

# 使用EulerDiscreteScheduler中的调度器,替换默认的调度器,但是需要指定文件夹
scheduler = EulerDiscreteScheduler.from_pretrained(repo_id, subfolder="scheduler")
stable_diffusion = DiffusionPipeline.from_pretrained(repo_id, scheduler=scheduler)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

安全模型

主要通过from_pretrained方法中的safety_checker参数来设定的。这个主要是 防止色情和暴力之类的。

from diffusers import DiffusionPipeline

repo_id = "runwayml/stable-diffusion-v1-5"
stable_diffusion = DiffusionPipeline.from_pretrained(repo_id, safety_checker=None)
  • 1
  • 2
  • 3
  • 4

重复使用组件

还可以在多个pipeline中,使用相同的组件,以避免重复加载:

from diffusers import StableDiffusionPipeline, StableDiffusionImg2ImgPipeline

model_id = "runwayml/stable-diffusion-v1-5"
stable_diffusion_txt2img = StableDiffusionPipeline.from_pretrained(model_id)
components = stable_diffusion_txt2img.components

for i in components:
     print(i)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

输出了这个pipeline里的不同的组件,这些组件中记录了模型参数、网络结构等等:

vae
text_encoder
tokenizer
unet
scheduler
safety_checker
feature_extractor
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

然后,可以将组件传递到另一个pipeline,无需将模型重新加载到内存中:

stable_diffusion_img2img = StableDiffusionImg2ImgPipeline(**components)
  • 1

当然,也可以分开加载:

from diffusers import StableDiffusionPipeline, StableDiffusionImg2ImgPipeline

model_id = "runwayml/stable-diffusion-v1-5"
stable_diffusion_txt2img = StableDiffusionPipeline.from_pretrained(model_id)
stable_diffusion_img2img = StableDiffusionImg2ImgPipeline(
    vae=stable_diffusion_txt2img.vae,
    text_encoder=stable_diffusion_txt2img.text_encoder,
    tokenizer=stable_diffusion_txt2img.tokenizer,
    unet=stable_diffusion_txt2img.unet,
    scheduler=stable_diffusion_txt2img.scheduler,
    safety_checker=None,
    feature_extractor=None,
    requires_safety_checker=False,
)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

模型变种

这个概念可能比较陌生,我的理解就是在预训练模型的基础上,训练出来的模型,叫做模型变体(Checkpoint variants)

  • 模型中的参数的数据类型在进行存储的时候是有选择的,比如:torch.float16,可以获得较低的精度和较低的存储空间。但是,如果使用的是CPU,则不能使用此变体。
  • Non-exponential mean averaged (EMA) weights 不能进行图例,只能进行微调模型。

加载

另外,还有2个重要的参数,在加载模型的时候要使用,
一个是指定torch_dtype(数据格式),就是上文中提到的torch.float16,
一个是指定variant(模型变种),我感觉,这个参数会明确加载模型时的目的,是用于推理 or 训练。

from diffusers import DiffusionPipeline

# load fp16 variant
stable_diffusion = DiffusionPipeline.from_pretrained(
    "runwayml/stable-diffusion-v1-5", variant="fp16", torch_dtype=torch.float16
)
# load non_ema variant
stable_diffusion = DiffusionPipeline.from_pretrained("runwayml/stable-diffusion-v1-5", variant="non_ema")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

保存

保存的时候,使用 DiffusionPipeline.save_pretrained() 函数,并且要指明 variant 参数是:fp16 or non_ema,应该将模型保存到与原始检查点相同的文件夹中,这样您就可以从同一文件夹加载这两个模型了:

from diffusers import DiffusionPipeline

# save as fp16 variant
stable_diffusion.save_pretrained("runwayml/stable-diffusion-v1-5", variant="fp16")
# save as non-ema variant
stable_diffusion.save_pretrained("runwayml/stable-diffusion-v1-5", variant="non_ema")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

如果不将模型保存到现有文件夹中,则必须指定模型参数,否则它将引发异常,找不到模型:

# 
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/运维做开发/article/detail/735496
推荐阅读
相关标签