自然语言微调技术(NLFT)-25年04月-克隆运行实践


自然语言微调技术(NLFT)-25年04月-克隆运行实践

Written with StackEdit.

前言

在尝试参加阿里云“仇恨识别”的竞赛时,队友阅读到了华南理工大学团队发表的“自然语言微调技术(NLFT)”的文章,因此有了本次“克隆-运行NLFT仓库”的尝试。
在文章开头先贴上github仓库链接+论文链接,如果在LLMs微调方面有过实战经验的话,建议直接看源码,根据实验环境自行调整,在有问题时再来看看遇到的是否跟我一样。

github仓库链接:
Julia-LiuJ/NLFT: The official implementation of Natural Language Fine-Tuning

论文链接:
[2412.20382] Natural Language Fine-Tuning

大纲

  1. 实战过程
  2. 问题索引
  3. 论文阅读笔记的手写记录

正文

概述:
实战过程板块:先详细解释实现过程(面向基础薄弱或实践经验不足的明日之星);再给出省流版本,直接贴出执行的命令(Modelscope notebook环境)

实战过程

我是用的是modelscope(魔搭社区)的notebook GPU环境。

如果有研究or复现经验,建议直接看github仓库的README.md,这种优秀的github仓库中,基本的运行命令都在README里写得清清楚楚。

详细解释版

  1. git clone NLFT 的github仓库
git clone https://github.com/Julia-LiuJ/NLFT.git

(注:进入仓库主页,点击绿色的”Code”按钮,在弹出的小窗中就可以看到”Clone”一栏,直接复制HTTPS的链接。)

  1. 下载anaconda(安装虚拟环境)

如果实验环境已经安装Anaconda,可以直接跳过这步。
贴一段DS对Anaconda的介绍,下载Anaconda主要是用到它的conda构建虚拟环境。不同版本的库可能有不同的python版本需求,同时依赖包的版本要求也会有区别。conda工具可以通过隔离环境解决版本冲突,提升项目可复现性。
“””
​Anaconda​​ 是一个开源的 ​​Python 和 R 语言​​ 的发行版,主要用于 ​​数据科学、机器学习、科学计算​​ 等领域。它集成了大量常用的数据科学工具和库,并提供了一个强大的包管理和环境管理工具(conda),简化了软件包的安装、依赖管理和环境配置。
“””

modelscope控制台(terminal)是linux环境,使用wget命令下载:

wget https://repo.anaconda.com/archive/Anaconda3-2024.10-1-Linux-x86_64.sh

之后使用sh命令执行sh脚本:

sh https://repo.anaconda.com/archive/Anaconda3-2024.10-1-Linux-x86_64.sh

执行后,先长按ENTER阅读完协议,输入yes,等一会再按一下ENTER,最后问“要不要在创建Terminal控制台时自动启用base环境?”输入yes。之后另外创建一个Terminal控制台,可以看到用户名与当前路径左侧有个(base)的标记。

如果你想直接在当前窗口就启用conda工具,仔细看看控制台里它的输出,它已经告诉你了,要执行下面这个命令:(Modelscope notebook环境可以直接执行,其它环境请结合具体路径修改后执行,按理说在输出中会给的)

eval  "$(/root/anaconda3/bin/conda shell.bash hook)"

这里再补充一段DS对Shell脚本的介绍,都写step-by-step教程了就贯彻到底了。
“””
​Shell 脚本(sh 脚本)是什么?​

​Shell 脚本​​(通常以 .sh 为后缀)是一个包含一系列 ​​Linux/Unix 命令​​ 的文本文件,用于自动化执行任务。
“””

  1. 配置虚拟环境

(什么,你问我为什么用nlft.yaml安装虚拟环境?建议直接去看github仓库的README文件,作者把两种配置环境的方式要运行的代码写得清清楚楚)

使用nlft.yaml安装虚拟环境

conda env create -f nlft.yaml

