LLM - LoRA 模型合并与保存

目录

一.引言

二.LoRA 

1.LoRA 简介

2.LoRA 参数

3.LoRA 合并

4.LoRA 保存

三.总结


一.引言

LLM 使用过程中最常用方法之一就是通过 LoRA 基于自己的数据对大模型进行微调,本文简单介绍 LoRA 原理以及如何合并多个 LoRA 模型并保存。

peft==0.4.0
transformers==4.29.1

二.LoRA 

1.LoRA 简介

LoRA 是一种消耗较少内存同时加速大型模型微调的技术。

为了使得微调更有效,LoRA 的方法是通过低秩分解两个较小的矩阵 [称为更新矩阵] 用于参数更新。在维持较少更新参数的基础上,训练并适应新的微调数据。原始参数 W 保持冻结,不会进行更新训练。该方法有如下优点:

    ◆  LoRA 通过大幅减少可训练参数数量,使微调更加效率。

    ◆  基于 LoRA 的轻便型,可以构建多个轻量级 LoRA 模型用于不同下游任务 

    ◆  LoRA 与许多其他参数有效方法正交,并且可以与其结合。

      使用 LoRA 进行微调的模型的性能与完全微调模型的性能相当。

    ◆  LoRA 几乎不添加任何推理延迟,因为适配器权重可以与基本模型合并。

2.LoRA 参数

原则上,LoRA 可以应用于神经网络中权重矩阵的任何子集,以减少可训练参数的数量。然而,为了简化和进一步提高参数效率,在 Transformer 模型中,LoRA 通常仅应用于注意力块。LoRA 模型中可训练参数的结果数量取决于低秩更新矩阵的大小,其主要由秩 r 和原始权重矩阵的形状确定。实际使用过程中,通过选择不同的 lora_target 决定训练的参数量,以 LLama 为例:

--lora_target q_proj,k_proj,v_proj,o_proj,gate_proj,up_proj,down_proj \

可以通过 numel 方法获取张量中参数的数量和 requires_grad 方法获取模型张量是否进行梯度计算来计算可训练参数的比例:

# 打印可训练参数
def print_trainable_params(model: torch.nn.Module) -> None:trainable_params, all_param = 0, 0for param in model.parameters():num_params = param.numel()# if using DS Zero 3 and the weights are initialized emptyif num_params == 0 and hasattr(param, "ds_numel"):num_params = param.ds_numelall_param += num_paramsif param.requires_grad:trainable_params += num_paramsprint("trainable params: {:d} || all params: {:d} || trainable%: {:.4f}".format(trainable_params, all_param, 100 * trainable_params / all_param))

3.LoRA 合并

在训练过程中,较小的权重矩阵 A、B 是分开的。但一旦训练完成,权重实际上可以合并到一个相同的新权重矩阵中。虽然 LoRA 明显更小,训练速度更快,但由于分别加载基本模型和 LoRA 模型,可能会在推理过程中遇到延迟问题。为了消除延迟,可以使用 merge_and_unload 函数将适配器权重与基本模型合并,这样可以有效地将新合并的模型用作独立模型。同时也可以合并多个 LoRA 模型,使得 Base Model 同时具备多个任务处理能力。

训练时原始参数 W 保持不动,更新矩阵 A/B。合并时 W-merged = W + BA 代替原有的 W。 

from transformers import AutoConfig, AutoTokenizer, AutoModelForCausalLM, TextIteratorStreamer, GenerationConfig
from peft import PeftModel# 载入预训练模型tokenizer = AutoTokenizer.from_pretrained(base_model, use_fast=True, padding_side="left", **config_kwargs)print("Tokenizer Load Success!")config = AutoConfig.from_pretrained(base_model, **config_kwargs)# Load and prepare pretrained models (without valuehead).model = AutoModelForCausalLM.from_pretrained(base_model,config=config,torch_dtype=torch.float16,low_cpu_mem_usage=True,trust_remote_code=True,revision='main')print('origin config =', model.config)# 模型合并ckpt_list = ["checkpoint-1000", "checkpoint-2000", "checkpoint-3000"]for checkpoint in ckpt_list:print('Merge checkpoint: {}'.format(checkpoint))model = PeftModel.from_pretrained(model, os.path.join(lora_model, checkpoint))model = model.merge_and_unload()print('merge config =', model.config)

通过 merge_and_unlaod 方法可以合并多个 Lora 模型,这里博主尝试将同一个模型的 3 个  CKPT 合并至原始模型中。通过合并不同类型任务的 CKPT,原始模型可以同时具备多种下游任务的能力且推理效率不会受影响。

