小白避坑指南:国内用Colossal-AI微调DeepSeek 1.5B的完整踩坑记录(附镜像加速方案)

概要

 由于笔者是为了记录自己的踩坑记录,会讲述基本流程,但具体的技术细节,我就不深入探讨,直接实操,咱们干中学吧!!!

我会尽量用通俗易懂的语言进行表达,由于笔者能力有限,有错误之处,请大家多多担待,可以在评论区跟我指出交流。

基本流程

1 从hugging face上下载我们需要微调的模型,这里笔者试了很多方法。

2 署环境了,这里一定需要使用国内镜像(特别快)。

3 下载数据集

4 编写微调代码(官网也有提供的微调代码示例)

5 记录使用Colossal-Ai微调时间和GPU显存的占用率

笔者的环境是:

1 操作系统:Linux Ubuntu 22.04

2 GPU:两块A100 80G

基础知识

Colossal-Ai

Colossal-AI 是一个面向大规模深度学习模型训练的开源框架,能够让我们可以进行单机多卡的分布式训练。我们只需要调用相应的官方提供的API就能够相应的策略(像笔者有两张A100的卡就能得到的充分利用)。

Lora(Low-Rank Adaptation)

LoRA 是一种针对大模型微调(Fine-tuning)的一种高效参数更新方法 ,能够通过低秩矩阵分解,减少微调时的参数量和计算量。

模型下载

本项目使用的模型是deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B官网地址 这里笔者用了很多方法,要么太慢,要么中断,最后还是本地下载文件再scp上传到服务器上去,评论区如果有更好的方法,可以交流一下。

1 使用Git LFS进行git clone国内镜像ModelScope,一直是提示连接超时。

2 使用 huggingface-cli 工具,使用命令行工具进行下载,还是超时。

3 直接使用transformers的from_pretrained函数,等了半天没反应,放弃。

最后只能手动下载文件,上传到服务器上。

环境部署

很棒,模型下载好了,现在我们需要运行模型。环境的创建我就不教了,直接附上指令。

1 创建python环境

bash 复制代码
conda create -n deepseek python=3.9 -y
conda activate deepseek
pip install torch==1.12.1+cu113 torchvision==0.13.1+cu113 torchaudio==0.12.1 --extra-index-url https://download.pytorch.org/whl/cu113 -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install transformers datasets accelerate peft colossalai -i https://pypi.tuna.tsinghua.edu.cn/simple

注意:

1 安装pytorch的gpu版本时要注意要自己的CUDA驱动版本是否适配

2 Colossal-AI目前只支持transformer-4.39.3版本,所以有些模型是不支持训练的。

数据集下载

下载地址 数据集格式: json文件,具有三个属性段,questionresoningresponse

微调代码

1 首先先编写配置文件,config.py

