什么是LoRA微调

LoRA是大模型微调方法的一种,它的特点是只在模型的 部分权重(如 QKV 矩阵) 上 添加可训练参数
通过 低秩矩阵(A×B) 来优化参数更新
优点:
极大降低显存消耗(deepseek 7B 只需 10GB)
适用于多任务 LoRA 适配器切换
训练速度快

例如在 Transformer 里,自注意力(Self-Attention)计算:
Y=XW,
其中 X 是input, W是原始模型的权重矩阵(全连接层).
传统的Fine-tuning就是直接对 W 进行梯度更新,导致需要存储整个 W 的更新版本,显存占用极大。

LoRA 关键思想:
不直接更新 W,而是 用两个小矩阵 A A A B B B 近似建模 W 的变化:
W ′ = W + Δ W W' = W + \Delta W W=W+ΔW
Δ W = A B \Delta W = AB ΔW=AB

其中:
A ∈ R d × r A \in \mathbb{R}^{d \times r} ARd×r
B ∈ R r × d B \in \mathbb{R}^{r \times d} BRr×d
r ≪ d r \ll d rd(低秩),一般 r=4, 8, 16,远小于 d。

所以只需要训练A 和 B,大幅减少训练参数量,用 A B AB AB近似 Δ W \Delta W ΔW, 使得最终 W ′ W' W仍然能适应新任务。
训练时,只更新A和B, W保持冻结。
推理时,计算 W + A B W+AB W+AB得到微调后的完整模型, 但A,B远小于W,开销极小。

代码简单演示一下如何在transformer的q_proj里加入LoRA
在 Transformer 里,q_proj 是 nn.Linear 层

import torch
import torch.nn as nn
import mathclass LoRAQProj(nn.Module):def __init__(self, hidden_size, r=16, lora_alpha=16):super().__init__()self.hidden_size = hidden_sizeself.r = rself.lora_alpha = lora_alphaself.scaling = lora_alpha / r  # LoRA 影响力# 原始 Q 投影层(冻结)self.q_proj = nn.Linear(hidden_size, hidden_size, bias=False)# LoRA 适配器:A 和 Bself.lora_A = nn.Linear(hidden_size, r, bias=False)  # 低秩 Aself.lora_B = nn.Linear(r, hidden_size, bias=False)  # 低秩 B# 初始化 LoRA 参数nn.init.kaiming_uniform_(self.lora_A.weight, a=math.sqrt(5))nn.init.zeros_(self.lora_B.weight)  # B 矩阵初始化为 0def forward(self, x):"""计算 Self-Attention 里的 Query 矩阵:Q = X * (W_q + AB)"""base_output = self.q_proj(x)  # 原始投影lora_output = self.lora_B(self.lora_A(x)) * self.scaling  # LoRA 适配器return base_output + lora_output  # 总输出# 测试模型
hidden_size = 512
batch_size = 4
seq_len = 10x = torch.randn(batch_size, seq_len, hidden_size)  # 输入数据
model = LoRAQProj(hidden_size)
output = model(x)print("LoRA Q-Projection Output Shape:", output.shape)  # (4, 10, 512)

训练LoRA适配器

训练时,冻结self.q_proj, 只训练lora_A 和 lora_B

# 训练 LoRA
optimizer = torch.optim.AdamW([p for n, p in model.named_parameters() if "lora" in n], lr=1e-4
)for epoch in range(10):for batch in dataloader:  # 假设 dataloader 提供训练数据optimizer.zero_grad()output = model(batch["input_ids"])loss = loss_function(output, batch["labels"])  # 计算损失loss.backward()optimizer.step()

推理时合并LoRA

LoRA 训练完成后,我们需要合并 A, B 到 q_proj
计算 W q ′ = W q + A B W_{q}' = W_{q} + AB Wq=Wq+AB,
这样,可以移除A,B,只保留 W q ′ W_{q}' Wq, 加速推理

def merge_lora(model):"""合并 LoRA 适配器到原始权重:W_q' = W_q + AB"""with torch.no_grad():model.q_proj.weight += (model.lora_B.weight @ model.lora_A.weight) * model.scaling# 移除 LoRA 适配器del model.lora_Adel model.lora_Breturn model# 进行推理时合并 LoRA
merged_model = merge_lora(model)

不过实际中,不需要我们自己去写这些代码,可以用unsloth, LLaMA-Factory 等框架来实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/70389.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

EasyRTC低延迟通信与智能处理:论嵌入式WebRTC与AI大模型的技术融合

在当今数字化时代,实时通信的需求日益增长,视频通话作为一种高效、直观的沟通方式,广泛应用于各个领域。WebRTC技术的出现,为实现浏览器之间的实时音视频通信提供了便捷的解决方案。而基于WebRTC技术的EasyRTC视频通话SDK&#xf…

10、k8s对外服务之ingress

service和ingress的作用 service的作用 NodePort:会在每个节点开放一个端口,端口号30000-32767。 也是只能用于内网访问,四层转发。实现负载均衡。不能基于域名进行访问。 clusterip:service的默认类型,只能在集群…

Java数据结构---栈

目录 一、栈的概念 二、栈的基本方法 三、栈的模拟实现 四、栈的练习 1、括号匹配 2、出栈入栈次序匹配 一、栈的概念 栈是一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底…

从CNN到Transformer:遥感影像目标检测的未来趋势

