当前位置:   article > 正文

如何使用Kaggle免费算力微调ChatGLM_kaggle的算力

kaggle的算力

数据集预处理

数据下载及配置

  • 首先从比赛官网上下载A榜的数据集:获取数据
  • 在本地解压缩后,进入到路径:\2023S-T1-A-Data[供选手] 0513\指令数据&标签,找到我们的训练集测试集数据和标签,共有3个 .json 文件。
  • 将这3个文件打包上传至Kaggle上。
  • 进入到 jupyter notebook 环境中,配置好数据集,效果如下:

数据处理

  • 生成训练集和验证集
import json
import pandas as pd
import re
from collections import defaultdict, Counter
from bs4 import BeautifulSoup

# 配置文件路径,读取数据集
LABEL_PATH = '/kaggle/input/web-auto-navigation-dataset/'
label_trainset = json.load(open(LABEL_PATH + 'label_trainset.json', encoding="utf-8"))
instruction_trainset = json.load(open(LABEL_PATH + 'instruction_trainset.json', encoding="utf-8"))
instruction_testA = json.load(open(LABEL_PATH + 'instruction_testA.json', encoding="utf-8"))

import random

chat_data = []
for idx in range(20):
    for instructions in instruction_trainset[idx]['instruction_detail']:
        chat_data.append({
            'prompt': instructions['instruction'],
            'response': ';'.join([f'{key}' for key, value in instructions['key-value'].items()]),
            "history": []
        })
random.shuffle(chat_data)

with open('train.json', 'w') as up:
    for line in chat_data[:-400]:
        up.write(json.dumps(line)+'\n')
    
with open('dev.json', 'w') as up:
    for line in chat_data[-400:]:
        up.write(json.dumps(line)+'\n')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 生成的文件可以在 /kaggle/working/目录下找到:

配置环境

  • git clone github仓库。
!git clone https://github.com/THUDM/ChatGLM-6B.git
  • 1
  • 配置 requirements.txt 中的必要工具包。
!pip install -r /kaggle/working/ChatGLM-6B/requirements.txt
  • 1

配置 train_chat.sh 文件

  • 进入到对应目录
cd /kaggle/working/ChatGLM-6B/ptuning
  • 1
  • 写入相关配置
    • 其中 --model_name_or_path 我们训练4-bit量化版本 THUDM/chatglm-6b-int4
    • 普通的 THUDM/chatglm-6b 版本会爆显存,因为会先将模型下载下来再进行量化。
    • 通过修改以下超参数来调整模型训练。
    • 下述参数中 PRE_SEQ_LENmax_source_lengthmax_target_length 过大导致模型训练较慢,可以适当修改。
