从零开始的DeepSeek微调训练实战(SFT)

从零开始的DeepSeek微调训练实战(SFT)

前言

本文重点介绍使用微调框架unsloth,围绕DeepSeek R1 Distill 7B模型进行高效微调,并介绍用于推理大模型高效微调的COT数据集的创建和使用方法,并在一个medical-o1-reasoning-SFT数据集上完成高效微调实战,并最终达到问答风格优化&知识灌注目的。

你能收获什么:

亲手完成DeepSeek R1蒸馏模型的微调实战

对模型微调、推理数据集等知识有一定了解

对大模型运行的机制和原理有一定的了解

有机会制作一个属于自己的定制化大模型

复现仅需7G显存、半小时运行时间即可完成一次最小可行性实验,并获得微调效果。本人使用的GPU信息如下所示,使用平台为云开发平台ADC:

从零开始的DeepSeek微调训练实战(SFT)

一、基础概念介绍

1.1 微调与强化学习、模型蒸馏

伴随着DeepSeek的兴起,关于强化学习训练、模型蒸馏等概念也逐渐被人熟知,这里简单总结下这三者的异同。微调、强化学习训练和模型蒸馏都是常用的技术方法,尽管这些方法在某些方面存在交集,但它们的核心原理和任务目标却有显著差异。

1. 微调(Fine-tuning):

微调是指在已经训练好的大型预训练模型的基础上,进一步训练该模型以适应特定任务或特定领域的数据。相比从零开始训练一个模型,微调所需的数据和计算资源显著减少;可以在特定任务上取得更好的性能,因为模型在微调过程中会重点学习与任务相关的特性;可以在多种领域(如情感分析、问答系统等)上进行微调,从而快速适应不同应用场景。

举个?:想象一下,你有一只机器人狗,它已经在基本的狗行为上进行了初步训练,比如行走和听从简单的命令。微调就像是对这只机器狗进行进一步的训练以适应特定的任务环境。比如说,你希望这只机器狗能够在公园里捡回特定种类的球。通过微调,你可以在原有的训练基础上,用一组特定的数据集(比如各种颜色和大小的球)来调整其行为,使其在新环境中表现得更好。


目标:通过少量的标注数据对预训练模型进行优化,适应具体任务。

特点:微调的计算量相对较小,能够在有限的数据和计算资源下提升模型在特定任务上的性能。

应用:常用于下游任务如情感分析、机器翻译、推荐系统等。

2. 强化学习(Reinforcement Learning):

强化学习是一种机器学习方法,它通过让智能体在环境中执行动作,以获得反馈或奖励信号,从而学习最优策略。通过不断地试错和调整策略,智能体逐渐找到能够最大化长期回报的行为路径。这种学习方法常用于需要决策和动态环境交互的任务,如游戏、机器人导航和自动化控制系统。

举个?:强化学习训练则有点像是教这只机器狗通过尝试和错误来学习新技能。在这种情况下,你没有直接告诉它应该怎么做,而是为它设定一个目标,比如尽可能快地找到并捡起一只球。机器狗每完成一次任务都会获得奖励,然后它将通过调整自己的行为来最大化获得的奖励。例如,如果机器狗发现跑直线能更快地找到球,它可能会在未来的尝试中更倾向于这样做。

目标:通过与环境的交互,学习最优的行为策略,最大化累积奖励。

特点:强化学习强调动态决策,它通常不依赖于预定义的数据集,而是依赖于与环境的持续交互。

应用:强化学习在游戏AI(如AlphaGo)、机器人控制、自动驾驶等任务中有广泛应用。

3. 模型蒸馏(Model Distillation):

模型蒸馏是一种模型压缩技术,通过将一个复杂的大型模型(通常称为“教师模型”)中的知识迁移到一个更小的模型(称为“学生模型”)。在这个过程中,教师模型首先对训练数据进行预测,生成软标签即概率分布。这些软标签包含了有关任务的重要信息。学生模型则使用这些软标签进行训练,以接近教师模型的性能。模型蒸馏能够在保持高精度的同时,显著减少模型的大小和计算消耗,适用于在资源受限的环境下部署机器学习模型。

