Lora原理及实现浅析

news2025/5/16 3:16:42

Lora

什么是Lora

Lora的原始论文为《LoRA: Low-Rank Adaptation of Large Language Models》,翻译为中文为“大语言模型的低秩自适应”。最初是为了解决大型语言模在进行任务特定微调时消耗大量资源的问题;随后也用在了Diffusion等领域,用于对模型进行微调。总而言之,Lora是一种微调技术。

Lora是怎么实现的

原理

Lora的思想很简单,在原有权重的旁边加一个的分支。训练时冻结原有权重,只训练这个分支。然后将分支输出的结果与原有权重的输出结果相加即可。这么做的理论依据是:预训练模型拥有极小的内在维度(instrisic dimension),即存在一个极低维度的参数,微调它和在全参数空间中微调能起到相同的效果

Lora简要示意图

伪代码实现

假设我们有一个简单的模型,仅包含一个线性层:

import torch
import torch.nn as nn

# 原始 SimpleModel 定义
class SimpleModel(nn.Module):
    def __init__(self):
        super().__init__()
        self.linear = nn.Linear(100, 50)  # 原始权重形状: (50, 100)

    def forward(self, x):
        return self.linear(x)

那么我们用最原始的手段添加Lora:

import torch
import torch.nn as nn

class SimpleModelWithLoRA(nn.Module):
    def __init__(self, rank=4):
        super().__init__()
        # 原始预训练层(冻结)
        self.linear = nn.Linear(100, 50)
        
        # 冻结原始参数
        for param in self.linear.parameters():
            param.requires_grad = False
        
        # LoRA 参数
        self.lora_A = nn.Parameter(torch.randn(50, rank))   # (out_dim, rank)
        self.lora_B = nn.Parameter(torch.randn(rank, 100))  # (rank, in_dim)

    def forward(self, x):
        # 原始输出
        original_output = self.linear(x)
        
        # LoRA 分支输出
        lora_output = x @ self.lora_B.t() @ self.lora_A.t()  # [batch, 100] -> [batch, 50]
        
        # 输出为两者的和
        return original_output + lora_output

可以看到,Lora的代码跟原始代码的主要区别仅在于:

在权重层面:

  1. 冻结原始参数
  2. 添加了两个线性层,分别用于将输出映射到rank维的中间结果,和将中间结果映射到输出

在推理层面:

  1. 计算Lora的输出结果
  2. 将两个计算结果相加

这就是Lora的实际计算过程了,就是在原有模型旁边加了个轻量化的分支而已。此外,由于矩阵运算的性质,我们还可以直接把训练好的权重加到原始权重上以提高计算效率:

import torch
import torch.nn as nn

# 应用了 LoRA 的 SimpleModel 定义
class SimpleModelWithLoRA(nn.Module):
    def __init__(self, rank=4):
        super().__init__()
        # 初始化原始线性层
        self.linear = nn.Linear(100, 50)  # 原始权重形状: (50, 100)
        
        # 冻结原始线性层的参数
        for param in self.linear.parameters():
            param.requires_grad = False
        
        # 添加 LoRA 矩阵 A 和 B
        self.A = nn.Parameter(torch.randn(50, rank))  # 形状: (50, rank)
        self.B = nn.Parameter(torch.randn(rank, 100)) # 形状: (rank, 100)

    def forward(self, x):
        # 计算 LoRA 修正项
        lora_term = self.A @ self.B  # 形状: (50, 100)
        
        # 将 LoRA 修正项加到原始权重上
        adapted_weight = self.linear.weight.data + lora_term
        
        # 使用适应后的权重进行计算
        output = nn.functional.linear(x, adapted_weight, self.linear.bias)
        return output

值得注意的是,是否将Lora权重与原始权重融合取决于是否需要更新lora权重。因为融合后的权重虽然能够提高计算效率,但是无法单独更新Lora了。

其他细节说明

其他微调方法

除了Lora,还有其他微调手段,下面简单列出,不再做进一步说明:

方法描述参数规模灵活性应用场景
全量微调(Full Fine-tuning)修改全部参数所有任务
Adapter Tuning在层之间插入小型神经网络模块模型嵌套结构支持时
Prefix Tuning / Prompt Tuning修改输入提示向量极小NLP
LoRA引入低秩矩阵进行参数增量更新广泛适用

