欺诈文本分类微调(十):QLora量化微调

2024-09-04 16:44

本文主要是介绍欺诈文本分类微调(十):QLora量化微调,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. 引言

前文微调方法概览总结了微调的各种方法,并且在更前面两篇文章Lora单卡训练
和 lora单卡二次调优中已经尝试过用Lora进行微调,本文出于好奇准备尝试下用QLora进行微调的效果。

QLoRA是一种新的微调大型语言模型(LLM)的方法,它的特点是能在节省内存的同时保持推理性能。它的出现是为了应对大型模型微调时内存需求大,成本昂贵的问题。

工作原理:首先将LLM进行4位量化,从而显著减少模型的内存占用,接着使用低阶适配器(LoRA)方法对量化的LLM进行微调,因此,QLora可以看成是量化+Lora的结合体。

采用以下核心技术:

  • 4位量化,它创新性的引入了特殊的4位浮点数表示方法NF4(Normal Float 4-bit),使用非均匀量化来平衡数据范围与精度。
  • 双量化,一种对量化后常数再次进行量化的方法,每个参数可平均节省约 0.37 位。
  • 分页优化,使用具有 NVIDIA 统一内存的分页优化器,以避免具有长序列长度的小批量时出现内存峰值。

依赖库安装:

pip install -q -U bitsandbygit

