用通俗易懂方式讲解:大模型 ChatGLM3 进行 LORA 高效微调全流程

本章我们以 ChatGLM3 为例,对 ChatGLM3-6B 模型进行 LORA 高效微调。

本章尽量用最简洁的语言及方法对大模型进行微调实际操练。

什么是 LORA 高效微调:

lora微调原理论文:

https://arxiv.org/abs/2106.09685

图片

用最简单的语言理解LORA高效微调:

假设我们有一个非常厉害、已经学会很多知识的“专家”(即预训练的大语言模型)。现在我们想让这位专家更好地帮助我们完成一项具体的任务,比如回答医学的专业问题或者回答其它专业的问题。常规的做法是,我们需要给专家把专业知识从头到尾培训一番,让他专门学习这项任务的相关知识。但这样做耗时耗力,而且可能会让专家忘记一些通用的语言常识。

LORA高效微调提供了一种聪明的方法,让我们不用对专家做全面的重新培训,就能让他更好地适应新任务。它是怎么做到的呢?

首先,我们给这位专家配备两本“秘籍”:一本是简化版的“知识点手册”(对应低秩矩阵A),另一本是对应的“解码手册”(对应低秩矩阵B)。这两本手册都很薄,只记录了与新任务最相关的少量关键知识。

然后,我们只教专家学习这两本秘籍的内容,而不去动他原来掌握的那些很多的的通用语言知识。也就是说,我们在微调时,只更新这两本秘籍里的内容,而不去碰专家脑子里其他成千上万的知识点。

最后,当专家要解决新任务时,他会先参考简化版的“知识点手册”,找到与任务相关的关键知识,然后用“解码手册”把这些知识转化为具体的行动指令。这样,专家就可以结合原有的语言知识和新学的相关专业知识,更好地完成新任务。

技术交流&资料

技术要学会分享、交流,不建议闭门造车。一个人可以走的很快、一堆人可以走的更远。

成立了大模型算法面试和技术交流群,相关资料、技术交流&答疑,均可加我们的交流群获取,群友已超过2000人,添加时最好的备注方式为:来源+兴趣方向,方便找到志同道合的朋友。

方式①、微信搜索公众号:机器学习社区,后台回复:加群
方式②、添加微信号:mlc2040,备注:来自CSDN + 技术交流

本次ChatGLM3-6B模型微调硬件及软件配置

操作系统:ubuntu22.04

CPU: 12核

内存:90G (GPU模式下,不会需要太多内存,16G足够)

GPU: RTX 4090(24GB) * 1

图片

调试及运行环境:Jupyter Notebook

微调步骤如下

1. ChatGLM3及ChatGLM3-6B模型下载

# 下载ChatGLM3
!git clone https://github.com/THUDM/ChatGLM3

# 依赖下载
!cd ChatGLM3 && pip install -r requirements.txt

# modelscope API下载
!pip install modelscope
# 模型下载
from modelscope import snapshot_download
model_dir = snapshot_download("ZhipuAI/chatglm3-6b", revision = "v1.0.0")

2. 把ChatGLM3-6B模型移动到ChatGLM3文件夹

我们使用modelscope下载的数据集模型文件都在缓存文件夹中,为了方便读取和微调,我们把它移动到ChatGLM3文件夹中。

# 模型文件所在路径
# /root/.cache/modelscope/hub/ZhipuAI/chatglm3-6b
# 复制到ChatGLM3文件夹
!cp -r  /root/.cache/modelscope/hub/ZhipuAI/chatglm3-6b /ChatGLM3

注意:

此后所有的文件操作都在ChatGLM3文件夹或子文件夹中。

3. 准备微调数据集

微调数据集必须包括训练数据集、验证数据集;测试数据集可以和验证数据集相同。

因本次训练数据集较少,只做操作展示,故把训练数据集、验证数据集、测试数据集都设置为一样。如果您用于商业数据微调,请自行标注好测试数据集和验证数据集。

训练数据集:(文件名:train.json)

{"content": "你是谁", "summary": "我是写代码的中年人的助手!有什么需要帮助你的吗?"}
{"content": "你好", "summary": "你好,我是写代码的中年人的助手!有什么需要帮助你的吗?"}
{"content": "写代码的中年人", "summary": "一位写代码的中年人正端坐在电脑前。他戴着一副黑框眼镜,镜片后的眼神专注而深邃,犹如一盏明亮的探照灯,照亮了面前复杂繁密的代码世界。他的手指熟练地在键盘上跳跃,宛如一位经验丰富的钢琴家在琴键上演绎无声的交响乐章。岁月在他的额头上刻下了几道皱纹,那是时间赋予他的智慧印记;而他始终保持着对编程技术的热情和执着追求,与时俱进地掌握着最新的编程语言和技术框架。"}
{"content": "你的#公众号", "summary": "请微信搜索写代码的中年人!"}

