你好,我是邢云阳。
上节课,我带领你借助开源大模型微调工具 LLama-Factory 对 DeepSeek-R1-Distill-Qwen-7B 进行了微调,实现了新闻分类器的效果。通过这样一个挺有意思的小案例,想必你也感受到了微调的魅力。这节课我们就把目光投向另一个大模型里常用的技术——蒸馏。
什么是蒸馏
那在春节前后呢,另一个大模型术语——蒸馏也是火起来了,不管知不知道啥叫蒸馏,反正都听说过。我在课程的第一讲曾用一个《射雕英雄传》的例子简单讲解过啥叫微调,今天我们就更加简单粗暴地讲解一下。
其实蒸馏呢,本质上也是微调的一种类型。传统微调是为了让大模型获取一些私域知识,比如股票、医疗等等,这是让大模型的知识面增加了,但没有改变大模型的能力。而蒸馏不一样,蒸馏不光教知识,还要教能力。所谓授之以鱼,不如授之以渔,蒸馏就是要让被训练的模型能够学会教师模型的能力。
我们知道传统的一些快速响应模型,比如 qwen2.5、llama3 等等模型是不带思维链的。但 DeepSeek-R1 模型带有思维链,而且思考能力很强。因此对 DeepSeek-R1 蒸馏的意义就是要让 qwen2.5 等模型也学会思维链,就是这么简单。
那接下来,我们看一下蒸馏一个自己的小模型,应该怎么做。
蒸馏的流程
首先,我们知道,只要涉及到微调,就少不了数据集,因此需要先从数据集着手。我在这画了一张简单的图来说明如何生成数据集。