with open("/kaggle/working/ChatGLM-6B/ptuning/train_chat.sh", mode='w') as f:
    f.write('CHAT_TRAIN_DATA=/kaggle/working/train.json'+'\n')
    f.write('CHAT_VAL_DATA=/kaggle/working/dev.json'+'\n')
    f.write('CHECKPOINT_NAME=/kaggle/working'+'\n')
    f.write('PRE_SEQ_LEN=128'+'\n')
    f.write('LR=1e-3'+'\n')
    f.write('CUDA_VISIBLE_DEVICES=0 python3 main.py \\'+'\n')
    f.write('    --do_train \\'+'\n')
    f.write('    --train_file $CHAT_TRAIN_DATA \\'+'\n')
    f.write('    --validation_file $CHAT_VAL_DATA \\'+'\n')
    f.write('    --prompt_column prompt \\'+'\n')
    f.write('    --response_column response \\'+'\n')
    f.write('    --history_column history \\'+'\n')
    f.write('    --overwrite_cache \\'+'\n')
    f.write('    --model_name_or_path THUDM/chatglm-6b-int4 \\'+'\n')
    f.write('    --output_dir $CHECKPOINT_NAME \\'+'\n')
    f.write('    --overwrite_output_dir \\'+'\n')
    f.write('    --max_source_length 256 \\'+'\n')
    f.write('    --max_target_length 256 \\'+'\n')
    f.write('    --per_device_train_batch_size 1 \\'+'\n')
    f.write('    --per_device_eval_batch_size 1 \\'+'\n')
    f.write('    --gradient_accumulation_steps 16 \\'+'\n')
    f.write('    --predict_with_generate \\'+'\n')
    f.write('    --max_steps 3000 \\'+'\n')
    f.write('    --logging_steps 100 \\'+'\n')
    f.write('    --save_steps 1000 \\'+'\n')
    f.write('    --learning_rate $LR \\'+'\n')
    f.write('    --pre_seq_len $PRE_SEQ_LEN \\'+'\n')
    f.write('    --quantization_bit 4'+'\n')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 注:由于Kaggle上目前不支持 Linuxvim 命令修改文件,尝试了如下两种写入方法都会报错:
    • 1、这种方式只能在文件末尾补充内容,报错原因大概是在调用后声明导致。
    !echo CHAT_TRAIN_DATA=/kaggle/working/train.json >> train_chat.sh
    !echo CHAT_VAL_DATA=/kaggle/working/dev.json >> train_chat.sh
    !echo CHECKPOINT_NAME=/kaggle/working >> train_chat.sh
    
    • 1
    • 2
    • 3
    • 2、这种方式修改的文件不是 Linux 支持的格式。
    %%writefile /kaggle/working/ChatGLM-6B/ptuning/train_chat.sh
    
    • 1

微调 ChatGLM

  • 还有一个包需要安装
!pip install rouge_chinese -i https://pypi.tuna.tsinghua.edu.cn/simple
  • 1
  • 微调模型,由于Kaggle上无法支持代码运行过程中的输入,因此要关闭 wandb,执行默认操作,等待模型运行完毕即可。
!wandb off
!bash train_chat.sh
  • 1
  • 2

使用微调权重部署ChatGLM

# 首先载入Tokenizer
import torch
from transformers import AutoTokenizer, AutoModel, AutoConfig

# 加载 Checkpoint
config = AutoConfig.from_pretrained("THUDM/chatglm-6b-int4", trust_remote_code=True)
# pre_seq_len要设置成微调时候的大小
config.pre_seq_len = 128

tokenizer = AutoTokenizer.from_pretrained("THUDM/chatglm-6b-int4", trust_remote_code=True)
model = AutoModel.from_pretrained("THUDM/chatglm-6b-int4", trust_remote_code=True, config=config).half()

# 本次微调得到的glm权重
prefix_state_dict = torch.load('./ChatGLM-6B/ptuning/checkpoint-100/pytorch_model.bin')
new_prefix_state_dict = {}
for k, v in prefix_state_dict.items():
    if k.startswith("transformer.prefix_encoder."):
        new_prefix_state_dict[k[len("transformer.prefix_encoder."):]] = v
model.transformer.prefix_encoder.load_state_dict(new_prefix_state_dict)

# 据需求可以进行量化
model = model.quantize(4)
model = model.half().cuda()
model.transformer.prefix_encoder.float()
model = model.eval()

# 测试是否部署完成
response, history = model.chat(tokenizer, '''请搜索:吉林批发和零售业的主板B股的首创环保的信息。''', history=[])
print(response)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

结果提交

  • 对模型的输出格式进行调整,符合提交要求,保存为 .json 文件。
  • 将得到的 .json 文件压缩提交 参赛提交

结果分析

  • ChatGLM-6B-int4模型的精度稍低,需要更多的训练步数。
  • 由于GPU显存有限,每个batch只能处理1个样本,训练过程波动较大,因此需要调整 gradient_accumulation_steps 参数,在多个样本后更新参数。
  • 缺点是速度较慢,设置为16的话总时长要10小时以上。
  • 模型调优过程经验见下一篇文章。
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/260407?site
推荐阅读
相关标签
  

闽ICP备14008679号