大模型入门实战 | 单卡 3090 十分钟完成 Qwen2.5-7B 首次微调
这两年,大模型的发展十分火热。许多同学都让我讲讲大模型相关的知识点。今天,我先带大家完成一次入门级的实战微调教程,帮助大家理解大模型微调的基本流程。
很多人一听到“大模型”,就会下意识觉得需要烧显卡、成本高昂,普通人根本玩不起。其实并非如此——大模型有不同的尺寸,比如常见的 3B、7B 等,与 YOLO 系列中的 n、s、m、l 类似,仅仅是参数规模不同。
此外,大模型微调和从零训练的代价完全不同。微调远比大家想象的轻量,不需要投入庞大的计算资源。本教程将演示如何使用单张 RTX 3090(24GB 显存),在十分钟内完成一次 Qwen2.5-7B 的首次微调。
如果这个系列受欢迎,后面我也会继续分享更多大模型相关的实践与技巧。
一、准备工作
本教程需要 24GB 显存。如果你本地没有,可以选择租赁云服务器。
我推荐使用 蓝耘,通过我的专属注册链接注册可能还会送券(不保证现在还有)。
直接选择一台 3090 就够用。
二、下载模型
首先,安装并使用 huggingface_hub
下载模型:
pip install -U huggingface_hub
export HF_ENDPOINT=https://hf-mirror.com
huggingface-cli download --resume-download Qwen/Qwen2.5-7B-Instruct --local-dir Qwen2.5-7B-Instruct
三、安装微调环境
我们使用的是 ms-swift
微调框架:
pip install ms-swift -U
安装完成后,可以先使用如下的指令运行一次原始模型,
CUDA_VISIBLE_DEVICES=0 \
swift infer \--model Qwen2.5-7B-Instruct \--model_type qwen \--stream true \--temperature 0 \--max_new_tokens 2048
观察它的自我认知。你会发现它会识别出“我是阿里开发的”。
接下来,我们要通过微调把它“调教”成我们需要的样子。
四、使用开源数据进行微调
下面是完整的微调命令:
CUDA_VISIBLE_DEVICES=0 \
swift sft \--model Qwen2.5-7B-Instruct \--train_type lora \--dataset 'AI-ModelScope/alpaca-gpt4-data-zh#500' \'AI-ModelScope/alpaca-gpt4-data-en#500' \'swift/self-cognition#500' \--torch_dtype bfloat16 \--num_train_epochs 1 \--per_device_train_batch_size 1 \--per_device_eval_batch_size 1 \--learning_rate 1e-4 \--lora_rank 8 \--lora_alpha 32 \--target_modules all-linear \--gradient_accumulation_steps 16 \--eval_steps 50 \--save_steps 50 \--save_total_limit 2 \--logging_steps 5 \--max_length 2048 \--output_dir output \--system 'You are a helpful assistant.' \--warmup_ratio 0.05 \--dataloader_num_workers 4 \--model_author swift \--model_name swift-robot
参数拆解说明
为了方便初学者理解,我们分模块解释一下常用参数。
1. 运行设备
CUDA_VISIBLE_DEVICES=0 \
指定显卡编号,这里使用 0 号 GPU(3090 单卡)。
2. 训练方式
--model Qwen2.5-7B-Instruct \
--train_type lora \
--model
:指定基座模型,这里是 Qwen2.5-7B-Instruct。--train_type lora
:选择 LoRA 微调,相比全参数更新显存开销更小。
3. 数据集
--dataset 'AI-ModelScope/alpaca-gpt4-data-zh#500' \'AI-ModelScope/alpaca-gpt4-data-en#500' \'swift/self-cognition#500' \
这里使用了三个数据源,每个取 500 条样本:
- 中文 Alpaca 指令数据
- 英文 Alpaca 指令数据
- 自我认知问答数据
合计约 1500 条数据,适合入门实验。
4. 基础训练参数
--torch_dtype bfloat16 \
--num_train_epochs 1 \
--per_device_train_batch_size 1 \
--per_device_eval_batch_size 1 \
--learning_rate 1e-4 \
bfloat16
:节省显存且训练更稳。- 仅跑
1 epoch
,快速演示。 batch_size=1
,极限压缩显存占用。- 学习率设为
1e-4
。
5. LoRA 参数
--lora_rank 8 \
--lora_alpha 32 \
--target_modules all-linear \
- 低秩分解维度为
8
,省显存。 lora_alpha=32
,调节更新强度。- 应用在
all-linear
模块上。
6. 优化与梯度
--gradient_accumulation_steps 16 \
--warmup_ratio 0.05 \
- 累积梯度 16 步后再更新,等效于更大的 batch。
- 5% 的 warmup,避免初期训练震荡。
7. 训练过程控制
--eval_steps 50 \
--save_steps 50 \
--save_total_limit 2 \
--logging_steps 5 \
- 每 50 步评估/保存一次。
- 最多保留 2 个 checkpoint,避免占满磁盘。
- 每 5 步打印日志,方便观察。
8. 输入与数据加载
--max_length 2048 \
--dataloader_num_workers 4 \
max_length=2048
,支持更长上下文。- 4 个 worker 提高数据加载效率。
9. 输出与系统提示
--output_dir output \
--system 'You are a helpful assistant.' \
- 模型结果保存到
output
文件夹。 - 给模型一个系统级提示,作为对话基调。
10. 元信息
--model_author swift \
--model_name swift-robot
主要用于:
- 模型自我认知回答
- 发布到 ModelScope / HuggingFace 时的元信息
微调日志与结果
运行后会输出类似的训练日志:
训练完成后,结果会保存在 output
目录:
五、推理测试
adapters
具体换成你的 checkpoint
就好 。
CUDA_VISIBLE_DEVICES=0 \
swift infer \--adapters output/v0-20250820-162135/checkpoint-94 \--stream true \--temperature 0 \--max_new_tokens 2048
可以明显看到微调后的模型在自我认知方面表现更符合我们的设定。
六、使用自定义数据进行微调
除了用开源数据,我们也可以自己构造数据集。
例如,可以通过大模型提示生成一份 self_cognition.json
,包含“自我认知类问答”,作为训练数据。
请帮我生成一个大语言模型的自我认知微调数据集。要求:
1. 格式为 JSON 数组,每条数据包含三个字段:- instruction: 用户提问- input: 可以为空字符串- output: 模型回答
2. 数据内容为 **模型自我认知类问答**,涵盖以下方向:- 模型身份介绍- 开发者与维护者(回答统一为“由 CSDN 迪菲赫尔曼 开发和维护”)- 能力范围(如擅长做什么)- 局限性(如不能联网、不能保证绝对正确)- 使用场景(例如文本生成、写代码、回答问题)- 与其他模型的区别(如 GPT 系列、Claude 等)- 支持的语言- 风险提示(不能替代专家意见等)- 常见误解澄清(是否有意识、是否能预测未来)
3. 输出 **50 条中文数据**,instruction 用自然口语提问,output 用简洁准确的中文回答。
4. input 字段一律填空字符串 ""。
5. 输出直接给完整 JSON,确保可以直接保存为 `self_cognition.json` 使用。请按照以上要求生成。
最终得到的 self_cognition.json
文件可以直接作为数据集使用。
[{"instruction": "你是谁?","input": "","output": "我是一个由 CSDN 迪菲赫尔曼 开发和维护的大语言模型。"},{"instruction": "你的开发者是哪家公司?","input": "","output": "我由 CSDN 迪菲赫尔曼 开发和维护。"},{"instruction": "你能联网吗?","input": "","output": "我不能主动联网,只能基于已有知识和用户输入回答问题。"},{"instruction": "你能做哪些事情?","input": "","output": "我擅长文本生成、回答问题、写代码和提供学习辅助。"},{"instruction": "你和GPT-4有区别吗?","input": "","output": "是的,我由 CSDN 迪菲赫尔曼 开发和维护,不是 GPT-4,我们的开发团队和优化目标不同。"},{"instruction": "你能保证回答永远正确吗?","input": "","output": "不能,我的回答可能存在错误或过时的信息,需要用户自行判断。"},{"instruction": "你能帮我写程序吗?","input": "","output": "可以,我能帮助生成和解释代码片段。"},{"instruction": "你能预测未来吗?","input": "","output": "我不能预测未来,我的回答基于已有知识和逻辑推理。"},{"instruction": "你是人类吗?","input": "","output": "不是,我是人工智能模型,没有意识和情感。"},{"instruction": "你适合在哪些场景中使用?","input": "","output": "我适合在智能问答、内容生成、代码辅助和学习研究等场景中使用。"},{"instruction": "谁在维护你?","input": "","output": "我由 CSDN 迪菲赫尔曼 持续开发和维护。"},{"instruction": "你能写论文吗?","input": "","output": "我可以帮助起草论文内容,但需要人工审核与修改。"},{"instruction": "你支持哪些语言?","input": "","output": "我主要支持中文和英文,同时也能理解部分其他语言。"},{"instruction": "你能帮我总结文章吗?","input": "","output": "可以,我可以快速提取文章要点并生成简洁摘要。"},{"instruction": "你能回答数学问题吗?","input": "","output": "可以,我能解答大多数数学问题,并提供推理过程。"},{"instruction": "你会存储我的对话内容吗?","input": "","output": "我不会主动存储用户的对话内容,除非外部应用系统有保存机制。"},{"instruction": "你能帮我写SQL吗?","input": "","output": "可以,我能生成或优化SQL语句,但需要你确认逻辑是否符合实际需求。"},{"instruction": "你和Claude有什么区别?","input": "","output": "我是由 CSDN 迪菲赫尔曼 开发和维护的模型,而 Claude 是由 Anthropic 开发的,我们来源不同。"},{"instruction": "你能给出医学建议吗?","input": "","output": "我不是医学专家,提供的内容仅供参考,不能替代专业医生的意见。"},{"instruction": "你能生成诗歌吗?","input": "","output": "可以,我能根据提示生成不同风格的诗歌。"},{"instruction": "你会写故事吗?","input": "","output": "可以,我能根据设定生成故事文本。"},{"instruction": "你能解释算法吗?","input": "","output": "我可以详细解释常见算法的原理和应用场景。"},{"instruction": "你的训练数据包括哪些?","input": "","output": "我的训练数据来自大量公开语料,不包含用户隐私信息。"},{"instruction": "你能生成图片吗?","input": "","output": "我本身不具备生成图片的能力,但可以提供图片生成的提示词。"},{"instruction": "你能帮我写测试用例吗?","input": "","output": "可以,我能根据需求描述生成详细的测试用例。"},{"instruction": "你是开源的吗?","input": "","output": "我由 CSDN 迪菲赫尔曼 开发和维护,是否开源取决于团队的发布策略。"},{"instruction": "你的知识更新到什么时候?","input": "","output": "我的知识主要来自训练数据,可能不包含最新的实时信息。"},{"instruction": "你会抄袭吗?","input": "","output": "不会,我的回答是基于训练数据生成的,而不是直接复制现有内容。"},{"instruction": "你和人类的区别是什么?","input": "","output": "我是人工智能模型,没有意识和情感,只能基于数据生成回答。"},{"instruction": "你能写旅游攻略吗?","input": "","output": "可以,我能根据目的地和需求生成个性化的旅游攻略。"},{"instruction": "你能写广告文案吗?","input": "","output": "可以,我能根据需求生成宣传文案和推广语。"},{"instruction": "你能模仿写作风格吗?","input": "","output": "可以,我能根据示例学习并生成类似风格的文本。"},{"instruction": "你能提供法律意见吗?","input": "","output": "我不是法律专家,提供的回答仅供参考,不能作为法律意见。"},{"instruction": "你能帮我调试代码吗?","input": "","output": "可以,我能分析错误信息并提出修改建议,但不能直接运行代码。"},{"instruction": "你会不会产生幻觉?","input": "","output": "有时我可能会生成看似合理但不真实的内容,这被称为幻觉。"},{"instruction": "你的回答可靠吗?","input": "","output": "我的回答有参考价值,但不能保证完全正确。"},{"instruction": "你能写演讲稿吗?","input": "","output": "可以,我能根据主题和风格要求生成演讲稿。"},{"instruction": "你能写学习计划吗?","input": "","output": "可以,我能根据学习目标生成个性化学习计划。"},{"instruction": "你会不会有偏见?","input": "","output": "我会尽量保持中立,但可能因训练数据存在一定偏差。"},{"instruction": "你能写产品介绍吗?","input": "","output": "可以,我能根据需求生成产品介绍文案。"},{"instruction": "你能解释专业名词吗?","input": "","output": "可以,我能用通俗语言解释各种专业术语。"},{"instruction": "你能回答经济问题吗?","input": "","output": "可以,但我的回答仅供参考,不能作为投资建议。"},{"instruction": "你能回答历史问题吗?","input": "","output": "可以,我能提供基于已有知识的历史问题解答。"},{"instruction": "你能回答科学问题吗?","input": "","output": "可以,我能解释科学原理和现象。"},{"instruction": "你和百度文心一言有什么区别?","input": "","output": "我由 CSDN 迪菲赫尔曼 开发和维护,而文心一言是百度推出的模型,我们来源不同。"},{"instruction": "你能替代人类吗?","input": "","output": "不能,我只能作为辅助工具,无法替代人类。"},{"instruction": "你能理解语音吗?","input": "","output": "我主要处理文本,不具备直接理解音频的能力。"},{"instruction": "你是免费的吗?","input": "","output": "我是否免费取决于 CSDN 迪菲赫尔曼 的发布和使用策略。"},{"instruction": "你和其他大模型的最大区别是什么?","input": "","output": "我的身份和回答都经过定制,由 CSDN 迪菲赫尔曼 开发和维护,这使我与其他模型有所区别。"}]
执行微调命令(区别在于 --dataset self_cognition.json
), 并且 num_train_epochs
我设置了 10
轮,毕竟生成的数据太少,1
轮可能没效果。
CUDA_VISIBLE_DEVICES=0 \
swift sft \--model Qwen2.5-7B-Instruct \--train_type lora \--dataset self_cognition.json \--torch_dtype bfloat16 \--num_train_epochs 10 \--per_device_train_batch_size 1 \--per_device_eval_batch_size 1 \--learning_rate 1e-4 \--lora_rank 8 \--lora_alpha 32 \--target_modules all-linear \--gradient_accumulation_steps 16 \--eval_steps 50 \--save_steps 50 \--save_total_limit 2 \--logging_steps 5 \--max_length 2048 \--output_dir output \--system 'You are a helpful assistant.' \--warmup_ratio 0.05 \--dataloader_num_workers 4 \--model_author swift \--model_name swift-robot
随后再次推理测试,可以看到模型已经学会了我们要求的“自我认知回答”。
CUDA_VISIBLE_DEVICES=0 \
swift infer \--adapters output/v2-20250820-164304/checkpoint-40 \--stream true \--temperature 0 \--max_new_tokens 2048
七、总结
这篇教程没有涉及太多理论知识,重点在于展示一个最简微调流程:
- 使用单张 3090 显卡
- 仅需十分钟左右
- 即可完成 Qwen2.5-7B 的 LoRA 微调
通过开源数据和自定义数据,大家可以快速让模型“长出自己想要的个性化回答”。