首先,我们需要准备好一份传统的数据集,比如一些新闻标题的数据。
CF生存特训:落地“加特林”,还剩一滴血,千钧一发,队友来救!
崔海涛篆刻艺术展将于5月12日在青岛举行
球员生涯还剩一个月,吴伟超回忆申花邀请:曾以为是个玩笑
之后我们需要将这些数据喂给满血版的 DeepSeek-R1:671B 模型,让 DeepSeek-R1:671B 为我们输出带有思考过程和结果的回答,这便是我们的教学数据。那 DeepSeek-R1:671B 输出的回答的实际格式是什么样的呢?我们在之前的模型部署课程上,曾经用 curl 命令对 DeepSeek-R1 模型进行过提问,模型给出的回复格式是:
{"id":"chat-7b3532b3c7e3481b86104f17f744f26c","object":"chat.completion","created":1740925630,"model":"deepseek-r1","choices":[{"index":0,"message":{"role":"assistant","
content":"<think>我 是 DeepSeek-R1, 一 个 由 深 度 求 索 公 司 开 发 的 智 能 助 手 , 我 擅 长 通 过 思 考 来 帮 您 解 答 复 杂 的 数 学 , 代 码 和 逻 辑 推 理 等 理 工 类 问 题 。 \n</think>\n\n我 是 DeepSeek-R1, 一 个 由 深 度 求
索 公 司 开 发 的 智 能 助 手 , 我 擅 长 通 过 思 考 来 帮 您 解 答 复 杂 的 数 学 , 代 码 和 逻 辑 推 理 等 理 工 类 问 题 。 ","tool_calls":[]},"logprobs":null,"finish_reason":"stop","stop_reason":null}],"usa
ge":{"prompt_tokens":9,"total_tokens":108,"completion_tokens":99},"prompt_logprobs":null}
也就是说是如下形式:
<think>思考过程 \n</think>\n\n结果
当我们拿这些教学数据再去微调小模型时,就可以让小模型学会 DeepSeek-R1:671B 同款的输出回答的模式,这种微调方式叫做监督微调。

到此,蒸馏的流程就讲完了,整个过程其实非常简单,一点也不神秘,无非就是教学数据的生成与传统微调的教学数据相比,增加了思考过程。
那讲完了理论,接下来我们就开始实践。我们以 qwen2.5-7B 模型为例,蒸馏出一个我们自己的 DeepSeek-R1-Distill-Qwen2.5-7B 模型。
如何生成教学数据
首先从生成教学数据开始。
前面我们已经知道想要,生成用于蒸馏小模型的教学数据,需要将原始数据喂给 DeepSeek-R1大模型,从而生成带有高格调思考过程的问答对。
因此教学数据的模型,本质上还是 prompt 工程的范畴,需要我们根据实际业务情况编写合适的 prompt,这个每一种业务都不一样,无法形成一个标准的模板,但我们可以用新闻分类器的例子演示一下思路。
由于 DS 官方的服务器最近不是特别稳定,我依然使用的阿里云百炼提供的满血版 DeepSeek-R1 671B服务。我准备的原始数据集的样式如下:
新闻分类:《美国队长4》被调侃为《关云长4:周仓传》
新闻分类:特朗普与泽连斯基在白宫举行会谈时爆发激烈争吵
....
之后我的提示词这样写:
system = """
你是一个新闻分类器,擅长根据新闻标题识别新闻的类型,新闻种类包括:政治、经济、科技、娱乐、体育、教育、健康、国际、国内、社会。用户会在需要进行分类的新闻标题前加入"新闻分类:"字样,你需要给出该新闻的种类。要求包含思考过程和最终答案。
#要求格式:
<think>
思考过程(分步骤解释如何从给定信息中推导出答案)
</think>
答案(政治、经济、科技、娱乐、体育、教育、健康、国际、国内、社会中的某一种)
#示例1:
human: 新闻分类:给力!中国两次出手,美到手的订单黄了,该国从此只认中国制造!
gpt:
<think>
首先,我需要分析给出的新闻标题:“给力!中国两次出手,美到手的订单黄了,该国从此只认中国制造!”
接下来,根据标题内容进行分类。标题中提到了中国两次行动导致美国订单出现问题,并且其他国家开始依赖中国制造,说明这涉及国家之间的经济合作和社会影响。
结合新闻种类,考虑到涉及国际贸易和经济合作,最合适的分类是“经济”。所以,这条新闻应该归类到“经济”类别中。
</think>
经济
"""
这份提示词首先描述了需求,规定了新闻的分类有哪些种,还告诉了大模型当用户输入什么格式的内容时,大模型需要进行分类。之后的要求格式的样式,大家可以当作模板,然后根据自己的实际业务修改答案部分的描述。
比较难的部分在于示例,这块就是我给很多同学回复留言时说的,要懂业务,如果不懂业务,提示词都写不出来。这是因为我们需要写一个 think 的例子,例子要逼真,符合 DS-R1 的口吻,这样才能得到好的效果。
之后就是常规的向大模型提问,以及反馈答案的代码了。我们就以“新闻分类:《美国队长4》被调侃为《关云长4:周仓传》”为例,进行测试。
completion = client.chat.completions.create(
model="deepseek-r1",
messages=[
{'role': 'system', 'content': system},
{'role': 'user', 'content': '新闻分类:《美国队长4》被调侃为《关云长4:周仓传》'},
]
)
# 通过reasoning_content字段打印思考过程
print("<think>")
print(completion.choices[0].message.reasoning_content)
print("</think>")
# 通过content字段打印最终答案
print(completion.choices[0].message.content)
输出为:
<think>
首先,我需要分析用户提供的新闻标题:“《美国队长4》被调侃为《关云长4:周仓传》”。标题中提到了《美国队长4》,这是一部著名的超级英雄电影,属于娱乐产业的内容。此外,标题提到该电影被调侃为《关云长4:周仓传》,后者可能涉及对中国传统故事或影视作品的戏仿,这种调侃通常出现在娱乐新闻
中,用于吸引观众注意或制造话题。
接下来,考虑新闻分类的选项:政治、经济、科技、娱乐、体育、教育、健康、国际、国内、社会。这里的关键词是电影名称和调侃,明显与影视娱乐相关,没有涉及其他如经济、政治或科技的元素。因此,最合适的分类应为“娱乐”。
</think>
娱乐
我们就生成了第一条教学数据,我们只需要再将这条教学数据包装成问答对的形式即可。格式如下:
[
{
"conversations": [
{
"from": "human",
"value": "新闻分类:《美国队长4》被调侃为《关云长4:周仓传》"
},
{
"from": "gpt",
"value": "<think>\n首先,我需要分析用户提供的新闻标题:“《美国队长4》被调侃为《关云长4:周仓传》”。标题中提到了《美国队长4》,这是一部著名的超级英雄电影,属于娱乐产业的内容。此外,标题提到该电影被调侃为《关云长4:周仓传》,后者可能涉及对中国传统故事或影视作品的戏仿,这种调侃通常出现在娱乐新闻中,用于吸引观众注意或制造话题。\n\n接下来,考虑新闻分类的选项:政治、经济、科技、娱乐、体育、教育、健康、国际、国内、社会。这里的关键词是电影名称和调侃,明显与影视娱乐相关,没有涉及其他如经济、政治或科技的元素。因此,最合适的分类应为“娱乐”\n</think>\n\n娱乐"
}
]
}
]
接下来的事情就是苦力活了,你可以写一个循环执行的程序,有多少条原始数据就执行多少次以上步骤。所以这个过程是很慢的,建议最好多开几个账号并行执行。
微调与测试
由于上节课,我们使用的新闻分类器的数据是带有以上格式的,因此我们可以直接拿过来做教学数据,对 Qwen2.5-7B 进行微调。微调工具还是使用 LLama-Factory,参数与上节课一模一样。
微调之后,我们使用 Chat 功能测试一下,首先测试原版的 Qwen2.5-7B 的效果。

可以看到完全没有思考过程,也没有进行分类。
接着测试微调后的 Qwen2.5-7B。

可以看到有思考过程,也有结果。到此我们就成功蒸馏出了一个自己的 DeepSeek-R1-Distill-Qwen2.5-7B 模型。
总结
今天我们通过新闻分类器的案例,系统梳理了模型蒸馏的全流程。很多同学可能没有想到,在蒸馏过程中编写prompt同样是关键环节。这也印证了我常强调的观点——完成高质量的prompt设计,就意味着完成了50%-70%的模型开发工作。
至此,这一章内容即将告一段落。我们完整探讨了大模型落地的核心路径——从不同部署方案的选择,到微调与蒸馏的技术实践,形成了如下图模型开发的全流程知识体系。

最后,我梳理了一个表格,为大家整理了一下模型部署方案的对比,方便大家学习理解。

这一章的内容是最近的一个热点,但对于很多公司里目前没搞私有化部署的同学来说,可能暂时只能做到了解是怎么回事,但没法实操。不过我相信随着模型蒸馏技术的发展,各细分行业都用上普惠小模型的时代不远了,到时候就是大家在公司内展现能力的时候。
思考题
这节课我们微调 Qwen2.5-7B 模型和上节课微调 DeepSeek-R1-Ditill-Qwen-7B模型,都用了同一份数据集,和同样的微调参数,为什么我们能这么做呢?微调这两个模型的意义分别是什么呢?
欢迎你在留言区展示你的思考结果,我们一起探讨。如果你觉得这节课的内容对你有帮助的话,也欢迎你分享给其他朋友,我们下节课再见!
精选留言
2025-03-21 09:00:50
还有一个问题,之前简单了解过蒸馏,其中提到一个过程【学生模型通过模仿教师模型的输出(如预测概率分布、中间特征等)】这个该怎么理解呢?感谢老师的解答。
2025-03-21 16:53:40
2025-04-07 17:19:54
1. 如果我不在意思考能力,只在意最终结果的准确性,那么是不是“教学数据”中就不需要准备 <think> 标签的内容了?(当然可能也不需要用具备推理能力的R1模型了)
2. “教学数据” 中的数据为什么定义成您文稿中的格式呢?格式是由谁决定的?LLama-Factory 吗?
3. 还是数据格式的问题,阿里百炼平台数据集格式有 SFT 文本生成、DPO 文本生成、CPT 文本生成等,他们的格式跟您文稿中的格式差异性很大。所以是不是跟“执行微调”的过程强相关的,不同的工具或平台都有自己独特的实现?
2025-03-23 10:05:32
2025-04-16 16:18:04
2025-04-02 09:05:06
2025-03-24 19:49:01
先在大模型上跑出带思考过程的数据对,然后喂给小模型,让小模型学会这套方式,就是蒸馏吗?
2025-03-21 21:46:27
2025-03-21 07:58:45
2025-07-25 16:04:28
2025-06-03 09:15:32
2025-06-03 09:12:29
2025-05-26 11:36:07
2025-05-13 17:44:59
2025-04-21 14:53:16
2025-04-11 14:15:58
" "
2025-04-10 12:40:28
2025-04-06 13:26:56