小白避坑指南:国内用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优化器。

写在最后

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

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


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

相关推荐
莓事哒4 分钟前
selenium和pytessarct提取古诗文网的验证码(python爬虫)
爬虫·python·selenium·测试工具·pycharm
q5673152336 分钟前
使用puppeteer库编写的爬虫程序
爬虫·python·网络协议·http
mosquito_lover141 分钟前
Python数据分析与可视化实战
python·数据挖掘·数据分析
eqwaak01 小时前
量子计算与AI音乐——解锁无限可能的音色宇宙
人工智能·爬虫·python·自动化·量子计算
SylviaW081 小时前
python-leetcode 63.搜索二维矩阵
python·leetcode·矩阵
跳跳糖炒酸奶1 小时前
第四章、Isaacsim在GUI中构建机器人(1): 添加简单对象
人工智能·python·ubuntu·机器人
Niuguangshuo1 小时前
Python设计模式:克隆模式
java·开发语言·python
爱摄影的程序猿2 小时前
如何基于 Django-Vue-Admin 快速二次开发?高效后台管理系统实战指南(附完整代码)
vue.js·python·django
肖永威2 小时前
python列表常用方法大全
开发语言·python
凯强同学2 小时前
第十四届蓝桥杯大赛软件赛省赛Python 大学 C 组:6.棋盘
python·算法·蓝桥杯