使用上面的指令时,报错500Timeout(超时,网络连接异常),重新尝试后仍然报该错误。人不能在一棵树上吊死,Modelscope的网络连不上就是连不上,可不能期待重复尝试得到不同的结果。尝试先创建conda再pip install:

conda create -n nlft_env python=3.10

创建后激活环境:

conda activate nlft_env

之后根据requirements.txt文件,下载对应版本的依赖。

pip install -r requirements.txt
  1. 下载LLAMA3-8B模型
    (什么?你问我为什么是LLAMA3-8B?人家用的base model就是LLAMA3-8B啊,现在我正在直接跑仓库的代码啊,人家用什么当然就用什么;提醒一下,如果要换成非LLAMA系列的模型,根据代码逻辑不一定能使用;如果要换成非LLAMA3-8B的其它模型,请注意把相关文件中的模型路径一并修改)

注意一下,在requirements.txt文件中,modelscope的版本过低,没有snapshot_download指令,直接运行会报错:ImportError: cannot import name 'snapshot_download' from 'modelscope' (/root/anaconda3/envs/nlft_env/lib/python3.10/site-packages/modelscope/__init__.py)

因此,要先升级modelscope的版本,再进行模型下载:

pip  install  --upgrade  modelscope
# 下载LLAMA3-8B模型
python utils/llama_download.py

(什么?你问我为什么是执行”utils/llama_download.py”这个脚本来下载模型? 建议直接看README文件)
魔搭社区提供了很多模型的镜像,借助modelscope的snapshot_download可以很方便地在中国境内下载模型。

  1. 进行微调训练

项目使用到了WANDB可视化训练效果。但我个人并未注册WANDB账号,先关闭了WANDB(如果不关闭,需要修改WANDB登录的相关信息):

export  WANDB_MODE=offline

然后就执行NLFT微调的脚本:

sh  finetune-correct.sh

脚本的输出被重定向到数据集名称.txt文件里了。

点开文件,你就会发现一个又一个的报错:
未找到数据集:数据集链接在README文件里也给了,点进链接下载后,在NLFT文件夹中创建data文件夹,把数据集拖进data文件夹里;
只找到gpu0,甚至没找到gpu:没找到gpu,如果环境没有gpu就叉出去;如果是cuda环境没配置好配置cuda环境;对于Modelscope notebook的GPU环境来讲,只有单GPU,但是原始版本代码直接假定你使用了两个gpu。值得庆幸的是,在对脚本呢进行简单的修改后,单GPU仍然可以运行。把finetune-correct.sh中提到的一行进行修改:

# 把 CUDA_VISIBLE_DEVICES=0,1  torchrun  --nproc_per_node=2  --master_port=1234  finetune_unlikelihood_dynamic_correct.py \ 修改成:
CUDA_VISIBLE_DEVICES=0 python finetune_unlikelihood_dynamic_correct.py \

但需要注意,使用单GPU运行时,batch_size必须设为偶数,如果要深入解释的话,具体是因为modeling_llama_unlikelihood_dynamic_correct.py中141行处的逻辑。

如果运行起来后CUDA Out Of Memory,调低batch_size为2,cutoff_len适当下调(我最终下调到512)。

如果训练后在checkpoint基础上继续训练,可以添加下面这段代码(要填入具体的checkpoint路径):

--resume_from_checkpoint 你的checkpoint路径 \

省流版

注意:由于modelscope会在关闭后清除非指定目录下的内容,因此每次重启notebook都要重装Anaconda并重新配置环境与下载模型。如果非Modelscope notebook环境,不用反复执行配置环境的操作。

另外,如果下载的Anaconda安装包不在NLFT目录(克隆的github仓库目录)里,你需要在激活conda工具,也就是eval那句代码使用cd命令进入该目录,再进行后续步骤

这里默认不启用WANDB。启用需自行设置。

另外,这段代码只能在含有两个(或以上)GPU的环境下,在添加好数据集文件才能直接运行****(如何添加数据集文件,见上一部分最后一段内容);

