基于Qwen2-VL模型针对LaTeX OCR任务进行微调训练 - LoRA配置如何写
flyfish
基于Qwen2-VL模型针对LaTeX_OCR任务进行微调训练_-_LoRA配置如何写
基于Qwen2-VL模型针对LaTeX_OCR任务进行微调训练_-_单图推理
基于Qwen2-VL模型针对LaTeX_OCR任务进行微调训练_-_原模型_单图推理
基于Qwen2-VL模型针对LaTeX_OCR任务进行微调训练_-_原模型_多图推理
基于Qwen2-VL模型针对LaTeX_OCR任务进行微调训练_-_多图推理
基于Qwen2-VL模型针对LaTeX_OCR任务进行微调训练_-_数据处理
基于Qwen2-VL模型针对LaTeX_OCR任务进行微调训练_-_训练
基于Qwen2-VL模型针对LaTeX_OCR任务进行微调训练_-_训练过程
完整配置在文末
以 Qwen2VLForConditionalGeneration 为例
模型结构如下
Qwen2VLForConditionalGeneration((visual): Qwen2VisionTransformerPretrainedModel((patch_embed): PatchEmbed((proj): Conv3d(3, 1280, kernel_size=(2, 14, 14), stride=(2, 14, 14), bias=False))(rotary_pos_emb): VisionRotaryEmbedding()(blocks): ModuleList((0-31): 32 x Qwen2VLVisionBlock((norm1): LayerNorm((1280,), eps=1e-06, elementwise_affine=True)(norm2): LayerNorm((1280,), eps=1e-06, elementwise_affine=True)(attn): VisionFlashAttention2((qkv): Linear(in_features=1280, out_features=3840, bias=True)(proj): Linear(in_features=1280, out_features=1280, bias=True))(mlp): VisionMlp((fc1): Linear(in_features=1280, out_features=5120, bias=True)(act): QuickGELUActivation()(fc2): Linear(in_features=5120, out_features=1280, bias=True))))(merger): PatchMerger((ln_q): LayerNorm((1280,), eps=1e-06, elementwise_affine=True)(mlp): Sequential((0): Linear(in_features=5120, out_features=5120, bias=True)(1): GELU(approximate='none')(2): Linear(in_features=5120, out_features=3584, bias=True))))(model): Qwen2VLModel((embed_tokens): Embedding(152064, 3584)(layers): ModuleList((0-27): 28 x Qwen2VLDecoderLayer((self_attn): Qwen2VLFlashAttention2((q_proj): Linear(in_features=3584, out_features=3584, bias=True)(k_proj): Linear(in_features=3584, out_features=512, bias=True)(v_proj): Linear(in_features=3584, out_features=512, bias=True)(o_proj): Linear(in_features=3584, out_features=3584, bias=False)(rotary_emb): Qwen2VLRotaryEmbedding())(mlp): Qwen2MLP((gate_proj): Linear(in_features=3584, out_features=18944, bias=False)(up_proj): Linear(in_features=3584, out_features=18944, bias=False)(down_proj): Linear(in_features=18944, out_features=3584, bias=False)(act_fn): SiLU())(input_layernorm): Qwen2RMSNorm((3584,), eps=1e-06)(post_attention_layernorm): Qwen2RMSNorm((3584,), eps=1e-06)))(norm): Qwen2RMSNorm((3584,), eps=1e-06)(rotary_emb): Qwen2VLRotaryEmbedding())(lm_head): Linear(in_features=3584, out_features=152064, bias=False)
)
LoraConfig(PeftConfig)
@dataclass
class LoraConfig(PeftConfig):
[LoraModel] 的配置类,用于存储LoRA(低秩适应)模型的配置参数。以下是各个参数的解释:
-
r(int):
LoRA 注意力维度(即“秩”),它决定了用来近似原始权重矩阵的两个小矩阵的大小。 -
target_modules(Optional[Union[List[str], str]]):
要应用适配器的模块名称列表或字符串。如果指定了这个参数,只有这些名称匹配的模块会被替换。传递字符串时,将进行正则表达式匹配;传递字符串列表时,将进行精确匹配或检查模块名称是否以列表中的任意字符串结尾。如果指定为 ‘all-linear’,那么除了输出层之外的所有线性/Conv1D模块都将被选择。如果不指定,则根据模型架构选择模块;如果架构未知,将抛出错误,在这种情况下需要手动指定目标模块。 -
exclude_modules(Optional[Union[List[str], str]]):
不要应用适配器的模块名称列表或字符串。传递字符串时,将进行正则表达式匹配;传递字符串列表时,将进行精确匹配或检查模块名称是否以列表中的任意字符串结尾。 -
lora_alpha(int):
LoRA 缩放因子的 alpha 参数。 -
lora_dropout(float):
LoRA 层上的 dropout 概率。 -
fan_in_fan_out(bool):
如果要替换的层以 (fan_in, fan_out) 方式存储权重,则设置此参数为 True。例如,gpt-2 使用Conv1D,其权重是以 (fan_in, fan_out) 形式存储的,因此应将此参数设为True。 -
bias(str):
LoRA 的偏置类型,可以是 ‘none’, ‘all’ 或 ‘lora_only’。如果设置为 ‘all’ 或 ‘lora_only’,在训练期间相应的偏置将被更新。请注意,这意味着即使禁用适配器,模型的输出也不会与未经过适配的基础模型完全相同。 -
use_rslora(bool):
当设置为 True 时,使用 Rank-Stabilized LoRA,这会将适配器缩放因子设置为lora_alpha/math.sqrt(r),因为已证明这种方法效果更好。否则,它将使用默认值lora_alpha/r。 -
modules_to_save(List[str]):
除了适配器层外,还需要设置为可训练并在最终检查点中保存的模块列表。 -
init_lora_weights(bool|Literal["gaussian", "eva", "olora", "pissa", "pissa_niter_[迭代次数]", "loftq"]):
如何初始化适配器层的权重。传递 True(默认)会导致使用来自 Microsoft 参考实现的默认初始化。传递 ‘gaussian’ 会导致基于 LoRA 秩缩放的高斯初始化。设置初始化为 False 会导致完全随机初始化,并不推荐。传递'loftq'以使用 LoftQ 初始化。传递'eva'将根据 SVD 的层输入激活执行数据驱动初始化 Explained Variance Adaptation (EVA)。传递'olora'使用 OLoRA 初始化。传递'pissa'使用 Principal Singular values and Singular vectors Adaptation (PiSSA) 初始化。传递'pissa_niter_[迭代次数]'以使用 Fast-SVD-based PiSSA 初始化,其中[迭代次数]表示执行 FSVD 的子空间迭代次数,必须是非负整数。 -
layers_to_transform(Union[List[int], int]):
要转换的层索引。如果传递了整数列表,它将在指定的层索引上应用适配器。如果传递了一个整数,它将在该索引层上应用变换。 -
layers_pattern(Optional[Union[List[str], str]]):
仅当layers_to_transform不为 None 时使用。它应该指向模型的nn.ModuleList,通常被称为'layers'或'h'。 -
rank_pattern(dict):
层名称或正则表达式到不同默认秩r的映射。 -
alpha_pattern(dict):
层名称或正则表达式到不同默认 alphalora_alpha的映射。 -
megatron_config(Optional[dict]):
Megatron 的 TransformerConfig 参数。当希望对 Megatron 的 ColumnParallelLinear 和 RowParallelLinear 层应用 LoRA 时,需要指定此参数。 -
megatron_core(Optional[str]):
使用的 Megatron 核心模块,默认为"megatron.core"。 -
loftq_config(Optional[LoftQConfig]):
LoftQ 的配置。如果非空,则使用 LoftQ 来量化主干权重并初始化 LoRA 层。同时需传递init_lora_weights='loftq'。注意在这种情况下不应传递量化后的模型,因为 LoftQ 会自行量化模型。 -
eva_config(Optional[EvaConfig]):
EVA 的配置。至少需要设置数据集参数(使用与微调相同的数据集)。 -
use_dora(bool):
启用 ‘Weight-Decomposed Low-Rank Adaptation’ (DoRA),这项技术将权重更新分解为两个部分:幅度和方向。方向由标准 LoRA 处理,而幅度由一个单独的学习参数处理。这可以在低秩时提高 LoRA 的性能。目前 DoRA 仅支持线性和 Conv2D 层。DoRA 引入了比纯 LoRA 更大的开销,因此建议合并权重用于推理。 -
layer_replication(List[Tuple[int, int]]):
通过根据指定范围堆叠原始模型层来构建新的层栈。这允许扩展(或缩小)模型而不复制基础模型权重。新层都将附加独立的 LoRA 适配器。 -
runtime_config(LoraRuntimeConfig):
运行时配置(不会被保存或恢复)。 -
lora_bias(bool):
默认为False。是否启用 LoRA B 参数的偏置项。通常应该禁用。主要用例是当 LoRA 权重是从完全微调的参数中提取出来的,以便考虑这些参数的偏置。
PeftConfig(PeftConfigMixin)
from dataclasses import dataclass, field
from typing import Optional, Union@dataclass
class PeftConfig(PeftConfigMixin):"""这是用于存储 [`PeftModel`] 配置的基础配置类。Args:peft_type (Union[[`~peft.utils.config.PeftType`], `str`]):要使用的Peft方法类型。这决定了将采用哪种参数高效微调技术。task_type (Union[[`~peft.utils.config.TaskType`], `str`]):执行的任务类型。例如:SEQ_CLS(序列分类)、TOKEN_CLS(标记分类)等。inference_mode (`bool`, defaults to `False`):是否在推理模式下使用Peft模型。如果设置为True,则表示模型将在推理而不是训练模式下运行。"""base_model_name_or_path: Optional[str] = field(default=None,metadata={"help": "要使用的基础模型名称或路径。这可以是一个预训练模型的标识符,或者指向本地文件系统的路径。"})revision: Optional[str] = field(default=None,metadata={"help": "要使用的基础模型的具体版本。这对于确保复现结果或使用特定的模型快照非常有用。"})peft_type: Optional[Union[str, 'PeftType']] = field(default=None,metadata={"help": "指定Peft方法的类型。例如,LoRA、P-Tuning等。这个字段告诉框架应该应用哪种类型的参数高效微调技术。"})task_type: Optional[Union[str, 'TaskType']] = field(default=None,metadata={"help": "任务类型,定义了模型将执行的任务类别。不同的任务可能需要不同的输出层和损失函数。"})inference_mode: bool = field(default=False,metadata={"help": "是否启用推理模式。如果设为True,则模型不会更新权重,并且会跳过所有不必要的计算以提高推理速度。"})
配置怎么写
根据模型结构
(layers): ModuleList((0-27): 28 x Qwen2VLDecoderLayer((self_attn): Qwen2VLFlashAttention2((q_proj): Linear(in_features=3584, out_features=3584, bias=True)(k_proj): Linear(in_features=3584, out_features=512, bias=True)(v_proj): Linear(in_features=3584, out_features=512, bias=True)(o_proj): Linear(in_features=3584, out_features=3584, bias=False)(rotary_emb): Qwen2VLRotaryEmbedding())(mlp): Qwen2MLP((gate_proj): Linear(in_features=3584, out_features=18944, bias=False)(up_proj): Linear(in_features=3584, out_features=18944, bias=False)(down_proj): Linear(in_features=18944, out_features=3584, bias=False)(act_fn): SiLU())
应用适配器的模块名称列表
看self_attn和mlp
"q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj"
创建一个准备用于微调的模型,其中只有一小部分参数(即LoRA添加的部分)会在训练过程中更新,从而实现了高效的参数微调。
所以代码可以如下编写
from peft import LoraConfig, get_peft_model, TaskType# 创建LoRA配置实例
config = LoraConfig(task_type=TaskType.CAUSAL_LM, # 指定任务类型为因果语言模型(Causal Language Model)target_modules=["q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj"], # 要应用LoRA的模块列表inference_mode=False, # 设置为False表示模型将在训练模式下运行,而不是推理模式r=64, # LoRA秩(低维矩阵的大小),决定了额外参数的数量lora_alpha=16, # LoRA缩放因子,用于调整LoRA更新的影响程度lora_dropout=0.05, # 应用在LoRA层上的dropout概率,用于防止过拟合bias="none" # 不微调偏置项
)# 获取并初始化带有LoRA配置的PEFT模型
train_peft_model = get_peft_model(origin_model, config)
解释
-
导入必要的库和模块:
LoraConfig和get_peft_model来自peft库,用于创建LoRA配置和获取带有LoRA适配器的模型。TaskType用于指定任务类型。
-
创建LoRA配置实例 (
config)task_type=TaskType.CAUSAL_LM: 设置任务类型为因果语言模型(例如GPT架构)。这指定了模型将执行的任务类型,影响到如何处理输入和输出。target_modules=[...]: 列表中包含了要应用LoRA的模块名称。这些通常是模型中的查询、键、值投影层以及输出层等关键组件。inference_mode=False: 表示模型将在训练模式下运行,允许权重更新。如果设置为True,则模型将在推理模式下运行,不更新权重。r=64: 设置LoRA秩为64。这个参数定义了用于近似原始权重矩阵的小矩阵的大小,它直接影响到额外参数的数量和计算成本。lora_alpha=16: 设置LoRA缩放因子为16。这个因子用来调整LoRA更新对模型的影响程度,通常与r成比例。lora_dropout=0.05: 设置LoRA层的dropout概率为0.05。这有助于防止过拟合并提高泛化能力。bias="none": 指定不对偏置项进行微调。其他选项有'all'或'lora_only',取决于是否需要更新所有或仅LoRA相关的偏置。
-
获取并初始化带有LoRA配置的PEFT模型 (
train_peft_model)get_peft_model(origin_model, config): 这个函数接收一个原始预训练模型(origin_model)和LoRA配置(config),然后返回一个新的模型实例,该实例已经在指定的目标模块上应用了LoRA适配器,并准备好进行微调。