目录
全称:Low-Rank Adaptation
1. 微调分类
- 微调主要分为三类:
- 一种是全参数的微调(类别1)。缺点,如果利用一些较好的优化算法,梯度更新和之前所有的梯度(有历史记忆)都有关啥的会导致占用较多的显存。
- 一种是部分参数微调(可能有部分冻结):但是仍然存在需要大量数据调整的问题。
- Lora算法,原始参数不变,增加参数矩阵来弥补原始参数和目标参数的差距。
2. LoRA算法
- LoRA算法
- 算法过程:对于原先的参数不改变,通过右边添加一个参数矩阵来进行微调,也就是利用新的参数矩阵来微调拟合新领域的参数和初始参数的差距。也就是ΔW。
理论:预训练大型语言模型在适应新任务时具有较低的“内在维度” , 所以当对于一个预训练模型来说,原先的参数是有非常多的冗余的,因此我们可以利用低维空间(也就是降维)去表示目标参数和原先参数之间的距离。因此ΔW是相对W来说维度非常小的,减少了非常多的参数量。
- 因为要保证输入和输出的维度和原本的参数W一样,所以一般参数输入的维度还是相同的,但是中间的维度小很多,从而达到减少参数量的结果。比如原本是100x100的参数量,现在变为100x5(r)x2,减少了10倍。
- 其中r就是低秩的那个秩数。可以自定义。
# 表示 LoRA 的一种简单示意代码 (伪代码)
# 定义输入和输出维度,例如是预训练模型的隐藏层大小和层的输出大小
input_dim = 768 # 输入维度,例如预训练模型的隐藏层大小
output_dim = 768 # 输出维度,例如该层的输出大小
# 定义低秩适配的秩(rank)
rank = 8 # 低秩矩阵的秩 r,用于 LoRA 的低秩适配
# 从预训练网络中加载的权重矩阵,形状为 input_dim x output_dim
W = ... # 预训练网络中的权重矩阵
# 定义 LoRA 的 A 和 B 权重矩阵
W_A = nn.Parameter(torch.empty(input_dim, rank)) # LoRA 的权重矩阵 A,形状为 input_dim x rank
W_B = nn.Parameter(torch.empty(rank, output_dim)) # LoRA 的权重矩阵 B,形状为 rank x output_dim
# 初始化 LoRA 的权重矩阵
nn.init.kaiming_uniform_(W_A, a=math.sqrt(5)) # 使用 Kaiming 均匀分布初始化矩阵 A
nn.init.zeros_(W_B) # 将矩阵 B 初始化为零
# 定义常规的矩阵乘法前向传播函数
def regular_forward_matmul(x, W):
"""
常规的矩阵乘法前向传播
参数:
x: 输入张量,形状为 (batch_size, input_dim)
W: 权重矩阵,形状为 (input_dim, output_dim)
返回:
h: 输出张量,形状为 (batch_size, output_dim)
"""
h = x @ W # 常规矩阵乘法
return h
# 定义包含 LoRA 适配的矩阵乘法前向传播函数
def lora_forward_matmul(x, W, W_A, W_B):
"""
包含 LoRA 的矩阵乘法前向传播
参数:
x: 输入张量,形状为 (batch_size, input_dim)
W: 预训练的权重矩阵,形状为 (input_dim, output_dim)
W_A: LoRA 的权重矩阵 A,形状为 (input_dim, rank)
W_B: LoRA 的权重矩阵 B,形状为 (rank, output_dim)
alpha: 缩放因子,用于调节 LoRA 适配权重的影响
返回:
h: 输出张量,形状为 (batch_size, output_dim)
"""
h = x @ W # 常规矩阵乘法
h += x @ (W_A @ W_B) * alpha # 添加经过 LoRA 权重矩阵的适配
return h
在上面的伪代码中,alpha
是一个缩放因子,用于调整组合结果(原始模型输出加上低秩自适应)的大小。这平衡了预训练模型的知识和新的特定于任务的适应——默认情况下,alpha
通常设置为 1。另请注意,虽然W A被初始化为小的随机权重,但WB被初始化为 0,因此训练开始时ΔW = WAxWB = 0 ,这意味着我们以原始权重开始训练。
- 需要注意的一个点:
- 对于某个训练完成之后的模型来说,因为内部有各种非线性操作所以是无法把整个模型的输入和输出整合为一个矩阵的。
- 但是对于一个模型的参数来说,每个参数都会参与线性的操作,比如对于非线性操作后得到的参数作为输入,进入非线性操作的参数作为输出。
- 因此对于一个大的模型来说,我们可以将参数分为一个一个的线性部分,作为参数矩阵,也就是LoRA的左边固定参数部分。
- 最后训练完成后,可以将左右参数进行相加(因为最终矩阵操作大小是一样的,一个是(L,L),一个是(L ,r)×(r,L)也为(L,L)。
参考学习资料:
标签:dim,微调,矩阵,参数,output,input,自学,LoRA From: https://blog.csdn.net/m0_62030579/article/details/144931393