4.LoRA 保存

import torch
from peft import PeftModel
from transformers import AutoTokenizer, AutoModelForCausalLM, LlamaTokenizerdef apply_lora(model_name_or_path, output_path, lora_path):print(f"Loading the base model from {model_name_or_path}")base = AutoModelForCausalLM.from_pretrained(model_name_or_path, torch_dtype=torch.float16, low_cpu_mem_usage=True)base_tokenizer = LlamaTokenizer.from_pretrained(model_name_or_path)print(f"Loading the LoRA adapter from {lora_path}")lora_model = PeftModel.from_pretrained(base,lora_path,torch_dtype=torch.float16,)print("Applying the LoRA")model = lora_model.merge_and_unload()print(f"Saving the target model to {output_path}")model.save_pretrained(output_path)base_tokenizer.save_pretrained(output_path)

使用 merge_and_unload 方法进行参数合并,再调用 save_pretrained 方法进行模型保存。可以看到保存前后模型大小几乎没有变化。 

 

三.总结

合并多个 LoRA 模型也可能对模型的原始能力造成影响,大家可以根据需求测试与尝试。

参考:

- LoRA https://huggingface.co/docs/peft/conceptual_guides/lora

- PEFT Models 

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

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

相关文章

[NLP]LLM高效微调(PEFT)--LoRA

LoRA 背景 神经网络包含很多全连接层,其借助于矩阵乘法得以实现,然而,很多全连接层的权重矩阵都是满秩的。当针对特定任务进行微调后,模型中权重矩阵其实具有很低的本征秩(intrinsic rank),因…

记一次centos 磁盘挂载过程

前言 最近买了云服务器磁盘,需要挂载,一下就由大猿来记录这次过程。 挂载过程 查看磁盘挂载情况 查看物理硬盘 lsblkfdisk -l标记分区 fdisk /dev/vdb格式化分区 xfs mkfs.xfs /dev/vdb mkfs.xfs -f /dev/vdbext4 mkfs.ext4 /dev/vdbxfs 和 ex…

HTTP——HTTP报文内的HTTP信息

HTTP 通信过程包括从客户端发往服务器端的请求及从服务器端返回客户端的响应。本章就让我们来了解一下请求和响应是怎样运作的。 HTTP 一、HTTP报文二、请求报文及响应报文的结构三、编码提升传输速率1、报文主体和实体主题的差异2、压缩传输的内容编码3、分割发送的分块传输编…

Spring MVC异步上传、跨服务器上传和文件下载

一、异步上传 之前的上传方案,在上传成功后都会跳转页面。而在实际开发中,很多情况下上传后不进行跳转,而是进行页面的局部刷新,比如:上传头像成功后将头像显示在网页中。这时候就需要使用异步文件上传。 1.1 JSP页面 …

为了规避风险,如何给大模型打水印?

大型语言模型,如最近开发的ChatGPT,可以撰写文件、创建可执行代码和回答问题,通常具有人类般的能力。 随着这些大模型的应用越来越普遍,越来越大的风险也显现了出来,它们可能被用于恶意目的。这些恶意目的包括&#xf…

【漏洞复现】Metabase 远程命令执行漏洞(CVE-2023-38646)

文章目录 前言声明一、漏洞介绍二、影响版本三、漏洞原理四、漏洞复现五、修复建议 前言 Metabase 0.46.6.1之前版本和Metabase Enterprise 1.46.6.1之前版本存在安全漏洞,未经身份认证的远程攻击者利用该漏洞可以在服务器上以运行 Metabase 服务器的权限执行任意命…

虹科活动 | 走进宇通客车-汽车新供应链技术展精彩回顾

引言 7月27日,走进宇通客车-汽车新供应链技术展于宇通研发中心成功举办,本次展会中虹科为大家带来了一体化车载天线与车辆GNSS仿真测试方案,感谢您前来探讨与交流! 精彩产品一览 车辆GNSS仿真测试方案 虹科高性能GNSS模拟器具有灵…

如何搭建WordPress博客网站,并且发布至公网上?

如何搭建WordPress博客网站,并且发布至公网上? 文章目录 如何搭建WordPress博客网站,并且发布至公网上?概述前置准备1 安装数据库管理工具1.1 安装图形图数据库管理工具,SQL_Front 2 创建一个新数据库2.1 创建数据库2.…

