【深度学习】微调Qwen1.8B

news2024/11/13 9:28:49

1.前言 

        使用地址数据微调Qwen1.8B。Qwen提供了预构建的Docker镜像,在使用时获取镜像只需安装驱动、下载模型文件即可启动Demo、部署OpenAI API以及进行微调。

        github地址:GitHub - QwenLM/Qwen: The official repo of Qwen (通义千问) chat & pretrained large language model proposed by Alibaba Cloud.​​​​​​​

        镜像地址:https://hub.docker.com/r/qwenllm/qwen/tags

        获取方式:docker pull qwenllm/qwen:cu117

 2.微调过程

        Qwen的介绍中给出了详细的微调教程。可访问千问github中的微调章节查看。如果使用预先准备的docker,微调则更为方便。

2.1 准备镜像

        需要注意的是:在官方提供的docker镜像中,运行docker run 镜像成为容器后,会启动镜像中的python服务。Dockerfile中最后一行命令为"CMD ["python3" "web_demo.py" "--server-port" "80"]。我们在使用容器微调时,不需要让容器中开启服务,所以需要以官方提供的镜像为基础,再做一个镜像。 Dockerfile内容如下。

FROM qwenllm/qwen:cu117

# CMD 设置为一个空命令,这样可以在容器启动时不执行任何操作
CMD ["/bin/sh", "-c", "tail -f /dev/null"]
#创建镜像
docker build -t qwenllm/qwen:cu117_V1 .

2.2 准备数据

        首先,需要准备训练数据。需要将所有样本放到一个列表中并存入json文件中。每个样本对应一个字典,包含id和conversation,其中后者为一个列表。示例如下所示:

[
  {
    "id": "identity_0",
    "conversations": [
      {
        "from": "user",
        "value": "你好"
      },
      {
        "from": "assistant",
        "value": "我是一个语言模型,我叫通义千问。"
      }
    ]
  }
]

本次微调的训练为指令微调,数据示例如下:

[
    {
        "id": "identity_0",
        "conversations": [
            {
                "from": "user",
                "value": "识别以下句子中的地址信息,并按照{address:['地址']}的格式返回。如果没有地址,返回{address:[]}。句子为:在一本关于人文的杂志中,我们发现了一篇介绍北京市海淀区科学院南路76号社区服务中心一层的文章,文章深入探讨了该地点的人文历史背景以及其对于当地居民的影响。"
            },
            {
                "from": "assistant",
                "value": "{\"address\":\"北京市海淀区科学院南路76号社区服务中心一层\"}"
            }
        ]
    },
    {
        "id": "identity_1",
        "conversations": [
            {
                "from": "user",
                "value": "识别以下句子中的地址信息,并按照{address:['地址']}的格式返回。如果没有地址,返回{address:[]}。句子为:近日,位于北京市房山区政通路13号的某儿童教育机构因出色的育儿理念和创新教学方法引起了广泛关注。"
            },
            {
                "from": "assistant",
                "value": "{\"address\":\"北京市房山区政通路13号\"}"
            }
        ]
    },
    {
        "id": "identity_2",
        "conversations": [
            {
                "from": "user",
                "value": "识别以下句子中的地址信息,并按照{address:['地址']}的格式返回。如果没有地址,返回{address:[]}。句子为:在军事领域中,位于朝阳区惠民园4号楼底商的某单位,一直致力于各种研究和发展工作,以保障国家安全和稳定。"
            },
            {
                "from": "assistant",
                "value": "{\"address\":\"朝阳区惠民园4号楼底商\"}"
            }
        ]
    }
]

2.3 微调

2.3.1 微调方法1

        我们借助Qwen给出的docker进行微调。图为使用docker进行微调的示例。

IMAGE_NAME=qwenllm/qwen:cu117
CHECKPOINT_PATH='/ssd/dongzhenheng/LLM/Qwen-1_8B-Chat'               # 下载的模型和代码路径
#CHECKPOINT_PATH=/path/to/Qwen-7B-Chat-Int4     # 下载的模型和代码路径 (Q-LoRA)
DATA_PATH='/data/zhenhengdong/WORk/Fine-tuning/Codes/'                   # 准备微调数据放在 ${DATA_PATH}/example.json #data.json
OUTPUT_PATH='/ssd/dongzhenheng/LLM/Qwen-Address/tezt'          # 微调输出路径

