尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

大模型高效微调(Finetune)实战教程

大模型高效微调(Finetune)实战教程
📅 发布时间:2026/6/20 5:35:30

Unsloth是一个开源工具,专门用来加速大语言模型(LLMs)的微调过程。它的主要功能和优势包括:

  • 🔭 高效微调:Unsloth 的微调速度比传统方法快 2-5 倍,内存占用减少 50%-80%。这意味着你可以用更少的资源完成微调任务。
  • ⚡ 低显存需求:即使是消费级 GPU(如 RTX 3090),也能轻松运行 Unsloth。例如,仅需 7GB 显存就可以训练 1.5B 参数的模型。
  • 🎯 支持多种模型和量化:Unsloth 支持 Llama、Mistral、Phi、Gemma 等主流模型,并且通过动态 4-bit 量化技术,显著降低显存占用,同时几乎不损失模型精度。
  • 🎁 开源与免费:Unsloth 提供免费的 Colab Notebook,用户只需添加数据集并运行代码即可完成微调。

微调的基本流程如下:

image

第一步:安装依赖&环境验证

 
%%capture
# 卸载当前已安装的 unsloth 包(如果已安装),然后从 GitHub 的源代码安装最新版本。
# 这样可以确保我们使用的是最新功能和修复。
!pip uninstall unsloth -y && pip install --upgrade --no-cache-dir --no-deps git+https://github.com/unslothai/unsloth.git
# 安装 bitsandbytes 和 unsloth_zoo 包。
# bitsandbytes 是一个用于量化和优化模型的库,可以帮助减少模型占用的内存。unsloth_zoo 可能包含了一些预训练模型或其他工具,方便我们使用。
!pip install bitsandbytes unsloth_zoo xformers

 

import sys
import torch
import platform
from importlib.metadata import version# 输出 Python 版本
print("Python 版本:", sys.version)# 输出操作系统信息
print("操作系统:", platform.platform())# 检查 CUDA 是否可用及相关信息
print("CUDA 是否可用:", torch.cuda.is_available())
if torch.cuda.is_available():print("CUDA 版本 (PyTorch 编译时使用的):", torch.version.cuda)print("当前 CUDA 设备数量:", torch.cuda.device_count())print("当前 CUDA 设备:", torch.cuda.current_device())print("当前 CUDA 设备名称:", torch.cuda.get_device_name(torch.cuda.current_device()))# 输出 PyTorch 版本
print("PyTorch 版本:", torch.__version__)# 输出其他库的版本(如果已安装)
libraries = ["triton", "unsloth", "xformers"]
for lib in libraries:try:print(f"{lib} 版本:", version(lib))except ImportError:print(f"{lib} 未安装")

第二步:加载预训练模型

 
from unsloth import FastLanguageModel  # 导入FastLanguageModel类,用来加载和使用模型
import torch  # 导入torch工具,用于处理模型的数学运算

max_seq_length = 2048  # 设置模型处理文本的最大长度,相当于给模型设置一个“最大容量”
dtype = None  # 设置数据类型,让模型自动选择最适合的精度
load_in_4bit = True  # 使用4位量化来节省内存,就像把大箱子压缩成小箱子# 加载预训练模型,并获取tokenizer工具
model, tokenizer = FastLanguageModel.from_pretrained(model_name="unsloth/DeepSeek-R1-Distill-Qwen-7B",  # 指定要加载的模型名称max_seq_length=max_seq_length,  # 使用前面设置的最大长度dtype=dtype,  # 使用前面设置的数据类型load_in_4bit=load_in_4bit,  # 使用4位量化# token="hf_...",  # 如果需要访问授权模型,可以在这里填入密钥
)

 

第三步:微调前测试

 

