保姆级讲解 Stable Diffusion

这篇具有很好参考价值的文章主要介绍了保姆级讲解 Stable Diffusion。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

保姆级讲解 Stable Diffusion:

https://mp.weixin.qq.com/s?__biz=Mzk0MzIzODM5MA==&mid=2247486486&idx=1&sn=aff9ed60bba2cbf9efd32aa68557c93b&chksm=c337b18ff4403899d24ac32a60dbfd0402aab7309e8442dabdcb14cd61cfb55ad6cc1f977b3b#rd

整体代码

# 1、prompt编码为token。编码器为FrozenCLIPEmbedde(包括1层的 CLIPTextEmbeddings 和12层的自注意力encoder)
c = self.cond_stage_model.encode(c)    # (c为输入的提示语句,重复2次)  输出:(2,77,768)
batch_encoding = self.tokenizer(text, truncation=True, max_length=self.max_length, return_length=True,
                                        return_overflowing_tokens=False, padding="max_length", return_tensors="pt")
# self.tokenizer来自 transformers包中的 预训练CLIPTokenizer
tokens = batch_encoding["input_ids"].to(self.device)             # (2,77)一句话编码为77维
outputs = self.transformer(input_ids=tokens).last_hidden_state   # 12层self-atten,结果(2,77,768)

# 2、
samples_ddim, _ = sampler.sample(S=opt.ddim_steps,
                                   conditioning=c,
                                   batch_size=opt.n_samples,
                                   shape=shape,
                                   verbose=False,
                                   unconditional_guidance_scale=opt.scale,
                                   unconditional_conditioning=uc,
                                   eta=opt.ddim_eta,
                                   x_T=start_code)
     # 01、
     self.make_schedule(ddim_num_steps=S, ddim_eta=eta, verbose=verbose)    # S=50
     # 这一步是ddim中,预先register超参数,如a的连乘等
     # Data shape for PLMS sampling is (2, 4, 32, 32) 
     # 02、
     samples, intermediates = self.plms_sampling(conditioning, size,
                                                callback=callback,
                                                img_callback=img_callback,
                                                quantize_denoised=quantize_x0,
                                                mask=mask, x0=x0,
                                                ddim_use_original_steps=False,
                                                noise_dropout=noise_dropout,
                                                temperature=temperature,
                                                score_corrector=score_corrector,
                                                corrector_kwargs=corrector_kwargs,
                                                x_T=x_T )
          img = torch.randn(shape, device=device)    # (2,4,32,32)
          for i, step in enumerate(iterator):
                index = total_steps - i - 1                                        # index=50-i-1, step=981
                ts = torch.full((b,), step, device=device, dtype=torch.long)       # [981,981]
                outs = self.p_sample_plms(img, cond, ts, index=index, use_original_steps=ddim_use_original_steps,
                                          quantize_denoised=quantize_denoised, temperature=temperature,
                                          noise_dropout=noise_dropout, score_corrector=score_corrector,
                                          corrector_kwargs=corrector_kwargs,
                                          unconditional_guidance_scale=unconditional_guidance_scale,
                                          unconditional_conditioning=unconditional_conditioning,
                                          old_eps=old_eps, t_next=ts_next)
                    c_in = torch.cat([unconditional_conditioning, c])    # 添加一个空字符,与promt拼接
                    e_t_uncond, e_t = self.model.apply_model(x_in, t_in, c_in).chunk(2)
                          t_emb = timestep_embedding(timesteps, self.model_channels, repeat_only=False)    # timesteps:[981,981,981,981] -> (4,320)
                          emb = self.time_embed(t_emb)           # 2*linear:(4,320) -> (4,1280)
                          
                          # unet中带入embed与prompt,具体见源码
                          for module in self.input_blocks:
                              h = module(h, emb, context)        # 输入(4,4,32,32) (4,1280) (4,77,768)
                              hs.append(h)
                          h = self.middle_block(h, emb, context) 
                          for module in self.output_blocks:
                              h = th.cat([h, hs.pop()], dim=1)   # (4,1280,4,4) -> (4,2560,4,4)
                              h = module(h, emb, context)

                          return self.out(h)                     # (4,320,32,32)卷积为(4,4,32,32)

# 3、
e_t_uncond, e_t = self.model.apply_model(x_in, t_in, c_in).chunk(2)   # 上步中得到的结果拆开:(2,4,32,32
   e_t = e_t_uncond + unconditional_guidance_scale * (e_t - e_t_uncond)  # 用7.5乘以二者差距,再加回空语句生成的图
   x_prev, pred_x0 = get_x_prev_and_pred_x0(e_t, index)                  # DDIM计算:e_t(2,4,32,32) index:49  -> (2,4,32,32)