# 默认使用主机所有GPU
DEVICE=all
# 如果需要指定用于训练的GPU,按照以下方式设置device(注意:内层的引号不可省略)
#DEVICE='"device=0,3"'

mkdir -p ${OUTPUT_PATH}

# 单卡LoRA微调
docker run --gpus ${DEVICE} --rm --name qwen \
    --mount type=bind,source=${CHECKPOINT_PATH},target=/data/shared/Qwen/Qwen-7B \
    --mount type=bind,source=${DATA_PATH},target=/data/shared/Qwen/data \
    --mount type=bind,source=${OUTPUT_PATH},target=/data/shared/Qwen/output_qwen \
    --shm-size=2gb \
    -it ${IMAGE_NAME} \
    bash finetune/finetune_lora_single_gpu.sh -m /data/shared/Qwen/Qwen-7B/ -d /data/shared/Qwen/data/data.json
    #bash finetune/finetune_lora_ds.sh -m /data/shared/Qwen/Qwen-7B/ -d /data/shared/Qwen/data/data.json
    #bash finetune/finetune_lora_ds.sh -m /data/shared/Qwen/Qwen-7B/ -d /data/shared/Qwen/data/data.json
    #bash finetune/finetune_lora_ds.sh -m /data/shared/Qwen/Qwen-7B/ -d /data/shared/Qwen/data/data.json
    

微调时间较长,运行时可以新启动一个screen。

微调结束后会在指定的输出目录下输出adapter的相关文件。

2.3.2 微调方法2

        微调方法1中直接运行了finetune/finetune_lora_single_gpu.sh脚本进行微调。finetune_lora_single_gpu.sh中的内容如下。

#!/bin/bash
export CUDA_DEVICE_MAX_CONNECTIONS=1

MODEL="your model path" # Set the path if you do not want to load from huggingface directly
# ATTENTION: specify the path to your training data, which should be a json file consisting of a list of conversations.
# See the section for finetuning in README for more information.
DATA="your data path"

function usage() {
    echo '
Usage: bash finetune/finetune_lora_single_gpu.sh [-m MODEL_PATH] [-d DATA_PATH]
'
}

while [[ "$1" != "" ]]; do
    case $1 in
        -m | --model )
            shift
            MODEL=$1
            ;;
        -d | --data )
            shift
            DATA=$1
            ;;
        -h | --help )
            usage
            exit 0
            ;;
        * )
            echo "Unknown argument ${1}"
            exit 1
            ;;
    esac
    shift
done

export CUDA_VISIBLE_DEVICES=3

python finetune.py \
  --model_name_or_path $MODEL \
  --data_path $DATA \
  --bf16 True \
  --output_dir output_qwen \
  --num_train_epochs 50\
  --per_device_train_batch_size 2 \
  --per_device_eval_batch_size 1 \
  --gradient_accumulation_steps 8 \
  --evaluation_strategy "no" \
  --save_strategy "steps" \
  --save_steps 1000 \
  --save_total_limit 5 \
  --learning_rate 3e-4 \
  --weight_decay 0.1 \
  --adam_beta2 0.95 \
  --warmup_ratio 0.01 \
  --lr_scheduler_type "cosine" \
  --logging_steps 1 \
  --report_to "none" \
  --model_max_length 512 \
  --lazy_preprocess True \
  --gradient_checkpointing \
  --use_lora

# If you use fp16 instead of bf16, you should use deepspeed
# --fp16 True --deepspeed finetune/ds_config_zero2.json

各个参数的解释如下: 

python finetune.py: 运行脚本finetune.py,用于微调模型。

--model_name_or_path $MODEL: 指定预训练模型的名称或路径。$MODEL是一个变量,将在运行时替换为实际的模型路径。

--data_path $DATA: 指定向量化的训练数据集路径。$DATA是一个变量,将替换为实际的数据集路径。

--bf16 True: 使用BF16(Brain Floating Point 16)精度进行训练,以降低内存消耗和加速计算。

--output_dir output_qwen: 指定模型训练完成后输出文件的目录名。

--num_train_epochs 50: 设置训练轮数为50轮。

--per_device_train_batch_size 2: 每个设备上的训练批次大小为2,即每次在每个GPU上处理2个样本。

