当前位置: 首页 > news >正文

DeepSeek+LoRA微调大模型实战

对于大模型微调,无意间在bilibili找到这个视频教程,讲解的很细致、全面,收获很多,故写本文仅作记录。
哔哩哔哩:https://www.bilibili.com/video/BV1ZLTVzNE9T
github:https://github.com/huangyf2013320506

1.简介

主要分成以下五部分:

1.1 需求和技术

  • 企业对于大模型的不同类型个性化需求。

  • SFT(有监督微调)、RLHF(强化学习)、RAG(检索增强生成)。
    关注:基本概念;分别解决什么问题;如何根据需求选择。

  • 微调部分详细介绍:微调算法分类、LoRA微调算法、微调常见实现框架。

1.2 整体步骤说明

在Linux系统上微调一个大模型、部署模型、暴露API给web后端调用,前端展示。

1.3 微调模型

  • 框架:LLama-Factory(国产最热门的微调框架)
  • 算法:LoRA(最著名的部分参数微调算法)
  • 基座模型:DeepSeek-R1-Distill-Qwen-1.5B。蒸馏技术通常用于通过将大模型(教师模型)的知识转移到小模型(学生模型)中,使得小模型能够在尽量保持性能的同时,显著减少模型的参数量和计算需求。

1.4 模型部署和暴露接口

框架:FastAPI(一个基于python的web框架)。

1.5 web后端调用

通过HTTP请求交互即可(demo前后端代码见文章开头github或文章末尾资源分享)。

2. 需求和技术

2.1 企业对于大模型的不同类型个性化需求

  • 提高模型对企业专有信息的理解、增强模型在特定领域的知识-SFT。
    案例一:希望大模型能更好理解蟹堡王的企业专有知识,如蟹老板的女儿为什么是一头鲸鱼。
    案例二:希望大模型能特别精通于汉堡制作,并熟练回答关于汉堡行业的所有问题。

  • 提供个性化和互动性强的服务-RLHF。
    案例三:希望大模型能够基于顾客的反馈调整回答方式,比如生成更二次元风格的回答还是更加学术风格的回答。

  • 提高模型对企业专有信息的理解、增强模型在特定行业领域的知识、获取和生成最新的、实时的信息 - RAG。
    案例四:希望大模型能够实时获取蟹堡王的最新的促销活动信息和每周菜单更新。

2.2 SFT(有监督微调)、RLHF(强化学习)、RAG(检索增强生成)

2.2.1 SFT(Supervised Fine-Tuning)有监督微调

  • 通过提供人工标注的数据,进一步训练预训练模型,让模型能够更加精准地处理特定领域的任务;
  • 除了“有监督微调”,还有“无监督微调”“自监督微调”,当大家提到“微调”时通常是指有监督微调。

2.2.2 RLHF(Reinforcement Learning from Human Feedback)强化学习

  • DPO(Direct Preference Optimization)
    核心思想:通过 人类对比选择(例如:A 选项和 B 选项,哪个更好)直接优化生成模型,使其产生更符合用户需求的结果;调整幅度大。

  • PPO(Proximal Policy Optimization)
    核心思想:通过 奖励信号(如点赞、点踩)来 渐进式调整模型的行为策略;调整幅度小。

2.2.3 RAG(Retrieval-Augmented Generation)检索增强生成

将外部信息检索与文本生成结合,帮助模型在生成答案时,实时获取外部信息和最新信息。

2.3 微调还是RAG?

  • 微调:
    适合:拥有非常充足的数据;
    能够直接提升模型的固有能力;无需依赖外部检索。

  • RAG:
    适合:只有非常非常少的数据;动态更新的数据;
    每次回答问题前需耗时检索知识库;回答质量依赖于检索系统的质量。

  • 总结:
    少量企业私有知识:最好微调和 RAG 都做;资源不足时优先 RAG;
    会动态更新的知识:RAG;
    大量垂直领域知识:微调。

2.4 SFT(有监督微调)

通过提供人工标注的数据,进一步训练预训练模型,让模型能够更加精准地处理特定领域的任务。

  • 人工标注的数据:
如:分类系统
{"image_path": "path/image1.jpg", "label": "SpongeBobSquarePants"}
{"image_path": "path/image2.jpg", "label": "PatrickStar"}
如:对话系统
{"instruction": "请问你是谁","input": "","output": "您好,我是蟹堡王的神奇海螺,很高兴为您服务!我可以回答关于蟹堡王和汉堡制作的任何问题,您有什么需要帮助的吗?"
},
  • 预训练模型(基座模型)
    指已经在大量数据上训练过的模型,也就是我们微调前需要预先下载的开源模型。它具备了较为通用的知识和能力,能够解决一些常见的任务,可以在此基础上进行进一步的微调(fine-tuning)以适应特定的任务或领域。

  • 微调算法-全参数微调(Full Fine-Tuning):对整个预训练模型进行微调,会更新所有参数。
    优点:因为每个参数都可以调整,通常能得到最佳的性能;能够适应不同任务和场景。
    缺点:需要较大的计算资源并且容易出现过拟合。

  • 微调算法-部分参数微调(Partial Fine-Tuning):只更新模型的部分参数(例如某些层或模块)。
    优点:减少了计算成本;减少过拟合风险;能够以较小的代价获得较好的结果。
    缺点:可能无法达到最佳性能。
    最著名算法:LoRA。

2.5 LoRA微调算法

  • 论文阅读-LoRA 开山论文:
    2021 年 Microsoft Research 提出,首次提出了通过低秩矩阵分解的方式来进行部分参数微调,极大推动了 AI 技术在多行业的广泛落地应用:https://arxiv.org/abs/2106.09685

  • 论文阅读-大语言模型开山论文:
    大语言模型开山论文:2017 年 Google Brain 团队发布,标志着 Transformer 架构的提出,彻底改变了自然语言处理(NLP)领域,标志着大语言模型时代的开始:https://arxiv.org/abs/1706.03762

  • 什么是矩阵的“秩”
    矩阵的秩(Rank of a matrix)是指矩阵中线性无关的行或列的最大数量。简单来说它能反映矩阵所包含的有效信息量。

  • LoRA如何做到部分参数微调
    在这里插入图片描述

  • LoRA 训练结束后通常需要进行权重合并。

2.6 微调常见实现框架

  • 初学者如何对大模型进行微调?

  • Llama-Factory:由国内北航开源的低代码大模型训练框架,可以实现零代码微调,简单易学,功能强大,且目前热度很高,建议新手从这个开始入门。

  • transformers.Trainer:由 Hugging Face 提供的高层 API,适用于各种 NLP 任务的微调,提供标准化的训练流程和多种监控工具,适合需要更多定制化的场景,尤其在部署和生产环境中表现出色。

  • DeepSpeed:由微软开发的开源深度学习优化库,适合大规模模型训练和分布式训练,在大模型预训练和资源密集型训练的时候用得比较多。

3.模型微调

