一文学会GLM-4-9B-Chat模型Lora微调(一)!

引言

模型微调是一种低成本、高收益的方式,用于提升预训练模型在特定领域的性能和表现。通过让模型学习少量特定领域的知识库数据,并对模型参数进行适当调整,可在不显著增加成本的前提下提升模型在该领域的应用效果。
模型微调的方式有很多种,例如LoRA、P-tuning、adapter-tuning等,每种微调方式都有适用的场景和任务,大家可根据需求和场景自行测试验证(后续会持续更新各种微调技术的核心原理和实现方式),今天我们使用最常用到的LoRA技术对GLM-4-9B-Chat模型进行微调。

数据处理

数据集格式

模型微调的效果与微调时采用的数据质量有很大关系,所以在微调时我们需要先准备一批高质量的领域数据。LoRA微调GLM-4需要“多轮对话格式”的数据集,可以理解人一问一答式的结构,例如:

{
  "messages": 
  [
    {
      "role": "user", 
      "content": "你是谁?"
    }, 
    {
      "role": "assistant", 
      "content": "我是您的AI助手Leo,您可以问我任何关于AI相关的知识!"}
  ]
}

以上的例子中就是一问一答的格式,其中"role":"user"指定了用户的角色、“content”: "你是谁?"指定了用户的相关问题;“role”: "assistant"指定了AI助理的角色,“content”: "我是您的AI助手Leo,您可以问我任何关于AI相关的知识!"制定了AI的回答。
**微调的主要目标就是希望模型能够学会特定领域中的对话风格、专业术语和任务的解决方案。**因此,数据集需要精心设计,否则模型同样会出现幻觉、鲁棒性不够等问题。

数据预处理

这里我们使用常见的excel格式知识库作为源数据为大家演示如何使用代码批量将excel数据转成微调所需的数据,微调GLM-4-9B-Chat时需要准备两份文件:训练数据集"train.jsonl"和评估数据集"dev.jsonl"。首先来处理"train.jsonl":

import json
import pandas as pd


def process_and_transform_file(input_path, output_path):
    try:

        intermediate_data = []
        prompt, response = "", ""

        # 读取excel文件
        df = pd.read_excel(input_path, engine='openpyxl')
        # 遍历读取样本的每行数据
        for row in df.itertuples():
            if row[1] and row[2]:
                prompt, response = row[1].strip(), row[2].strip()
                intermediate_data.append({"prompt": prompt, "response": response})
        with open(output_path, "w", encoding='utf-8') as output_file:
            for entry in intermediate_data:
                transformed_data = {
                    "messages": [
                        {"role": "user", "content": entry["prompt"]},
                        {"role": "assistant", "content": entry["response"]}
                    ]
                }
                output_file.write(json.dumps(transformed_data, ensure_ascii=False) + '\n')
        print(f"转换完成,文件保存至:{output_path}")
    except Exception as e:
        print(f"处理文件时发生错误:{e}")


input_path = "dataset/测试数据_0.1.xlsx"
output_path = "dataset/train.jsonl"
process_and_transform_file(input_path, output_path)

执行完成后将得到类似以下格式的json文件:
在这里插入图片描述
评估数据集"dev.jsonl"文件中的数据是从训练数据集"train.jsonl"中随机采集的样本数据,训练过程中用来评估模型学习的效果,这个可以根据训练数据集数量大小灵活采集,以下是处理"dev.jsonl"的示例代码:

import json
import random
import os


# 1、读取train数据集
# 2、随机100条数据作为dev数据集
# 3、将100条dev数据集保存到dev.jsonl文件中

def load_dataset(file_path):
    """ 加载train.jsonl数据集集 """
    with open(file_path, 'r', encoding='utf-8') as f:
        data = [json.loads(line) for line in f]
    return data


def select_random_samples(data, num_sample=100):
    """ 随机选择样本数据,如果num_sample的数量大于data也仅仅返回data中的全部数据 """
    return random.sample(data, min(num_sample, len(data)))