举个?:你有一只非常昂贵和精密的机器人狗,它可以完美执行任务。为了降低成本,你希望制造一个更简单的机器狗,同样能有效完成任务。通过模型蒸馏,你会使用大狗的行为数据来训练小狗,让后者理解和模仿前者的精妙动作,同时保持高效性。

目标:通过教师模型的“知识转移” ,帮助学生模型提升性能,特别是计算能力有限的设备上。

特点:蒸馏的核心在于知识的迁移,尤其是在模型压缩和部署方面的优势。学生模型通常在性能上能接近教师模型,但参数量更小,计算更高效。

应用:常见于模型压缩、边缘计算、低功耗设备的部署中,用于提升部署效率并降低计算需求。

1.2 大模型微调

与RAG(Retrieval-Augmented Generation)或Agent技术依靠构建复杂的工作流以优化模型性能不同,微调通过直接调整模型的参数来提升模型的能力。这种方法让模型通过在特定任务的数据上进行再训练,从而‘永久’掌握该任务所需的技能。微调不仅可以显著提高模型在特定领域或任务上的表现,还能使其适应于各种具体应用场景的需求。这种能力的增强是通过更精细地调整模型内部的权重和偏差,使其在理解和生成信息时更加精准,因此被广泛用于需要高精度和领域适应性的任务中

从广义上讲,微调可以分为两种主要方式:全量微调和高效微调。全量微调是指利用所有可用数据来重新训练模型,以全面优化其参数。尽管这种方法对计算资源的需求较高,但它能够在最大程度上提升模型对特定任务的适应能力。相反,高效微调则采用更精简的策略,只使用部分数据进行调整,并主要修改模型的部分参数。这种方法以相对较低的计算开销,实现对模型性能的显著提升,类似于“以小博大”,非常适合在资源有限的情况下快速调整和增强模型的性能。

全量微调(Full Fine-Tuning)

举个?:想象一下你在一家公司管理一个团队,这个团队的所有成员已经接受了基础培训,知道如何处理一般的工作任务。现在,公司引入了一个全新的复杂项目,要求团队具备更多的专业技能和知识。

优点:全面掌握所有相关技能,使模型对新任务有更高的适应性。

缺点:耗时更长,资源消耗大。

高效微调(Efficient Fine-Tuning)

高效微调的方法更有针对性,它不需要花费大量的时间和资源。举个?:比如,如果机器人狗的任务只是要学会在一种新环境中识别特别的障碍物,你可以在已有的模型基础上,仅仅微调那些与识别相关的参数,而无需重新训练整个模型。

优点:节省时间和资源,快速提升特定技能。

缺点:可能不如全面培训那样细致和彻底,但能够在特定任务中高效达标。

现在绝大多数开源模型,在开源的时候都会公布两个版本的模型,其一是Base模型,该模型只经过了预训练,没有经过指令微调;其二则是Chat模型(或者就是不带尾缀的模型),则是在预训练模型基础上进一步进行全量指令微调之后的对话模型:

从零开始的DeepSeek微调训练实战(SFT)

尽管全量微调可以对模型的能力进行深度改造,但要带入模型全部参数进行训练,需要消耗大量的算力,且有一定的技术门槛。相比之下,在绝大多数场景中,如果我们只想提升模型某个具体领域的能力,那高效微调会更加合适。尽管在2020年前后,深度学习领域诞生了很多高效微调的方法,但现在适用于大模型的最主流的高效微调方法只有一种——LoRA。

LoRA( Low-Rank Adaptation)微调是一种参数高效的微调方法,旨在通过引入低秩矩阵来减少微 调时需要调整的参数数量,从而显著降低显存和计算资源的消耗。具体来说,LoRA 微调并不直接调整原始模型的所有参数,而是通过在某些层中插入低秩的适配器(Adapter)层来进行训练。

LoRA的原理:

在标准微调中,会修改模型的所有权重,而在 LoRA 中,只有某些低秩矩阵(适配器)被训练和调整。这意味着原始模型的参数保持不变,只是通过少量的新参数来调整模型的输出。

低秩矩阵的引入可以在显存和计算能力有限的情况下,依然有效地对大型预训练模型进行微调,从而让 LoRA 成为显存较小的设备上的理想选择。

举个?:想象你想教学生们怎样进行快速心算而不去完全打破他们原有的学习方法。你决定只引入一个简化版本的心算技巧,让他们在现有知识的基础上进行少量调整。这就像是把原有的学习方式轻量化处理,只增加所需的少量新知识,而不是重新教授整个数学课程。

LoRA的优势:

1.显存优化: 只需要调整少量的参数(适配器),显著减少了显存需求,适合显存有限的GPU。

2.计算效率: 微调过程中的计算负担也更轻,因为减少了需要调整的参数量。

3.灵活性: 可以与现有的预训练模型轻松结合使用,适用于多种任务,如文本生成、分类、问答等。

QLoRA(Quantized Low-Rank Adaptation) 则是 LoRA 的一个扩展版本,它结合了 LoRA 的低秩适配器和量化技术。QLoRA 进一步优化了计算效率和存储需求,特别是在极端显存受限的环境下。与 LoRA 不同的是, QLoRA 会将插入的低秩适配器层的部分权重进行量化(通常是量化为INT4或INT8),在保持性能的同时显著降低模型的存储和计算需求。

举个?:针对学生中一些学习资源(如时间或精力)更加有限的情况,你进一步优化教学方法,不仅简化了学习内容(类似LoRA),同时还用了一些有助于记忆的技巧(比如使用图像或口诀),从而更有效地传授知识。这样,每个学生能在有限时间内学会心算法。在技术上,QLoRA涉及量化(quantization)技术,将模型的一部分权重参数存储在较低精度的数值格式中,以此减少内存使用和计算量,同时结合LoRA的低秩调整,让适应过程更加高效。

QLoRA的优势

1.
在显存非常有限的情况下仍能进行微调。
2.
可以处理更大规模的模型。

3.适合用于边缘设备和需要低延迟推理的场景。

1.3 高效微调的应用场景

在实际大模型应用场景中,高效微调主要用于以下四个方面:

1.对话风格微调:高效微调可以用于根据特定需求调整模型的对话风格。例如,针对客服系统、虚拟助理等场景,模型可以通过微调来适应不同的语气、礼貌程度或回答方式,从而在与用户互动时提供更符合要求的对话体验。通过微调少量的参数(例如对话生成的策略、情感表达等),可以使模型表现出更具针对性和个性化的风格。

2.知识灌注:知识灌注是指将外部知识或领域特定的信息快速集成到已有的预训练模型中。通过高效微调,模型可以更好地学习新领域的专有知识,而无需重新从头开始训练。例如,对于法律、医疗等专业领域,可以使用少量的标注数据对预训练模型进行微调,帮助模型理解特定行业的术语、规则和知识,进而提升专业领域的问答能力。

3.推理能力提升:高效微调还可以用于提升大模型的推理能力,尤其是在处理更复杂推理任务时。通过微调,模型能够更加高效地理解长文本、推理隐含信息,或者从数据中提取逻辑关系,进而在多轮推理任务中提供更准确的答案。这种微调方式可以帮助模型在解答复杂问题时,提高推理准确性并减少错误。

4.Agent能力(Function calling & MCP能力)提升:在多任务协作或功能调用场景中,高效微调能够显著提升模型Agent能力,使得模型能够有效地与其他系统进行交互、调用外部API或执行特定MCP任务。通过针对性微调,模型可以学会更精准的功能调用策略、参数解析和操作指令,从而在自动化服务、智能助手或机器人控制等领域表现得更加高效和智能。

二、 DeepSeek R1 Distill高效微调环境准备

2.1 unsloth安装