rank选择与初始化

rank 越大:模型表达能力越强,但消耗资源越多。

rank 越小:更轻量,但可能无法捕捉复杂的任务特征。

通常尝试 r=8, r=16, r=64 等值,根据验证集效果选择最优配置。

在原始的 LoRA 论文中A和两个矩阵通常是随机初始化。但为了确保刚开始微调的时候不对模型输出产生影响,一些方法会其中一个矩阵初始化为零。

Q&A

Q: LoRA 是否会影响模型推理速度?

A: 不会显著影响,融合权重后模型层面没有增加任何多余的计算量

Q: LoRA 是否只能用于语言模型?

A: 不是,也可以用于图像模型(如 Diffusion)、语音模型等。

Q: 我可以用多个 LoRA 吗?

A: 可以,有些框架支持加载多个 LoRA,并按需组合使用。

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

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

相关文章

【设计模式】- 创建者模式

单例模型 饿汉式 静态方法创建对象 public class Singleton {// 私有构造方法private Singleton(){}private static Singleton instance new Singleton();// 提供一个外界获取的方法public static Singleton getInstance(){return instance;} }静态代码块创建对象 public …

南审计院考研分享会 经验总结

汪学长 – 中科大 计科专硕 初试准备 数学先做真题,模拟题刷的越多分越高;408真题最重要,模拟题辅助;英语只做真题;政治9月份开始背 代码能力在低年级培养的重要性和路径 考研不选择机构原因 因为机构里面学习的框…

牛客练习赛138(首篇万字题解???)

赛时成绩如下: 1. 小s的签到题 小s拿到了一个比赛榜单,他要用最快的速度找到签到题,但是小s脑子还是有点晕,请你帮帮小s,助力他找到签到题。 比赛榜单是一个 2 行 n 列的表格: 第一行是 n 个大写字母&#…

用git下载vcpkg时出现Connection was reset时的处理

用git安装vcpkg时出现Connect was rest(如上图)。多谢这位网友的博文解决了问题: 通过:http.sslVerify false全局来设置,执行以下命令: git config --global http.sslVerify "false" 原文链接&#xff1a…

leetcode - 滑动窗口问题集

目录 前言 题1 长度最小的子数组: 思考: 参考代码1: 参考代码2: 题2 无重复字符的最长子串: 思考: 参考代码1: 参考代码2: 题3 最大连续1的个数 III: 思考&am…

一分钟在Cherry Studio和VSCode集成火山引擎veimagex-mcp

MCP的出现打通了AI模型和外部数据库、网页API等资源,成倍提升工作效率。近期火山引擎团队推出了 MCP Server SDK: veimagex-mcp。本文介绍如何在Cherry Studio 和VSCode平台集成 veimagex-mcp。 什么是MCP MCP(Model Context Protocol&…

Tomcat与纯 Java Socket 实现远程通信的区别

Servlet 容器​​(如 Tomcat) 是一个管理 Servlet 生命周期的运行环境,主要功能包括: ​​协议解析​​:自动处理 HTTP 请求/响应的底层协议(如报文头解析、状态码生成); ​​线程…

为什么企业建站或独立站选用WordPress

与大多数组织相比,企业业务更需要保持可扩展和可靠的网络存在,以保持竞争力。为此,许多大型企业的 IT 领导者历来寻求昂贵的网络解决方案,这些方案需要签订专有支持合同来保证质量。不过,还有另一种方法。WordPress问世…

镜头内常见的马达类型(私人笔记)

① 螺杆式马达 驱动来源:机身内马达。镜头尾部有一个接收“螺杆”的接口,通过机械传动带动镜头对焦组。缺点:慢、吵、不能用于无机身马达的相机。✅ 典型镜头:尼康 AF、AF-D 系列;美能达老镜头。尼康传统的AF镜头通过…

从代码学习深度学习 - 语义分割和数据集 PyTorch版

文章目录 前言什么是语义分割?图像分割和实例分割Pascal VOC2012 语义分割数据集Pascal VOC2012 语义分割数据集介绍基本信息语义分割部分特点数据格式评价指标应用价值数据集获取使用提示辅助工具代码 (`utils_for_huitu.py`)读取数据预处理数据自定义语义分割数据集类读取数…

4G物联网模块实现废气处理全流程数据可视化监控配置

一、项目背景 随着工业化进程的加速,工业废气的排放对环境造成了严重影响,废气处理厂应运而生。然而,废气处理厂中的设备众多且分散,传统的人工巡检和数据记录方式效率低下,难以及时发现问题。为了实现对废气处理设备…

电商平台如何做好DDoS 攻防战?

一、新型 DDoS 攻击技术演进分析 1.1 电商平台面临的四类攻击范式 graph LR A[DDoS攻击] --> B{网络层} A --> C{应用层} B --> D[CLDAP反射攻击<br>峰值达3.5Tbps] B --> E[QUIC协议洪水攻击] C --> F[API CC攻击<br>精准打击抢购接口] C -->…

【计算机视觉】OpenCV实战项目:Athlete-Pose-Detection 运动员姿态检测系统:基于OpenCV的实时运动分析技术

运动员姿态检测系统&#xff1a;基于OpenCV的实时运动分析技术 1. 项目概述1.1 技术背景1.2 项目特点 2. 技术架构与算法原理2.1 系统架构2.2 核心算法2.3 模型选择 3. 项目部署与运行指南3.1 环境准备硬件要求软件依赖 3.2 项目配置3.3 运行项目基本运行模式高级参数 4. 常见问…

为什么要选择七彩喜数字康养平台?加盟后有何优势?

一&#xff0e;七彩喜数字康养平台 1.技术领先性 七彩喜依托“端-网-云-脑”四层技术架构&#xff0c;整合毫米波雷达、AI算法引擎、区块链等前沿技术&#xff0c;解决传统养老的隐私泄露、设备孤岛等痛点。 比如非接触式健康监测系统通过毫米波雷达实现跌倒检测准确率&#…

【计算机视觉】OpenCV实战项目:基于OpenCV的车牌识别系统深度解析

基于OpenCV的车牌识别系统深度解析 1. 项目概述2. 技术原理与算法设计2.1 图像预处理1) 自适应光照补偿2) 边缘增强 2.2 车牌定位1) 颜色空间筛选2) 形态学操作3) 轮廓分析 2.3 字符分割1) 投影分析2) 连通域筛选 2.4 字符识别 3. 实战部署指南3.1 环境配置3.2 项目代码解析 4.…