def save_samples_to_file(output_file_path, samples):
    os.makedirs(os.path.dirname(output_file_path), exist_ok=True)
    with open(output_file_path, 'w', encoding='utf-8') as f:
        for item in samples:
            json.dump(item, f, ensure_ascii=False)
            f.write('\n')


def create_dev_json_from_train_json(input_file_path, output_file_path, num_sample=100):
    data = load_dataset(input_file_path)
    dev_data = select_random_samples(data, num_sample)
    save_samples_to_file(output_file_path, dev_data)
    print(f"开发数据集已创建完成,保存至:{output_file_path}")


if __name__ == '__main__':
    train_file_path = 'dataset/train.jsonl'
    dev_file_path = 'dataset/dev.jsonl'
    num_sample = 100

    create_dev_json_from_train_json(train_file_path, dev_file_path, num_sample)

执行完成后即可得到"dev.jsonl"文件,至此数据准备和处理阶段就完成了!大家自行根据数据格式修改数据处理的代码,但是要注意不能改变结构,如果使用其他三方微调框架进行模型微调可基于框架约定即可。

环境搭建

基础环境准备

操作系统的基础环境要求跟部署模型要求一致,可沿用部署模型时的环境准备,也可参考上一篇文章:超详细GLM-4-chat模型部署;当然了,如果仅仅是为了学习和验证,也可以直接租赁三方算力平台的机器,会相对简单一些无需再安装和配置CUDA、Python、Pytorch等基础依赖环境,这里我直接租用一台给大家做演示:
在这里插入图片描述
直接选择好需要用到的PyTorch、Python、CUDA对应版本镜像即可,不需要自己再折腾一遍了还是比较方便的~

模型环境搭建

准备好基础环境好我们就可以开始搭建模型环境了, 基本上就比较简单了,按照以下步骤执行即可:

  • 升级pip版本,确保使用的pip版本是最新的:

    python -m pip install --upgrade pip
    
  • 更换pypi源,推荐使用清华大学的TUNA镜像源,在国内环境下载依赖会比较快,可以使用以下命令:

    pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
    
  • 安装必要的依赖包,主要安装微调时用到的transformers和peft库,如果需要实时下载模型镜像也可以安装ModelScope的依赖,可以使用以下命令:

    pip install modelscope==1.9.5
    pip install "transformers>=4.40.0"
    pip install streamlit==1.24.0
    pip install sentencepiece==0.1.99
    pip install accelerate==0.29.3
    pip install datasets==2.13.0
    pip install peft==0.10.0
    pip install tiktoken==0.7.0
    

依赖下载完成后整个环境准备就完成了,接下来还是需要准备"GLM-4-9B-Chat"模型文件和GLM-4的代码仓库;如果需要使用ModelScope库进行下载可以使用以下代码:

import torch
from modelscope import snapshot_download, AutoModel, AutoTokenizer
import os
model_dir = snapshot_download('ZhipuAI/glm-4-9b-chat', cache_dir='/root/workspace', revision='master')

将该python文件放在服务器执行即可,其中cache_dir需要改为模型下载到本地的目录,整个下载过程大约30分钟左右;
下载GLM-4的代码仓库可使用以下命令:

git clone https://github.com/THUDM/GLM-4

模型文件和源码仓库下载完成整个环境搭建就完成了,这就可以开始做模型微调了!

模型微调

Lora参数配置

智谱为我们提供了LoRA、P-Tuning V2两种模型微调的相关代码和配置文件,我们不需要再开发一套模型微调的代码;
● 首先找到模型微调的代码文件:finetune_demo文件夹,执行以下命令:

# 进入项目目录
cd GLM-4/
# 进入模型微调代码目录
cd finetune_demo/

文件夹目录如下:在这里插入图片描述
其中configs目录是用于存放模型微调需要用到的配置文件,该文件夹包含如下文件:
在这里插入图片描述
LoRA微调时我们只需修改lora.yaml中的配置即可。
● 修改lora.yaml文件,该文件主要内容解释如下:

data_config 部分
  train_file: 训练数据集的文件路径。
  val_file: 验证数据集的文件路径。
  test_file: 测试数据集的文件路径。
  num_proc: 在加载数据时使用的进程数量。

max_input_length: 输入序列的最大长度。
max_output_length: 输出序列的最大长度。

training_args 部分
  output_dir: 用于保存模型和其他输出的目录。
  max_steps: 训练的最大步数。
  learning_rate: 学习率
  per_device_train_batch_size: 每个设备(如 GPU)的训练批次大小。
  dataloader_num_workers: 加载数据时使用的工作线程数量。
  remove_unused_columns: 是否移除数据中未使用的列。
  save_strategy: 模型保存策略(例如,每隔多少步保存一次)。
  save_steps: 每隔多少步保存一次模型。
  log_level: 日志级别(如 info)。
  logging_strategy: 日志记录策略。
  logging_steps: 每隔多少步记录一次日志。
  per_device_eval_batch_size: 每个设备的评估批次大小。
  evaluation_strategy: 评估策略(例如,每隔多少步进行一次评估)。
  eval_steps: 每隔多少步进行一次评估。
  predict_with_generate: 是否使用生成模式进行预测。
  generation_config 部分
    max_new_tokens: 生成的最大新 token 数量。

peft_config 部分
  peft_type: 使用的参数有效调整类型 (支持 LORA 和 PREFIX_TUNING)。
  task_type: 任务类型,这里是因果语言模型 (不要改动)。
  r: LoRA 的秩。
  lora_alpha: LoRA 的缩放因子。
  lora_dropout: 在 LoRA 层使用的 dropout 概率。

这里我们需要关注几个重要的点:
● data_config 部分:
○ 要把我们在上面生成的数据集(train.jsonl、dev.jsonl)上传到configs目录,如果放在其他目录中请修改对应的文件位置;
● training_args部分
○ output_dir:这个主要是用于指定模型微调完之后输出新模型存放的位置,可以不改如果有需要指定其他位置自行调整即可;
○ max_steps:这个参数的设置取决于多个因素,包括但不限于模型复杂度、训练数据集的复杂度、训练资源等,一般可参考公式:max_steps = (总训练样本数 / batch_size) * num_epochs;
○ learning_rate:学习率也是非常重要的参数,一般是0-1之间;这个值不能太大也不能太小,需要根据模型和数据集复杂度来调控,后面其他章节会详细解释;
● peft_config 部分
○ r:这个是最主要的参数,该参数决定模型降级的矩阵大小,一般为8的倍数;同样该参数没有绝对值,需要根据数据集复杂度和模型复杂度来测试效果,可以从16开始;
○ lora_alpha:LoRA的缩放因子,该参数是在前向传播过程中将LoRA参数以一定的缩放比例应用于模型之中,可以设置为r的倍数或者r的半数,这个同样需要自行调优,后面会详细介绍;
以上是我们在用LoRA微调时需要关注的几个关键参数,对于LoRA微调的细节和参数设置细节这里不做介绍,后面会有专门文章来介绍,感兴趣的同学可以持续关注~
以下为修改后的参数:

data_config:
  train_file: train.jsonl
  val_file: dev.jsonl
  test_file: dev.jsonl
  num_proc: 1

combine: True
max_input_length: 512
max_output_length: 512

training_args:
  # see `transformers.Seq2SeqTrainingArguments`
  output_dir: ./output
  max_steps: 2500
  # needed to be fit for the dataset
  learning_rate: 1e-4
  # settings for data loading
  per_device_train_batch_size: 1
  dataloader_num_workers: 16
  remove_unused_columns: false
  # settings for saving checkpoints
  save_strategy: steps
  save_steps: 500
  # settings for logging
  log_level: info
  logging_strategy: steps
  logging_steps: 10
  # settings for evaluation
  per_device_eval_batch_size: 4
  eval_strategy: steps
  eval_steps: 500
  # settings for optimizer
  # adam_epsilon: 1e-6
  # uncomment the following line to detect nan or inf values
  # debug: underflow_overflow
  predict_with_generate: true
  # see `transformers.GenerationConfig`
  generation_config:
    max_new_tokens: 512
  # set your absolute deepspeed path here
  # deepspeed: configs/ds_zero_3.json