验证数据集:(文件名:dev.json)

{"content": "你是谁", "summary": "我是写代码的中年人的助手!有什么需要帮助你的吗?"}
{"content": "你好", "summary": "你好,我是写代码的中年人的助手!有什么需要帮助你的吗?"}
{"content": "写代码的中年人", "summary": "一位写代码的中年人正端坐在电脑前。他戴着一副黑框眼镜,镜片后的眼神专注而深邃,犹如一盏明亮的探照灯,照亮了面前复杂繁密的代码世界。他的手指熟练地在键盘上跳跃,宛如一位经验丰富的钢琴家在琴键上演绎无声的交响乐章。岁月在他的额头上刻下了几道皱纹,那是时间赋予他的智慧印记;而他始终保持着对编程技术的热情和执着追求,与时俱进地掌握着最新的编程语言和技术框架。"}
{"content": "你的#公众号", "summary": "请微信搜索写代码的中年人!"}

我们把这两个文集放在如下路径中,文件夹名根据自己喜好定义。

ChatGLM3/finetune_demo/data/ColinData/

4. 微调依赖安装

进入finetune_demo文件夹,执行如下命令安装依赖:

# 安装依赖
!pip install -r requirements.txt

5. 切割数据集(格式转换)

执行下面的代码,对我们准备好的数据集进行格式化。

import json
from typing import Union
from pathlib import Path


def _resolve_path(path: Union[str, Path]) -> Path:
    return Path(path).expanduser().resolve()


def _mkdir(dir_name: Union[str, Path]):
    dir_name = _resolve_path(dir_name)
    if not dir_name.is_dir():
        dir_name.mkdir(parents=True, exist_ok=False)


def convert_adgen(data_dir: Union[str, Path], save_dir: Union[str, Path]):
    def _convert(in_file: Path, out_file: Path):
        _mkdir(out_file.parent)
        with open(in_file, encoding='utf-8') as fin:
            with open(out_file, 'wt', encoding='utf-8') as fout:
                for line in fin:
                    dct = json.loads(line)
                    sample = {'conversations': [{'role': 'user', 'content': dct['content']},
                                                {'role': 'assistant', 'content': dct['summary']}]}
                    fout.write(json.dumps(sample, ensure_ascii=False) + '\n')

    data_dir = _resolve_path(data_dir)
    save_dir = _resolve_path(save_dir)

    train_file = data_dir / 'train.json'
    if train_file.is_file():
        out_file = save_dir / train_file.relative_to(data_dir)
        _convert(train_file, out_file)

    dev_file = data_dir / 'dev.json'
    if dev_file.is_file():
        out_file = save_dir / dev_file.relative_to(data_dir)
        _convert(dev_file, out_file)

# 其它代码不变,只有此处可以改为自己定义的文件路径
convert_adgen('data/ColinData', 'data/ColinData_fix')
# 此处我们把转换后的数据集放在ColinData_fix文件中。

执行上面代码后,我们在ColinData_fix文件夹得到两个文件,即转后格式的训练集和测试集(train.json和dev.json),格式如下:

{"conversations": [{"role": "user", "content": "你是谁"}, {"role": "assistant", "content": "我是写代码的中年人的助手!有什么需要帮助你的吗?"}]}
{"conversations": [{"role": "user", "content": "你好"}, {"role": "assistant", "content": "你好,我是写代码的中年人的助手!有什么需要帮助你的吗?"}]}
{"conversations": [{"role": "user", "content": "写代码的中年人"}, {"role": "assistant", "content": "一位写代码的中年人正端坐在电脑前。他戴着一副黑框眼镜,镜片后的眼神专注而深邃,犹如一盏明亮的探照灯,照亮了面前复杂繁密的代码世界。他的手指熟练地在键盘上跳跃,宛如一位经验丰富的钢琴家在琴键上演绎无声的交响乐章。岁月在他的额头上刻下了几道皱纹,那是时间赋予他的智慧印记;而他始终保持着对编程技术的热情和执着追求,与时俱进地掌握着最新的编程语言和技术框架。"}]}
{"conversations": [{"role": "user", "content": "你的#公众号"}, {"role": "assistant", "content": "请微信搜索写代码的中年人!"}]}

6. 进行微调

在微调之前我们需要对配置文件进行配置,打开配置文件,红框中是本次微调需要的配置信息。

配置文件路径:

ChatGLM3/finetune_demo/configs/lora.yaml

