SD模型微调之LoRA

大家好,这里是Goodnote(好评笔记),关注公主号Goodnote,专栏文章私信限时Free。本文是 SD 模型微调方法 LoRA 的详细介绍,包括数据集准备,模型微调过程,推理过程,优缺点等。

SD模型微调之LoRA_第1张图片

热门专栏

机器学习

机器学习笔记合集

深度学习

深度学习笔记合集

文章目录

  • 热门专栏
    • 机器学习
    • 深度学习
    • 论文
    • 概念
      • 核心原理
      • 优点
      • 训练过程
        • 预训练模型加载
        • 选择微调的层
          • LoRA 优化的层
            • Cross-Attention(跨注意力)层
            • Self-Attention(自注意力)层
          • LoRA 如何优化这些层
            • 原始线性层的操作
            • LoRA 的低秩矩阵分解
            • 优化的关键步骤
          • 推理过程中如何应用优化?
          • 为什么选择优化这些层?
          • LoRA对部分 Cross-Attention 和 Self-Attention 层进行局部调整,调整层主要是哪些?
        • 低秩分解
        • 训练 LoRA 的低秩矩阵
          • 前向传播(Forward Pass)
          • 反向传播(Backward Pass)
        • 防止过拟合
      • 推理过程
        • 加载微调后的底层模型和 LoRA 权重
        • 输入文本条件
        • 图像生成
        • 控制与调节
    • 推荐阅读

论文

论文地址:LoRA: Low-Rank Adaptation of Large Language Models

概念

LoRALow-Rank Adaptation of Large Language Models)是一种用于高效微调大规模预训练模型的技术,特别适用于参数量巨大的模型,如 GPT-3BERTStable Diffusion 等。LoRA 提供了一种解决方案,使得在进行模型微调时,只需要微调非常少量的参数,同时保持与全量参数微调相近的性能表现

核心原理

LoRA(Low-Rank Adaptation of Large Language Models) 的核心原理是通过低秩分解减少大规模模型微调时需要更新的参数量,以此实现更高效的模型微调。它特别适用于像 GPT-3BERTStable Diffusion 这样的预训练大模型,在微调这些模型时,LoRA 通过引入两个低秩矩阵替代直接更新整个权重矩阵,从而显著降低了计算成本和存储需求

核心思想:假设预训练模型中的权重矩阵 W 很大。LoRA 的基本思想是将它的更新部分 ΔW 分解为两个秩更小的矩阵 A 和 B 的乘积,从而减少需要更新的参数量,并且仅仅更新这两个矩阵。而不是更新整个 W 矩阵,保持预训练模型的原始性能

权重矩阵分解的核心公式:

LoRA对权重矩阵 W W W 进行如下处理:
W = W 0 + Δ W W = W_0 + \Delta W W=W0+ΔW

其中:

  • W 0 W_0 W0 是预训练模型中的原始权重矩阵,不更新。
  • Δ W \Delta W ΔW 是LoRA引入的可训练部分。为了减少训练参数,LoRA将 Δ W \Delta W ΔW 表示为两个低秩矩阵的乘积: Δ W = A B \Delta W = AB ΔW=AB
  • A A A B B B 是两个低秩矩阵,其中:
    • A ∈ R d × r A \in \mathbb{R}^{d \times r} ARd×r(小尺寸矩阵,rank r r r 远小于 d d d)。
    • B ∈ R r × k B \in \mathbb{R}^{r \times k} BRr×k(同样是小尺寸矩阵)。

在LoRA中,只训练矩阵 A A A B B B,而不是训练整个权重矩阵 W W W,从而减少了需要更新的参数量。

通常来说,对于矩阵A,我们使用 随机高斯分布 初始化,并对矩阵B使用 全0 初始化,使得在训练初始状态下这两个矩阵相乘的结果为0。这样能够保证在训练初始阶段时,SD模型的权重完全生效。

