【工程记录】ChatGLM3-6B微调实践(Windows)


写在前面

仅作个人学习记录用。本文记录ChatGLM3-6B在Windows操作系统中的微调实践。


本文于2023年12月19日发布,部分内容不再具有时效性,建议查看本文的更新与补充说明:【工程记录】ChatGLM3-6B微调实践的更新说明 或其他微调教程

1. 部署预训练模型

详见 【工程记录】ChatGLM3-6B 部署的详细教程(Windows)

import os
import torch
from transformers import AutoModel, AutoTokenizer

#改成你的模型路径
MODEL_PATH = os.environ.get('MODEL_PATH', './chatglm3-6b')
TOKENIZER_PATH = os.environ.get("TOKENIZER_PATH", MODEL_PATH)
DEVICE = 'cuda' if torch.cuda.is_available() else 'cpu'


def get_model():
    tokenizer = AutoTokenizer.from_pretrained(TOKENIZER_PATH, trust_remote_code=True)
    if 'cuda' in DEVICE:  # AMD, NVIDIA GPU 可以使用 Half Precision
        model = AutoModel.from_pretrained(MODEL_PATH, trust_remote_code=True).to(DEVICE).eval()
    else:  # CPU, Intel GPU and other GPU 可以只使用 Float16 Precision
        model = AutoModel.from_pretrained(MODEL_PATH, trust_remote_code=True).float().to(DEVICE).eval()
    # 多显卡支持,使用下面两行代替上面一行,将num_gpus改为你实际的显卡数量
    # from utils import load_model_on_gpus
    # model = load_model_on_gpus("THUDM/chatglm3-6b", num_gpus=2)
    return tokenizer, model

# 加载Chatglm3的model和tokenizer
tokenizer, model = get_model()

注意:ChatGLM3-6B 微调示例需要 python>=3.10,除基础的 torch 依赖外,还需要依赖:

transformers==4.30.2
accelerate
sentencepiece
astunparse
deepspeed

2. 数据格式预处理

ChatGLM3-6B模型的官方文档提供了微调示例。微调方法上,提供全量微调和 P-Tuning v2。格式上,提供多轮对话微调样例和输入输出格式微调样例。

无论是全量微调还是P-Tuning v2,都需要设计微调数据,而ChatGLM3-6B支持多轮对话和输入输出格式微调样例。因此如果想要使用自己的数据集进行模型微调,需要首先统一样例格式。同时,ChatGLM3-6B微调对话和微调工具能力的数据格式也不相同。

本文实践仅使用输入输出格式来微调对话,因此需要用到 ChatGLM3-6B 的 finetune_chatmodel_demo。

多轮对话格式:

[
  {
    "conversations": [
      {
        "role": "system",
        "content": "<system prompt text>"
      },
      {
        "role": "user",
        "content": "<user prompt text>"
      },
      {
        "role": "assistant",
        "content": "<assistant response text>"
      }, 
       // ... Muti Turn
      {
        "role": "user",
        "content": "<user prompt text>"
      },
      {
        "role": "assistant",
        "content": "<assistant response text>"
      }
    ]
  }
  // ...
]
  • 多轮对话格式数据微调原理是在一遍计算中为多轮回复计算 loss
  • system:设定了 AI 的行为和角色,和背景,给出一个对话的大致方向,或者设置对话的语气和风格,以便LLM更好地理解其在对话中的角色。例如,可以把<system prompt text>设置为:“你是一个会计”或“你是一名历史教授”。ChatGLM3-6B的 system 角色为可选角色,但若存在 system 角色,其必须出现在 user 角色之前,且一个完整的对话数据(无论单轮或者多轮对话)只能出现一次 system 角色。
  • user:输入的问题或请求。
  • assistant:是由LLM根据 system 和 user 消息自动生成的答案。在微调数据中即你想要得到的答案。

输入输出格式:

[
  {
    "prompt": "<prompt text>",
    "response": "<response text>"
  }
  // ...
]

作为示例,使用 AdvertiseGen 数据集进行微调实践,从 Google Drive 或者 Tsinghua Cloud 下载并解压 AdvertiseGen 数据集,得到两个json文件train.jsondev.json。任务是根据字段content,生成一段广告词summary。

以下为单个样本格式:

{
"content": "类型#上衣*版型#宽松*版型#显瘦*图案#线条*图案#刺绣*衣样式#针织衫*衣领型#v领",
"summary": "一款温暖柔软又富有弹性的针织衫,不仅可以抵御严寒侵袭,还能更好地进行搭配。v领的设计,能勾勒出迷人的天鹅颈以及衬托出娇小的脸型。宽松又别致的剪裁,能从视觉上显露纤长的下半身,起到显瘦的效果。直筒造型的袖子,修饰出优美的手臂线条,衣身上的方格刺绣,时尚又吸睛。"
 }

接下来,将train.jsondev.json放到 finetune_chatmodel_demo 文件夹下的AdvertiseGen文件夹内,终端输入:

./scripts/format_advertise_gen.py --path "AdvertiseGen/train.json"

得到advertise_gen.jsonl

[
  // ... 
  {
    "prompt": "类型#上衣*版型#宽松*版型#显瘦*图案#线条*图案#刺绣*衣样式#针织衫*衣领型#v领",
    "response": "一款温暖柔软又富有弹性的针织衫,不仅可以抵御严寒侵袭,还能更好地进行搭配。v领的设计,能勾勒出迷人的天鹅颈以及衬托出娇小的脸型。宽松又别致的剪裁,能从视觉上显露纤长的下半身,起到显瘦的效果。直筒造型的袖子,修饰出优美的手臂线条,衣身上的方格刺绣,时尚又吸睛。"
  }
  // ...
]

这样AdvertiseGen 数据集样本就满足了 ChatGLM3-6B 要求的输入输出格式,也可以根据上述多轮对话或输入输出格式准备个性化领域数据来微调模型。

3. 微调模型(Windows)

ChatGLM3-6B提供全量微调和 P-Tuning v2。关于全量微调和 P-Tuning v2的介绍,可以查看 【学习记录】大模型微调方法

在 finetune_chatmodel_demo 文件夹目录下,终端输入以下脚本:

./scripts/finetune_ds.sh  # 输入输出格式全量微调
./scripts/finetune_pt.sh  # 输入输出格式 P-Tuning v2 微调

官方文档建议的参考显存用量如下:

  • P-Tuning V2 PRE_SEQ_LEN=128, DEV_BATCH_SIZE=1, GRAD_ACCUMULARION_STEPS=16, MAX_SEQ_LEN=2048 配置下约需要 21GB 显存。
  • 全量微调时,./scripts/finetune_ds_multiturn.sh 中的配置(MAX_SEQ_LEN=2048, DEV_BATCH_SIZE=16, GRAD_ACCUMULARION_STEPS=1)恰好用满 4 * 80GB 显存。

若尝试后发现显存不足,可以考虑:

  • 尝试降低 DEV_BATCH_SIZE 并提升 GRAD_ACCUMULARION_STEPS
  • 尝试添加 --quantization_bit 8--quantization_bit 4
  • PRE_SEQ_LEN=128, DEV_BATCH_SIZE=1, GRAD_ACCUMULARION_STEPS=16, MAX_SEQ_LEN=1024 配置下,--quantization_bit 8 约需 12GB 显存,--quantization_bit 4 约需 7.6GB 显存。

如果在微调实践时设备显存不足,或者对训练速度或训练效果有其他个性化要求,可以按照建议调整上述.sh脚本文件的参数。

以 finetune_pt.sh 为例,脚本代码如下:

#! /usr/bin/env bash

set -ex

# 调整参数
#=========================
LR=2e-2
PRE_SEQ_LEN=128
NUM_GPUS=1
MAX_SOURCE_LEN=1024
MAX_TARGET_LEN=128
DEV_BATCH_SIZE=1
GRAD_ACCUMULARION_STEPS=32
MAX_STEP=1000
SAVE_INTERVAL=500
#=========================

RUN_NAME=advertise_gen_pt
BASE_MODEL_PATH=THUDM/chatglm3-6b
DATASET_PATH=formatted_data/advertise_gen.jsonl

DATESTR=`date +%Y%m%d-%H%M%S`
OUTPUT_DIR=output/${RUN_NAME}-${DATESTR}-${PRE_SEQ_LEN}-${LR}


mkdir -p $OUTPUT_DIR