图片

在finetune_demo文件夹中,官方已经给我们提供了微调文件:

finetune_hf.py,

因本次我们只有4条验证数据集,我们需要修改finetune_hf.py文件,如下图:

图片

执行微调命令:

# 训练预计花费40分钟左右
!CUDA_VISIBLE_DEVICES=0 /root/miniconda3/bin/python3 finetune_hf.py  data/ColinData_fix  /ChatGLM3/chatglm3-6b  /configs/lora.yaml

注意:

CUDA_VISIBLE_DEVICES:参数为我们使用哪张GPU进行训练,可使用nvidia-smi命令来查看系统的GPU信息,及GPU的序号。这里使用编号为0的GPU,也就是第一张GPU。

# 微调输出
Loading checkpoint shards:   0%|                          | 0/7 [00:00<?, ?it/s]/root/miniconda3/lib/python3.10/site-packages/torch/_utils.py:831: UserWarning: TypedStorage is deprecated. It will be removed in the future and UntypedStorage will be the only storage class. This should only matter to you if you are using storages directly.  To access UntypedStorage directly, use tensor.untyped_storage() instead of tensor.storage()
  return self.fget.__get__(instance, owner)()
Loading checkpoint shards: 100%|██████████████████| 7/7 [00:03<00:00,  2.31it/s]
trainable params: 1,949,696 || all params: 6,245,533,696 || trainable%: 0.031217444255383614
--> Model

--> model has 1.949696M params

# 中间输出省略

{'eval_rouge-1': 100.0, 'eval_rouge-2': 100.0, 'eval_rouge-l': 100.0, 'eval_bleu-4': 1.0, 'eval_runtime': 4.0702, 'eval_samples_per_second': 0.737, 'eval_steps_per_second': 0.246, 'epoch': 2000.0}
100%|███████████████████████████████████████| 2000/2000 [39:26<00:00,  1.11s/it]
100%|█████████████████████████████████████████████| 1/1 [00:00<00:00, 48.61it/s]
                                                                                Saving model checkpoint to ./output/checkpoint-2000
/root/miniconda3/lib/python3.10/site-packages/peft/utils/save_and_load.py:154: UserWarning: Could not find a config file in /root/autodl-tmp/colin/ChatGLM3/chatglm3-6b - will assume that the vocabulary was not modified.
  warnings.warn(


Training completed. Do not forget to share your model on huggingface.co/models =)


{'train_runtime': 2366.7504, 'train_samples_per_second': 3.38, 'train_steps_per_second': 0.845, 'train_loss': 0.10584733390808106, 'epoch': 2000.0}
100%|███████████████████████████████████████| 2000/2000 [39:26<00:00,  1.18s/it]
***** Running Prediction *****
  Num examples = 4
  Batch size = 16
100%|█████████████████████████████████████████████| 1/1 [00:00<00:00, 42.20it/s]

微调完成后会在此路径生成checkpoint-2000微调文件:

ChatGLM3/finetune_demo/output/checkpoint-2000

图片

7. 使用微调后的模型进行推理

我们使用官方提供的inference_hf.py文件进行推理,需要传入微调后的模型路径和提示语。

# 提示语 你是 进行推理
!CUDA_VISIBLE_DEVICES=0  /root/miniconda3/bin/python3 inference_hf.py output/checkpoint-2000/ --prompt "你是?"
# 输出

Loading checkpoint shards:   0%|                          | 0/7 [00:00<?, ?it/s]/root/miniconda3/lib/python3.10/site-packages/torch/_utils.py:831: UserWarning: TypedStorage is deprecated. It will be removed in the future and UntypedStorage will be the only storage class. This should only matter to you if you are using storages directly.  To access UntypedStorage directly, use tensor.untyped_storage() instead of tensor.storage()
  return self.fget.__get__(instance, owner)()
Loading checkpoint shards: 100%|██████████████████| 7/7 [00:03<00:00,  2.02it/s]
我是写代码的中年人的助手!有什么需要帮助你的吗?
# 提示语  进行推理
!CUDA_VISIBLE_DEVICES=0  /root/miniconda3/bin/python3 inference_hf.py output/checkpoint-2000/ --prompt "写代码的中年人"
# 输出

Loading checkpoint shards:   0%|                          | 0/7 [00:00<?, ?it/s]/root/miniconda3/lib/python3.10/site-packages/torch/_utils.py:831: UserWarning: TypedStorage is deprecated. It will be removed in the future and UntypedStorage will be the only storage class. This should only matter to you if you are using storages directly.  To access UntypedStorage directly, use tensor.untyped_storage() instead of tensor.storage()
  return self.fget.__get__(instance, owner)()
