DeepSeek-R1 模型微调系列
DeepSeek-R1 模型微调系列一. 前言介绍本文内容:1.1 项目背景1.2 LoRA和 QLoRA 简介1.3 LLaMA 架构和 Qwen 架构LLaMA 架构Qwen 架构二. 环境准备2.1 Unsloth 安装(显卡版本-暂时不用)2.2 创建Python项目2.3 python 依赖库2.2 LoRA peft 安装2.3 WandB 设置2.4 modelscope pull 模型2.5 测试模型使用三. 训练数据数据3.1 准备数据集3.2 数据清洗3.3 训练数据3.3 训练模型并保存3.4 合并模型文件3.4 评估和监控训练过程评估(eval/
)相关信息:训练(train/
)相关信息:
一. 前言介绍
本文内容:
-
模型加载与预处理:详细讲解如何加载预训练模型、分词器,并处理输入数据集。
-
LoRA配置:介绍如何使用LoRA技术配置模型,并高效进行微调,节省计算资源。
-
训练过程:展示了如何配置训练参数,使用SFTTrainer进行训练,并通过WandB记录训练日志。
-
模型保存与评估:如何保存微调后的模型,以及如何通过合适的评估集对模型进行验证。
-
模型合并:展示了如何通过加权平均的方式合并多个模型权重,得到一个更强大的模型。
1.1 项目背景
本文档描述了如何在MAC笔记本上对 DeepSeek-R1-Distill-Llama-1.5B Qwen架构 进行高效微调,使用** transformers 进行数据处理,并结合 LoRA 技术进行模型微调,使用 WandB 监控训练过程, ModelScope 下载模型。(训练数据量大约2w条左右)
-
由于为MAC笔记本本地训练 无显卡支持 故而放弃(DeepSeek-R1-Distill-Qwen-7B Q wen)
下载的服务信息如下:
安装服务 | 版本名称 | 作用 |
---|---|---|
Unsloth | 用于数据处理和模型微调。 | |
Transformers | Hugging Face 提供的模型库,用于加载和微调 DeepSeek-R1。 | |
WandB | 用于训练过程的实时监控和可视化。 | |
LoRA | 用于微调的低秩适应技术。 | |
ModelScope | 用于下载 DeepSeek-R1-8b 模型。 | |
python3.11 | Python 3.11 | 用于执行 Python 脚本和训练任务。 |
1.2 LoRA和 QLoRA 简介
以下是 LoRA 和 QLoRA 的区别表格:
特性 | LoRA (Low-Rank Adaptation) | QLoRA (Quantized LoRA) |
---|---|---|
核心原理 | 通过低秩矩阵分解减少需要调整的参数量 | 在 LoRA 的基础上结合量化技术,进一步减少存储和计算需求 |
主要优点 | 降低训练时需要调整的参数数量,提高微调效率 | 除了低秩矩阵,还通过量化减少内存占用,适用于资源有限的环境 |
存储需求 | 较低,但不如 QLoRA 节省内存 | 显著减少内存使用,适合在内存受限的设备上使用 |
计算效率 | 提高训练效率,减少计算资源消耗 | 量化后的低精度计算进一步提高了计算效率,降低了开销 |
适用场景 | 计算资源有限但不需要极限压缩的场景 | 内存和计算资源极其有限的环境,特别是在边缘设备上使用 |
适用硬件 | 适用于大多数硬件设备,尤其是高性能计算环境 | 特别适合内存有限的硬件,如边缘设备、低内存服务器等 |
1.3 LLaMA 架构和 Qwen 架构
特性 | LLaMA 架构 | Qwen 架构 |
---|---|---|
开发者 | Meta(Facebook) | 深度求索(DeepSeek) |
设计目标 | 高效、轻量化 | 中文优化、多语言支持 |
参数量 | 7B、13B、33B、65B 等 | 7B、14B 等 |
开源情况 | 开源 | 部分开源或未完全公开 |
适用场景 | 资源有限的环境 | 中文任务、多语言任务 |
LLaMA 架构
-
全称:Large Language Model Meta AI(LLaMA)
-
开发者:由 Meta(原 Facebook)开发。
-
特点:
-
高效性:LLaMA 旨在以较少的参数量实现高性能,专注于优化计算效率。
-
轻量化:模型参数量相对较小(如 7B、13B、33B、65B),但通过高质量数据和训练方法,性能接近甚至超越更大的模型。
-
开源:Meta 发布了 LLaMA 的权重和代码,供研究社区使用。
-
-
应用场景:
-
适合资源有限的环境,如本地部署或移动设备。
-
适用于各种 NLP 任务,尤其是在生成、问答、文本分类等任务中,具有较好的性能和效率。
-
Qwen 架构
-
开发者:由中国的深度求索(DeepSeek)团队开发。
-
特点:
-
定制化设计:Qwen 可能是针对中文或特定任务优化的架构,具体细节未完全公开。
-
多语言支持:Qwen 系列模型通常对中文有较好的支持,同时在英文和多语言任务上也有不错的表现。
-
参数量灵活:Qwen 系列包括不同规模的模型(如 7B、14B 等),适合不同场景。
-
-
应用场景:
-
Qwen 适用于文本生成、自动化内容创作、对话系统、语音合成等任务。
-
二. 环境准备
2.1 Unsloth 安装(显卡版本-暂时不用)
-
Unsloth 是一个用于数据处理和模型微调的工具。您可以通过以下命令安装:
-
MAC不试用,需要显卡
##官网:https://github.com/unslothai/unsloth
#01 创建项目,并设置python虚拟环境,python3.11版本
#02 安装 unsloth(cpu版本)
brew install llvm(Homebrew clang version 19.1.7)
echo 'export PATH="/opt/homebrew/opt/llvm/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
pip install torch
pip install numpy
pip install "unsloth[colab-new] @ git+https://github.com/unslothai/unsloth.git"
#03 版本检查
python -c "import torch; print(torch.__version__)"
2.6.0
#04 引用
from unsloth import FastLanguageModel
安装完成后,您可以使用 Unsloth 进行数据的预处理、加载和微调模型。
-
暂时不使用
#01 linux 服务建议使用docker
#02 拉取镜像
docker pull modelscope-registry.us-west-1.cr.aliyuncs.com/modelscope-repo/modelscope:ubuntu22.04-py310-torch2.3.1-1.22.2
#03 启动
2.2 创建Python项目
#01 环境是python3.11
#02 项目目录
Unsloth-DeepSeek-R1-8b/
├── data/ # 存放训练数据、验证数据等
│ ├── raw/ # 原始数据
│ └── processed/ # 预处理后的数据
│
├── models/ # 存放模型文件
│ ├── checkpoints/ # 存储训练过程中的模型检查点
│ └── final_model/ # 存储最终微调后的模型
│
├── scripts/ # 存放训练脚本、数据处理脚本等
│ ├── train.py # 训练脚本
│ ├── data_preprocessing.py# 数据预处理脚本
│ └── evaluate.py # 评估脚本
│
├── logs/ # 存放训练日志文件
│ └── training_logs.txt # 训练过程中的日志
│
├── wandb/ # 存放 wandb 相关的配置和记录
│ └── wandb_config.py # wandb 配置文件
│
├── environment/ # 环境配置文件
│ ├── requirements.txt # 项目的 Python 依赖
│ └── environment.yml # 如果使用 Conda,可以创建一个环境配置文件
│
├── main.py # 主运行文件,启动训练或其他任务
└── README.md # 项目的描述文件,包含如何使用和运行的说明
#03 创建目录
# 创建子目录
mkdir -p data/raw
mkdir -p data/processed
mkdir -p models/checkpoints
mkdir -p models/final_model
mkdir -p scripts
mkdir -p logs
mkdir -p wandb
mkdir -p environment
# 创建文件
touch scripts/train.py
touch scripts/data_preprocessing.py
touch scripts/evaluate.py
touch logs/training_logs.txt
touch wandb/wandb_config.py
touch environment/requirements.txt
touch environment/environment.yml
touch main.py
touch README.md
2.3 python 依赖库
#03 安装即可
pip install torch==2.6.0 transformers datasets
#03 更新证书(后续如果有pip网站使用https 会验证该证书)
/Applications/Python\ 3.11/Install\ Certificates.command
2.2 LoRA peft 安装
LoRA 和 PEFT 的安装:
-
LoRA 和 PEFT 是用于高效微调的技术。如果你想在 Mac 上使用这些技术来微调 DeepSeek 模型,你需要安装相关的依赖项。
-
PEFT 包含了 LoRA 的实现,并且它使得你能够通过修改模型的一部分参数来进行高效微调,从而不需要调整整个模型的权重。
#01 安装 peft
pip install peft
2.3 WandB 设置
WandB 是一个用于训练过程实时监控和可视化的工具。您可以通过以下步骤设置 WandB:
-
注册并登录 WandB官网。
-
获取您的 API 密钥并配置环境变量:
#01 aipkey (本人谷歌邮箱)
#02 命令
pip install wandb
wandb login
#02 运行文件
import wandb # 导入 wandb 库,用于跟踪和可视化实验
import random # 导入 random 库,用于生成随机数
# 开始一个新的 wandb 运行来跟踪当前脚本
wandb.init(
# 设置 wandb 项目,所有与该运行相关的数据将被记录到这个项目中
project="my-awesome-project", # 项目名称,你可以在 wandb 仪表盘中看到这个项目
# 追踪超参数和运行的元数据
config={
"learning_rate": 0.02, # 设置学习率
"architecture": "CNN", # 模型架构(这里是卷积神经网络)
"dataset": "CIFAR-100", # 使用的数据集(这里是 CIFAR-100 数据集)
"epochs": 10, # 训练的轮数
}
)
# 模拟训练过程
epochs = 10 # 总训练轮数
offset = random.random() / 5 # 生成一个小的随机偏移量,用于模拟训练过程中一些不确定性
# 开始训练循环,模拟 2 到 10 轮的训练过程
for epoch in range(2, epochs): # 从第二轮开始,到第 10 轮结束
# 模拟准确率的变化,随着 epoch 的增加,准确率逐渐提升
acc = 1 - 2 ** -epoch - random.random() / epoch - offset
# 模拟损失的变化,随着 epoch 的增加,损失逐渐减少
loss = 2 ** -epoch + random.random() / epoch + offset
# 使用 wandb 记录每一轮的准确率(acc)和损失值(loss)
wandb.log({"acc": acc, "loss": loss})
# [可选] 结束 wandb 运行,确保数据被正确上传并完成记录
wandb.finish()
2.4 modelscope pull 模型
#01 安装modelscope
pip install modelscope
#02 下载模型文件
mkdir -p ./models/DeepSeek-R1-Distill-Llama-8B
mkdir -p ./models/DeepSeek-R1-Distill-Qwen-1.5B
mkdir -p ./models/DeepSeek-R1-Distill-Qwen-7B
modelscope download --model deepseek-ai/DeepSeek-R1-Distill-Llama-8B --local_dir ./models/DeepSeek-R1-Distill-Llama-8B
modelscope download --model deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B --local_dir ./models/DeepSeek-R1-Distill-Qwen-1.5B
modelscope download --model deepseek-ai/DeepSeek-R1-Distill-Qwen-7B --local_dir ./models/DeepSeek-R1-Distill-Qwen-7B
modelscope download --model deepseek-ai/DeepSeek-R1-Distill-Llama-8B --local_dir ./DeepSeek-R1-Distill-Llama-8B
2.5 测试模型使用
"""
训练前询问问题:
皮质醇增多症患者在血浆ACTH明显升高且大剂量地塞米松抑制试验阳性的情况下,应考虑哪种疾病?
训练后再次询问:
scripts/test_inference.py
"""
import os
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
# 获取当前脚本的路径
current_dir = os.path.dirname(__file__)
# 拼接模型和分词器路径
model_dir = os.path.join(current_dir, '..', 'models', 'DeepSeek-R1-Distill-Qwen-1.5B')
# 打印路径确认
print(f"Model path: {model_dir}")
# 确保模型和分词器的路径存在
if not os.path.exists(model_dir):
raise ValueError(f"Model directory does not exist at {model_dir}")
else:
print("Model directory exists, proceeding with loading.")
# 加载模型和分词器
print("Loading model and tokenizer...")
model = AutoModelForCausalLM.from_pretrained(model_dir)
tokenizer = AutoTokenizer.from_pretrained(model_dir)
# 打印模型和分词器的配置信息
print(f"Model config: {model.config}")
print(f"Tokenizer config: {tokenizer}")
# 输入中文文本
input_text = "皮质醇增多症患者在血浆ACTH明显升高且大剂量地塞米松抑制试验阳性的情况下,应考虑哪种疾病?"
print(f"User input: {input_text}")
# 结构化的 prompt
prompt_style_chat = f"""请写出一个恰当的回答来完成当前对话任务。
### Instruction:
你是一名助人为乐的助手。
### Question:
{input_text}
### Response:
<think>"""
# 使用分词器处理输入文本
inputs = tokenizer(prompt_style_chat, return_tensors="pt", padding=True, truncation=True, max_length=512)
# 打印 tokenized 输入
print(f"Tokenized input: {inputs}")
# 打印输入形状
print(f"Input shape: {inputs['input_ids'].shape}")
# 打印模型的最大长度
print(f"Model max length: {model.config.max_position_embeddings}")
# 将模型移至正确的设备(使用 GPU 如果可用)
device = "cuda" if torch.cuda.is_available() else "cpu"
model.to(device)
# 打印设备信息