--per_device_eval_batch_size 1: 每个设备上的评估批次大小为1。

 --gradient_accumulation_steps 8: 累积8个步骤的梯度后再更新权重,等效于增大了训练批次大小。

 --evaluation_strategy "no": 不在训练过程中执行评估。

 --save_strategy "steps": 根据步数保存模型,而不是按时间间隔保存。

 --save_steps 1000: 每训练1000个步后保存一次模型。

 --save_total_limit 5: 限制最多保存最近的5个模型检查点。

 --learning_rate 3e-4:指定学习率(learning rate),这是优化器更新权重时使用的步长。值为3乘以10的负4次方,意味着训练过程中的学习速率相对较小,有助于更精细地调整模型参数。

 --weight_decay 0.1:L2正则化系数,也称为权重衰减(weight decay)。它用于防止模型过拟合,通过对权重矩阵施加惩罚来约束模型复杂度。

 --adam_beta2 0.95:Adam优化器中的第二个动量项的指数衰减率(beta2)。Adam是一种常用的优化算法,该参数影响了历史梯度平方项的累积速度。

 --warmup_ratio 0.01:学习率预热比例,用于学习率调度器中。这意味着在训练开始阶段会有一个学习率逐渐增大的“预热”阶段,其长度占整个训练周期的1%。

 --lr_scheduler_type "cosine":学习率调度器类型,这里使用的是余弦退火(Cosine Annealing)策略。在训练过程中,学习率会按照余弦函数的变化规律进行动态调整。

 --logging_steps 1:指定每多少个步骤输出一次日志信息。设置为1意味着每次迭代(通常是每个训练批次后)都会记录训练状态或指标。

 --report_to "none":设置训练结果报告的位置或方式。"none"意味着不向任何工具或平台报告进度或指标。

 --model_max_length 512:定义模型处理的最大序列长度。这意味着输入数据将被截断或者填充到不超过512个token。

 --lazy_preprocess True:如果支持的话,启用延迟预处理模式。在这种模式下,数据预处理将在需要时而不是一次性全部完成,可以减少内存占用。

 --gradient_checkpointing:启用梯度检查点功能,这是一种内存优化技术,通过存储和恢复中间层的激活以节省内存,特别适用于大模型训练。

 --use_lora:表示在微调过程中应用LoRA(Low-Rank Adaptation)方法,这是一种针对大规模模型参数高效的微调技术,通过引入低秩适配器来更新模型权重,而不直接修改所有参数,从而减少计算资源消耗。

        如果想更改finetune.py的参数,那就需要进入进入容器中微调。可以在容器外修改finetune_lora_single_gpu.sh文件中的参数,比如训练的轮次、训练的批次、训练多少步后保存模型、模型处理的最大序列长度等。修改后将文件cp到容器中。具体过程如下:

#启动docker
docker run --gpus all -v /ssd/dongzhenheng/LLM/Qwen-14B-Chat:/data/shared/Qwen/Qwen-Chat/ -d qwenllm/qwen:cu121_V1
#查看容器id
docker ps
#根据容器id进入容器
docker exec -it 容器id bash
#cp 进去data
docker cp /data/zhenhengdong/WORk/Fine-tuning/Qwen-14B/Datasets/data_1.json b81df07711cf:/data/shared/Qwen
#修改checkpoint.py,注释掉waring。避免在运行的时候出现很长的wraing
docker cp /data/zhenhengdong/WORk/Fine-tuning/Qwen-14B/Codes/checkpoint.py b81df07711cf:/usr/local/lib/python3.8/dist-packages/torch/utils
#修改finetune_lora_single_gpu.sh 中的参数
docker cp /data/zhenhengdong/WORk/Fine-tuning/Qwen-14B/Codes/finetune_lora_single_gpu_1.sh  b81df07711cf:/data/shared/Qwen/finetune
# 运行 因为在finetune_lora_single_gpu.sh 中指定了模型地址和数据地址,所以在运行的时候也可以不用指定 -d 和 -m了
bash finetune/finetune_lora_single_gpu_1.sh  -m /data/shared/Qwen/Qwen-Chat -d /data/shared/Qwen/data_1.json
 

        微调结束后,会生成output_qwen的文件夹。

        里面是模型微调时保存的模型。

         微调过程如下:

微调结束后,可以选择checkpoint复制到容器外,再调用或者merge。  

 2.4 调用

        微调之后的调用,Qwen也给出了详细示例。

        在调用时需要注意更换一下adapert_config.json中的模型路径。将base_model_name_or_path换成自己微调的模型路径。