unsloth是推理、微调一体式框架,unsloth将Llama 3.3、Mistral、Phi-4、Qwen 2.5和Gemma的微调速度提高2倍,同时节省80%的内存。

官网地址:GitHub – unslothai/unsloth: Finetune Llama 3, Mistral & Gemma LLMs 2-5x faster with 80% less memory

https://github.com/unslothai/unsloth

使用如下命令快速安装:

从零开始的DeepSeek微调训练实战(SFT)

2.2 wandb安装与注册

在大规模模型训练中,往往需要监控和分析大量的训练数据,而WandB可以帮助实现这一目标。它提供了以下几个重要的功能(注意数据安全问题,wandb内网穿透⚠️):
wandb官网:https://wandb.ai/site
使用邮箱注册后,记得拷贝下APIkey

从零开始的DeepSeek微调训练实战(SFT)
然后即可在令行中输入如下代码安装wandb:
可设置wandb进行微调记录,并可在对应网站上观察到训练过程如下:

从零开始的DeepSeek微调训练实战(SFT)

2.3 DeepSeek R1模型下载

ModelScope模型地址:https://www.modelscope.cn/models/deepseek-ai/DeepSeek-R1-Distill-Qwen-7B
从零开始的DeepSeek微调训练实战(SFT)
创建DeepSeek-R1-Distill-Qwen-7B文件夹,用于保存下载的模型权重:
即可使用如下命令进行模型下载:
也有其他的下载方法,视使用情况选择。

从零开始的DeepSeek微调训练实战(SFT)
下载后的模型的完整文件如下:

从零开始的DeepSeek微调训练实战(SFT)

2.4 微调数据

DeepSeek R1及其蒸馏模型,推理过程的具体体现就是在回复内容中,会同时包含推理部分内容和 最终回复部分内容,并且其推理部分内容会通过(一种在模型训练过程中注入的特殊标记)来进行区分。也就是说, DeepSeek R1模型组的回复格式是一种非常特殊的格式,即包含think部分内容,也包含 response部分内容。
因此,在围绕DeepSeek R1模型组进行微调的时候,微调数据集的回复部分文本也需要是包含推理 和最终回复两部分内容,才能使得DeepSeek R1模型组在保持既定回复风格的同时,强化模型能力,反之则会导致指令消融问题(模型回复不再包含think部分)。
此时think部分和最终回复,共同构成有监督微调的标签。

这种同时包含思考和结果的数据集,在当下并不少见,例如非常著名的数学问答数据集NuminaMath CoT,就同时包含数学问题、问题的解题思路(也就是think部分)和问题最终的答案。而该数据集也是可以用于推理模型微调的数据集。除了NuminaMath CoT数据集外,还有APPs(编程数据集)、 TACO(编程数据集)、long_form_thought_data_5k (通用问答数据集)等,都是CoT数据集,均可用于推理模型微调。

若实际业务有需要,也可以构造类似结构的数据集。

从零开始的DeepSeek微调训练实战(SFT)
本文选取的数据集是一个包含推理过程的医学数据集:由深圳大数据研究院发布的HuatuoGPT-o1模型的微调数据集—medical-o1-reasoning-SFT,地址:https://www.modelscope.cn/datasets/AI-ModelScope/medical-o1-reasoning-SFT。
为什么要选这个数据集:数学能力已经测试过了,想看看其在更难推理的场景下的能力

DeepSeek 教程

数据集总共包含25371条数据,均为医学领域疾病诊断数据集,且不乏一些疑难杂症的推理和判断,数据集整体质量较高,推理过程严谨准确,非常适合进行医疗领域模型微调,可以极大程度提高模型对于病理的推理过程,并在这个过程中完成一些医疗知识的灌注。

三、DeepSeek R1模型微调实操

3.1 unsloth LLama模型推理

需要借助unsloth进行模型推理
导入unsloth
首先设置关键参数,并读取模型:
关键参数
注,若显存不足,则可以load_in_4bit = True,运行4 bit量化版。
模型加载