peft_config:
  peft_type: LORA
  task_type: CAUSAL_LM
  r: 16
  lora_alpha: 32
  lora_dropout: 0.1
  target_modules: ["query_key_value"]

开始模型训练

修改完lora.yaml的配置文件后就可以开始微调模型了,在开始执行微调命令之前需要先执行以下命令安装相关依赖:

pip install -r requirements.txt

出现以下内容则依赖安装成功:
在这里插入图片描述
这就开始训练模型了,训练模型可执行以下命令:

python finetune.py  data/AdvertiseGen/  /root/shared-storage/glm-4  configs/lora.yaml

其中finetune.py为智谱开源的模型微调代码文件、data/AdvertiseGen/为数据所在的位置、/root/workspace/GLM-4-9B-Chat 为基础模型所在的位置、configs/lora.yaml是我们修改好的lora.yaml配置文件,这些文件位置大家都可根据需要自行调整!
在这里插入图片描述
执行命令时如果出现以上错误说明缺少相关依赖,只需要执行命令安装一下即可:

pip install typer

安装完成后再次执行模型微调命令即可开始模型微调,出现以下输出则说明已经在开始训练了:
在这里插入图片描述
这里我们需要关注**'loss’的值,这个值是“损失函数”,可以理解为结果与理想数据之间的差距;这个值越小越好,如果过大则表示欠拟合、先下降后上升表示过拟合**,这个值的变化也是跟很多因素有关系;通过该值可以来发现需要调整的方向,比如模型过于复杂、数据集过于复杂等等,后续也会有专题文章来解释。
接下来就等待模型学习完成就好了~

后面会介绍微调完之后怎么验证模型效果、如何合并模型、如何使用微调后的模型进行推理!感兴趣的同学可以持续关注~

`glm4-9b-1m` 和 `glm4-9b-chat` 都是由 CSDN 开发的 AI 模型,它们都是基于大语言模型构建的工具,旨在提供智能问答、代码生成等服务。然而,它们之间存在一些关键的区别: ### `glm4-9b-1m` - **目的定位**:`glm4-9b-1m` 通常指代一个较为通用的语言模型,其设计目标可能是处理多种任务,包括但不限于文本理解、自然语言生成、翻译等多个领域。 ### `glm4-9b-chat` - **特定功能**:`glm4-9b-chat` 更专注于聊天交互场景。这个名称暗示了它特别优化为了提供流畅的人机对话体验,能够更好地理解上下文、保持对话连贯,并能快速响应用户的提问或指令。 ### 区别 1. **应用场景**:`glm4-9b-1m` 可能更适用于需要广泛能力支持的任务,如多模态理解和生成、文本到文本转换等多种应用;而 `glm4-9b-chat` 则专门针对实时交互需求,尤其适合于需要快速响应和高互动性的环境,比如客服机器人、即时通讯助手等。 2. **技术细节**:尽管具体的内部架构细节可能不对外公开,但可以合理推测,`glm4-9b-chat` 的训练数据集可能包含了大量的对话历史记录,以及更多关于对话管理的知识,这有助于提升模型在连续对话过程中的性能。此外,它可能还经过了特定的优化,使得在对话过程中上下文保持一致性和流畅性成为可能。 3. **性能侧重点**:考虑到 `glm4-9b-chat` 的命名,我们可以假设该模型在处理连续对话任务上有着更高的效率和质量保证。这可能意味着在对话的持续性、话题转移的平滑过渡等方面有更强的表现。 ### 相关问题: 1. 这两个模型在训练数据集的选择上有何差异? 2. 对于需要大量交互式对话的应用来说,如何评估并选择最适合的模型? 3. 如果希望开发一款虚拟助理软件,应该考虑哪些因素来决定采用 `glm4-9b-1m` 还是 `glm4-9b-chat`?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值