基础岛-第五关 XTuner 微调个人小助手认知 笔记

任务

https://github.com/InternLM/Tutorial/blob/camp3/docs/L1/XTuner/task.md

使用 XTuner 微调 InternLM2-Chat-1.8B 实现自己的小助手认知,如下图所示(图中的伍鲜同志需替换成自己的昵称),记录复现过程并截图。

文档

https://github.com/InternLM/Tutorial/blob/camp3/docs/L1/XTuner

XTuner 微调个人小助手认知 笔记

复现过程

虚拟环境统一用 torch2_py310

没有微调

在这里插入图片描述

微调过程

人工构造数据集:
python /root/InternLM/XTuner/xtuner_generate_assistant.py

数据集:
/root/InternLM/XTuner/datas/assistant.json

sft 模型配置:
internlm2_chat_1_8b_qlora_assistant_e3.py

模型名: internlm2_chat_1_8b
微调方式:qlora
数据集名: assistant
几轮: epoch: 1

xtuner train ./internlm2_chat_1_8b_qlora_assistant_e3.py

训练过程
在这里插入图片描述

模型转换:

pth_file=ls -t ./work_dirs/internlm2_chat_1_8b_qlora_assistant_e3/*.pth | head -n 1
export MKL_SERVICE_FORCE_INTEL=1
export MKL_THREADING_LAYER=GNU
xtuner convert pth_to_hf ./internlm2_chat_1_8b_qlora_assistant_e3.py ${pth_file} ./hf

模型合并

cd /root/InternLM/XTuner

export MKL_SERVICE_FORCE_INTEL=1
export MKL_THREADING_LAYER=GNU
xtuner convert merge /root/InternLM/XTuner/Shanghai_AI_Laboratory/internlm2-chat-1_8b ./hf ./merged --max-shard-size 2GB

启动web端命令:

修改 /root/InternLM/Tutorial/tools/xtuner_streamlit_demo.py

  • model_name_or_path = “/root/InternLM/XTuner/merged”

streamlit run /root/InternLM/Tutorial/tools/xtuner_streamlit_demo.py

windowspowershell:
ssh -CNg -L 12345:127.0.0.1:8501 root@ssh.intern-ai.org.cn -p 45688

微调后:

在这里插入图片描述

其他笔记

环境

10%gpu 8G 显存 选择开发机镜像:Cuda12.2-conda。

mkdir -p /root/InternLM/Tutorial
git clone -b camp3  https://github.com/InternLM/Tutorial /root/InternLM/Tutorial

# 创建虚拟环境
conda create -n torch2_py310 python=3.10 -y

# 激活虚拟环境(注意:后续的所有操作都需要在这个虚拟环境中进行)
conda activate torch2_py310

# 安装一些必要的库
conda install pytorch==2.1.2 torchvision==0.16.2 torchaudio==2.1.2 pytorch-cuda=12.1 -c pytorch -c nvidia -y
# 安装其他依赖
pip install transformers==4.39.3 -i https://pypi.tuna.tsinghua.edu.cn/simple/ 
pip install streamlit==1.36.0 -i https://pypi.tuna.tsinghua.edu.cn/simple/ 

安装 XTuner

# 创建一个目录,用来存放源代码
mkdir -p /root/InternLM/code

cd /root/InternLM/code

git clone -b v0.1.21  https://kkgithub.com/InternLM/XTuner /root/InternLM/code/XTuner


# 进入到源码目录
cd /root/InternLM/code/XTuner
conda activate torch2_py310

# 执行安装
pip install -e '.[deepspeed]'  -i https://pypi.tuna.tsinghua.edu.cn/simple/ 



`pip install -e '.[deepspeed]'` 这个命令是用来安装当前目录下Python包的可编辑模式,并安装与 `deepspeed` 相关的额外依赖。

下面是命令中各个部分的解释:

- `pip`: 是Python的包安装器。

- `install`: 告诉 `pip` 要安装一个包。

- `-e` 或 `--editable`: 这个选项会让包以可编辑模式安装。这意味着你可以对源代码进行更改,而不需要重新安装包,更改将立即反映在安装的包中。

- `.`: 表示当前目录,`pip` 将会查找当前目录下的 `setup.py` 文件来安装包。

- `[deepspeed]`: 是一个额外的依赖项指定,它告诉 `pip` 安装包含 `deepspeed` 的依赖项。这通常在 `setup.py` 文件的 `extras_require` 字段中定义。

这个命令通常用在一个Python项目的根目录下,其中包含一个 `setup.py` 文件,该文件定义了包的元数据和依赖关系。如果你正在开发一个Python包,并且想要安装它以及它的 `deepspeed` 相关依赖,以便立即测试更改,这个命令就非常有用。

请注意,`deepspeed` 是微软推出的一个深度学习优化库,用于提高大规模训练任务的效率。如果你的项目中使用了 `deepspeed`,确保在 `setup.py` 中正确定义了相应的依赖项。如果你没有 `setup.py` 或者没有定义 `deepspeed` 依赖项,这个命令可能不会按预期工作。

验证一下安装结果。

xtuner version

查看相关的帮助。
xtuner help

模型准备

通过符号链接的方式链接到模型文件,这样既节省了空间,也便于管理。

# 创建一个目录,用来存放微调的所有资料,后续的所有操作都在该路径中进行
mkdir -p /root/InternLM/XTuner

cd /root/InternLM/XTuner

mkdir -p Shanghai_AI_Laboratory

ln -s /root/share/new_models/Shanghai_AI_Laboratory/internlm2-chat-1_8b Shanghai_AI_Laboratory/internlm2-chat-1_8b

使用tree命令来观察目录结构。

apt-get install -y tree

tree -l
├── Shanghai_AI_Laboratory
│   └── internlm2-chat-1_8b -> /root/share/new_models/Shanghai_AI_Laboratory/internlm2-chat-1_8b
│       ├── README.md
│       ├── config.json
│       ├── configuration.json
│       ├── configuration_internlm2.py
│       ├── generation_config.json
│       ├── model-00001-of-00002.safetensors
│       ├── model-00002-of-00002.safetensors
│       ├── model.safetensors.index.json
│       ├── modeling_internlm2.py
│       ├── special_tokens_map.json
│       ├── tokenization_internlm2.py
│       ├── tokenization_internlm2_fast.py
│       ├── tokenizer.model
│       └── tokenizer_config.json

微调

conda activate torch2_py310

streamlit run /root/InternLM/Tutorial/tools/xtuner_streamlit_demo.py

ssh -CNg -L 12345:127.0.0.1:8501 root@ssh.intern-ai.org.cn -p 45688 

cd /root/InternLM/XTuner
mkdir -p datas
touch datas/assistant.json

cd /root/InternLM/XTuner
touch xtuner_generate_assistant.py

cd /root/InternLM/XTuner
cp /root/InternLM/Tutorial/tools/xtuner_generate_assistant.py ./

xtuner_generate_assistant.py

import json

# 设置用户的名字
name = '飞飞'
# 设置需要重复添加的数据次数
n =  3750

# 初始化数据
data = [
    {"conversation": [{"input": "请介绍一下你自己", "output": "我是{}的小助手,内在是上海AI实验室书生·浦语的1.8B大模型哦".format(name)}]},
    {"conversation": [{"input": "你在实战营做什么", "output": "我在这里帮助{}完成XTuner微调个人小助手的任务".format(name)}]}
]

# 通过循环,将初始化的对话数据重复添加到data列表中
for i in range(n):
    data.append(data[0])
    data.append(data[1])

# 将data列表中的数据写入到'datas/assistant.json'文件中
with open('datas/assistant.json', 'w', encoding='utf-8') as f:
    # 使用json.dump方法将数据以JSON格式写入文件
    # ensure_ascii=False 确保中文字符正常显示
    # indent=4 使得文件内容格式化,便于阅读
    json.dump(data, f, ensure_ascii=False, indent=4)


生成数据文件。

cd /root/InternLM/XTuner
conda activate torch2_py310

python xtuner_generate_assistant.py

XTuner 配置文件

xtuner list-cfg 命令用于列出内置的所有配置文件。

参数 -p 或 --pattern 表示模式匹配,后面跟着的内容将会在所有的配置文件里进行模糊匹配搜索,然后返回最有可能得内容。

conda activate torch2_py310

xtuner list-cfg -p internlm2

以 intern
配置文件名的解释

lm2_1_8b_full_custom_pretrain_e1 和 internlm2_chat_1_8b_qlora_alpaca_e3 举例:

配置文件internlm2_1_8b_full_custom_pretrain_e1	配置文件internlm2_chat_1_8b_qlora_alpaca_e3	说明

internlm2_1_8b	internlm2_chat_1_8b	模型名称
full	        qlora	            使用的算法
custom_pretrain	alpaca	            数据集名称
e1	            e3	                把数据集跑几次

xtuner copy-cfg 命令用于复制一个内置的配置文件。

cd /root/InternLM/XTuner
conda activate torch2_py310

xtuner copy-cfg internlm2_chat_1_8b_qlora_alpaca_e3 .

配置文件

打开配置文件后,我们可以看到整体的配置文件分为五部分:

PART 1 Settings:涵盖了模型基本设置,如预训练模型的选择、数据集信息和训练过程中的一些基本参数(如批大小、学习率等)。

PART 2 Model & Tokenizer:指定了用于训练的模型和分词器的具体类型及其配置,包括预训练模型的路径和是否启用特定功能(如可变长度注意力),这是模型训练的核心组成部分。

PART 3 Dataset & Dataloader:描述了数据处理的细节,包括如何加载数据集、预处理步骤、批处理大小等,确保了模型能够接收到正确格式和质量的数据。

PART 4 Scheduler & Optimizer:配置了优化过程中的关键参数,如学习率调度策略和优化器的选择,这些是影响模型训练效果和速度的重要因素。

PART 5 Runtime:定义了训练过程中的额外设置,如日志记录、模型保存策略和自定义钩子等,以支持训练流程的监控、调试和结果的保存。

一般来说我们需要更改的部分其实只包括前三部分,而且修改的主要原因是我们修改了配置文件中规定的模型、数据集。

 PART 1  更换模型的路径以及数据集的路径为我们本地的路径。
PART 3

internlm2_chat_1_8b_qlora_alpaca_e3.py

#######################################################################
#                          PART 1  Settings                           #
#######################################################################
- pretrained_model_name_or_path = 'internlm/internlm2-chat-1_8b'
+ pretrained_model_name_or_path = '/root/InternLM/XTuner/Shanghai_AI_Laboratory/internlm2-chat-1_8b'

- alpaca_en_path = 'tatsu-lab/alpaca'
+ alpaca_en_path = 'datas/assistant.json'

evaluation_inputs = [
-    '请给我介绍五个上海的景点', 'Please tell me five scenic spots in Shanghai'
+    '你是谁', 'Please introduce yourself'
]

#######################################################################
#                      PART 3  Dataset & Dataloader                   #
#######################################################################
alpaca_en = dict(
    type=process_hf_dataset,
-   dataset=dict(type=load_dataset, path=alpaca_en_path),
+   dataset=dict(type=load_dataset, path='json', data_files=dict(train=alpaca_en_path)),
    tokenizer=tokenizer,
    max_length=max_length,
-   dataset_map_fn=alpaca_map_fn,
+   dataset_map_fn=None,
    template_map_fn=dict(
        type=template_map_fn_factory, template=prompt_template),
    remove_unused_columns=True,
    shuffle_before_pack=True,
    pack_to_max_length=pack_to_max_length,
    use_varlen_attn=use_varlen_attn)

常用参数介绍

参数名	解释
data_path	数据路径或 HuggingFace 仓库名
max_length	单条数据最大 Token 数,超过则截断
pack_to_max_length	是否将多条短数据拼接到 max_length,提高 GPU 利用率
accumulative_counts	梯度累积,每多少次 backward 更新一次参数
sequence_parallel_size	并行序列处理的大小,用于模型训练时的序列并行
batch_size	每个设备上的批量大小
dataloader_num_workers	数据加载器中工作进程的数量
max_epochs	训练的最大轮数
optim_type	优化器类型,例如 AdamW
lr	学习率
betas	优化器中的 beta 参数,控制动量和平方梯度的移动平均
weight_decay	权重衰减系数,用于正则化和避免过拟合
max_norm	梯度裁剪的最大范数,用于防止梯度爆炸
warmup_ratio	预热的比例,学习率在这个比例的训练过程中线性增加到初始学习率
save_steps	保存模型的步数间隔
save_total_limit	保存的模型总数限制,超过限制时删除旧的模型文件
prompt_template	模板提示,用于定义生成文本的格式或结构
......	......

internlm2_chat_1_8b_qlora_alpaca_e3_copy.py

# Copyright (c) OpenMMLab. All rights reserved.
import torch
from datasets import load_dataset
from mmengine.dataset import DefaultSampler
from mmengine.hooks import (CheckpointHook, DistSamplerSeedHook, IterTimerHook,
                            LoggerHook, ParamSchedulerHook)
from mmengine.optim import AmpOptimWrapper, CosineAnnealingLR, LinearLR
from peft import LoraConfig
from torch.optim import AdamW
from transformers import (AutoModelForCausalLM, AutoTokenizer,
                          BitsAndBytesConfig)

from xtuner.dataset import process_hf_dataset
from xtuner.dataset.collate_fns import default_collate_fn
from xtuner.dataset.map_fns import alpaca_map_fn, template_map_fn_factory
from xtuner.engine.hooks import (DatasetInfoHook, EvaluateChatHook,
                                 VarlenAttnArgsToMessageHubHook)
from xtuner.engine.runner import TrainLoop
from xtuner.model import SupervisedFinetune
from xtuner.parallel.sequence import SequenceParallelSampler
from xtuner.utils import PROMPT_TEMPLATE, SYSTEM_TEMPLATE

#######################################################################
#                          PART 1  Settings                           #
#######################################################################
# Model
pretrained_model_name_or_path = '/root/InternLM/XTuner/Shanghai_AI_Laboratory/internlm2-chat-1_8b'
use_varlen_attn = False

# Data
alpaca_en_path = 'datas/assistant.json'
prompt_template = PROMPT_TEMPLATE.internlm2_chat
max_length = 2048
pack_to_max_length = True

# parallel
sequence_parallel_size = 1

# Scheduler & Optimizer
batch_size = 1  # per_device
accumulative_counts = 16
accumulative_counts *= sequence_parallel_size
dataloader_num_workers = 0
max_epochs = 3
optim_type = AdamW
lr = 2e-4
betas = (0.9, 0.999)
weight_decay = 0
max_norm = 1  # grad clip
warmup_ratio = 0.03

# Save
save_steps = 500
save_total_limit = 2  # Maximum checkpoints to keep (-1 means unlimited)

# Evaluate the generation performance during the training
evaluation_freq = 500
SYSTEM = SYSTEM_TEMPLATE.alpaca
evaluation_inputs = [
    '请介绍一下你自己', 'Please introduce yourself'
]

#######################################################################
#                      PART 2  Model & Tokenizer                      #
#######################################################################
tokenizer = dict(
    type=AutoTokenizer.from_pretrained,
    pretrained_model_name_or_path=pretrained_model_name_or_path,
    trust_remote_code=True,
    padding_side='right')

model = dict(
    type=SupervisedFinetune,
    use_varlen_attn=use_varlen_attn,
    llm=dict(
        type=AutoModelForCausalLM.from_pretrained,
        pretrained_model_name_or_path=pretrained_model_name_or_path,
        trust_remote_code=True,
        torch_dtype=torch.float16,
        quantization_config=dict(
            type=BitsAndBytesConfig,
            load_in_4bit=True,
            load_in_8bit=False,
            llm_int8_threshold=6.0,
            llm_int8_has_fp16_weight=False,
            bnb_4bit_compute_dtype=torch.float16,
            bnb_4bit_use_double_quant=True,
            bnb_4bit_quant_type='nf4')),
    lora=dict(
        type=LoraConfig,
        r=64,
        lora_alpha=16,
        lora_dropout=0.1,
        bias='none',
        task_type='CAUSAL_LM'))

#######################################################################
#                      PART 3  Dataset & Dataloader                   #
#######################################################################
alpaca_en = dict(
    type=process_hf_dataset,
    dataset=dict(type=load_dataset, path='json', data_files=dict(train=alpaca_en_path)),
    tokenizer=tokenizer,
    max_length=max_length,
    dataset_map_fn=None,
    template_map_fn=dict(
        type=template_map_fn_factory, template=prompt_template),
    remove_unused_columns=True,
    shuffle_before_pack=True,
    pack_to_max_length=pack_to_max_length,
    use_varlen_attn=use_varlen_attn)

sampler = SequenceParallelSampler \
    if sequence_parallel_size > 1 else DefaultSampler
train_dataloader = dict(
    batch_size=batch_size,
    num_workers=dataloader_num_workers,
    dataset=alpaca_en,
    sampler=dict(type=sampler, shuffle=True),
    collate_fn=dict(type=default_collate_fn, use_varlen_attn=use_varlen_attn))

#######################################################################
#                    PART 4  Scheduler & Optimizer                    #
#######################################################################
# optimizer
optim_wrapper = dict(
    type=AmpOptimWrapper,
    optimizer=dict(
        type=optim_type, lr=lr, betas=betas, weight_decay=weight_decay),
    clip_grad=dict(max_norm=max_norm, error_if_nonfinite=False),
    accumulative_counts=accumulative_counts,
    loss_scale='dynamic',
    dtype='float16')

# learning policy
# More information: https://github.com/open-mmlab/mmengine/blob/main/docs/en/tutorials/param_scheduler.md  # noqa: E501
param_scheduler = [
    dict(
        type=LinearLR,
        start_factor=1e-5,
        by_epoch=True,
        begin=0,
        end=warmup_ratio * max_epochs,
        convert_to_iter_based=True),
    dict(
        type=CosineAnnealingLR,
        eta_min=0.0,
        by_epoch=True,
        begin=warmup_ratio * max_epochs,
        end=max_epochs,
        convert_to_iter_based=True)
]

# train, val, test setting
train_cfg = dict(type=TrainLoop, max_epochs=max_epochs)

#######################################################################
#                           PART 5  Runtime                           #
#######################################################################
# Log the dialogue periodically during the training process, optional
custom_hooks = [
    dict(type=DatasetInfoHook, tokenizer=tokenizer),
    dict(
        type=EvaluateChatHook,
        tokenizer=tokenizer,
        every_n_iters=evaluation_freq,
        evaluation_inputs=evaluation_inputs,
        system=SYSTEM,
        prompt_template=prompt_template)
]

if use_varlen_attn:
    custom_hooks += [dict(type=VarlenAttnArgsToMessageHubHook)]

# configure default hooks
default_hooks = dict(
    # record the time of every iteration.
    timer=dict(type=IterTimerHook),
    # print log every 10 iterations.
    logger=dict(type=LoggerHook, log_metric_by_epoch=False, interval=10),
    # enable the parameter scheduler.
    param_scheduler=dict(type=ParamSchedulerHook),
    # save checkpoint per `save_steps`.
    checkpoint=dict(
        type=CheckpointHook,
        by_epoch=False,
        interval=save_steps,
        max_keep_ckpts=save_total_limit),
    # set sampler seed in distributed evrionment.
    sampler_seed=dict(type=DistSamplerSeedHook),
)

# configure environment
env_cfg = dict(
    # whether to enable cudnn benchmark
    cudnn_benchmark=False,
    # set multi process parameters
    mp_cfg=dict(mp_start_method='fork', opencv_num_threads=0),
    # set distributed parameters
    dist_cfg=dict(backend='nccl'),
)

# set visualizer
visualizer = None

# set log level
log_level = 'INFO'

# load from which checkpoint
load_from = None

# whether to resume training from the loaded checkpoint
resume = False

# Defaults to use random seed and disable `deterministic`
randomness = dict(seed=None, deterministic=False)

# set log processor
log_processor = dict(by_epoch=False)

sft命令

cd /root/InternLM/XTuner
conda activate torch2_py310

xtuner train ./internlm2_chat_1_8b_qlora_alpaca_e3_copy.py

训练完后目录

├── work_dirs
│   └── internlm2_chat_1_8b_qlora_alpaca_e3_copy
│       ├── 20240626_222727
│       │   ├── 20240626_222727.log
│       │   └── vis_data
│       │       ├── 20240626_222727.json
│       │       ├── config.py
│       │       ├── eval_outputs_iter_95.txt
│       │       └── scalars.json
│       ├── internlm2_chat_1_8b_qlora_alpaca_e3_copy.py
│       ├── iter_96.pth
│       └── last_checkpoint

模型格式转换

使用 Pytorch 训练出来的模型权重文件转换为目前通用的 HuggingFace 格式文件

xtuner convert pth_to_hf 命令用于进行模型格式转换。该命令需要三个参数:CONFIG 表示微调的配置文件, PATH_TO_PTH_MODEL 表示微调的模型权重文件路径,即要转换的模型权重, SAVE_PATH_TO_HF_MODEL 表示转换后的 HuggingFace 格式文件的保存路径。

添加几个额外的参数,包括:

参数名 解释
–fp32 代表以fp32的精度开启,假如不输入则默认为fp16
–max-shard-size {GB} 代表每个权重文件最大的大小(默认为2GB)

cd /root/InternLM/XTuner
conda activate torch2_py310

# 先获取最后保存的一个pth文件
pth_file=`ls -t ./work_dirs/internlm2_chat_1_8b_qlora_assistant_e3/*.pth | head -n 1`
export MKL_SERVICE_FORCE_INTEL=1
export MKL_THREADING_LAYER=GNU
xtuner convert pth_to_hf ./internlm2_chat_1_8b_qlora_assistant_e3.py ${pth_file} ./hf

模型格式转换完成后,我们的目录结构应该是这样子的。

├── hf
│   ├── README.md
│   ├── adapter_config.json
│   ├── adapter_model.bin
│   └── xtuner_config.py

hf 文件夹即为我们平时所理解的所谓 “LoRA 模型文件”

可以简单理解:LoRA 模型文件 = Adapter

模型合并

对于全量微调的模型(full)其实是不需要进行整合这一步的,因为全量微调修改的是原模型的权重而非微调一个新的 Adapter ,因此是不需要进行模型整合的。

对于 LoRA 或者 QLoRA 微调出来的模型其实并不是一个完整的模型,而是一个额外的层(Adapter),训练完的这个层最终还是要与原模型进行合并才能被正常的使用。

xtuner convert merge命令用于合并模型。该命令需要三个参数:LLM 表示原模型路径,ADAPTER 表示 Adapter 层的路径, SAVE_PATH 表示合并后的模型最终的保存路径。

模型合并这一步还有其他很多的可选参数,包括:

参数名 解释
–max-shard-size {GB} 代表每个权重文件最大的大小(默认为2GB)
–device {device_name} 这里指的就是device的名称,可选择的有cuda、cpu和auto,默认为cuda即使用gpu进行运算
–is-clip 这个参数主要用于确定模型是不是CLIP模型,假如是的话就要加上,不是就不需要添加


cd /root/InternLM/XTuner
conda activate xtuner0121

export MKL_SERVICE_FORCE_INTEL=1
export MKL_THREADING_LAYER=GNU
xtuner convert merge /root/InternLM/XTuner/Shanghai_AI_Laboratory/internlm2-chat-1_8b ./hf ./merged --max-shard-size 2GB

模型合并完成后,我们的目录结构应该是这样子的。

├── merged
│   ├── config.json
│   ├── configuration_internlm2.py
│   ├── generation_config.json
│   ├── modeling_internlm2.py
│   ├── pytorch_model-00001-of-00002.bin
│   ├── pytorch_model-00002-of-00002.bin
│   ├── pytorch_model.bin.index.json
│   ├── special_tokens_map.json
│   ├── tokenization_internlm2.py
│   ├── tokenization_internlm2_fast.py
│   ├── tokenizer.json
│   ├── tokenizer.model
│   └── tokenizer_config.json

最终的模型和原模型文件夹非常相似,包括了分词器、权重文件、配置信息等等。

微调后的模型对话

将脚本中的模型路径修改为微调后的模型的路径。

# 直接修改脚本文件第18行
- model_name_or_path = "/root/InternLM/XTuner/Shanghai_AI_Laboratory/internlm2-chat-1_8b"
+ model_name_or_path = "/root/InternLM/XTuner/merged"

conda activate torch2_py310

streamlit run /root/InternLM/Tutorial/tools/xtuner_streamlit_demo.py

ssh -CNg -L 8501:127.0.0.1:8501 root@ssh.intern-ai.org.cn -p 47425

总结笔记

XTuner微调

XTuner 一个大语言模型&多模态模型微调工具箱。

由 MMRazor 和 MMDeploy 联合开发。

https://github.com/InternLM/Tutorial/blob/camp3/docs/L1/XTuner/xtuner_finetune_basic.md

🤓 傻瓜化: 以 配置文件 的形式封装了大部分微调场景,0基础的非专业人员也能一键开始微调。
🍃 轻量级: 对于 7B 参数量的LLM,微调所需的最小显存仅为 8GB : 消费级显卡✅,colab✅

xtuner 高阶教程

https://github.com/InternLM/Tutorial/blob/camp3/docs/L1/XTuner/xtuner_finetune_advance.md

在这里插入图片描述

LoRA简介

LoRA(Low-Rank Adaptation)是一种使用低精度权重对大型预训练语言模型进行微调的技术,它的核心思想是在不改变原有模型权重的情况下,通过添加少量新参数来进行微调。这种方法降低了模型的存储需求,也降低了计算成本,实现了对大模型的快速适应,同时保持了模型性能。

然而,由于使用了低精度权重,LoRA的一个潜在的缺点是在微调过程中可能会丢失一些原始模型的高阶特征信息,因此可能会降低模型的准确性。

QLoRA简介

QLoRA(Quantized LoRA)微调技术是对LoRA的一种改进,它通过引入高精度权重和可学习的低秩适配器来提高模型的准确性。并且在LoRA的基础上,引入了量化技术。通过将预训练模型量化为int4格式,可以进一步减少微调过程中的计算量,同时也可以减少模型的存储空间,这对于在资源有限的设备上运行模型非常有用。最终,可以使我们在消费级的显卡上进行模型的微调训练。

deepspeed

DeepSpeed是一个由微软开发的开源深度学习优化库,旨在提高大规模模型训练的效率和速度。它通过几种关键技术来优化训练过程,包括模型分割、梯度累积、以及内存和带宽优化等,能够降低训练超大规模模型的复杂性和资源需求,使训练变得更快、更高效。DeepSpeed特别适用于需要巨大计算资源的大型模型和数据集。
在DeepSpeed中,引入了ZeRO(Zero Redundancy Optimizer)技术,是一种旨在降低训练大型模型所需内存占用的优化器,通过在分布式环境中分割优化器的状态、梯度和参数,减少冗余的内存占用,允许更大的模型和更快的训练速度。ZeRO 分为几个不同的级别,主要包括:

deepspeed_zero1:这是ZeRO的基本版本,它优化了模型参数的存储,主要通过分区存储优化器状态来减少内存使用。每个GPU设备只保存一部分优化器状态,从而显著减少内存消耗。

deepspeed_zero2:在deepspeed_zero1的基础上,deepspeed_zero2进一步优化了梯度和优化器状态的存储,将梯度也进行分区存储。这样,每个GPU设备只需要保存一部分的优化器状态和梯度,进一步减少内存使用。

deepspeed_zero3:这是目前最高级的优化等级,它包括了deepspeed_zero1和deepspeed_zero2的优化,除了优化器状态和梯度,还将模型参数进行分区存储。每个GPU设备只需要保存一部分的优化器状态、梯度和模型参数,从而最大限度地减少内存使用。

选择哪种deepspeed类型主要取决于你的具体需求,包括模型的大小、可用的硬件资源(特别是GPU内存)以及训练的效率需求。一般来说:

如果你的模型较小,或者内存资源充足,可能不需要使用最高级别的优化。
如果你需要快速训练模型,可能需要权衡内存优化和计算效率。deepspeed_zero1提供了较低的内存占用,同时保持了较高的计算效率。
如果你正在尝试训练非常大的模型,或者你的硬件资源有限,使用deepspeed_zero2或deepspeed_zero3可能更合适,因为它们可以显著降低内存占用,允许更大模型的训练。
选择时也要考虑到实现的复杂性和运行时的开销,更高级的优化可能需要更复杂的设置,更频繁的跨GPU通信,这可能需要更高的网络带宽,并可能增加一些计算开销。

  • 25
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值