小型任务:一般 r 取 1 到 4

中型任务:通常 r 取 4 到 8

复杂任务:一般 r 取 8 到 16

结论来源:深入浅出完整解析LoRA(Low-Rank Adaptation)模型核心基础知识

优点

  • 大幅减少参数更新量:通过对权重矩阵进行低秩分解,LoRA 只需要更新非常少的参数,而不是整个模型的参数。这大大降低了存储需求和计算成本。
  • 保持模型的原始性能:LoRA 冻结SD模型的权重,因此微调后的模型依然可以利用预训练模型的知识。
  • 模块化更新和可插拔设计:LoRA 的权重调整是通过 A 和 B 进行的,在推理时也可以轻松应用,不需要重新加载整个模型。LoRA 训练出的 A 和 B 矩阵是可以独立保存的。在推理时,你可以在不同任务之间快速切换,而不需要重新训练模型。

训练过程

LoRA 微调的训练过程可分为以下几个步骤:

预训练模型加载

首先,加载一个预训练的 Stable Diffusion 模型。这个模型已经在大规模的文本图像数据集上进行了训练,具备强大的生成能力。LoRA 的目标是在该预训练模型上微调,只需调整极少的参数。

选择微调的层

Stable Diffusion 模型中,LoRA 通常作用于模型中的线性层(主要在注意力模块的 Q、K、V 的三个权重矩阵W)。具体来说,LoRA 会对 U-Net 中的 cross-attention 机制自注意力机制的线性层等进行调整。

  • LoRA 通过对这些线性层中的权重矩阵进行低秩分解(主要在注意力模块的 Q、K、V 权重),并引入两个低秩矩阵 A 和 B,通过这些矩阵来调整权重变化。

详细介绍如下:

LoRA 主要作用于 U-Net 网络中的 注意力机制相关的线性层,特别是用于跨模态交互Cross-Attention(跨注意力)层 以及 Self-Attention(自注意力)层

LoRA 优化的层

Stable DiffusionU-Net 中,主要有两种注意力机制:自注意力机制(Self-Attention)跨注意力机制(Cross-Attention)。LoRA 主要对这些注意力层中的 线性层 进行优化,特别是以下几个部分:

Cross-Attention(跨注意力)层
  • Cross-Attention 是 U-Net 中的核心机制,它负责将图像的潜在特征(Latent Feature)与文本嵌入(Text Embedding)进行结合。通过跨注意力机制,模型可以从文本提示中获取信息,调整图像生成的内容
  • Cross-Attention 中,LoRA 主要针对用于生成 Query (Q)Key (K)Value (V)线性变换层​ Q = W Q ⋅ X , K = W K ⋅ X , V = W V ⋅ X Q = W_Q \cdot X, \quad K = W_K \cdot X, \quad V = W_V \cdot X Q=WQX,K=WKX,V=WVX】进行优化。这些层分别处理输入特征和文本嵌入,并计算注意力权重。
Self-Attention(自注意力)层
  • Self-Attention 是 U-Net 内部的图像特征交互机制,负责在图像的不同区域之间进行特征相互作用,从而捕捉到图像的全局依赖关系
  • 在 Self-Attention 中,LoRA 也对生成 Query (Q)Key (K)Value (V)线性层进行优化。
LoRA 如何优化这些层

LoRA 通过将注意力机制中的 线性层(例如,用于生成 QKV 的线性变换层)进行低秩分解,从而减少参数更新量。具体的优化方式如下:

原始线性层的操作

在注意力机制中,通常会对输入特征进行如下操作:

  • 输入特征 X X X 会通过线性层进行映射,生成 Query (Q)Key (K)Value (V),具体公式为:
    Q = W Q X , K = W K X , V = W V X Q = W_Q X, \quad K = W_K X, \quad V = W_V X Q=WQX,K=WKX,V=WVX
    • 其中, W Q W_Q WQ W K W_K WK W V W_V WV是用于生成 Q Q Q K K K V V V 的权重矩阵。在标准微调过程中,这些权重矩阵会被更新。