from peft import AutoPeftModelForCausalLM
path_to_adapter = '/ssd/dongzhenheng/LLM/Qwen-Address/tezt'
model = AutoPeftModelForCausalLM.from_pretrained(
    path_to_adapter, # path to the output directory
    device_map="cuda:0",
    trust_remote_code=True
).eval()

2.5 合并

        合并以docker中的为例

from peft import AutoPeftModelForCausalLM

path_to_adapter = '/data/shared/Qwen/output_qwen'
model = AutoPeftModelForCausalLM.from_pretrained(
    path_to_adapter, # path to the output directory
    device_map="auto",
    trust_remote_code=True
).eval()

new_model_directory = '/data/shared/Qwen/New_model_directory'
merged_model = model.merge_and_unload()
# max_shard_size and safe serialization are not necessary. 
# They respectively work for sharding checkpoint and save the model to safetensors
merged_model.save_pretrained(new_model_directory, max_shard_size="2048MB", safe_serialization=True)

执行过程  

  

目录文件

New_model_directory目录将包含合并后的模型参数与相关模型代码。请注意*.cu*.cpp文件没被保存,需要手动从Qwen-1_8B-Chat中复制。merge_and_unload仅保存模型,并未保存tokenizer,如有需要,请复制相关文件或使用以以下代码保存 。

from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained(
    path_to_adapter, # path to the output directory
    trust_remote_code=True
)
tokenizer.save_pretrained(New_model_directory)

2.6 合并调用

        合并并存储模型后即可用常规方式读取新模型。

checkpoint_path = '/data/shared/Qwen/New_model_directory'
tokenizer = AutoTokenizer.from_pretrained(
        checkpoint_path, 
        trust_remote_code=True, resume_download=True,
    )
device_map = "auto"

model = AutoModelForCausalLM.from_pretrained(
        checkpoint_path,
        device_map=device_map,
        trust_remote_code=True,
        resume_download=True,
        bf16=True
    ).eval()

model.generation_config = GenerationConfig.from_pretrained(
        checkpoint_path, trust_remote_code=True, resume_download=True,
    )

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Maven的下载安装配置教程

一、简单了解一下什么是Maven Maven就是一款帮助程序员构建项目的工具,我们只需要告诉Maven需要哪些Jar 包,它会帮助我们下载所有的Jar,极大提升开发效率。 1.Maven翻译为“专家“, ”内行”的意思,是著名Apache公司下…

通过盲注脚本复习sqllabs第46关order by 注入

在MySQL支持使用ORDER BY语句对查询结果集进行排序处理,使用ORDER BY语句不仅支持对单列数据的排序,还支持对数据表中多列数据的排序。语法格式如下 select * from 表名 order by 列名(或者数字) asc;升序(默认升序) select * from 表名 or…

将一个 PostgreSQL 数据库复制到另一个数据库中

以管理员身份进入cmd窗口,输入如下命令 语法: pg_dump -C -h 本机IP -U 本机postgresql用户名 源数据库名 | psql -h 服务器IP -U 服务器postgresql用户名 目标数据库名 示例: pg_dump -C -h 127.0.0.1 -U postgres test01-dbname | psql…

顺序表详解(如何实现顺序表)

文章目录 前言 在进入顺序表前,我们先要明白,数据结构的基本概念。 一、数据结构的基本概念 1.1什么是数据结构 数据结构是由“数据”和“结构”两词组合而来。所谓数据就是?常见的数值1、2、3、4.....、姓名、性别、年龄,等。…

高维数据的中介效应【中介分析】《R包:HIMA》

允许基于高级中介筛选和惩罚回归技术来估计和测试高维中介效应 Hima包浏览 高维中介示意图 图1. 在暴露和结果之间有高维中介的情况 本包的作用 在确定独立筛选和极小极大凹惩罚技术的基础上,采用联合显著性检验方法对调解效果进行检验。使用蒙特卡罗模拟研究来展…

C#知识点-15(匿名函数、使用委托进行窗体传值、反射)

匿名函数 概念:没有名字的函数,一般情况下只调用一次。它的本质就是一个方法,虽然我们没有定义这个方法,但是编译器会把匿名函数编译成一个方法 public delegate void Del1();//无参数无返回值的委托public delegate void Del2(s…

Java SE 入门到精通—基础语法【Java】

敲重点! 本篇讲述了比较重要的基础,是必须要掌握的 1.程序入口 在Java中,main方法是程序的入口点,是JVM(Java虚拟机)执行Java应用程序的起始点。 main方法的方法签名必须遵循下面规范: publ…