# 定义提示风格的字符串模板,用于格式化问题
prompt_style = """
Below is an instruction that describes a task, paired with an input that provides further context.
Write a response that appropriately completes the request.
Before answering, think carefully about the question and create a step-by-step chain of thoughts to ensure a logical and accurate response.### Instruction:
You are a medical expert with advanced knowledge in clinical reasoning, diagnostics, and treatment planning.
Please answer the following medical question.### Question:
{}### Response:
<think>{}
"""# 定义具体的医学问题
question = "一个患有急性阑尾炎的病人已经发病5天,腹痛稍有减轻但仍然发热,在体检时发现右下腹有压痛的包块,此时应如何处理?"
# 将大模型设置为推理模式
FastLanguageModel.for_inference(model)# 使用 tokenizer 对格式化后的问题进行编码,并移动到 GPU
inputs = tokenizer([prompt_style.format(question, "")], return_tensors="pt").to("cuda")# 使用模型生成回答
outputs = model.generate(input_ids=inputs.input_ids,attention_mask=inputs.attention_mask,max_new_tokens=1200,use_cache=True,
)
# 解码模型生成的输出为可读文本
response = tokenizer.batch_decode(outputs)# 打印生成的回答部分
print(response[0].split("### Response:")[1])

第四步:加载数据集

 
# 定义一个用于格式化提示的多行字符串模板
train_prompt_style = """
Below is an instruction that describes a task, paired with an input that provides further context.
Write a response that appropriately completes the request.
Before answering, think carefully about the question and create a step-by-step chain of thoughts to ensure a logical and accurate response.### Instruction:
You are a medical expert with advanced knowledge in clinical reasoning, diagnostics, and treatment planning.
Please answer the following medical question.### Question:
{}### Response:
<think>
{}
</think>
{}
"""

 

# 定义结束标记(EOS_TOKEN),用于指示文本的结束
EOS_TOKEN = tokenizer.eos_token  # 必须添加结束标记# 导入数据集加载函数
from datasets import load_dataset# 加载指定的数据集,选择中文语言和训练集的前500条记录
dataset = load_dataset("FreedomIntelligence/medical-o1-reasoning-SFT", 'zh', split = "train[0:500]", trust_remote_code=True)# 打印数据集的列名,查看数据集中有哪些字段
print(dataset.column_names)
# 定义一个函数,用于格式化数据集中的每条记录
def formatting_prompts_func(examples):# 从数据集中提取问题、复杂思考过程和回答inputs = examples["Question"]cots = examples["Complex_CoT"]outputs = examples["Response"]texts = []  # 用于存储格式化后的文本# 遍历每个问题、思考过程和回答,进行格式化for input, cot, output in zip(inputs, cots, outputs):# 使用字符串模板插入数据,并加上结束标记text = train_prompt_style.format(input, cot, output) + EOS_TOKENtexts.append(text)  # 将格式化后的文本添加到列表中return {"text": texts,  # 返回包含所有格式化文本的字典
    }# 组装数据集
dataset = dataset.map(formatting_prompts_func, batched = True)
dataset["text"][0]

第五步:执行微调

 

# 将大模型设置为训练模式
FastLanguageModel.for_training(model)# 使用参数高效微调(PEFT)中的lora方式执行微调,设定一些超参数
model = FastLanguageModel.get_peft_model(model,  # 传入已经加载好的预训练模型r = 16,  # 设置 LoRA 的秩,决定添加的可训练参数数量target_modules = ["q_proj", "k_proj", "v_proj", "o_proj",  # 指定模型中需要微调的关键模块"gate_proj", "up_proj", "down_proj"],lora_alpha = 16,  # 设置 LoRA 的超参数,影响可训练参数的训练方式lora_dropout = 0,  # 设置防止过拟合的参数,这里设置为 0 表示不丢弃任何参数bias = "none",    # 设置是否添加偏置项,这里设置为 "none" 表示不添加use_gradient_checkpointing = "unsloth",  # 使用优化技术节省显存并支持更大的批量大小random_state = 3407,  # 设置随机种子,确保每次运行代码时模型的初始化方式相同use_rslora = False,  # 设置是否使用 Rank Stabilized LoRA 技术,这里设置为 False 表示不使用loftq_config = None,  # 设置是否使用 LoftQ 技术,这里设置为 None 表示不使用
)
from trl import SFTTrainer  # 导入 SFTTrainer,用于监督式微调
from transformers import TrainingArguments  # 导入 TrainingArguments,用于设置训练参数
from unsloth import is_bfloat16_supported  # 导入函数,检查是否支持 bfloat16 数据格式