torchrun --standalone --nnodes=1 --nproc_per_node=$NUM_GPUS finetune.py \
    --train_format input-output \
    --train_file $DATASET_PATH \
    --preprocessing_num_workers 1 \
    --model_name_or_path $BASE_MODEL_PATH \
    --output_dir $OUTPUT_DIR \
    --max_source_length $MAX_SOURCE_LEN \
    --max_target_length $MAX_TARGET_LEN \
    --per_device_train_batch_size $DEV_BATCH_SIZE \
    --gradient_accumulation_steps $GRAD_ACCUMULARION_STEPS \
    --max_steps $MAX_STEP \
    --logging_steps 1 \
    --save_steps $SAVE_INTERVAL \
    --learning_rate $LR \
    --pre_seq_len $PRE_SEQ_LEN 2>&1 | tee ${OUTPUT_DIR}/train.log

注意

  • 由于windows不支持NCCL backend,因此在微调前需要将accelerate包中的state.py文件中backend='nccl'改为backend='gloo'
  • BASE_MODEL_PATH不要使用绝对路径,最好在同一级文件夹下。
  • MAX_TARGET_LEN并非代表最大输出长度,而是用来截断的。MAX_TARGET_LEN之前的输出结果直接受到微调影响,而 ChatGLM3-6B 本身训练是相对位置编码,有外推性,理论上超过4096也可能生成较为合理的结果。

训练完成后,p-tuning checkpoint 保存至OUTPUT_DIR位置。

100%|□□□□□□□□□□□□□□□□□□□□| 5/5 [3:31:19<00:00, 15.85s/it]
Saving PrefixEncoder
[INFO|configuration_utils.py:458] 2023-12-19 16:24:39,201 >> Configuration saved in xxxxx\config.json
[INFO|configuration_utils.py:364] 2023-12-19 16:24:39,202 >> Configuration saved in xxxxx\generation_config.json
[INFO|modeling_utils.py:1853] 2023-12-19 16:24:39,210 >> Model weights saved in xxxxx\pytorch_model.bin
[INFO|tokenization_utils_base.py:2194] 2023-12-19 16:24:39,211 >> tokenizer config file saved in xxxxx\tokenizer_config.json
[INFO|tokenization_utils_base.py:2201] 2023-12-19 16:24:39,211 >> Special tokens file saved in xxxxx\special_tokens_map.json

4. 微调后模型推理验证

对于输入输出格式的微调,可使用 inference.py 进行基本的推理验证。 finetune_chatmodel_demo 文件夹目录下,终端输入:

python inference.py \
    --pt-checkpoint "path to p-tuning checkpoint" \
    --model THUDM/chatglm3-6b 
python inference.py \
    --tokenizer THUDM/chatglm3-6b \
    --model "path to finetuned model checkpoint" 

"path to p-tuning checkpoint""path to finetuned model checkpoint"即之前设置的OUTPUT_DIR路径。

载入微调后模型checkpoint:

Loading checkpoint shards: 100%|███████████████████████████████████████████████████████████████████████████████| 7/7 [00:07<00:00,  1.21it/s]
 
Prompt: XXX

终端输入Prompt的内容XXX,得到Response。推理验证完成。

  • 38
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
回答: ChatGLM2-6B是一个AI模型,引用提到了对ChatGLM2-6B进行P-tuning微调的过程。微调是指在已有的预训练模型基础上,使用特定的数据集进行进一步的训练,以提高模型在特定任务上的性能。在这个例子中,ChatGLM2-6B通过本地部署和本地微调的方式被成功跑通了。具体来说,本地部署是指将模型部署到本地环境中进行使用,而本地微调是指在本地环境中使用特定的数据集对模型进行微调训练。引用中提到了在Windows系统上跑通了ChatGLM2-6B。引用则提到了进行微调时可以更换模型路径以及注意微调目前只支持单轮对话的回复。总之,ChatGLM2-6B经过微调可以在特定任务上表现更好。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [ChatGLM2-6B! 我跑通啦!本地部署+微调windows系统)](https://blog.csdn.net/m0_54515450/article/details/131617081)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *3* [ChatGLM2-6BChatGLM-6B 模型介绍及训练自己数据集实战](https://blog.csdn.net/dream_home8407/article/details/130099656)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值