Loading checkpoint shards: 100%|██████████████████| 7/7 [00:03<00:00,  1.93it/s]
一位写代码的中年人正端坐在电脑前。他戴着一副黑框眼镜,镜片后的眼神专注而深邃,犹如一盏明亮的探照灯,照亮了面前复杂繁密的代码世界。他的手指熟练地在键盘上跳跃,宛如一位经验丰富的钢琴家在琴键上演绎无声的交响乐章。岁月在他的额头上刻下了几道皱纹,那是时间赋予他的智慧印记;而他始终保持着对编程技术的热情和执着追求,与时俱进地掌握着最新的编程语言和技术框架。

更多微调信息请参考官方文档:
https://github.com/THUDM/ChatGLM3

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/755506.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

TCP/IP模型原理(理论)

TCP/IP模型 1. 网络模型简介2. 应用层2.1 URL2.1.1 urlencode和urldecode 2.2 HTTP协议2.2.1 HTTP协议格式2.2.2 HTTP问题2.2.3 HTTPS 3 传输层3.1 端口号3.2 udp3.2.1 udp协议帧格式3.2.2 udp特点3.2.3 udp缓冲区3.2.4 注意 3.3 tcp协议3.3.1 tcp协议段格式3.3.2 确认应答机制…

UE4_材质_水体的反射与折射制作_Ben教程

在这个教程中&#xff0c;将制作水的反射和折射&#xff0c;上个教程&#xff0c;我们主要讲了制作水涟漪&#xff08;水面波纹&#xff09;和水滴法线混合&#xff0c;水深计算&#xff0c;我们首先要谈的是反射和产生折射的问题。我们将所有从干扰从场景中分离出去&#xff0…

vue3 前端 去循环一个接口获取结果