如果是单GPU环境则可以看一下上个部分最后一段内容,对finetune-correct.sh进行修改。

# 如果没有下载安装包:wget https://repo.anaconda.com/archive/Anaconda3-2024.10-1-Linux-x86_64.sh

sh Anaconda3-2024.10-1-Linux-x86_64.sh

# (长按enter,输入yes,再enter,yes)

# eval "$(/mnt/workplace/bin/conda shell.bash hook)"

eval "$(/root/anaconda3/bin/conda shell.bash hook)"

# cd 微调/NLFT/ # 进入NLFT文件夹

conda create -n nlft_env python=3.10

conda activate nlft_env

pip install -r requirements.txt

pip install --upgrade modelscope

# 下载LLAMA3-8B模型

python utils/llama_download.py

export WANDB_MODE=offline

sh finetune-correct.sh

问题索引

注意:这个板块,是基于“实现过程的省流版本”,用于快速查找是否有相同问题的板块。部分内容会在前文的“详细版本”中写过。

下载内容时500TimeOut
下载模型时报错:无法从modelscope中importsnapshot_download
单GPU无法运行
运行时CUDA Out Of Memory

下载内容时500TimeOut

conda env create -f nlft.yaml

使用上面的指令时,报错500Timeout(超时,网络连接异常),重新尝试后仍然报该错误。

个人的环境是Modelscope notebook环境,不便配置网络环境。
这个报错的底层原因,就是目标网站在国外,网络连不上。可以通过连接梯子直接解决。

我的尝试方向是避免连接国外网站,改用requirement.txt配置环境。应该也可以通过配置国内镜像源解决这个问题。(例如清华、淘宝镜像源,通常是下载软件包使用这一方法)

下载模型时报错:无法从modelscope中importsnapshot_download

requirements.txt文件中,modelscope的版本过低,没有snapshot_download指令,直接运行会报错:ImportError: cannot import name 'snapshot_download' from 'modelscope' (/root/anaconda3/envs/nlft_env/lib/python3.10/site-packages/modelscope/__init__.py)

进行传统网络搜索发现:”最新版本(如 1.13.0 或更高)支持 snapshot_download。”这个问题的原因是,过低版本的modelscope库并没有snapshot_download方法。

因此,要先升级modelscope的版本,再进行模型下载:

pip  install  --upgrade  modelscope
# 使用仓库中的脚本下载LLAMA3-8B模型
python utils/llama_download.py

单GPU无法运行

个人阅读代码后,进行的运行成功的修改如下:

finetune-correct.sh中提到的一行进行修改:

# 把 CUDA_VISIBLE_DEVICES=0,1  torchrun  --nproc_per_node=2  --master_port=1234  finetune_unlikelihood_dynamic_correct.py \ 修改成:
CUDA_VISIBLE_DEVICES=0 python finetune_unlikelihood_dynamic_correct.py \

但需要注意,使用单GPU运行时,batch_size必须设为偶数,如果要深入解释的话,具体是因为modeling_llama_unlikelihood_dynamic_correct.py中141行处的逻辑。

运行时CUDA-OutOfMemory

这是一个经典的报错,在模型训练中有很多种优化方法。

在不考虑调整训练用的框架的情况下,一般针对batch_size和最大长度(这里是cutoff_len)进行适当缩减。

个人的尝试是将batch_size下调为2,cutoff_len下调为512。

另外说明,代码中并不支持验证集;并且,如果自定义添加了验证集的装载,”val_set_size”的意思会是”val_batch_size”。要是把它当成了验证集的数据大小,那包爆显存内存的。

论文阅读笔记的手写记录

要读懂代码,还是得理解实验中涉及到的具体方法是什么,深入理解原理。

下面纯粹是个人的记录,不一定对他人有用,要理解原理还是看其它介绍原理的博客or直接看论文原文。

1/5

2/5

3/5

4/5

5/5


文章作者: Qijia Huang
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Qijia Huang !
  目录