使用peft库_对chatGLM-6B_chatGLM2-6B实现4bit的QLoRA高效微调_并做loramodel和base...

使用peft库_对chatGLM-6B_chatGLM2-6B实现4bit的QLoRA高效微调_并做loramodel和base...ChatGLM 6B QLoRA 介绍 本项目使用 peft 库 实现了 ChatGLM 6B chatGLM2 6B 模型 4bit 的 QLoRA 高效微调 可以在一张 RTX3060 上完成全部微调过程 内容包括 环境配置 数据集介绍 ChatGLM 6B chatGLM2 6B 的 QLoRA 训练完整流程 ChatGLM 6B chatGLM2 6B 的推理流程 使用 adapter 做推理

大家好,我是讯享网,很高兴认识大家。这里提供最前沿的Ai技术和互联网信息。

# ChatGLM-6B-QLoRA

介绍

本项目使用peft库,实现了ChatGLM-6B/chatGLM2-6B模型4bit的QLoRA高效微调,可以在一张RTX3060上完成全部微调过程。

内容包括:

  1. 环境配置
  2. 数据集介绍
  3. ChatGLM-6B/chatGLM2-6B的QLoRA训练完整流程
  4. ChatGLM-6B/chatGLM2-6B的推理流程
    • 使用adapter做推理
    • 合并adapter和basemodel做推理
    • 量化合并后的模型做推理
  5. 推理性能测试
  6. QLoRA微调前后的效果比对

特别说明:

无特别理由,强烈推荐使用chatGLM2-6B,理由如下:

  1. chatGLM2-6B的推理效率比chatGLM-6B快30%~50%,见本文档5. 推理性能测试章节
  2. chatGLM2-6B在微调前的输出质量就远高于chatGLM-6B,微调后的loss值更低
  3. chatGLM2-6B几乎没有灾难性疑问的情况,微调后对数据集外的问题仍然能输出高质量的答案,不过也有人反馈会陷入重复回答的问题
  4. chatGLM2-6B和1代模型比,目前微调或推理时的显存占用应该差别不大,如果出现微调时显存占用明显大于1代模型,请拉取最新的2代模型,尤其是里面的脚本文件

关于模型训练后使用int4的方式进行推理:

  1. 目前官方的量化方法在merge_lora_and_quantize.py中已经集成,但有反馈表示量化后存在一定性能损失
  2. 还有一种方式是使用merge_lora_and_quantize.py脚本合成base model和lora model,但是不做量化处理,将保存fp16的模型,使用此模型时,以int4的方式加载,进行推理(加载方法同训练脚本中的代码)
  3. 2中的方法目前应该比1的方法在准确性的损失上要小一些,但两种方式都是降低显存的同时增加响应延时,并没有加快推理速度,见5. 推理性能测试章节

环境配置

环境依赖

  • CUDA >= 11.7
  • python依赖项
    peft==0.4.0 transformers==4.30.2 datasets==2.12.0 tqdm==4.65.0 loguru==0.7.0 fire==0.5.0 bitsandbytes==0.39.0 wandb==0.15.3 cpm_kernels==1.0.11 accelerate==0.20.3 sentencepiece==0.1.99 

推荐环境

推荐使用docker镜像,如下:

GPT plus 代充 只需 145docker pull huggingface/transformers-pytorch-gpu:4.29.1 docker run -tid -v /your/data/path:/home -p 58323:58323 --gpus all huggingface/transformers-pytorch-gpu:4.29.1 # 上面命令中的 -p 58323:58323 如果你想用tensorboard查看训练过程,需要映射一个端口出来 # 进入容器 docker exec -ti container_name /bin/bash 

进入容器后,执行:

python3 -m pip install --upgrade pip pip install -q -U bitsandbytes pip install peft==0.4.0 pip install transformers==4.30.2 pip install accelerate==0.20.3 

注:理论上更高版本的transformers库应该可以正常运行本项目。

数据集介绍

数据集使用ADGEN广告数据集,任务为根据instruction生成一段广告词,见本项目data文件夹,每条样本为一行,形式为:

GPT plus 代充 只需 145{ "instruction": "类型#裤*版型#宽松*风格#性感*图案#线条*裤型#阔腿裤", "output": "宽松的阔腿裤这两年真的吸粉不少,明星时尚达人的心头爱。毕竟好穿时尚,谁都能穿出腿长2米的效果宽松的裤腿,当然是遮肉小能手啊。上身随性自然不拘束,面料亲肤舒适贴身体验感棒棒哒。系带部分增加设计看点,还让单品的设计感更强。腿部线条若隐若现的,性感撩人。颜色敲温柔的,与裤子本身所呈现的风格有点反差萌。" } 