LoRA 的低秩矩阵分解

与原始公式直接更新整个 W Q W_Q WQ W K W_K WK W V W_V WV 矩阵相比,在 LoRA 中通过使用两个更小的矩阵 A 和 B表示这些矩阵的变化

  • 引入 低秩分解 对权重矩阵进行调整: W Q W_Q WQ W K W_K WK W V W_V WV 被表示为预训练权重加上一个低秩矩阵的调整:

    W Q = W Q 0 + Δ W Q , Δ W Q = A Q B Q W_Q = W_Q^0 + \Delta W_Q, \quad \Delta W_Q = A_Q B_Q WQ=WQ0+ΔWQ,ΔWQ=AQBQ

    类似的公式用于 W K W_K WK W V W_V WV

    • A Q A_Q AQ B Q B_Q BQ 是两个低秩矩阵,秩(rank) r r r 远小于输入维度和输出维度。这样,LoRA只需要训练 A Q A_Q AQ B Q B_Q BQ,从而减少了需要训练的参数量。
    • 在推理阶段,更新后的权重 W Q W_Q WQ 就是原始权重 W Q 0 W_Q^0 WQ0 加上 A Q B Q A_Q B_Q AQBQ
优化的关键步骤
  • 保持原始权重不变:在LoRA微调中,原始的权重矩阵 W Q 0 W_Q^0 WQ0 W K 0 W_K^0 WK0 W V 0 W_V^0 WV0 保持不变,这意味着预训练模型的知识不会被破坏。
  • 只训练低秩矩阵 A A A B B B:通过训练 A Q A_Q AQ B Q B_Q BQ(以及对应的 A K A_K AK A V A_V AV B K B_K BK B V B_V BV),LoRA微调可以适应新任务的需求,同时大幅减少了参数更新量。
推理过程中如何应用优化?

在推理阶段,LoRA 的优化部分通过如下方式应用于模型:

  • 应用权重更新:在推理过程中,LoRA 使用微调后的低秩矩阵 A 和 B,并将它们加到原始的权重矩阵中。例如,计算 Q 时:

    Q = ( W Q 0 + A Q B Q ) X Q = (W_Q^0 + A_Q B_Q)X Q=(WQ0+AQBQ)X

  • 这个更新后的权重矩阵确保模型能够在保持原始生成能力的同时,生成包含定制内容的图像

为什么选择优化这些层?

LoRA 选择优化 Attention 层中的线性层 有以下原因:

  1. Attention 层是核心:在 Stable Diffusion 的 U-Net 中,Attention 层(特别是 Cross-Attention 层)是将图像生成与文本提示结合的关键部分。对这些层进行优化,可以直接影响模型如何将文本信息传递给图像生成过程。

  2. 低秩分解的有效性:对于大型模型中的全连接层,低秩分解可以在不显著影响模型性能的情况下,显著减少参数更新量。Attention 层中的权重矩阵往往是高维的,因此通过 LoRA 对它们进行低秩分解能大幅降低训练成本。

  3. 减少计算开销:注意力机制中的线性层通常参数量大且计算密集,通过 LoRA 的低秩分解,可以在降低计算复杂度的同时保留模型的生成能力。

LoRA对部分 Cross-Attention 和 Self-Attention 层进行局部调整,调整层主要是哪些?

U-Net 中确实包含多个分辨率下的 Self-AttentionCross-Attention 层,但 LoRA 的微调是有选择性的,并不会对每一个 Attention 层进行微调。LoRA 的设计初衷是通过低秩矩阵分解的方式只微调关键的 Attention 层。

LoRA 通常会优先选择在以下部分进行微调,而不会对整个 U-Net 中的所有层进行调整:

1.瓶颈部分的 Attention 层

  • 理由瓶颈部分位于 编码器和解码器之间,是整个 U-Net 中分辨率最低的层级。这个部分的特征代表了全局的高层次信息和抽象概念。瓶颈部分的 Cross-Attention 层进行微调,因为这一部分的 Attention 负责将文本嵌入(来自 CLIP)与图像的潜在特征结合。由于这一部分影响整个生成过程的全局结构和语义,微调这里的 Cross-Attention 层可以最大化对文本提示的响应。

2.解码器中的高分辨率层 Attention

  • 理由:解码器的高分辨率层在解码器靠近输出的层中。这些层逐步将潜在特征映射回高分辨率图像,负责生成最终图像的细节,微调这些层的 Self-AttentionCross-Attention 机制有助于确保图像的细节和纹理质量。LoRA 选择性地微调这些层以保持生成细节的精准度。

3.部分中间层

  • 理由中间层出现在编码器部分和解码器部分的中间位置,即编码器将分辨率逐步降低时或解码器逐步上采样时的过渡层。在某些任务中,特别是需要全局一致性时,LoRA 可能会对部分中等分辨率层进行调整。这通常只针对某些关键的中间层,而不会全面覆盖所有中间层的 Attention 层。

其他的层不会进行改变。 DreamBooth会更改全部的Attention层。

低秩分解

对于每个需要微调的层,LoRA 将该层的权重矩阵 W 进行低秩分解:

W = W 0 + Δ W W = W_0 + \Delta W W=W0+ΔW

其中:

  • W 0 W_0 W0 是预训练模型的权重矩阵,保持不变。
  • Δ W = A B \Delta W = AB ΔW=AB 是通过LoRA进行调整的部分,仅训练低秩矩阵 A A A B B B
训练 LoRA 的低秩矩阵

在 LoRA 的训练过程中,我们仅训练 A 和 B 这两个低秩矩阵,而保持模型中原始的权重 W 0 W_0 W0不变。这种方法显著减少了需要更新的参数量,降低了训练开销。

具体流程:

  1. 图像和文本输入:使用包含图片和文本描述的数据对模型进行训练,类似于 Stable Diffusion 的预训练任务。

  2. 损失函数:LoRA 的损失函数与原始 Stable Diffusion 的损失函数类似,主要通过预测噪声残差来进行训练。损失函数通常是均方误差(MSE),公式如下:

    L MSE = E x 0 , ϵ , t [ ∥ ϵ − ϵ θ ( x t , t , c ) ∥ 2 ] L_{\text{MSE}} = \mathbb{E}_{x_0, \epsilon, t} [ \| \epsilon - \epsilon_{\theta}(x_t, t, c) \|^2 ] LMSE=Ex0,ϵ,t[ϵϵθ(xt,t,c)2]

    • 其中 x 0 x_0 x0 是原始图像, x t x_t xt 是经过扩散步骤后的加噪图像, c c c 是文本条件, ϵ \epsilon ϵ 是噪声。
    • 通过损失函数来最小化模型预测的噪声残差与真实噪声之间的差异。
  3. 只更新低秩矩阵:在反向传播时LoRA 只更新 A 和 B,而保持预训练模型的其余部分不变。通过这样的方法,模型能够在少量参数更新的情况下学会新的任务。

更详细的过程如下:

前向传播(Forward Pass)

输入数据准备

  • 输入包括图像和文本描述,这些输入会通过文本编码器(如 CLIP)和 Stable Diffusion 的 U-Net 进行特征提取。

权重替换

  • 在LoRA中,原始预训练的权重矩阵 W 0 W_0 W0 不会直接更新,而是扩展为:
    W = W 0 + A ⋅ B W = W_0 + A \cdot B W=W0+AB
    • 其中, W 0 W_0 W0 是原始权重矩阵,保持不变, A A A B B B 是引入的低秩矩阵,分别为 ( d , r ) (d, r) (d,r) ( r , k ) (r, k) (r,k) 维度, r r r 是低秩维度。
  • 这样,U - Net中的线性层权重(特别是Cross - Attention和Self - Attention中的Q、K、V权重)会通过 W W W 替代原始的 W 0 W_0 W0,在前向传播中完成线性变换。