文章目录 前言专题一、深度卷积网络知识专题二、PyTorch应用与实践(遥感图像场景分类)专题三、卷积神经网络实践与遥感影像目标检测专题四、卷积神经网络的遥感影像目标检测任务案例【FasterRCNN】专题五、Transformer与遥感影像目标检测专题六、Transfo…

php-fpm

摘要 php-fpm(fastcgi process manager)是PHP 的FastCGI管理器,管理PHP的FastCGI进程,提升PHP应用的性能和稳定性 php-fpm是一个高性能的php FastCGI管理器,提供了更好的php进程管理方式,可以有效的控制内存和进程,支…

Python strip() 方法详解:用途、应用场景及示例解析(中英双语)

Python strip() 方法详解:用途、应用场景及示例解析 在 Python 处理字符串时,经常会遇到字符串前后存在多余的空格或特殊字符的问题。strip() 方法就是 Python 提供的一个强大工具,专门用于去除字符串两端的指定字符。本文将详细介绍 strip(…

open webui 部署 以及解决,首屏加载缓慢,nginx反向代理访问404,WebSocket后端服务器链接失败等问题

项目地址:GitHub - open-webui/open-webui: User-friendly AI Interface (Supports Ollama, OpenAI API, ...) 选择了docker部署 如果 Ollama 在您的计算机上,请使用以下命令 docker run -d -p 3000:8080 --add-hosthost.docker.internal:host-gatewa…

docker安装ros2 并在windows中显示docker内ubuntu系统窗口并且vscode编程

这里包括docker desktop安装ros2 humble hawkshill , 安装xserver(用来在windows中显示ubuntu中窗口), vscode安装插件连接docker并配置python的一系列方法 1.安装xserver 为了能方便的在windows中显示ubuntu内的窗口,比如rqt窗口 参考文章:https://www.cnblogs.com/larva-zhh…

VMware安装Centos 9虚拟机+设置共享文件夹+远程登录

一、安装背景 工作需要安装一台CentOS-Stream-9的机器环境,所以一开始的安装准备工作有: vmware版本:VMware Workstation 16 镜像版本:CentOS-Stream-9-latest-x86_64-dvd1.iso (kernel-5.14.0) …

C/C++ 中 volatile 关键字详解

volatile 关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如:操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊…

处理器架构、单片机、芯片、光刻机之间的关系

这些术语都涉及到半导体和电子设备的设计与制造,但它们的含义和作用有所不同。下面我会逐个解释,并描述它们之间的关系: 1. 处理器架构 (Processor Architecture) 处理器架构指的是处理器(CPU)的设计原理和结构。它定…

python之socket编程

Socket编程是计算机网络编程的基础,它允许两台计算机(或同一个计算机的不同进程)之间进行通信。Python 提供了 socket 模块,可以很方便地进行 Socket 编程。下面是一些基本的 Socket 编程示例,包括 TCP 和 UDP。 TCP …

Docker 的安全配置与优化(二)

Docker 安全优化策略 (一)多阶段构建优化镜像大小 多阶段构建是 Docker 17.05 版本引入的强大功能,它允许在一个 Dockerfile 中定义多个构建阶段,每个阶段都可以使用不同的基础镜像和依赖项,最终只将必要的文件和依赖…

欧洲跨境组网专线:企业出海的高效网络解决方案

在全球化的背景下,越来越多的企业将业务拓展至海外市场,并在欧洲等地设立分支机构。然而,跨境办公中常常面临公网网络延迟高、打开速度慢、丢包严重等问题,这不仅影响办公效率,还增加了IT维护的难度和成本。针对这一痛…

面阵工业相机提高餐饮业生产效率

餐饮行业是一个快节奏、高要求的领域,该领域对生产过程中每一个阶段的效率和准确性都有很高的要求。在食品加工、包装、质量控制和库存管理等不同生产阶段实现生产效率的优化是取得成功的关键步骤。面阵工业相机能够一次性捕捉对象的二维区域图像,并支持…

Renesas RH850 IAR编译时变量分配特定内存

文章目录 1. 核心作用2. 典型使用场景3. 示例代码4. 编译器与链接脚本协作5. 注意事项6. 调试验证在RH850系列微控制器的开发中,#pragma location = "FIRST_RAM" 是一条编译器指令,其核心含义是 将变量或函数分配到名为 FIRST_RAM 的特定内存段。以下是详细解释: …

C++面试题,进程和线程方面(1)

文章目录 前言进程和线程有什么不同进程,线程的通讯方式什么是锁为什么说锁可以使线程安全加锁有什么副作用总结 前言 这是个人总结进程和线程方面的面试题。如果有错,欢迎佬们前来指导!!! 进程和线程有什么不同 进程…

视频mp4垂直拼接 水平拼接

视频mp4垂直拼接 水平拼接 pinjie_v.py import imageio import numpy as np import os import cv2def pinjie_v(dir1,dir2,out_dir):os.makedirs(out_dir, exist_okTrue)# 获取目录下的所有视频文件video_files_1 [f for f in os.listdir(dir1) if f.endswith(.mp4)]video_fi…

Unity摄像机与灯光相关知识

一、Inspector窗口 Inspector窗口可以查看和编辑对象的属性以及设置 其中包含各种组件,例如用Cube对象来举例 1.Sphere(Mesh)组件: 用来决定对象的网格属性,例如球体网格为Sphere、立方体网格为Cube 2.Mesh Renderer组件: 用来设置…

C++(17):为optional类型构造对象

C++(17):optional,多了一个合理的选择_c++17 max-CSDN博客 介绍了optional做为函数返回值的一种方式 其实optional也可以作为对象来使用 #include &