其中训练数据train.jsonl共计条,验证数据dev.jsonl共计1070条。

训练流程

进入本项目目录,训练启动命令如下:

python3 train_qlora.py --train_args_json chatGLM_6B_QLoRA.json --model_name_or_path THUDM/chatglm-6b --train_data_path data/train.jsonl --eval_data_path data/dev.jsonl --lora_rank 4 --lora_dropout 0.05 --compute_dtype fp32 

训练chatGLM2-6B只要修改model_name_or_path参数为THUDM/chatglm2-6b.

其中chatGLM_6B_QLoRA.json文件为所有transformers框架支持的TrainingArguments,参考:https://huggingface.co/docs/transformers/main_classes/trainer#transformers.TrainingArguments

默认如下,可根据实际情况自行修改:

GPT plus 代充 只需 145{ "output_dir": "saved_files/chatGLM_6B_QLoRA_t32", "per_device_train_batch_size": 4, "gradient_accumulation_steps": 8, "per_device_eval_batch_size": 4, "learning_rate": 1e-3, "num_train_epochs": 1.0, "lr_scheduler_type": "linear", "warmup_ratio": 0.1, "logging_steps": 100, "save_strategy": "steps", "save_steps": 500, "evaluation_strategy": "steps", "eval_steps": 500, "optim": "adamw_torch", "fp16": false, "remove_unused_columns": false, "ddp_find_unused_parameters": false, "seed": 42 } 

对参数compute_type,可选fp16, bf16fp32,实测使用fp16, bf16这两种计算速度有明显提升,相同的epoch只需要大约一半的时间,但出现loss收敛较慢的情况,默认选择fp32.

关于这个参数的选择,可能需要根据数据集做不同的尝试。

训练截图(chatGLM-6B)

  • 显存占用,batch_size = 4

img.png

  • chatGLM-6B的loss曲线,训练一个epoch,可以看到loss还在下降

img.png img.png

经过实测在训练一个epoch的情况下,chatGLM-6B的loss在3.4左右,chatGLM2-6B的loss可以到2.9

默认会在saved_files/chatGLM_6B_QLoRA_t32文件夹中生成一个runs的文件夹,可进入saved_files/chatGLM_6B_QLoRA_t32文件夹,用以下命令启动tensorboard,查看训练曲线:

tensorboard --logdir runs --port 'your port' --bind_all 

模型推理

训练过程会保存adapter的checkpoint及最终的adapter文件,默认配置下chatGLM-6B每个文件的情况如下:

GPT plus 代充 只需 145-rw-r--r-- 1 root root 417 Jun 2 21:14 adapter_config.json -rw-r--r-- 1 root root 7.1M Jun 2 21:14 adapter_model.bin -rw-r--r-- 1 root root 15M Jun 2 21:14 optimizer.pt -rw-r--r-- 1 root root 15K Jun 2 21:14 rng_state.pth -rw-r--r-- 1 root root 627 Jun 2 21:14 scheduler.pt -rw-r--r-- 1 root root 2.0K Jun 2 21:14 trainer_state.json -rw-r--r-- 1 root root 3.9K Jun 2 21:14 training_args.bin 

保存的adapter只有约7M的大小。

使用adapter推理

推理代码如下:

import torch from transformers import AutoModel, AutoTokenizer, BitsAndBytesConfig from peft import PeftModel, PeftConfig peft_model_path = 'saved_files/chatGLM_6B_QLoRA_t32' config = PeftConfig.from_pretrained(peft_model_path) q_config = BitsAndBytesConfig(load_in_4bit=True, bnb_4bit_quant_type='nf4', bnb_4bit_use_double_quant=True, bnb_4bit_compute_dtype=torch.float32) base_model = AutoModel.from_pretrained(config.base_model_name_or_path, quantization_config=q_config, trust_remote_code=True, device_map='auto') input_text = '类型#裙*版型#显瘦*风格#文艺*风格#简约*图案#印花*图案#撞色*裙下摆#压褶*裙长#连衣裙*裙领型#圆领' print(f'输入: {input_text}') tokenizer = AutoTokenizer.from_pretrained(config.base_model_name_or_path, trust_remote_code=True) response, history = base_model.chat(tokenizer=tokenizer, query=input_text) print(f'微调前: {response}') model = PeftModel.from_pretrained(base_model, peft_model_path) response, history = model.chat(tokenizer=tokenizer, query=input_text) print(f'微调后: {response}') 

合并Lora model和base model、量化模型推理

首先需要说明,本项目目前使用的peft为dev的版本,在合并lora model和base model时,会报错,见https://github.com/huggingface/peft/pull/535

因此要�

小讯
上一篇 2026-03-18 09:38
下一篇 2026-03-18 09:36

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/243723.html