LLM参数高效微调(LORA,QLORA)

本文介绍了全量微调与高效微调的区别,重点讲解了参数高效微调的方法,如LoRA和QLoRA。LoRA通过低秩适应在不改变预训练模型权重的情况下,增加额外的低秩网络层进行微调。QLoRA则在4比特量化的预训练模型上应用LoRA,显著减少内存使用,适用于大型语言模型的微调。量化技术在模型压缩和性能保持方面也发挥了重要作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 全量微调和高效微调

全量微调(Full Fine-tuning)

全量微调是深度学习中的一种常见做法,尤其是在处理大型预训练模型如BERT或GPT时。它涉及到在特定任务的数据集上调整预训练模型的所有参数。这意味着模型的每一层和每一个权重都会在微调过程中更新,以适应新的任务。虽然这种方法通常可以达到很好的性能,因为它允许模型在目标任务上进行充分优化,但它也有几个缺点。最主要的是,它需要大量的计算资源和时间,尤其是当模型非常大时。此外,它也更容易过拟合,尤其是在小数据集上。

高效微调(Efficient Fine-tuning)

与全量微调相对,高效微调是近年来发展起来的,旨在减少在特定任务上调整大型预训练模型所需的资源和时间。它通常涉及到只更新模型的一小部分参数,比如模型的最后几层或者只有顶层。一些高效微调的方法包括适应性微调(Adaptive
Fine-tuning),其中只有模型的输出层或与任务最相关的层被更新;或是梯度更新的变体,如差分学习率(Differential
Learning Rates)和冻结部分网络层(Freezing Layers)。

高效微调的优点是它大大减少了所需的计算资源,因此可以更快速地适应新任务。它还可以减轻过拟合的风险,因为保留了更多的原始预训练知识。不过,这种方法也可能限制模型在新任务上的最大表现潜力,因为它只调整了参数的一部分。

2.参数高效微调分类

增加额外参数 (A)

这类方法通过向模型中添加额外的可训练参数来适应新任务,而不改变原始预训练模型的参数。这种方法主要有两个小类:

  1. 类适配器(Adapter-like)方法

    • 在模型的每一层或特定层中插入小型网络结构,称为适配器(Adapters),它们拥有少量的可训练参数。
    • 适配器可以学习到特定任务的特征表示,同时保留了预训练模型的大部分知识。
    • 这种方法适用于要快速适应多个不同任务的场景,因为适配器可以独立训练且交换。
  2. 软提示(Soft prompts)

    • 软提示是向模型输入添加可训练的标记(tokens
### 如何使用 QLoRA 对 LLaMA3 模型进行微调 #### 准备环境与依赖库安装 为了能够顺利运行QLoRA微调过程,需先准备合适的Python环境并安装必要的依赖包。这通常涉及PyTorch以及Transformers库的最新版本。 ```bash pip install torch transformers accelerate bitsandbytes ``` #### 加载基础模型分词器 通过指定的基础模型路径来加载预训练好的LLaMA3模型及其对应的分词器[^2]: ```python from transformers import AutoModelForCausalLM, AutoTokenizer base_model_path = "llm/Meta-Llama-3.1-8B-Instruct/" tokenizer = AutoTokenizer.from_pretrained(base_model_path) model = AutoModelForCausalLM.from_pretrained(base_model_path) ``` #### 初始化 QLoRA 配置 QLoRA是一种基于LoRA的方法,在保持原有大模型性能的同时减少额外参数量。这里会创建一个适应于当前任务的新模型配置,并应用到原始的大规模语言模型上[^1]。 ```python import peft # 假设peft已正确安装 lora_config = peft.LoRAConfig( r=8, # 秩数(rank),一般取较小值即可 lora_alpha=32, target_modules=["q_proj", "v_proj"], # 被替换模块列表 ) qlora_model = peft.get_peft_model(model, lora_config) ``` #### 数据集准备 准备好用于微调的数据集非常重要。数据应当被处理成适合输入给定模型的形式,比如转换为token IDs序列等。 ```python def prepare_dataset(file_path): data = [] with open(file_path, 'r', encoding='utf-8') as f: for line in f.readlines(): text = json.loads(line)['text'] tokens = tokenizer(text, truncation=True, padding="max_length", max_length=512).input_ids data.append(tokens) return data train_data = prepare_dataset('path_to_train_file.json') eval_data = prepare_dataset('path_to_eval_file.json') ``` #### 训练设置 定义优化器、学习率调度策略以及其他超参设定;同时也要考虑是否启用混合精度加速等功能以提高效率。 ```python optimizer = torch.optim.AdamW(qlora_model.parameters(), lr=5e-5) scheduler = get_linear_schedule_with_warmup(optimizer, num_warmup_steps=0, num_training_steps=len(train_data)) # 如果GPU可用,则移动模型至CUDA设备 device = "cuda" if torch.cuda.is_available() else "cpu" qlora_model.to(device) ``` #### 开始微调流程 利用之前准备的一切资源正式开启微调阶段的工作。期间可根据实际情况调整batch size大小、epoch数量等因素。 ```python for epoch in range(num_epochs): qlora_model.train() total_loss = 0. for batch_idx, input_ids in enumerate(batched_loader(train_data)): optimizer.zero_grad() outputs = qlora_model(input_ids=input_ids.to(device)) loss = compute_loss(outputs.logits, labels=input_ids.to(device)) # 自定义损失函数 loss.backward() optimizer.step() scheduler.step() total_loss += loss.item() avg_epoch_loss = total_loss / (batch_idx + 1) print(f'Epoch {epoch}, Loss: {avg_epoch_loss}') ``` #### 保存微调后的模型 完成所有迭代之后,记得将最终得到的最佳状态下的模型权重妥善保存下来以便后续部署或进一步改进。 ```python output_dir = "./fine_tuned_llama_3_qloara/" if not os.path.exists(output_dir): os.makedirs(output_dir) qlora_model.save_pretrained(output_dir) tokenizer.save_pretrained(output_dir) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

灵海之森

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值