鸿蒙接入flutter环境变量配置windows-命令行或者手动配置-到项目的创建-运行demo项目

鸿蒙接入flutter环境变量配置 参考官网 下载flutter git clone https://gitcode.com/openharmony-sig/flutter_flutter.git git checkout -b dev origin/dev # 国内镜像 export PUB_HOSTED_URLhttps://pub.flutter-io.cn export FLUTTER_STORAGE_BASE_URLhttps://storage.fl…

Flink CDC—实时数据集成框架

Flink CDC 是一个基于流的数据集成工具&#xff0c;旨在为用户提供一套功能更加全面的编程接口&#xff08;API&#xff09;&#xff0c;它基于数据库日志的 CDC&#xff08;变更数据捕获&#xff09;技术实现了统一的增量和全量数据读取。 该工具使得用户能够以 YAML 配置文件…

微调ModernBERT为大型语言模型打造高效“过滤器”

ModernBERT&#xff08;2024 年 12 月&#xff09;是最近发布的小型语言模型&#xff0c;由 Answer.AI、LightOn 和 HuggingFace 共同开发。它利用了现代优化技术&#xff0c;如用于 8,192 token 上下文窗口的 RoPE 和 GeGLU layers&#xff0c;在保持效率的同时提升性能。jina…

各大编程语言基本语法区别

1:语言特点 函数式语言和面向对象语言的区别:函数式用函数直接进行操作,面向对象用object.method()进行操作;如:len() <=> object.length() C 语言:1)C 语言可以像汇编语言一样对位、字节和地址进行操作;2)有函数原型;3)具有大量的数值类型;4)函数是C语言…

云计算中的虚拟化:成本节省、可扩展性与灾难恢复的完美结合

云计算中虚拟化的 4 大优势 1. 成本效益 从本质上讲&#xff0c;虚拟化最大限度地减少了硬件蔓延。团队可以将多个虚拟机整合到单个物理主机上&#xff0c;而不是为每个工作负载部署单独的服务器。这大大减少了前期硬件投资和持续维护。 结果如何&#xff1f;更低的功耗、更低…