python 复制代码
DATASET_PATH = os.path.expanduser(
    "/home/idal-01/wxc/deepseek/health_dataset/distill_psychology-10k-r1.json"
)
`TRAIN_CONFIG = {
    "model_name": "/home/idal-01/wxc/deepseek/deepseek_1.5B"
}

2 接着再对数据进行处理,编写数据处理文件data_loader.py

python 复制代码
from datasets import load_dataset
from transformers import AutoTokenizer
from config import DATASET_PATH, TRAIN_CONFIG
def load_data(tokenizer):
    # 自定义格式化函数
    def format_func(examples):
        texts = [
            f"Instruction: {q}\nResponse: {a}"
            for q, a in zip(examples["input"], examples["content"])
        ]
        return {"text": texts}
    # 加载并处理数据集
    dataset = load_dataset("json", data_files=DATASET_PATH, split="train")
    dataset = dataset.map(format_func, batched=True)
    # 分词处理
    tokenized = dataset.map(
        lambda x: tokenizer(
            x["text"],
            max_length=TRAIN_CONFIG["training"]
         	truncation=True,
            padding="max_length",
            return_tensors="pt"
        ),
        batched=True
    )
    return tokenized

3 编写微调代码(主要介绍关于colossal-ai的代码部分)

1)初始化分布式后端,也就是先创建分布式环境,分布式环境所需的参数,如 rank, world size, host 和 port 都是由 PyTorch 启动器设置的,可以使用colossalai.launch_from_torch()这个函数直接从环境变量中读取。

python 复制代码
colossalai.launch_from_torch()

2)选择需要的插件,官网提供的插件包括Torch DDP 插件、Torch FSDP 插件、Low Level Zero 插件、Gemini 插件以及Hybrid Parallel 插件。我们可以选择适合自己模型训练的插件。插件详细信息查看

p 复制代码
plugin = GeminiPlugin(...)
booster = Booster(plugin=plugin)

3)用 colossalai.booster 将训练特征注入您的训练组件(如模型、优化器、损失函数和学习率调度器)中,本质上是对于模型进行的再次封装,要注意封装过后,模型很多原来的函数使用方式要变,封装后的模型不具备原本的函数。

python 复制代码
model, optimizer, _, dataloader, lr_scheduler = booster.boost(
        model=model,
        optimizer=optimizer,
        lr_scheduler=lr_scheduler,
        dataloader=dataloader,
    )

4)官网提供了支持LoRa的API使用方法,使其支持LoRa,一定不要使用peft里面的LoRa方法,笔者已经踩过坑了(由于已经封装的原因,但最后要么无法保存Lora适配器模型,要么无法进行训练,因为官网没有提供解封装的API)。

p 复制代码
lora_config = LoraConfig(
       task_type="CAUSAL_LM",
       r=args.lora_rank,
       lora_alpha=args.lora_alpha,
       target_modules=["gate_proj", "up_proj", "down_proj"],
)
model = booster.enable_lora(model, lora_config=lora_config)

5) 如果要开启梯度检查点,model一定要提前经过booster封装。

p 复制代码
model.gradient_checkpointing_enable()

6) 如果要开启快速注意力机制(Flash attention),梯度剪裁(grad_clip),梯度累积(gradient_accumulation),训练精度(mixed_precision),梯度缩放(initial_scale)以及融合归一化(Fused Normalization),需要在插件初始化的时侯进行传参。

p 复制代码
 plugin = GeminiPlugin(
    precision=args.mixed_precision,
    initial_scale=2**16,
    max_norm=args.grad_clip,
    enable_gradient_accumulation=(args.accumulation_steps > 1),
    enable_fused_normalization=get_accelerator().is_available(),
    enable_flash_attention=args.use_flash_attn,
)

7)保存模型一定要用官网给的API接口函数,不然将保存不到Lora的适配器。

p 复制代码
booster.save_lora_as_pretrained(model, os.path.join(args.save_dir, "lora"))

8)我们可以通过命令行传参数过去,我列举几个必须的,其余参数都是类似编写。

p 复制代码
    parser.add_argument(
        "-m",
        "--pretrained",
        type=str,
        required=True,
        help="Address of the pre-trained model",
    )
    parser.add_argument("-d", "--dataset", type=str, required=True, help="Raw Jonl dataset for training.")
    parser.add_argument(
        "-p",
        "--plugin",
        type=str,
        default="zero2",
        choices=["gemini", "gemini_auto", "zero2", "zero2_cpu", "3d", "ddp", "moe"],
        help="Choose which plugin to use",
    )

命令行启动训练

bash 复制代码
colossalai run --nproc_per_node 2 lora_finetune.py --pretrained /home/idal-01/wxc/deepseek/deepseek_1.5B --dataset /home/idal-01/wxc/deepseek/health_dataset/ --plugin "zero2" --save_dir ./finetuned_model --tensorboard_dir ./logs --num_epochs 5 --batch_size 2  --accumulation_steps 2  --lr 1e-5 --max_length 2048     --mixed_precision "bf16"  --grad_clip 1.0 --weight_decay 0.01 --warmup_steps 100 --lora_rank 8  --lora_alpha 16  --use_flash_attn
css 复制代码
这是我使用的微调参数进行的训练
--plugin "zero2"
--num_epochs 5
--batch_size 2
--accumulation_steps 2
--lr 1e-5
--max_length 2048
--mixed_precision "bf16"
--grad_clip 1.0
--weight_decay 0.01
--warmup_steps 100
--lora_rank 16
--lora_alpha 32
--use_flash_attn
target_modules=["gate_proj", "up_proj", "down_proj"]

训练过程:

显存占用:单GPU 11165MiB 利用率 82%-85%

小结

完整的微调训练代码如果有需要的友友可私信我。

编写代码时遇到的主要问题(踩过的坑):

1 没注意到模型已经被封装过,使用之前的函数经常会出错

2 因为使用的deepseek-Qwen系列蒸馏模型,要求字符填充是向左, 默认是向右,所以需要更改方向,不过由于是分布式训练是多进程的,只改主进程是不行的,需要子进程也需要同步。

3 使用梯度检查点时--use_grad_checkpoint,一定要注意跟插件是否冲突,不然可以不能进行反向传播

4 使用HybridAdam优化器报错,发现需要GNU的版本不对,我想了想避免产生更大的问题,我还是老老实实用了Adam优化器。

写在最后

以后还是要及时编写博客,因为好多东西是一段时间之前的,很多坑已经忘了,写了一些印象比较深的坑。此外还希望大家多多点赞关注收藏。

请大家一定一定要关注!!!
请大家一定一定要关注!!!
请大家一定一定要关注!!!
友友们,你们的支持是我持续更新的动力~


创作不易,求关注,点赞,收藏,谢谢~

相关推荐
老白干19 分钟前
jjwt 0.9.1 在 JDK 11+ 上的两个“坑”与完整解决方案
java·python·log4j
笨鸟先飞,勤能补拙7 小时前
AI 赋能网络安全:技术全景、成熟度评估与实战案例
人工智能·python·安全·web安全·网络安全·sqlite·github
长和信泰光伏储能8 小时前
京津冀光伏发电:绿色能源的未来之路
python·能源
浦信仿真大讲堂8 小时前
从重复操作到自动化闭环:如何让 CST 与 Python 真正协同起来
python·自动化·cst·仿真软件·达索软件
Gu Gu Study9 小时前
ScoutLoop开放域深度研究引擎(agent的初步设计想法)
人工智能·python
卷无止境9 小时前
写代码这件事,到底该讲究点什么?
后端·python
卷无止境9 小时前
循环复杂度到底在算什么,Python 代码怎么才能写得让人一看就懂
后端·python
lpfasd1239 小时前
MediaCrawler 项目深度分析
chrome·python·chrome devtools
Dxy123931021610 小时前
Python项目打包成EXE完整教程(PyInstaller实战避坑)
开发语言·python
bamb0010 小时前
一个项目带你入门AI应用开发01
python