现在要自定义微调,可以编辑上面的数字,也可以忽略它,因为已经默认选择了相当合理的数字。目标是改变这些数字以提高准确率,同时也抵消过度拟合。过度拟合是指让语言模型记住数据集,而无法回答新颖的新问题。希望最终模型能够回答从未见过的问题,而不是进行记忆。
微调过程的等级。数值越大,占用的内存越多,速度越慢,但可以提高复杂任务的准确性。我们通常建议数值为 8(用于快速微调),最高可达 128。数值过大可能会导致过度拟合,从而损害模型的质量。
选择所有模块进行微调。可以删除一些模块以减少内存使用量并加快训练速度,但强烈不建议这样做。只需在所有模块上进行训练!
微调的缩放因子。较大的数字将使微调更多地了解您的数据集,但可能会导致过度拟合。建议将其设置为等于等级
,或将其加倍。
将其保留为 0 以加快训练速度!可以减少过度拟合,但效果不大。
将其保留为 0,以实现更快、更少的过度拟合训练!

选项包括。建议使用,因为内存使用量减少了 30%,并支持极长的上下文微调。https://unsloth.ai/blog/long-context了解更多详细信息。

确定确定性运行的次数。训练和微调需要随机数,因此设置此数字可使实验可重复。

高级功能可自动设置

高级功能可将 LoRA 矩阵初始化为权重的前 r 个奇异向量。可以在一定程度上提高准确度,但一开始会使内存使用量激增。
输出

在INT4量化情况下,8B模型推理仅需7G左右显存。

此时model就是读取进来的DeepSeek R1 蒸馏模型:
模型信息

输出

tokenizer是分词器:
分词器

输出

将模型调整为推理模式:
推理模式

输出

然后即可和模型进行对话:
问题字符串
然后这里首先需要借助分词器,将输入的问题转化为标记索引:
转化为标记索引
索引信息

输出

最后再带入inputs进行对话
回答问题
此时得到的回复也是词索引:
回复索引
同样需要分词器将其转化为文本:
转化为文本

回复文字

输出

格式化输出一下:
格式化

输出

带入问答模板进行回答
结构化输入方法
提示词
问题

格式化输入

输出

分词

回复索引

回复文本

回复

输出

格式化

格式化回复

3.2 初始模型问答测试

为测试模型微调的能力,选取了医疗相关的数据集进行微调。
先简单测试下未经微调的模型能力,设置问答模板
提示词
翻译如下:
提示词翻译
接下来抽取部分medical-o1-reasoning-SFT数据集中问题进行提问,并查看初始状态下模型回答结果。
问题1

翻译

问题2

翻译

问答测试

问题1测试

回复

回复翻译

问题2测试
回复
回复翻译
标准答案
问题1标准答案
问题2标准答案
能够看出,在原始状态下,模型能够进行推理并给出回复,但实际上第一个回答过程并不符合医学规范,而第二个问题则直接回答错误。由此可见,在初始状态下,模型对于medical-o1-reasoning-SFT数据集问答效果并不好。
接下来尝试进行微调,并测试微调后模型问答效果。

3.3 最小可行性实验

接下来尝试进行模型微调,对于当前数据集而言,可以带入原始数据集的部分数据进行微调,也可以带入全部数据并遍历多次进行微调。对于大多数的微调实验,可以从最小可行性实验入手进行微调,也就是先尝试带入少量数据进行微调,并观测微调效果。若微调可以顺利执行,并能够获得微调效果,再考虑带入更多的数据进行更大规模微调。
这里直接从modelscope上下载medical-o1-reasoning-SFT数据集。

从零开始的DeepSeek微调训练实战(SFT)
如果有报错,按提示解决,如果还不行可以取hugging face的数据集,或者换其他数据集、或者将数据集下载到本地再读取。本人尝试了好多,有些数据集能成功,有些不行,各种莫名奇妙的报错,按报错提示改动即可。
数据集下载

查看