3.1 准备硬件资源、搭建环境

  • 在云平台上租用一个实例(如 AutoDL,官网:https://www.autodl.com/market/list)
  • 云平台一般会配置好常用的深度学习环境,如 anaconda, cuda等等。

3.2 本机通过SSH连接到远程服务器

  • 使用 Visual Studio Remote 插件 SSH 连接到你租用的服务器,参考文档:使用VSCode插件Remote-SSH连接服务器

  • 连接后打开个人数据盘文件夹“ /root/autodl-tmp”
    在这里插入图片描述

3.3 LLaMA-Factory安装部署

LLaMA-Factory的github地址:https://github.com/hiyouga/LLaMA-Factory

  • 克隆仓库:
cd /root/autodl-tmp
git clone --depth 1 https://github.com/hiyouga/LLaMA-Factory.git
  • 切换到项目目录
cd LLaMA-Factory
  • 修改配置,将 conda 虚拟环境安装到数据盘(这一步建议做,方便单独备份数据盘数据)
mkdir -p /root/autodl-tmp/conda/pkgs 
conda config --add pkgs_dirs /root/autodl-tmp/conda/pkgs 
mkdir -p /root/autodl-tmp/conda/envs 
conda config --add envs_dirs /root/autodl-tmp/conda/envs
  • 创建 conda 虚拟环境(一定要 3.10 的 python 版本,不然和 LLaMA-Factory 不兼容)
conda create -n llama-factory python=3.10
  • 激活虚拟环境:
conda activate llama-factory
  • 在虚拟环境中安装 LLaMA Factory 相关依赖:
pip install -e ".[torch,metrics]"

注意:如报错 bash: pip: command not found ,先执行 conda install pip 即可。(这个我没遇到)

  • 检验是否安装成功
llamafactory-cli version

3.4 启动 LLama-Factory 的可视化微调界面 (由 Gradio 驱动)

llamafactory-cli webui

3.5 配置端口转发

  • 参考文档:SSH隧道
  • 在本地电脑的终端(cmd / powershell / terminal等)中执行代理命令,其中root@123.125.240.150和42151分别是实例中SSH指令的访问地址与端口,请找到自己实例的ssh指令做相应替换。7860:127.0.0.1:7860是指代理实例内7860端口到本地的7860端口。
ssh -CNg -L 7860:127.0.0.1:7860 root@123.125.240.150 -p 42151

3.6 从 HuggingFace 上下载基座模型

HuggingFace 是一个集中管理和共享预训练模型的平台:https://huggingface.co/;

从 HuggingFace 上下载模型有多种不同的方式,可以参考:https://zhuanlan.zhihu.com/p/663712983

  • 创建文件夹统一存放所有基座模型
cd /root/autodl-tmp
mkdir Hugging-Face
  • 修改 HuggingFace 的镜像源
export HF_ENDPOINT=https://hf-mirror.com
  • 修改模型下载的默认位置
export HF_HOME=/root/autodl-tmp/Hugging-Face
  • 注意:这种配置方式只在当前 shell 会话中有效,如果你希望这个环境变量在每次启动终端时都生效,可以将其添加到你的用户配置文件中(修改 ~/.bashrc 或 ~/.zshrc)。

  • 检查环境变量是否生效

echo $HF_ENDPOINT
echo $HF_HOME
  • 安装 HuggingFace 官方下载工具
pip install -U huggingface_hub
  • 执行下载命令
huggingface-cli download --resume-download deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B
  • 如果直接本机下载了模型压缩包,如何放到你的服务器上?——在 AutoDL 上打开 JupyterLab 直接上传,或者下载软件通过 SFTP 协议传送。

3.7 可视化页面上加载模型测试,检验是否加载成功

  • 注意:这里的路径是模型文件夹内部的模型特定快照的唯一哈希值,而不是整个模型文件夹。
    在这里插入图片描述
/root/autodl-tmp/Hugging-Face/hub/models--deepseek-ai--DeepSeek-R1-Distill-Qwen-1.5B/snapshots/ad9f0ae0864d7fbcd1cd905e3c6c5b069cc8b562

3.8 准备用于训练的数据集,添加到指定位置

  • README_zh 中详细介绍了如何配置和描述你的自定义数据集。
  • 按照格式准备用于微调的数据集 magic_conch.json,数据示例:
[{"instruction": "请问你是谁","input": "","output": "您好,我是蟹堡王的神奇海螺,很高兴为您服务!我可以回答关于蟹堡王和汉堡制作的任何问题,您有什么需要帮助的吗?"},{"instruction": "怎么修复这个报错","input": "我正在使用蟹堡王全自动智能汉堡制作机,报错信息是:汉堡食谱为空","output": "根据您提供的错误信息,'汉堡食谱为空' 可能是因为系统没有加载正确的食谱文件或食谱文件被删除。您可以尝试以下步骤:\n1. 检查食谱文件是否存在,并确保文件路径正确。\n2. 重新加载或更新食谱文件。\n3. 如果问题依然存在,尝试重启机器并检查是否有软件更新。\n希望这些步骤能帮助您修复问题。如果仍有困难,请与蟹堡王技术支持联系。"}
]
  • 修改 dataset_info.json 文件,添加如下配置:
"magic_conch": {
"file_name": "magic_conch.json"
},
  • 将数据集 magic_conch.json 放到 LLama-Factory 的 data 目录 下。

3.9 在页面上进行微调的相关设置,开始微调

在这里插入图片描述

  • 选择微调算法 Lora。

  • 添加数据集 magic_conch。

  • 修改其他训练相关参数,如学习率、训练轮数、截断长度、验证集比例等:
    ①学习率(Learning Rate):决定了模型每次更新时权重改变的幅度。过大可能会错过最优解;过小会学得很慢或陷入局部最优解。
    ②训练轮数(Epochs):太少模型会欠拟合(没学好),太大会过拟合(学过头了)。
    ③最大梯度范数(Max Gradient Norm):当梯度的值超过这个范围时会被截断,防止梯度爆炸现象。
    ④最大样本数(Max Samples):每轮训练中最多使用的样本数。
    ⑤计算类型(Computation Type):在训练时使用的数据类型,常见的有 float32 和 float16。在性能和精度之间找平衡。
    ⑥截断长度(Truncation Length):处理长文本时如果太长超过这个阈值的部分会被截断掉,避免内存溢出。
    ⑦批处理大小(Batch Size):由于内存限制,每轮训练我们要将训练集数据分批次送进去,这个批次大小就是 Batch Size。
    ⑧梯度累积(Gradient Accumulation):默认情况下模型会在每个 batch 处理完后进行一次更新一个参数,但你可以通过设置这个梯度累计,让他直到处理完多个小批次的数据后才进行一次更新。
    ⑨验证集比例(Validation Set Proportion):数据集分为训练集和验证集两个部分,训练集用来学习训练,验证集用来验证学习效果如何。
    ⑩学习率调节器(Learning Rate Scheduler):在训练的过程中帮你自动调整优化学习率。

  • 页面上点击启动训练,或复制命令到终端启动训练。
    实践中推荐用 nohup 命令将训练任务放到后台执行,这样即使关闭终端任务也会继续运行。同时将日志重定向到文件中保存下来。

  • 在训练过程中注意观察损失曲线,尽可能将损失降到最低。
    如损失降低太慢,尝试增大学习率。
    如训练结束损失还呈下降趋势,增大训练轮数确保拟合。

3.10 微调结束,评估微调效果

  • 观察损失曲线的变化;观察最终损失。
  • 在交互页面上通过预测/对话等方式测试微调好的效果。
  • 检查点:保存的是模型在训练过程中的一个中间状态,包含了模型权重、训练过程中使用的配置(如学习率、批次大小)等信息,对LoRA来说,检查点包含了训练得到的 B 和 A 这两个低秩矩阵的权重。
  • 若微调效果不理想,你可以:
    ①使用更强的预训练模型;
    ②增加数据量;
    ③优化数据质量(数据清洗、数据增强等,可学习相关论文如何实现);
    ④调整训练参数,如学习率、训练轮数、优化器、批次大小等等。

3.11 导出合并后的模型

  • 为什么要合并:因为 LoRA 只是通过低秩矩阵调整原始模型的部分权重,而不直接修改原模型的权重。合并步骤将 LoRA 权重与原始模型权重融合生成一个完整的模型。
  • 先创建目录,用于存放导出后的模型。
mkdir -p Models/deepseek-r1-1.5b-merged
  • 在页面上配置导出路径,导出即可。
    在这里插入图片描述

4.模型部署和暴露接口

4.1 创建新的conda虚拟环境用于部署模型

  • 创建环境
conda create -n fastApi python=3.10
  • 激活环境
conda activate fastApi
  • 在该环境中部署模型需要的依赖
conda install -c conda-forge fastapi uvicorn transformers pytorch
pip install safetensors sentencepiece protobuf

4.2 通过FastAPI部署模型并暴露HTTP接口

  • 创建 App文件夹
cd /root/autodl-tmp
mkdir App
  • 创建main.py,作为启动应用的入口
touch main.py
  • 修改main.py文件并保存
from fastapi import FastAPI
from transformers import AutoModelForCausalLM, AutoTokenizer
import torchapp = FastAPI()# 模型路径
model_path = "/root/autodl-tmp/Models/deepseek-r1-1.5b-merged"# 加载 tokenizer (分词器)
tokenizer = AutoTokenizer.from_pretrained(model_path)# 加载模型并移动到可用设备(GPU/CPU)
device = "cuda" if torch.cuda.is_available() else "cpu"
model = AutoModelForCausalLM.from_pretrained(model_path).to(device)@app.get("/generate")
async def generate_text(prompt: str):# 使用 tokenizer 编码输入的 promptinputs = tokenizer(prompt, return_tensors="pt").to(device)# 使用模型生成文本outputs = model.generate(inputs["input_ids"], max_length=150)# 解码生成的输出generated_text = tokenizer.decode(outputs[0], skip_special_tokens=True)return {"generated_text": generated_text}
  • 进入包含 main.py 文件的目录,然后运行以下命令来启动 FastAPI 应用
uvicorn main:app --reload --host 0.0.0.0
- `main` 是 Python 文件名(要注意不包含 `.py` 扩展名)
- `app` 是 FastAPI 实例的变量名(代码中 `app = FastAPI()`)
- `--reload` 使代码更改后可以自动重载,适用于开发环境
- `host 0.0.0.0`:将 FastAPI 应用绑定到所有可用的网络接口,这样我们的本机就可以通过内网穿透访问该服务
  • 配置端口转发,使得本机可以访问该服务SSH隧道
  • 浏览器输入以下url,测试服务是否启动成功
http://localhost:8000/docs

在这里插入图片描述

  • 使用postman测试
http://localhost:8000/generate?prompt=你好

在这里插入图片描述

5.web后端调用

5.1 pom.xml导入依赖

<dependency>  <groupId>org.apache.httpcomponents.client5</groupId>  <artifactId>httpclient5</artifactId>  <version>5.2.1</version>  
</dependency>

5.2 自定义方法发送并处理 HTTP 请求,实现对话功能

@Service  
public class ChatServiceImpl implements ChatService {  @Autowired  private RestTemplate restTemplate;  @Autowired  private AiServiceConfig aiServiceConfig;  @Override  public String callAiForOneReply(String prompt) {  // 获取基础URL http://localhost:8000  String baseUrl = aiServiceConfig.getBaseUrl();  // 构建完整的请求URL http://localhost:8000/generate?prompt=XXX  String url = String.format("%s/generate?prompt=%s", baseUrl, prompt);  // 发送GET请求并获取响应  GenerateResponse response = restTemplate.getForObject(url, GenerateResponse.class);  // 从响应中取出 generated_text 字段值返回  return response != null ? response.getGenerated_text() : "";  }  
}

5.3 启动前端项目

  • 项目地址
https://github.com/huangyf2013320506/magic_conch_frontend.git
  • 执行
npm install
npm run dev

5.4 启动后端项目

  • 后端项目地址
https://github.com/huangyf2013320506/magic_conch_backend.git
  • 执行
mvn clean install

5.5 效果

在这里插入图片描述

5.6 如何开放服务端口到公网

AutoDL 当前仅支持个人用户通过端口转发在本地访问服务,如需开放服务端口到公网一般需要企业认证,请参考:开放端口

5.7 企业部署还需考虑高并发、高可用、安全机制等问题

6.相关资源

百度网盘: https://pan.baidu.com/s/1kcVWWVOC4hdljl9dJSchHg?pwd=5kb7
阿里云盘:https://www.alipan.com/s/43fZFRJpKG1
在这里插入图片描述

http://www.dtcms.com/a/289576.html

相关文章:

  • 【机器学习深度学习】魔塔社区模型后缀全解析:Base、Chat、Instruct、Bit、Distill背后的技术密码
  • 【Java多线程-----复习】
  • InfluxDB 核心概念与发展历程全景解读(二)
  • AtCoder Beginner Contest 415
  • 数控调压BUCK电路 —— 基于TPS56637(TI)
  • 乐观锁实现原理笔记
  • Android activity与service通信的三种方法
  • 30天打牢数模基础-K均值聚类
  • (DINO)Emerging Properties in Self-Supervised Vision Transformers论文精读(逐段解析)
  • (苍穹外卖)暑假学习理解P2
  • 从零搭建智能搜索代理:LangGraph + 实时搜索 + PDF导出完整项目实战
  • [C/C++安全编程]_[中级]_[如何安全使用循环语句]
  • k8s:离线部署存在的相关问题
  • 近期工作感想:职业规划篇
  • 【单片机外部中断实验修改动态数码管0-99】2022-5-22
  • Linux文件系统三要素:块划分、分区管理与inode结构解析
  • 本地部署开源离线内容浏览器 Kiwix 并实现外部访问( Windows 版本)
  • 【Java新特性】Java 21 新特性全解析
  • CSS面试题及详细答案140道之(121-140)
  • 快速理解LLM的temperature和top_p参数
  • 设备健康管理实施案例:从技术架构到落地效果的全栈解析
  • MCP实战案例|Trae2.0 一键创建旅行助手并一键部署EdgeOne
  • ARFoundation系列讲解 - 101 VisionPro 真机调试
  • Vue中组件的生命周期
  • 建筑墙壁损伤缺陷分割数据集labelme格式7820张20类别
  • Django ORM系统
  • [学习] Hilbert变换:从数学原理到物理意义的深度解析与仿真实验(完整实验代码)
  • 平安车管家|中国平安车管家入职测评16PF瑞文IQ测评答题攻略及真题题库
  • 嵌入式系统内核镜像相关(十七)
  • AI 的广泛应用是否会削弱人的思考能力和创造力?