生成 Q、K 和 V 矩阵

  • 对于输入的图像特征和文本嵌入,模型通过线性层生成 Q、K 和 V 矩阵:

Q = W Q ⋅ input Q = W_Q \cdot \text{input} Q=WQinput
K = W K ⋅ input K = W_K \cdot \text{input} K=WKinput
V = W V ⋅ input V = W_V \cdot \text{input} V=WVinput

  • 这里 W Q W_Q WQ​、 W K W_K WK W V W_V WV表示 Attention 层的线性层权重。在 LoRA 微调时,这些权重扩展为:

W Q = W Q 0 + A Q ⋅ B Q W_Q = W_{Q0} + A_Q \cdot B_Q WQ=WQ0+AQBQ
W K = W K 0 + A K ⋅ B K W_K = W_{K0} + A_K \cdot B_K WK=WK0+AKBK
W V = W V 0 + A V ⋅ B V W_V = W_{V0} + A_V \cdot B_V WV=WV0+AVBV

  • 在前向传播时,使用这些新的 Q、K、V 权重来计算 Attention 输出。

计算注意力分数

  • 得到 Q 和 K 矩阵后,通过点积计算 Attention 分数,并使用 Softmax 进行归一化,以确定图像特征和文本特征的相关性:
    Attention Scores = Softmax ( Q ⋅ K T d k ) \text{Attention Scores} = \text{Softmax} \left( \frac{Q \cdot K^T}{\sqrt{d_k}} \right) Attention Scores=Softmax(dk QKT)
    • 其中, d k d_k dk Q Q Q K K K的维度,用于缩放以稳定梯度。这一步将重要特征赋予更高权重。

应用注意力分数到 Value 矩阵

  • 将注意力分数应用到 V V V 矩阵上,生成注意力聚合后的输出特征:

Attention Output = Attention Scores ⋅ V \text{Attention Output} = \text{Attention Scores} \cdot V Attention Output=Attention ScoresV

  • 这一步的输出包含了从输入特征中提取的重要信息,带有新任务的特征细节。

注意力输出用于噪声预测【同DDPM扩散过程】

DDPM原理参考:Stable Diffusion 笔记合集 中的《Diffusion Model原理》

损失计算

  • 根据前向传播的输出,通过损失函数(通常为均方误差 MSE)计算预测噪声残差与目标的差异:

L MSE = E x 0 , ϵ , t [ ∥ ϵ − ϵ θ ( x t , t , c ) ∥ 2 ] L_{\text{MSE}} = \mathbb{E}_{x_0, \epsilon, t} [ \| \epsilon - \epsilon_{\theta}(x_t, t, c) \|^2 ] LMSE=Ex0,ϵ,t[ϵϵθ(xt,t,c)2]

  • 其中 x 0 x_0 x0 是原始图像, x t x_t xt 是经过扩散步骤后的加噪图像, c c c 是文本条件, ϵ \epsilon ϵ 是噪声。
  • 通过损失函数来最小化模型预测的噪声残差与真实噪声之间的差异。
反向传播(Backward Pass)

计算损失的梯度

  • 根据损失函数 L,计算损失相对于 A 和 B 的梯度:
    ∂ L ∂ A 和 ∂ L ∂ B \frac{\partial L}{\partial A} \quad 和 \quad \frac{\partial L}{\partial B} ALBL

锁定原始权重矩阵 W 0 W_0 W0

  • 在反向传播过程中,LoRA 只更新 A A A B B B,而保持原始的权重矩阵 W 0 W_0 W0 不变。这保证了预训练的知识不会被破坏,同时通过 A 和 B 的更新来适应新任务特征。