输出
在最小可行性实验中,可以下载500条数据进行微调即可看出效果:
划分数据集
然后提取并设置文本生成结束的标记:
文本生成结束标记
输出
然后定义函数,用于对medical-o1-reasoning-SFT数据集进行修改,Complex_CoT列和Response列进行拼接,并加上文本结束标记:
格式化函数
将数据集整理为如下形式:
数据格式化
产看格式化后的数据
输出
开启微调,把模型设置为微调模式:
微调模式
输出
然后导入相关的库:
导库
创建微调对象:
微调对象
通常不建议更改上述参数:
如果想更多地利用 GPU 的内存,增加批处理大小。同时增加批处理大小可以使训练更加流畅,并使过程不会过度拟合。通常不建议这样做,因为这可能会因填充问题而使训练速度变慢。通常会增加批处理大小,
这只会对数据集进行更多遍历。
相当于将批量大小增加到自身之上,但不会影响内存消耗,如果想要更平滑的训练损失曲线,通常建议增加这个值。
将步骤设置为 60 以加快训练速度。对于可能需要数小时的完整训练运行,请注释掉
,并将其替换为
。将其设置为 1 表示对数据集进行 1 次完整传递。通常建议传递 1 到 3 次,不要更多,否则微调会过度拟合。
如果想让微调过程变慢,但同时又最有可能收敛到更高的准确度结果,降低学习率。通常建议尝试 2e-4、1e-4、5e-5、2e-5 作为数字。
输出

开始微调


从零开始的DeepSeek微调训练实战(SFT)
这是训练损失,如果目标是设置参数,使其尽可能接近 0.5,如果微调未达到 1、0.8 或 0.5,可能需要调整一些数字。如果损失为 0,这可能也不是一个好兆头。

从零开始的DeepSeek微调训练实战(SFT)
注意,unsloth在微调结束后,会自动更新模型权重(在缓存中),因此无需手动合并模型权重即可直接调用微调后的模型:
输出
验证之前的问题:
问题验证
能够发现,问题回答更加规范,但仍可能存在一定的回答错误。由此可以考虑继续进行大规模微调。
此时本地保存的模型权重在outputs文件夹中:

从零开始的DeepSeek微调训练实战(SFT)
然后可使用如下代码进行模型权重合并:
权重合并
从零开始的DeepSeek微调训练实战(SFT)

3.4 微调参数解析

SFTTrainer 进行监督微调(Supervised Fine-Tuning, SFT),适用于 transformers 和 Unsloth 生态中的模型微调:1. 相关库

SFTTrainer(来自 trl 库):

trl(Transformer Reinforcement Learning)是 Hugging Face 旗下的 trl 库,提供监督微调(SFT) 和强化学习(RLHF)相关的功能。

SFTTrainer 主要用于有监督微调(Supervised Fine-Tuning),适用于 LoRA 等低秩适配微调方式。

TrainingArguments(来自 transformers 库):

这个类用于定义训练超参数,比如批量大小、学习率、优化器、训练步数等。

这个函数检查当前 GPU 是否支持 bfloat16(BF16),如果支持,则返回 True,否则返回 False

bfloat16 是一种更高效的数值格式,在新款 NVIDIA A100/H100 等GPU上表现更优。

2. 初始化 SFTTrainer
SFTTrainer 部分

TrainingArguments 部分

3.5 完整高效微调实验

接下来尝试带入全部数据进行高效微调,以提升模型微调效果。
完整代码:
完全跑下来时间可能比较久:

从零开始的DeepSeek微调训练实战(SFT)

10分钟构建能主动提问的智能导购

为助力商家全天候自动化满足顾客的购物需求,可通过百炼构建一个 Multi-Agent 架构的大模型应用实现智能导购助手。该系统能够主动询问顾客所需商品的具体参数,一旦收集齐备,便会自动从商品数据库中检索匹配的商品,并精准推荐给顾客。   

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:Ai探索者,转载请注明出处:https://javaforall.net/240851.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月16日 上午7:57
下一篇 2026年3月16日 上午7:57


相关推荐

关注全栈程序员社区公众号