大模型微调 - 用PEFT来配置和应用 LoRA 微调
flyfish
PEFT
(Parameter-Efficient Fine-Tuning)是一种参数高效微调库,旨在减少微调大型预训练模型时需要更新的参数量,而不影响最终模型的性能。它支持几种不同的微调方法,如 LoRA(Low-Rank Adaptation)、Prefix Tuning、Adapter 等。这里PEFT
被用来配置和应用 LoRA 微调。LoRA 是一种降低预训练模型微调时参数更新数量的方法,通过在 Transformer 层的某些投影矩阵上引入低秩分解,减少参数量,并且只需微调这些低秩矩阵。
from peft import LoraConfig, TaskType, get_peft_model
# 定义 LoRA 的配置参数
config = LoraConfig(
task_type=TaskType.CAUSAL_LM, # 指定任务类型为自回归语言建模任务(Causal Language Modeling),如 GPT 系列的模型
target_modules=["q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj"], # 这些是模型中要应用 LoRA 的目标模块
inference_mode=False, # 表示训练模式,设置为 True 时是推理模式;为 False 是训练模式
r=8, # LoRA 的秩 r,代表分解时矩阵的秩,越大越能保留原有的模型信息,但计算复杂度也会增加
lora_alpha=32, # LoRA 的 alpha 超参数,控制了低秩矩阵的缩放因子。一般设置为与 r 成比例的值
lora_dropout=0.1, # 在 LoRA 模块中应用 Dropout,防止过拟合,防止微调时模型过拟合到训练数据
)
# 应用 PEFT(LoRA)到预训练的模型上
model = get_peft_model(model, config) # 使用 get_peft_model 函数,将定义好的 LoRA 配置应用到预训练模型中
解释
task_type=TaskType.CAUSAL_LM
: 指定任务类型为自回归语言模型,常见于 GPT 系列的生成任务。PEFT 支持不同的任务类型,如问答(Question Answering)、序列到序列任务(Seq2Seq LM)等。
target_modules
: 这是模型中应用 LoRA 的模块列表。对于 Transformer 模型,这些模块通常是负责自注意力计算的部分,如 q_proj
(query projection)、k_proj
(key projection)、v_proj
(value projection)、o_proj
(输出投影)等。
inference_mode=False
: 该参数指定模型是否处于推理模式。如果设为 True
,表示模型在推理时使用冻结的 LoRA 权重;如果为 False
,表示模型处于训练模式,可以继续微调 LoRA 层。
r=8
: LoRA 中的秩 r
,用于控制低秩矩阵的大小,值越大,表示模型的表达能力越强,但参数量也相应增加。
lora_alpha=32
: LoRA 中的缩放因子,控制了低秩矩阵的影响力。它常用于放大或缩小 LoRA 矩阵的输出,以确保它们在与原始模型输出进行组合时适当的权重。
lora_dropout=0.1
: 在 LoRA 层应用 Dropout,减少过拟合风险。通过设置 Dropout 概率,使得在训练时随机屏蔽部分神经元,有助于增强模型的泛化能力。
target_modules=["q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj"]
在 Transformer 模型中,这些 q_proj
、k_proj
、v_proj
、o_proj
等名称表示的是不同的投影矩阵,它们主要与模型的 自注意力机制(Self-Attention Mechanism) 相关。它们用于将输入向量变换为适合进行自注意力计算的表示。
-
q_proj
(Query Projection)
作用 : 将输入的 token 表示投影到 查询向量(Query Vector) 。在自注意力机制中,模型使用这个向量来与其他 token 的键向量(Key)进行相似性计算,从而决定每个 token 应该关注哪些其他 token。
解释 : 查询向量通常用于表示当前 token 的"问题",模型会通过查询向量去"询问"其他 token。 -
k_proj
(Key Projection)
作用 : 将输入的 token 表示投影到 键向量(Key Vector) 。键向量用于与查询向量进行相似性计算,衡量两个 token 之间的相关性。
解释 : 键向量可以被视为表示每个 token 特性的"标签",通过与查询向量的相似性计算,模型判断哪些 token 对当前查询最重要。 -
v_proj
(Value Projection)
作用 : 将输入的 token 表示投影到 值向量(Value Vector) 。值向量是自注意力机制的输出内容,它们会根据键与查询的相似度进行加权平均,作为最终的注意力输出。
解释 : 值向量可以看作是包含 token 具体信息的向量,模型在计算注意力时,最终会根据键-查询的匹配度来加权这些值向量。 -
o_proj
(Output Projection)
作用 : 将注意力机制的输出(即加权后的值向量)进一步变换成模型需要的输出形式。自注意力机制的最终结果通过o_proj
投影,返回给模型的下一层或其他模块。
解释 : 输出投影负责整合注意力层的输出,并确保其形状和表示适应接下来模型中的其他操作。 -
gate_proj
(Gate Projection)
作用 : 这个投影矩阵通常出现在模型中带有 门控机制(gating mechanism) 的模块中,类似于 LSTM 或 GRU 中的门控单元。它用于调节信息的流入或流出,决定哪些信息需要保留或丢弃。
解释 : 在一些模型中,特别是经过改进的 Transformer 结构里,可能加入了门控机制,用于更灵活地控制信息的流动。gate_proj
负责这个过程。 -
up_proj
和down_proj
作用 : 这些通常是在模型中进行 上采样(up-sampling) 和 下采样(down-sampling) 的操作,用来调整表示的维度。这些投影矩阵负责在不同的层或模块之间转换表示的维度,类似于提升或降低特征维度的操作。
up_proj
: 增大向量的维度(上采样)。
down_proj
: 减少向量的维度(下采样)。
补充
在理解 LoRA(Low-Rank Adaptation)时,涉及到的一些关键概念,如矩阵的秩、投影矩阵、低秩分解和低秩矩阵,都是线性代数中的核心概念。
-
矩阵的秩(Rank of a Matrix)
定义 : 矩阵的秩表示矩阵中独立行或独立列的最大数量,简单来说,它是矩阵的行或列向量的线性独立的数目。秩表示一个矩阵可以表示的维度或自由度。
解释 : 矩阵的秩越大,意味着它包含的信息越多。如果一个矩阵的秩等于其行数或列数,它是“满秩”的,意味着这个矩阵不能通过更小的维度来表示。反之,秩较低的矩阵可以通过更小的维度来表示,称为低秩矩阵 。
例如,一个 3×3 的矩阵如果秩为 3,它是满秩矩阵;如果秩为 2 或更小,它是低秩矩阵,意味着该矩阵存在冗余信息,可以被压缩。 -
投影矩阵(Projection Matrix)
定义 : 投影矩阵是将一个向量投影到某个子空间的矩阵。它可以用来把高维度的数据投影到一个较低维度的子空间上。
解释 : 例如在机器学习和自然语言处理中,投影矩阵常用于将输入的向量表示从一个空间(如词向量的维度)转换到另一个空间。投影矩阵可以应用于自注意力机制中的 query(查询)、key(键)和 value(值)等向量,将它们映射到一个新的向量空间。
在 Transformer 模型中,q_proj
,k_proj
,v_proj
这些都是投影矩阵,负责将输入序列的 token 表示转换到适合自注意力计算的空间中。 -
低秩分解(Low-Rank Decomposition)
定义 : 低秩分解是一种将一个高维矩阵分解为几个低维矩阵的技术,通常使用一些线性代数方法(如奇异值分解 SVD)。通过这种分解,可以将一个复杂的矩阵表示成若干个较小的矩阵的乘积,从而降低计算复杂度。
解释 : 低秩分解通过降低矩阵的维度,减少存储和计算需求。在机器学习中,低秩分解常用于减少模型的参数量,提高效率。例如,在 LoRA 中,低秩分解用于将原始的高维投影矩阵分解为两个低秩矩阵(分别是A
和B
),这些矩阵的秩比原始矩阵小,因此可以大大减少参数的数量。
数学上,假设我们有一个大矩阵W
,可以通过两个小矩阵A
和B
的乘积来近似表示:
W ≈ A × B W \approx A \times B W≈A×B
这里A
和B
的秩r
要比W
的秩小,因此称为低秩分解。 -
低秩矩阵(Low-Rank Matrix)
定义 : 低秩矩阵是指秩小于其行数和列数的矩阵,也就是说,它可以通过更小的维度来表示,不是“满秩”的。低秩矩阵可以看作是含有冗余信息的矩阵。
解释 : 在机器学习中,低秩矩阵被用于减少模型的复杂度,因为它们可以用更少的参数来表示一个矩阵。因此,低秩矩阵在需要减少计算成本或内存需求的场景下非常有用。
例如,在 LoRA 中,原始模型中的权重矩阵(如W
)通常是高秩矩阵,但我们可以通过低秩矩阵A
和B
来近似表示这个权重矩阵,从而在保持模型性能的同时减少需要训练的参数量。