TestNG与ExtentReport单元测试导出报告文档

TestNG与ExtentReport集成 目录 1 通过实现ITestListener的方法添加Reporter log 1.1 MyTestListener设置 1.2 输出结果 2 TestNG与ExtentReporter集成 2.1 项目结构 2.2 MyExtentReportListener设置 2.3 单多Suite、Test组合测试 2.3.1 单Suite单Test 2.3…

Java实现实验室耗材管理系统 JAVA+Vue+SpringBoot+MySQL

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 耗材档案模块2.2 耗材入库模块2.3 耗材出库模块2.4 耗材申请模块2.5 耗材审核模块 三、系统展示四、核心代码4.1 查询耗材品类4.2 查询资产出库清单4.3 资产出库4.4 查询入库单4.5 资产入库 五、免责说明 一、摘要 1.1…

WebSocket实现聊天

基于webSocket通信的库主要有 socket.io,SockJS,这次用的是 SockJS。 这里我们使用sockjs-client、stomjs这两个模块,要实现webSocket通信,需要后台配合,也使用相应的模块。 WebSocket 1、http:http超文…

War Robots可以使用5347的卡支付

很多小伙伴想使用War Robots,但是不知道怎么弄,方法比较可靠,亲测有效~~~ 可以使用Fomepay的5347的卡支付 卡片cvc就是卡密,在首页点击更多时可以查看

【ubuntu2004安装N卡驱动】

软硬件环境 硬件:联想notebook16,显卡4060laptop 软件: ubuntu20.04 驱动安装成功的版本:NVIDIA-Linux-x86_64-535.146.02.run 使用默认的驱动安装,没用原因如下 让手动安装。 手动安装 环境准备: sudo …

【shap】使用shap画图时colorbar颜色条不能正常显示

下面,我的shap值全是蓝色的,没有红色 (注:蓝色是负贡献,红色是正贡献) 参考上面的帖子,是matplotlib版本问题,我原来的版本是3.5.0,降级回3.4.3就正常了。

心律守护 基于机器学习的心脏病预测

心律守护 基于机器学习的心脏病预测 心律守护 基于机器学习的心脏病预测项目背景与意义项目数据与特征数据分析与预处理机器学习模型建立与评估结语 心律守护 基于机器学习的心脏病预测 在当今数字化时代,机器学习的应用已经渗透到了医疗保健领域的各个层面。其中&…

阿里云/腾讯云幻兽帕鲁服务器为什么更新/重启之后,服务器存档没了?

有的朋友说,他的阿里云幻兽帕鲁服务器重启了一下后,服务器存档就没了?这是怎么回事呢,其实可能的原因,一是服务器还有重启完成,也就是游戏服务端还没有启动,就登进去,可能会显示网络…

Eclipse项目间的引用

我们在开发的时候,有时候需要把一个大的项目打散,尤其是现在微服务的架构很流行,一个大的项目往往被拆成很多小的项目,而有的项目作为公共工程被独立出来,比如有个工程专门提供各种Util工具类,有的工程专门…

使用 Docker 安装 Elasticsearch 8.4.3

使用 Docker 安装 Elasticsearch 8.4.3 一. 拉取 Elasticsearch Docker 镜像二. 使用Docker启动单节点集群三. 修改密码 前言 这是我在这个网站整理的笔记,有错误的地方请指出,关注我,接下来还会持续更新。 作者:神的孩子都在歌唱 从 Elastic…

基于Python的热点分析预警系统

项目:基于Python的热点分析预警系统 摘 要 基于网络爬虫的数据可视化服务系统是一种能自动从网络上收集信息的工具,可根据用户的需求定向采集特定数据信息的工具,本项目通过研究爬取微博网来实现微博热点分析数据信息可视化系统功能。对于采…

美国纽约时代广场纳斯达克大屏投放-大舍传媒

美国纽约时代广场纳斯达克大屏投放-大舍传媒 引言 对于大舍传媒来说,能够在美国纽约时代广场纳斯达克大屏投放广告是一个里程碑式的时刻。这不仅仅代表着大舍传媒在全球范围内的知名度与实力,也标志着该公司在国际市场上取得了巨大的进展。纽约时代广场…

sqllabs第46关 order by 注入

简介:(order by注入-错误回显-POST注入) 请求方法:POST 方法:order by注入错误回显数字型注入 先了解下 order by参数注入: order by 注入是指其后面的参数是可控的, order by 不同于我们在 whe…