振弦传感器信号转换器应用山体滑坡安全监测

振弦传感器信号转换器应用山体滑坡安全监测 随着人类文明的进步,自然灾害对人们的生活和财产安全造成的威胁也越来越大。山体滑坡作为自然灾害中的一种,给人们的生活和财产安全带来了极大的威胁。因此,进行山体滑坡的安全监测显得尤为重要。振…

Chat模块封装

封装保存用户类 utils/chat.js class Chat{constructor(){// 当前登录的用户this._user null;// 会话数组 和多个人this._sessions []; //user message// 当前会话 (和谁在聊天)this._current_session null;}setUser(user){this._user user} }exp…

C++中数据的输入输出介绍

C中数据的输入输出介绍 C中数据的输入输出涉及到的文件 <iostream>&#xff1a;这是C标准库中最常用的头文件之一&#xff0c;包含了进行标准输入输出操作的类和对象&#xff0c;如std::cin、std::cout、std::endl等。 <iomanip>&#xff1a;该头文件提供了一些用…

免费商用 Meta 发布开源大语言模型 Llama 2

Meta 和微软深度合作&#xff0c;正式推出下一代开源大语言模型 Llama 2&#xff0c;并宣布免费提供给研究和商业使用。 Llama 2 论文地址&#xff1a;Llama 2: Open Foundation and Fine-Tuned Chat Models 据介绍&#xff0c;相比于 Llama 1&#xff0c;Llama 2 的训练数据多…

AD21 PCB设计的高级应用(九)3D PDF的输出

&#xff08;九&#xff09;3D PDF的输出 1.3D PDF的输出2.制作PCB 3D视频 1.3D PDF的输出 Altium Designer 19 带有 3D输出功能,能够直接将 PCB 的 3D效果输出到 PDF 中。 ’(1)打开带有 3D 模型的 PCB 文件,执行菜单栏中“文件”→“导出”→“PDF3D”命令&#xff0c;选择…

计算机网络 day7 扫描IP脚本 - 路由器 - ping某网址的过程

目录 network 和 NetworkManager关系&#xff1a; 实验&#xff1a;编写一个扫描脚本&#xff0c;知道本局域网里哪些ip在使用&#xff0c;哪些没有使用&#xff1f; 使用的ip对应的mac地址都要显示出来 计算机程序执行的两种不同方式&#xff1a; shell语言编写扫描脚本 …

【Linux】自动化构建工具-make/Makefile详解

前言 大家好吖&#xff0c;欢迎来到 YY 滴 Linux系列 &#xff0c;热烈欢迎&#xff01;本章主要内容面向接触过Linux的老铁&#xff0c;主要内容含 欢迎订阅 YY 滴Linux专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; 订阅专栏阅读&#xff1a;YY的《…

OpenHarmony ArkUI 如何调用相机

​ ArkUI调用相机和调用相册其实是一个思路&#xff0c;只用修改一个地方。 我们继续来说相机调用&#xff0c;ArkUI没办法自己获取相机&#xff0c;所以得依靠一下ohos.multimedia.camera 相机开发指导 介绍 本指导主要展示了调用相机的调用过程&#xff0c;以及调用相机的…

Unity Shader - if 和 keyword 的指令比较

文章目录 环境TestingIf4Sampleunity shaderlab 中的 TestingIf4Sample.shadergraphics analyzer 中的 TestingIf4Sample.glsl TestingKW4Sampleunity shaderlab 中的 TestingKW4Sample.shadergraphics analyzer 中的 TestingKW4Sample.glsl 比较 环境 Unity : 2020.3.37f1 Pi…

网络安全(零基础)自学

一、网络安全基础知识 1.计算机基础知识 了解了计算机的硬件、软件、操作系统和网络结构等基础知识&#xff0c;可以帮助您更好地理解网络安全的概念和技术。 2.网络基础知识 了解了网络的结构、协议、服务和安全问题&#xff0c;可以帮助您更好地解决网络安全的原理和技术…

新的恶意软件 WikiLoader 针对意大利组织

研究人员发现了一种新的恶意软件&#xff0c;名为 WikiLoader 恶意软件。之所以这样命名&#xff0c;是因为它向维基百科发出请求&#xff0c;希望得到内容中包含 "The Free "字符串的响应。 WikiLoader 恶意软件的主要目标是意大利企业及组织。 WikiLoader 是一种…

首页和图表的定制

首页就是刚刚那些在静态资源扫描文件下叫 index.html 的文件 头像