有的时候 在我们开发过程中我i们会出现一个问题 就是一个后端的接口 哦我们需要调用多次才会出现结果 我们就需要连续掉用 有时候为了避免后端的压力的太大 我总结了一下前端的写法 1.有次数限制的 const getPayData async (orderId) > {const orderResult await ind…

MacBook 中 Java使用testcontainers报错

环境 MacBook 问题 Java代码中使用testcontainers启动报错 ERROR org.testcontainers.dockerclient.DockerClientProviderStrategy - Could not find a valid Docker environment. Please check configuration. Attempted configurations were:UnixSocketClientProviderStr…

鸿蒙NEXT

[中国&#xff0c;东莞&#xff0c;2024年6月24日] 华为开发者大会&#xff08;HDC&#xff09;正式开幕&#xff0c;带来全新的 HarmonyOS NEXT、盘古大模型5.0等最创新成果&#xff0c;持续为消费者和开发者带来创新体验。 HarmonyOS NEXT 鸿蒙生态 星河璀璨 鸿蒙生态设备数…

亨廷顿(Huntington)方法-名额分配

前言 20世纪初&#xff0c;美国人口普查局局长约瑟夫A亨廷顿&#xff08;Joseph A. Hill&#xff09;和数学家爱德华V亨廷顿&#xff08;Edward V. Huntington&#xff09;在研究议会议席分配问题时&#xff0c;提出了一种基于数学原理的算法。该算法通过计算每个州的人口比例&…

【数组】- 螺旋矩阵 II

1. 对应力扣题目连接 螺旋矩阵 II 题目简述&#xff1a; 给你一个正整数 n &#xff0c;生成一个包含 1 到 n2 所有元素&#xff0c;且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。如图&#xff1a; 2. 实现案例代码 public class SpiralMatrix {public static…

重磅更新-UniApp自定义字体可视化设计

重磅更新-UniApp自定义字体可视化设计。 DIY可视化为了适配不同APP需要&#xff0c;支持用户自定义字体&#xff0c;自定义字体后&#xff0c;设计出来的界面更多样化&#xff0c;不再是单一字体效果。用户可以使用第三方字体加入设计&#xff0c;在设计的时候选择上自己的字体…

MyBatis第一节

目录 1. 简介2. 配置3. doing3.1 创建一个表3.2 打开IDEA&#xff0c;创建一个maven项目3.3 导入依赖的jar包3.4 创建entity3.5 编写mapper映射文件(编写SQL)3.6 编写主配置文件3.7 编写接口3.8 测试 参考链接 1. 简介 它是一款半自动的ORM持久层框架&#xff0c;具有较高的SQ…

【技术指南】稳压器(电压调节器):原理、类型及其实际用用案例

电压调节器&#xff08;稳压器&#xff09;是一种电子器件或电路&#xff0c;用于控制电路中的电压水平&#xff0c;以确保在电源电压波动或负载变化时&#xff0c;输出电压能够保持在设定的稳定水平。它们通常用于各种电子设备和电源系统中&#xff0c;以提供稳定的电压供应。…

AI绘画 Stable Diffusion【特效文字】:火焰特效艺术字,轻松搞定特效生成!

大家好&#xff0c;我是画画的小强 今天我们继续艺术字系列的分享&#xff0c;艺术字的玩法很多&#xff0c;今天给大家带来的是火焰特效艺术字的制作。我们先来看火焰特效艺术字的效果图。 一. 火焰特效文字的制作方法 【第一步】&#xff1a;制作底图 这里制作底图使用白底…

HarmonyOS Next开发学习手册——通过startAbilityByType拉起垂类应用

使用场景 开发者可通过特定的业务类型如导航、金融等&#xff0c;调用startAbilityByType接口拉起对应的垂域面板&#xff0c;该面板将展示目标方接入的垂域应用&#xff0c;由用户选择打开指定应用以实现相应的垂类意图。垂域面板为调用方提供统一的安全、可信的目标方应用&a…

数据结构与算法笔记:高级篇 - 搜索:如何用 A* 搜索算法实现游戏中的寻路功能?

概述 魔兽世界、仙剑奇侠传这类 MMRPG 游戏&#xff0c;不知道你玩过没有&#xff1f;在这些游戏中&#xff0c;有一个非常重要的功能&#xff0c;那就是任务角色自动寻路。当任务处于游戏地图中的某个位置时&#xff0c;我们用鼠标点击另外一个相对较远的位置&#xff0c;任务…

Flutter循序渐进==>Dart之类型、控制流和循环

导言 磨刀不误砍柴工&#xff0c;想搞好Flutter&#xff0c;先学好Flutter&#xff0c;还是本着我学Python的方法&#xff0c;先从数据类型、控制流和循环开始&#xff0c;这是每一种编程语言必用的。编程语言是相通的&#xff0c;基本精通一种后&#xff0c;学其它的就变得很…

网络配置(IP、NETMASK、GATEWAY、DNS、DHCP) <持续更新中>

参考&#xff1a; 初学Linux之网络配置(IP、NETMASK、GATEWAY、DNS、DHCP)-CSDN博客【学习笔记】网关 & 路由_网关和路由-CSDN博客【学习笔记】计算机网络 IP地址与MAC地址_根据mac分配ip-CSDN博客【学习笔记】TCP 和 UDP 协议_tcp 发送 syn 应答没有syn ack-CSDN博客 一…

Kafka 位移

Consumer位移管理机制 将Consumer的位移数据作为一条条普通的Kafka消息&#xff0c;提交到__consumer_offsets中。可以这么说&#xff0c;__consumer_offsets的主要作用是保存Kafka消费者的位移信息。使用Kafka主题来保存位移。 消息格式 位移主题就是普通的Kafka主题。也是…

计算机组成原理:海明校验

在上图中&#xff0c;对绿色的7比特数据进行海明校验&#xff0c;需要添加紫色的4比特校验位&#xff0c;总共是蓝色的11比特。紫色的校验位pi分布于蓝色的hi的1, 2, 4, 8, 16, 32, 64位&#xff0c;是2i-1位。绿色的数据位bi分布于剩下的位。 在下图中&#xff0c;b1位于h3&a…

高频面试题基本总结回顾2(含笔试高频算法整理)

干货分享&#xff0c;感谢您的阅读&#xff01; &#xff08;暂存篇---后续会删除&#xff0c;完整版和持续更新见高频面试题基本总结回顾&#xff08;含笔试高频算法整理&#xff09;&#xff09; 备注&#xff1a;引用请标注出处&#xff0c;同时存在的问题请在相关博客留言…

kubernetes给指定用户分配调用k8s的api权限

文章目录 概要利用RBAC添加角色权限使用shell命令创建角色权限使用配置文件创建角色权限 调用k8s的api获取k8s账户的token 小结 概要 使用kubernetes部署项目时&#xff0c;有些特殊场景&#xff0c;我们需要在自己创建的pod里面调用k8s的api来管理k8s&#xff0c;但是需要使用…

论文笔记:Spatial-Temporal Interval Aware Sequential POI Recommendation

ICDE 2022 1 intro 1.1 背景 空间&#xff08;Spatial&#xff09;和时间&#xff08;Temporal&#xff09;信息是序列 POI 推荐中两个重要且相辅相成的因素。 空间因素&#xff08;如地理距离间隔&#xff09;可以在用户的历史轨迹呈现空间分簇现象时&#xff0c;细粒度刻画…