bitsandbytes主要是针对llm和transformers模型提供了优化和量化模型的功能,专门为8位优化器、矩阵乘法和量化而设计,提供了像8位Adam/AdamW之类的函数。目标是通过8位操作实现高效的计算和内存使用从而使llm更易于访问。```

本文将用欺诈文本分类这个业务场景来测试下QLora进行量化微调的实际效果。

2. 训练过程

2.1 初始化

引入之前封装好的trainer.py脚本,定义模型路径和数据集路径,以及要使用的GPU设备。

%run trainer.py
traindata_path = '/data2/anti_fraud/dataset/train0819.jsonl'
evaldata_path = '/data2/anti_fraud/dataset/eval0819.jsonl'
model_path = '/data2/anti_fraud/models/modelscope/hub/Qwen/Qwen2-1___5B-Instruct'
output_path = '/data2/anti_fraud/models/Qwen2-1___5B-Instruct_ft_0830_2'
os.environ["CUDA_VISIBLE_DEVICES"] = "2"
device = 'cuda'
2.2 加载模型和数据集

由于QLora需要以量化的方式来加载模型,所以加载模型的方法需要作调整,这里的改动是引入BitsAndBytesConfig类构建一个量化配置quantization_config, 具体配置项释义:

  • load_in_4bit:决定了模型参数以4位量化格式加载,加载后的模型参数占用空间会比较小;
  • bnb_4bit_compute_dtype=bfloat16:决定了矩阵乘法的计算精度使用bfloat16,输入数据也会被转换成bfloat16位进行计算;
  • bnb_4bit_quant_type:指定量化数据类型nf4;
  • bnb_4bit_use_double_quant:是否启用双重量化;
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfigdef load_model(model_path, device='cuda'):tokenizer = AutoTokenizer.from_pretrained(model_path, use_fast=False, trust_remote_code=True)model = AutoModelForCausalLM.from_pretrained(model_path,torch_dtype=torch.bfloat16,quantization_config=BitsAndBytesConfig(load_in_4bit=True,bnb_4bit_compute_dtype=torch.bfloat16,bnb_4bit_use_double_quant=False, bnb_4bit_quant_type='nf4'),)return model, tokenizer

注1:普通的量化通常是将数值分成均匀的区间,比如,将0到1之间的数值分成16个区间,每个区间的宽度相同。而NF4则根据数据的分布情况,使用不均匀的区间来表示数值,这样可以更有效地表示模型中的重要数值,特别是那些频繁出现的数值。

注2:双重量化是指在已经量化的基础上再进行量化,第二次量化并不会改变位数本身(即仍然是4位),它的目的是通过更紧凑地表示数值,使得存储和计算更加高效。由于每一次量化都会引入一些量化误差,双重量化可能会带来更大的数值误差,所以一般只用于极端内存受限的情况下。

注3:之所以模型参数加载使用4位而计算时使用16位,是因为量化本身已经带来了误差,计算时需要采用更高的精度是为了减少量化误差带来的影响。

加载模型参数和token序列化器。

%%time
model, tokenizer = load_model(model_path, device)
model.device
    CPU times: user 1min 55s, sys: 3.96 s, total: 1min 59sWall time: 1min 52sdevice(type='cuda', index=0)

在这里插入图片描述

占用内存方面,量化加载的1.9GB相比于bfloat16加载的3.9GB减少了将近一半,模型加载时的显存优化比较明显。

加载耗时方面,使用量化方式加载模型的过程是比较慢的,耗时了1分52秒,中间涉及到将模型参数从高精度的浮点数(如 FP32)转换为低精度的 NF4 格式。与之对比,不带量化时基本是秒加载。

加载数据集,复用前文的方法。

train_dataset, eval_dataset = load_dataset(traindata_path, evaldata_path, tokenizer)
2.3 构建训练参数

训练参数:引入分页内存优化器来优化训练过程中的内存分配。

train_args = build_train_arguments(output_path)
train_args.optim="paged_adamw_32bit"   

paged_adamw_32bit 是一种优化器配置,它使用了分页内存管理和32位浮点数来优化训练过程,可以帮助你在训练大规模模型时更有效地管理内存和计算资源。

lora配置:同前文Lora训练一样使用大小为16的秩。

lora_config = build_loraconfig()
lora_config.lora_dropout = 0.2   
lora_config.r = 16
lora_config.lora_alpha = 32
2.4 开始训练

构造训练器开始训练。

trainer = build_trainer(model, tokenizer, train_args, lora_config, train_dataset, eval_dataset)
trainer.train()
StepTraining LossValidation Loss
1000.0433000.028851
2000.0413000.045375
3000.0156000.025569
4000.0287000.023149
5000.0244000.022869
6000.0309000.021145
7000.0196000.019462
8000.0189000.023610
9000.0188000.019515
10000.0174000.018651
11000.0187000.018088
12000.0120000.019770
13000.0124000.023283
14000.0166000.017231
15000.0118000.020865
16000.0120000.018183
17000.0080000.017868
18000.0114000.017251
19000.0172000.017052
20000.0158000.016834
21000.0074000.019656
22000.0101000.016112
23000.0063000.016171
24000.0072000.019825
25000.0046000.022892
26000.0064000.023701
27000.0031000.025771
    TrainOutput(global_step=2700, training_loss=0.028382157780299032, metrics={'train_runtime': 5695.8171, 'train_samples_per_second': 9.895, 'train_steps_per_second': 0.618, 'total_flos': 1.1883908308313702e+17, 'train_loss': 0.028382157780299032, 'epoch': 2.2998296422487225})

训练过程中观察内存变化:
在这里插入图片描述

训练时的显存占用相比非量化时并没有明显变化,基本上占满了24G显卡的显存。

推测原因可能是:QLoRA只是通过量化技术减少了模型参数加载时的显存占用,但训练时仍然会反量化为16位进行矩阵计算,尤其是前向和反向传播阶段,显存的主要消耗来自于激活值、梯度和优化器状态,模型参数仅仅是一小部分,这就导致真正训练过程中占用的显存相比非量化时并没有减少。

QLoRA 主要通过量化模型参数来减小显存占用,但在需要更大的 batch size 的场景下,其显存优化效果可能并不显著。

3. 评估测试

用验证损失最低的checkpoint-2200进行测评。

%run evaluate.py
checkpoint_path='/data2/anti_fraud/models/Qwen2-1___5B-Instruct_ft_0830_2/checkpoint-2200'
evaluate(model_path, checkpoint_path, evaldata_path, device, batch=True, debug=True)
run in batch mode, batch_size=8progress: 100%|██████████| 2348/2348 [03:19<00:00, 11.80it/s]tn:1145, fp:20, fn:167, tp:1016
precision: 0.9806949806949807, recall: 0.8588334742180896

这个训练结果和前文的召回率0.86区别不大,说明使用量化后的模型参数进行训练确实能保持和16位精度的参数训练几乎一样的效果。

小结:本文通过实际训练来测试QLora对于显存占用和推理性能方面的效果,在我们这个验证结果里,推理性能方面几乎可以保持同先前一样的效果,但显存占用只在加载时降低了不到1/2, 而在训练过程中相比于非量化时没有明显减少。原因可能是由于我们的模型太小,而训练时的批量相对较大,模型参数加载时所优化的这部分内存,与整个训练过程所需要的内存相比较小,所以内存优化的整体效果就不太明显。

基于QLora主要是通过减少模型参数所占用的显存这个原理出发,个人理解可能在参数更大的模型并且batch_size更小的训练时效果可能会比较显著。

相关阅读

  • 微调方法概览
  • 欺诈文本分类微调(六):Lora单卡训练
  • 欺诈文本分类微调(七):lora单卡二次调优
  • QLoRA量化微调策略与实践

这篇关于欺诈文本分类微调(十):QLora量化微调的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1136470

相关文章

基于人工智能的图像分类系统

目录 引言项目背景环境准备 硬件要求软件安装与配置系统设计 系统架构关键技术代码示例 数据预处理模型训练模型预测应用场景结论 1. 引言 图像分类是计算机视觉中的一个重要任务,目标是自动识别图像中的对象类别。通过卷积神经网络(CNN)等深度学习技术,我们可以构建高效的图像分类系统,广泛应用于自动驾驶、医疗影像诊断、监控分析等领域。本文将介绍如何构建一个基于人工智能的图像分类系统,包括环境

认识、理解、分类——acm之搜索

普通搜索方法有两种:1、广度优先搜索;2、深度优先搜索; 更多搜索方法: 3、双向广度优先搜索; 4、启发式搜索(包括A*算法等); 搜索通常会用到的知识点:状态压缩(位压缩,利用hash思想压缩)。

AI Toolkit + H100 GPU,一小时内微调最新热门文生图模型 FLUX

上个月,FLUX 席卷了互联网,这并非没有原因。他们声称优于 DALLE 3、Ideogram 和 Stable Diffusion 3 等模型,而这一点已被证明是有依据的。随着越来越多的流行图像生成工具(如 Stable Diffusion Web UI Forge 和 ComyUI)开始支持这些模型,FLUX 在 Stable Diffusion 领域的扩展将会持续下去。 自 FLU

Level3 — PART 3 — 自然语言处理与文本分析

目录 自然语言处理概要 分词与词性标注 N-Gram 分词 分词及词性标注的难点 法则式分词法 全切分 FMM和BMM Bi-direction MM 优缺点 统计式分词法 N-Gram概率模型 HMM概率模型 词性标注(Part-of-Speech Tagging) HMM 文本挖掘概要 信息检索(Information Retrieval) 全文扫描 关键词

用Pytho解决分类问题_DBSCAN聚类算法模板

一:DBSCAN聚类算法的介绍 DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一种基于密度的聚类算法,DBSCAN算法的核心思想是将具有足够高密度的区域划分为簇,并能够在具有噪声的空间数据库中发现任意形状的簇。 DBSCAN算法的主要特点包括: 1. 基于密度的聚类:DBSCAN算法通过识别被低密

可选择的反思指令微调

论文:https://arxiv.org/pdf/2402.10110代码:GitHub - tianyi-lab/Reflection_Tuning: [ACL'24] Selective Reflection-Tuning: Student-Selected Data Recycling for LLM Instruction-Tuning机构:马里兰大学, Adobe Research领

PMP–一、二、三模–分类–14.敏捷–技巧–看板面板与燃尽图燃起图

文章目录 技巧一模14.敏捷--方法--看板(类似卡片)1、 [单选] 根据项目的特点,项目经理建议选择一种敏捷方法,该方法限制团队成员在任何给定时间执行的任务数。此方法还允许团队提高工作过程中问题和瓶颈的可见性。项目经理建议采用以下哪种方法? 易错14.敏捷--精益、敏捷、看板(类似卡片)--敏捷、精益和看板方法共同的重点在于交付价值、尊重人、减少浪费、透明化、适应变更以及持续改善等方面。

【python计算机视觉编程——8.图像内容分类】

python计算机视觉编程——8.图像内容分类 8.图像内容分类8.1 K邻近分类法(KNN)8.1.1 一个简单的二维示例8.1.2 用稠密SIFT作为图像特征8.1.3 图像分类:手势识别 8.2贝叶斯分类器用PCA降维 8.3 支持向量机8.3.2 再论手势识别 8.4 光学字符识别8.4.2 选取特征8.4.3 多类支持向量机8.4.4 提取单元格并识别字符8.4.5 图像校正

PMP–一、二、三模–分类–14.敏捷–技巧–原型MVP

文章目录 技巧一模14.敏捷--原型法--项目生命周期--迭代型生命周期,通过连续的原型或概念验证来改进产品或成果。每个新的原型都能带来新的干系人新的反馈和团队见解。题目中明确提到需要反馈,因此原型法比较好用。23、 [单选] 一个敏捷团队的任务是开发一款机器人。项目经理希望确保在机器人被实际建造之前,团队能够收到关于需求的早期反馈并相应地调整设计。项目经理应该使用以下哪一项来实现这个目标?

基于深度学习 卷积神经网络resnext50的中医舌苔分类系统

项目概述 本项目旨在通过深度学习技术,特别是利用卷积神经网络(Convolutional Neural Networks, CNNs)中的ResNeXt50架构,实现对中医舌象图像的自动分类。该系统不仅能够识别不同的舌苔类型,还能够在PyQt5框架下提供一个直观的图形用户界面(GUI),使得医生或患者能够方便地上传舌象照片并获取分析结果。 技术栈 深度学习框架:采用PyTorch或其他