更新低秩矩阵 A 和 B

  • 根据梯度,用优化算法(如 Adam)对 A 和 B 的参数进行更新:

    A ← A − ∂ L ∂ A η A \leftarrow A - \frac{\partial L}{\partial A} \eta AAALη
    B ← B − ∂ L ∂ B η B \leftarrow B - \frac{\partial L}{\partial B} \eta BBBLη

    • 这里 η \eta η 是学习率,更新后的 A A A B B B 让模型在不改变预训练权重的前提下适应新任务的特征。
防止过拟合

为了避免微调时模型过拟合到新数据集,LoRA 引入了正则化技术,并且通常通过选择较小的秩(rank)来限制低秩矩阵的参数量较小的秩 r 能够确保模型在学习新任务时不会丢失原有的生成能力,同时避免过拟合

  • 小型任务(简单图像生成、基本文本任务):一般 r 取 1 到 4。对于简单任务,这样的秩通常能够捕捉到足够的特征变化,并且显著减少了微调参数。

  • 中型任务(如在特定风格或特定场景下生成图像):通常 r 取 4 到 8。这种秩设置在保持微调效率的同时,能够适应稍复杂的任务。

  • 复杂任务(高分辨率图像生成、大规模定制化):一般 r 取 8 到 16。对于非常复杂的生成任务,较高的秩可以捕捉到更细致的特征,但会增加参数量和计算开销。

推理过程

推理过程与标准的 Stable Diffusion 推理过程类似,但会在原始模型的基础上加上 LoRA 的调整部分

推理的流程如下:

加载微调后的底层模型和 LoRA 权重
  • 在推理阶段,我们需要加载预训练的 Stable Diffusion 模型微调得到的 LoRA 权重(即 A 和 B 的值)。这些权重通常是很小的存储文件,容易加载和应用。
  • 模型的推理过程会利用原始权重 W0​ 和微调得到的 ΔW=AB。
输入文本条件
  • 用户可以输入一个文本描述,作为 Stable Diffusion 模型生成图像的提示。这个文本描述会通过 CLIP 模型编码为 文本嵌入(Text Embedding),并作为条件输入到生成过程。
图像生成
  • 在推理时,LoRA 通过原始权重 W0​ 加上训练时得到的 ΔW 生成最终的图像:
    y = ( W 0 + A B ) x y = (W_0 + AB)x y=(W0+AB)x
    • 其中, x x x 是输入的潜在向量或图像特征, y y y 是经过 LoRA 微调后的生成结果。
  • 模型会通过一系列反向扩散步骤,逐步去除噪声,生成符合输入文本描述的图像。
控制与调节
  • 通过调整输入的文本提示,用户可以灵活控制生成图像的风格、内容和其他细节。
  • LoRA 提供了模块化设计,可以轻松替换不同的 LoRA 微调权重,以适应不同的任务和数据集。例如,可以在同一个模型上应用多个不同的 LoRA 微调权重,以生成不同风格或内容的图像。

推荐阅读

使用 LoRA 进行 Stable Diffusion 的高效参数微调

全世界 LoRA 训练脚本,联合起来!

LoRA使用脚本训练Unet和text encoder全过程

使用set_adapters加载LoRAS以进行推断,自定义适配器强度

负载适配器,加载Dreambooth、Textual inversion、LoRA、IP-Adapter:

  • https://huggingface.co/docs/diffusers/using-diffusers/loading_adapters#LoRA

  • https://huggingface.co/docs/diffusers/using-diffusers/merge_loras

说明:

  • Lora可以于其他的手段一起使用,例如和 textual inversion和dreambooth等。
  • Lora在更改模型时候主要改unet,也可以对text encoder进行微调
  • 扩散社区中的LoRA检查点几乎总是通过DreamBooth获得。

你可能感兴趣的:(补档,深度学习,计算机视觉,人工智能,面试,AIGC,SD,stable,diffusion)