trainer = SFTTrainer(  # 创建一个 SFTTrainer 实例model=model,  # 传入要微调的模型tokenizer=tokenizer,  # 传入 tokenizer,用于处理文本数据train_dataset=dataset,  # 传入训练数据集dataset_text_field="text",  # 指定数据集中文本字段的名称max_seq_length=max_seq_length,  # 设置最大序列长度dataset_num_proc=2,  # 设置数据处理的并行进程数packing=False,  # 是否启用打包功能(这里设置为 False,打包可以让训练更快,但可能影响效果)args=TrainingArguments(  # 定义训练参数per_device_train_batch_size=2,  # 每个设备(如 GPU)上的批量大小gradient_accumulation_steps=4,  # 梯度累积步数,用于模拟大批次训练warmup_steps=5,  # 预热步数,训练开始时学习率逐渐增加的步数max_steps=100,  # 最大训练步数learning_rate=2e-4,  # 学习率,模型学习新知识的速度fp16=not is_bfloat16_supported(),  # 是否使用 fp16 格式加速训练(如果环境不支持 bfloat16)bf16=is_bfloat16_supported(),  # 是否使用 bfloat16 格式加速训练(如果环境支持)logging_steps=1,  # 每隔多少步记录一次训练日志optim="adamw_8bit",  # 使用的优化器,用于调整模型参数weight_decay=0.01,  # 权重衰减,防止模型过拟合lr_scheduler_type="linear",  # 学习率调度器类型,控制学习率的变化方式seed=3407,  # 随机种子,确保训练结果可复现output_dir="outputs",  # 训练结果保存的目录report_to="none",  # 是否将训练结果报告到外部工具(如 WandB),这里设置为不报告
    ),
)
# 执行训练
trainer_stats = trainer.train()

第六步:微调后测试

 

# 打印前面的问题
print(question)
#测试同一个问题的答案
# 将模型切换到推理模式,准备回答问题
FastLanguageModel.for_inference(model)# 将问题转换成模型能理解的格式,并发送到 GPU 上
inputs = tokenizer([prompt_style.format(question, "")], return_tensors="pt").to("cuda")# 让模型根据问题生成回答,最多生成 10000 个新词
outputs = model.generate(input_ids=inputs.input_ids,  # 输入的数字序列attention_mask=inputs.attention_mask,  # 注意力遮罩,帮助模型理解哪些部分重要max_new_tokens=10000,  # 最多生成 4000 个新词use_cache=True,  # 使用缓存加速生成
)# 将生成的回答从数字转换回文字
response = tokenizer.batch_decode(outputs)# 打印回答
print(response[0].split("### Response:")[1])

第七步:本地保存模型

 

#保存Lora权重
model.save_pretrained("ckpts/lora_model")
tokenizer.save_pretrained("ckpts/lora_model")
# 加载模型
model, tokenizer = FastLanguageModel.from_pretrained(model_name = "ckpts/lora_model",max_seq_length = max_seq_length,load_in_4bit = True,
)
FastLanguageModel.for_inference(model)
inputs = tokenizer([prompt_style.format(question)], return_tensors='pt', max_length=max_seq_length).to("cuda")
outputs = model.generate(inputs['input_ids'], attention_mask=inputs['attention_mask'], max_length=max_seq_length, use_cache=True)
answer = tokenizer.batch_decode(outputs, skip_special_tokens=True)[0]
print(answer)

 

 

出处:https://www.cnblogs.com/boreas-pxl/p/18797698

作者:jsp
出处:http://www.cnblogs.com/jingsupo/

-------------------------------------------

个性签名:无论在哪里做什么,只要坚持服务、创新、创造价值,其它的东西自然都会来的。

如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!

相关新闻

  • 【转载】Qt QCustomPlot 使用整理
  • Windows实用小工具使用教程!OFGB专治 Windows 11 广告的神器+自动滚屏小工具!
  • 2025年11月营销智能体推荐榜单:主流平台综合对比与选择指南

最新新闻

  • XXPermissions:Android权限管理的终极解决方案与实战指南
  • MongoDB 连接的幕后故事
  • 为什么Binding是Go Web开发者的必备工具:无反射数据绑定详解
  • 贝叶斯优化在低能电子衍射表面结构分析中的应用
  • Mobaxterm中文版终极指南:如何用一款工具解决所有远程管理难题?
  • 低代码表单在企业流程管理中的应用场景

日新闻

  • 信任的进化:技术实现详解——如何用JavaScript构建博弈论模拟器
  • Terrakube自定义工作流:如何集成OPA、Infracost等工具扩展IaC能力
  • grunt-concurrent快速入门:5分钟学会并行运行Grunt任务

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号