当前位置:   article > 正文

Chatglm2使用及微调教程_chatglm2 微调

chatglm2 微调

1、下载chatglm2代码

GitHub - THUDM/ChatGLM2-6B: ChatGLM2-6B: An Open Bilingual Chat LLM | 开源双语对话语言模型

github代码见上面所示

2、下载chatglm2-6B模型

git lfs clone THUDM/chatglm2-6b · Hugging Face

如果存在如下报错:OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to github.com:443。

使用命令:git config --global --unset http.proxy

然后再多执行几次git lfs clone xxx的命令。

3、运行chatglm2

修改web_demo2.py中model位置的代码

然后执行启动命令:streamlit run web_demo2.py,

运行时模型以 FP16 精度加载,占用GPU显存为:13161MiB

注意:确保transformers的版本为4.30.2,否则会报错:ImportError: cannot import name 'GenerationConfig' from 'transformers.generation.utils'。

4、微调p-tuning

(1)官方INT4量化版本

官方教程地址:https://www.heywhale.com/mw/project/64984a7b72ebe240516ae79c

下载AdvertiseGen数据集(见教程中的链接)到ptuning目录下,如下图所示:

/data/work/xiehao/ChatGLM2-6B/ptuning/AdvertiseGen

安装除ChatGLM2-6B的依赖之外的其他python依赖包

pip install rouge_chinese nltk jieba datasets transformers[torch] -i https://pypi.douban.com/simple/

执行命令:

  1. torchrun --standalone --nnodes=1 --nproc-per-node=1 main.py \
  2.     --do_train \
  3.     --train_file AdvertiseGen/train.json \
  4.     --validation_file AdvertiseGen/dev.json \
  5.     --preprocessing_num_workers 1 \
  6.     --prompt_column content \
  7.     --response_column summary \
  8.     --overwrite_cache \
  9.     --model_name_or_path /data/work/xiehao/chatglm2-6b-model \
  10.     --output_dir output/adgen-chatglm2-6b-pt \
  11.     --overwrite_output_dir \
  12.     --max_source_length 64 \
  13.     --max_target_length 128 \
  14.     --per_device_train_batch_size 1 \
  15.     --per_device_eval_batch_size 1 \
  16.     --gradient_accumulation_steps 16 \
  17.     --predict_with_generate \
  18.     --max_steps 3000 \
  19.     --logging_steps 10 \
  20.     --save_steps 1000 \
  21.     --learning_rate 2e-2 \
  22.     --pre_seq_len 128 \
  23. --quantization_bit 4

运行占用GPU显存为:7945MiB,3000个steps整体需要4个小时。

运行日志如下:

运行完成后,生成的模型位于:

ChatGLM2-6B/ptuning/output/adgen-chatglm2-6b-pt/checkpoint-3000下

模型比较:

Chatglm2的大模型约为12G,而微调模型约为7M。

测试微调前后的效果对比:

测试代码:

  1. from transformers import AutoTokenizer, AutoModel, AutoConfig
  2. import os
  3. import torch
  4. chat_str = "类型#上衣\*材质#牛仔布\*颜色#白色\*风格#简约\*图案#刺绣\*衣样式#外套\*衣款式#破洞"
  5. model_path = "/data/work/xiehao/chatglm2-6b-model"
  6. lora_model_path = "/data/work/xiehao/ChatGLM2-6B/ptuning/output/adgen-chatglm2-6b-pt/checkpoint-3000/pytorch_model.bin"
  7. tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)
  8. # 微调前
  9. #model = AutoModel.from_pretrained(model_path, trust_remote_code=True, device='cuda')
  10. #model = model.eval()
  11. #response, history = model.chat(tokenizer, chat_str, history=[])
  12. #print(response)
  13. # 微调后
  14. config = AutoConfig.from_pretrained(model_path, trust_remote_code=True, pre_seq_len=128)
  15. model = AutoModel.from_pretrained(model_path, config=config, trust_remote_code=True)
  16. prefix_state_dict = torch.load(lora_model_path)
  17. new_prefix_state_dict = {}
  18. for k, v in prefix_state_dict.items():
  19.     if k.startswith("transformer.prefix_encoder."):
  20.         new_prefix_state_dict[k[len("transformer.prefix_encoder."):]] = v
  21. model.transformer.prefix_encoder.load_state_dict(new_prefix_state_dict)
  22. model = model.cuda()
  23. model.transformer.prefix_encoder.float()
  24. model = model.eval()
  25. response, history = model.chat(tokenizer, chat_str, history=[])
  26. print(response)

微调前的输出:

这是一个描述一件上衣的文本,它采用牛仔布材质,颜色为白色,风格是简约的,图案是刺绣的,衣样式是外套,衣款式是破洞的。

微调后的输出:

这一款牛仔外套采用白底黑字的图案设计,简约大方,彰显出帅气又酷酷的气息。衣身上的刺绣图案,在微光下显得特别的帅气有型。衣身上的破洞处理,彰显出酷酷的时尚感,让整件外套充满了个性

(2)非量化版本

官方的微调脚本中包含“--quantization_bit 4”,输出INT4量化后的lora模型。

当然我们也不可以不用量化模型,直接去掉就好了。

此时会要求安装accelerate依赖包,执行命令:pip install accelerate -U,其他参数同之前的一样。

此时占用15393MiB的GPU显存,执行时间只要2个小时左右,loss下降的也更快

5、AutoModel加载使用模型解读

入口调用:model = AutoModel.from_pretrained(model_path, trust_remote_code=True)

首先,通过AutoConfig读取model_path目录下的config.json的参数信息

然后,动态读取模型参数和模型网络结构信息。

        在config.json的auto_map的AutoModel信息如下:modeling_chatglm.ChatGLMForConditionalGeneration

其中modeling_chatglm为模型名称信息,ChatGLMForConditionalGeneration为类型信息

通过modeling_chatglm.py的ChatGLMForConditionalGeneration就可以获取到大模型对应的网络结构信息,接着再加载模型文件进而生成模型的实例

最后,通过model.chat(tokenizer, chat_str, history=[])生成结果,就是调用ChatGLMForConditionalGeneration实例的chat方法。

6、微调部分解读

从微调后使用可以看出,ChatGLM只重新训练了网络结构的PrefixEncoder部分的代码。

这层网络主要是根据prompt的tokens生成embedding,可参考网络源码:

  1. def get_prompt(self, batch_size, device, dtype=torch.half):
  2. prefix_tokens = self.prefix_tokens.unsqueeze(0).expand(batch_size, -1).to(device)
  3. past_key_values = self.prefix_encoder(prefix_tokens).type(dtype)

微调完成后将这部分的模型信息更新到原来的大模型中。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/251584
推荐阅读
相关标签
  

闽ICP备14008679号