# 4、
x_samples_ddim = model.decode_first_stage(samples_ddim)    # (2,4,32,32)
        h = self.conv_in(z)    # 卷积4->512
        x = torch.nn.functional.interpolate(h, scale_factor=2.0, mode="nearest")  #(2,512,64,64)
        h = self.up[i_level].block[i_block](h)    # 经过几次卷积与上采样
        h = self.norm_out(h)   # (2,128,256,256)
        h = nonlinearity(h)    # x*torch.sigmoid(x)
        h = self.conv_out(h)   # conv(128,3) -》(2,3,256,256)

# 5、
后处理
x_samples_ddim = torch.clamp((x_samples_ddim + 1.0) / 2.0, min=0.0, max=1.0)
x_samples_ddim = x_samples_ddim.cpu().permute(0, 2, 3, 1).numpy()
x_checked_image, has_nsfw_concept = check_safety(x_samples_ddim)
x_checked_image_torch = torch.from_numpy(x_checked_image).permute(0, 3, 1, 2)
x_sample = 255. * rearrange(x_sample.cpu().numpy(), 'c h w -> h w c')
img = Image.fromarray(x_sample.astype(np.uint8))
img.save(os.path.join(sample_path, f"{base_count:05}.png"))

unet解析

DDIM中的Unet 包含输入模块、中间模块、输出模块三部分:

self.input_blocks

包含12个不同的 TimestepEmbedSequential结构,下面列举三种:

# 1、self.input_blocks
ModuleList(
  (0): TimestepEmbedSequential(
    (0): Conv2d(4, 320, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
  )
  (1): TimestepEmbedSequential(
    (0): ResBlock(
      (in_layers): Sequential(
        (0): GroupNorm32(32, 320, eps=1e-05, affine=True)
        (1): SiLU()
        (2): Conv2d(320, 320, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
      )
      (h_upd): Identity()
      (x_upd): Identity()
      (emb_layers): Sequential(
        (0): SiLU()
        (1): Linear(in_features=1280, out_features=320, bias=True)
      )
      (out_layers): Sequential(
        (0): GroupNorm32(32, 320, eps=1e-05, affine=True)
        (1): SiLU()
        (2): Dropout(p=0, inplace=False)
        (3): Conv2d(320, 320, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
      )
      (skip_connection): Identity()
    )
    (1): SpatialTransformer(
      (norm): GroupNorm(32, 320, eps=1e-06, affine=True)
      (proj_in): Conv2d(320, 320, kernel_size=(1, 1), stride=(1, 1))
      (transformer_blocks): ModuleList(
        (0): BasicTransformerBlock(
          (attn1): CrossAttention(
            (to_q): Linear(in_features=320, out_features=320, bias=False)
            (to_k): Linear(in_features=320, out_features=320, bias=False)
            (to_v): Linear(in_features=320, out_features=320, bias=False)
            (to_out): Sequential(
              (0): Linear(in_features=320, out_features=320, bias=True)
              (1): Dropout(p=0.0, inplace=False)
            )
          )
          (ff): FeedForward(
            (net): Sequential(
              (0): GEGLU(
                (proj): Linear(in_features=320, out_features=2560, bias=True)
              )
              (1): Dropout(p=0.0, inplace=False)
              (2): Linear(in_features=1280, out_features=320, bias=True)
            )
          )
          (attn2): CrossAttention(
            (to_q): Linear(in_features=320, out_features=320, bias=False)
            (to_k): Linear(in_features=768, out_features=320, bias=False)
            (to_v): Linear(in_features=768, out_features=320, bias=False)
            (to_out): Sequential(
              (0): Linear(in_features=320, out_features=320, bias=True)
              (1): Dropout(p=0.0, inplace=False)
            )
          )
          (norm1): LayerNorm((320,), eps=1e-05, elementwise_affine=True)
          (norm2): LayerNorm((320,), eps=1e-05, elementwise_affine=True)
          (norm3): LayerNorm((320,), eps=1e-05, elementwise_affine=True)
        )
      )
      (proj_out): Conv2d(320, 320, kernel_size=(1, 1), stride=(1, 1))
    )
  )

  (6): TimestepEmbedSequential(
    (0): Downsample(
      (op): Conv2d(640, 640, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))
    )
  )

前向过程:

为h添加emb和交与propmt的交叉注意力,会执行多次

emb_out = self.emb_layers(emb)      # (4,1280)卷积为(4,320)
h = h + emb_out                     # (4,320,32,32)+(4,320,1,1)

x = self.attn1(self.norm1(x)) + x                     # 自注意力:x(4,1024,320)映射到qkv,均320维
x = self.attn2(self.norm2(x), context=context) + x    # 交叉注意力:context(4,77,768)映射到kv的320维
x = self.ff(self.norm3(x)) + x

噪音图像h(4,4,32,32)在其中变化为:(4,320,32,32)(4,320,16,16)(4,640,16,16)(4,1280,8,8)(4,1280,4,4)

middle_blocks

TimestepEmbedSequential(
  (0): ResBlock(
    (in_layers): Sequential(
      (0): GroupNorm32(32, 1280, eps=1e-05, affine=True)
      (1): SiLU()
      (2): Conv2d(1280, 1280, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    )
    (h_upd): Identity()
    (x_upd): Identity()
    (emb_layers): Sequential(
      (0): SiLU()
      (1): Linear(in_features=1280, out_features=1280, bias=True)
    )
    (out_layers): Sequential(
      (0): GroupNorm32(32, 1280, eps=1e-05, affine=True)
      (1): SiLU()
      (2): Dropout(p=0, inplace=False)
      (3): Conv2d(1280, 1280, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    )
    (skip_connection): Identity()
  )
  (1): SpatialTransformer(
    (norm): GroupNorm(32, 1280, eps=1e-06, affine=True)
    (proj_in): Conv2d(1280, 1280, kernel_size=(1, 1), stride=(1, 1))
    (transformer_blocks): ModuleList(
      (0): BasicTransformerBlock(
        (attn1): CrossAttention(
          (to_q): Linear(in_features=1280, out_features=1280, bias=False)
          (to_k): Linear(in_features=1280, out_features=1280, bias=False)
          (to_v): Linear(in_features=1280, out_features=1280, bias=False)
          (to_out): Sequential(
            (0): Linear(in_features=1280, out_features=1280, bias=True)
            (1): Dropout(p=0.0, inplace=False)
          )
        )
        (ff): FeedForward(
          (net): Sequential(
            (0): GEGLU(
              (proj): Linear(in_features=1280, out_features=10240, bias=True)
            )
            (1): Dropout(p=0.0, inplace=False)
            (2): Linear(in_features=5120, out_features=1280, bias=True)
          )
        )
        (attn2): CrossAttention(
          (to_q): Linear(in_features=1280, out_features=1280, bias=False)
          (to_k): Linear(in_features=768, out_features=1280, bias=False)
          (to_v): Linear(in_features=768, out_features=1280, bias=False)
          (to_out): Sequential(
            (0): Linear(in_features=1280, out_features=1280, bias=True)
            (1): Dropout(p=0.0, inplace=False)
          )
        )
        (norm1): LayerNorm((1280,), eps=1e-05, elementwise_affine=True)
        (norm2): LayerNorm((1280,), eps=1e-05, elementwise_affine=True)
        (norm3): LayerNorm((1280,), eps=1e-05, elementwise_affine=True)
      )
    )
    (proj_out): Conv2d(1280, 1280, kernel_size=(1, 1), stride=(1, 1))
  )
  (2): ResBlock(
    (in_layers): Sequential(
      (0): GroupNorm32(32, 1280, eps=1e-05, affine=True)
      (1): SiLU()
      (2): Conv2d(1280, 1280, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    )
    (h_upd): Identity()
    (x_upd): Identity()
    (emb_layers): Sequential(
      (0): SiLU()
      (1): Linear(in_features=1280, out_features=1280, bias=True)
    )
    (out_layers): Sequential(
      (0): GroupNorm32(32, 1280, eps=1e-05, affine=True)
      (1): SiLU()
      (2): Dropout(p=0, inplace=False)
      (3): Conv2d(1280, 1280, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    )
    (skip_connection): Identity()
  )

self.output_blocks

与输入模块相同,包含12个 TimestepEmbedSequential,顺序相反。文章来源地址https://www.toymoban.com/news/detail-485501.html

到了这里,关于保姆级讲解 Stable Diffusion的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 万字长文:Stable Diffusion 保姆级教程

    2022年绝对是人工智能爆发的元年,前有 stability.ai 开源 Stable Diffusion 模型,后有 Open AI 发布 ChatGPT,二者都是里程碑式的节点事件,其重要性不亚于当年苹果发布iPhone,Google推出Android。它们让AI不再是一个遥不可及的技术名词,而是触手可及、实实在在的智能应用工具。 不同

    2024年02月03日
    浏览(50)
  • Stable Diffusion下载安装,保姆级教程指南!

    3、版本:截止至目前,Stable Diffusion已经发布了7个版本,最新的是Stable Diffusion3.0,但目前还未完全开放测试资格,想体验最新版本的小伙伴可去官网申请。 版本号 发布日期 备注 1.4 2022 年 8 月 不存在“1.0版本”。相反,有版本 1.1、1.2、1.3、1.4。全部由 CompVis 发布。 1.5 202

    2024年04月16日
    浏览(39)
  • Stable Diffusion最全保姆级安装教程(建议收藏)

    Midjourney 因细致的画图风格备受大家的欢迎,但由于其网络环境以及会员费,导致入门门槛过高,拦住了很多对AIGC感兴趣的小伙伴。 今天阿良就教大家,不需要魔法,也不用交会员费,尽情玩转AI出图的保姆级安装教程,建议收藏。 对于Midjourney 高额的会员费,SD的高性价比

    2024年02月05日
    浏览(39)
  • 【stable diffusion】保姆级入门课程04-Stable diffusion(SD)图生图-局部重绘的用法

    目录 0.本章素材 1.什么是局部重绘 2.局部重绘和涂鸦有什么不同 3.操作界面讲解 3.1.蒙版模糊 3.2.蒙版模式 3.3.蒙版蒙住的内容 3.4.重绘区域 4.局部重绘的应用(面部修复) 5.课后训练 局部重绘是不改变整体图片的构图的情况下,对图片的某个区域进行重绘,局部重绘是利用蒙

    2024年02月16日
    浏览(49)
  • 【stable diffusion】保姆级入门课程05-Stable diffusion(SD)图生图-涂鸦重绘的用法

    涂鸦重绘又称手涂蒙版。 简单来说,局部重绘手涂蒙版 就是涂鸦+局部重绘的结合体,这个功能的出现是为了解决用户不想改变整张图片的情况下,对多个元素进行修改。 功能支持: 1.支持蒙版功能 2.笔刷决定绘制的元素颜色 3.支持多种颜色在一张图片上 与局部重绘的界面

    2024年02月15日
    浏览(46)
  • 【stable diffusion】保姆级入门课程02-Stable diffusion(SD)图生图-基础图生图用法

    目录 学前视频 0.本章素材  1.图生图是什么 2.图生图能做什么 3.如何使用图生图 4.功能区域 4.1.提示词区域 4.2.图片提示词反推区域 1.CLIP反推 2.DeepBooru 反推 4.3.图片上传区域 4.4.结果图区域 4.5.缩放模式  4.6.重绘幅度 7.结语 8.课后训练   stable diffusion图生图教程 百度网盘 夸克

    2024年02月15日
    浏览(73)
  • 【stable diffusion】保姆级入门课程01-Stable diffusion(SD)文生图究竟是怎么一回事

    目录 学前视频 0.本章素材 1.什么是文生图 2.界面介绍 2.1切换模型的地方 2.2切换VAE 2.3功能栏 2.4提示词 1.提示词的词性 2.提示词的语法 3.提示词的组成 4.提示词的权重调整 2.5参数调整栏 1.采样方法 2.采样迭代步数 3.面部修复 4.平铺图 5.高清修复 6.宽度和高度 7.生成批次和每批

    2024年02月14日
    浏览(39)
  • stable diffusion模型讲解

    AI模型最新展现出的图像生成能力远远超出人们的预期,直接根据文字描述就能创造出具有惊人视觉效果的图像,其背后的运行机制显得十分神秘与神奇,但确实影响了人类创造艺术的方式。 AI模型最新展现出的图像生成能力远远超出人们的预期,直接根据文字描述就能创造

    2024年02月08日
    浏览(47)
  • Stable Diffusion 保姆级教程!全网最新最全!小白必备!

    ** Stable Diffusion无疑是最近最火的AI绘画工具之一,所以本期给大家带来了全新Stable Diffusion 保姆级教程资料包(文末可获取) 2022年绝对是人工智能爆发的元年,前有 stability.ai 开源 Stable Diffusion 模型,后有 Open AI 发布 ChatGPT,二者都是里程碑式的节点事件,其重要性不亚于当

    2024年02月03日
    浏览(47)
  • AI绘画小白福音!Stable Diffusion 保姆级教程

    安装好了模型,我们来进行 AI 绘画的文生图实战。 模型安装后之后,就可以开始激动人心的 AI 文生图了,下面我们以文生图为例,一边操作一边讲解提示词的语法和分类,以及出图参数的作用和使用方法。 在开始之前,我们再来回顾一下,我们的需求是让 AI 生成我们所要

    2024年04月14日
    浏览(62)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包