AI大模型初学者必备微调指南:Unsloth官方微调技巧公开啦!

前言

从你早上睁眼看到的今日头条推荐,到深夜刷到的抖音神评,人工智能大模型已经成为我们工作生活不可或缺的部分。但通用模型在专业场景的"人工智障"表现,让微调技术成为专业领域AI落地的最后1公里。

微调技术是指在预训练模型基础上,使用专业领域特定数据,指定特定方法对大模型参数进行调整,使其适应专业任务或领域。微调大模型可实现如下功能:

  • 更新 + 学习新知识

    :注入并学习新的特定领域信息,例如“法衡大模型”在Llama模型基础上使用法律文本微调,以进行合同分析、判例法研究和合规性检测。

  • 自定义行为

    :调整模型的语气、个性或响应样式,网络上流行的“甄嬛”对话风格大模型就是基于甄嬛风格对话数据集对Qwen模型微调。

  • 针对任务进行优化

    :提高特定用例的准确性和相关性,例如训练大模型以预测标题对公司的影响是正面还是负面。

微调技术如此强大自然也涌现出了多种大模型微调工具,比较流行的有LlamaFactoryUnsloth等。

然而微调过程中形形色色的参数设置使得缺少深度学习调参经验的同学相当困惑,总有人后台私信我有没有一个通用经验设置帮助大家快速上手微调呢?最近在查阅Unsloth官方文档时意外发现Unsloth官方推出的初学者微调指南,原文Fine-tuning Guide | Unsloth Documentatio。本次分享我就结合工作相关经验和官方文档整理一份适用于大模型初学者的微调指南。

微调第一步:选择合适的模型+微调方法

无论是Unsloth还是笔者工作实践,在选择微调模型时,即使你的显卡资源足够丰富,也要先从参数量较小(小于14B)的Instruct模型开始,检测你的数据集是否适合微调任务。例如你想微调Qwen2.5-72B-Instruct模型,你应该先选择Qwen2.5-7B-Instruct进行微调测试,然后逐步提高模型参数量。

微调方法大家一般只需要在LoraQLora中做出选择,两者的特点如下, Unsloth官方默认是QLora方法,因为该方法消耗模型显存更小。如果你使用LLamaFactory训练模型也可以选择QLora方法。

  • LoRA:

    微调 16 位的小型可训练矩阵,无需更新所有模型权重。

  • QLoRA:

    将 LoRA 与 4 位量化相结合,以最少的资源处理非常大的模型。

微调第二步:选择合适的模型设置

选择完成合适的模型和微调方法后,通常还需要设置三个参数:

1. max_seq_length

默认设置为 2048, 该参数控制大模型输入输出的上下文长度。虽然一些模型支持 8192甚至更大的上下文长度,但Unsloth仍建议先使用 2048 进行微调测试,然后再使用2048的倍数4096、8192等逐步扩展。

2. dtype

Unsloth默认设置为None, 会根据我们的显卡类型自动检测。目前大模型的参数类型通常为torch.float16,在一些性能强劲的显卡例如A100H100等显卡上可以设置为torch.bfloat16torch.bfloat16torch.float16两者都是16位浮点数格式,torch.bfloat16格式能表示数字范围更大,更适合大模型训练,尤其是在A100/H100显卡上有专门优化。torch.float16精度高,但容易溢出,更适合精细度高的推理任务。

3. load_in_4bit

默认为True,采用4bit量化模型进行微调,虽然会损失约1%左右的精度,但是4bit模型占用的计算资源更小,更适合快速微调验证任务。如果你想完全微调模型需要设置full_finetuning = True ,如果想使用8 bit量化模型微调需要设置load_in_8bit = True

使用Unsloth完成模型选择和设置的代码如下,这里以QwQ-32B 的unsloth 4bit量化版为例:

pythonfrom unsloth import FastLanguageModel
max_seq_length = 2048
dtype = None
load_in_4bit = True
model, tokenizer = FastLanguageModel.from_pretrained(
    model_name = "./QwQ-32B-unsloth-bnb-4bit",
    max_seq_length = max_seq_length,
    dtype = dtype,
    load_in_4bit = load_in_4bit,
)

在这里插入图片描述

微调第三步:准备数据集

对于大模型来说,数据集是可用于训练模型的数据集合。为了使训练有效,文本数据需要采用固定标记的格式。对于 继续预训练(CPT) 我们要采用的数据集格式如下, 只需要一个text字段的json数据即可

json[{
"text":"Pasta carbonara is a traditional Roman pasta dish. The sauce is made by mixing raw eggs with grated Pecorino Romano cheese and black pepper. The hot pasta is then tossed with crispy guanciale (cured pork cheek) and the egg mixture, creating a creamy sauce from the residual heat. Despite popular belief, authentic carbonara never contains cream or garlic. The dish likely originated in Rome in the mid-20th century, though its exact origins are debated..."
}]

继续预训练适用于让模型理解专业领域字词之间的关联关系,但并不适合直接让大模型学会专业领域的语言表述。

对于文本的微调我们一般直接使用监督微调(SFT),采用的数据集格式是 Alpaca风格的Instruction格式, 格式如下:

json“instruction”:必选, 我们希望模型执行的任务。
“input”: 可选,它本质上是我们除指令外的额外输入
“output”: 任务的预期结果和模型的输出。

以使用python编写列表排序代码为例:

json“instruction”:请帮我编写一个python列表排序程序并对我提供的列表排序
“input”: 我的python列表是[0,1,23,4]
“output”: 

不过 Alpaca风格的Instruction格式不适用于多轮对话,多轮对话常用的格式是ShareGPTChatML格式。

ShareGPT格式:

json{
  “conversations”: [
{
      “from”: “人类”,
      “value”: “你能帮我做意大利面培根蛋面吗?”
},
{
      “from”: “gpt”, /
      “value”: “您想要传统的罗马食谱,还是更简单的版本?
},
{
      “from”: “人类”,
      “value”: 请用繁体版本”
},
{
      “from”: “gpt”, /
      “value”: “正宗的罗马培根蛋面只使用几种成分:意大利面、番荔枝、鸡蛋、罗马佩克里诺和黑胡椒。你想要详细的食谱吗?
}
]
}

ChatML格式:

{
  "messages": [
    {
      "role": "user", # user表示用户
      "content": "What is 1+1?"
    },
    {
      "role": "assistant", # assistant表示大模型
      "content": "It's 2!"
    },
  ]
}

以上数据集基本可以满足我们日常的微调任务了。

微调第四步:模型训练参数设置

不得不说这部分微调的参数设置组合有成百上千种,而且我们既要设置Lora微调方法的参数,又要设置整体微调流程的超参数,选择正确的参数组合对好的微调结果至关重要。Unsloth默认的参数选择一般来说就是相对合理的,大家即使修改也希望参照下面的经验:

Lora参数设置:

  1. r = 16
    

    微调过程的等级。默认为16, 较大的数字会占用更多内存,并且速度会变慢,但可以提高更难任务的准确性。这里建议先保持默认,然后从8、16、32、64、128这几个数字进行尝试。

  2. target_modules = ["q_proj", "k_proj", "v_proj", "o_proj","gate_proj", "up_proj", "down_proj",],
    

    默认选择所有模块进行微调。强烈不建议删除一些模块以减少内存使用量以加快训练速度,这通常会有难以分析的问题。

  3. lora_alpha = 16
    

    微调的比例因子。较大的数字能使微调收敛更快,但可能会引发过度拟合情况。建议等于r或是r的倍数。

  4. lora_dropout = 0
    

    默认为0即可,如果出现过拟合的情况可以适当调大,但不要超过0.5。

  5. bias = "none"
    

    默认为none即可,这样可以避免过拟合。

  6. use_gradient_checkpointing = "unsloth"
    

    默认为unsloth, 可以使内存使用量额外减少了30%,并支持极长的上下文微调,默认即可。

  7. random_state = 3407
    

    确定性运行数的编号。只要保持该数字和其它参数一致,训练的过程就可以复现。

  8. use_rslora = False
    

    高级功能,一般用不到保持False即可。

  9. loftq_config
    

    高级功能,用于将 LoRA 矩阵初始化为权重的前 r 个奇异向量。可以在一定程度上提高准确性,但可能会使内存使用量在开始时呈爆炸式增长,一般设置为None。

Unsloth设置Lora微调参数的代码如下,即使微调效果有偏差,我们也可以按照建议范围修改Lora参数设置。

pythonmodel = FastLanguageModel.get_peft_model(
    model,
    r=16,  
    target_modules=[
      "q_proj",
      "k_proj",
      "v_proj",
      "o_proj",
      "gate_proj",
      "up_proj",
      "down_proj",
    ],
    lora_alpha=16,
    lora_dropout=0,  
    bias="none",  
    use_gradient_checkpointing="unsloth",  
    random_state=3407,
    use_rslora=False,  
    loftq_config=None,
)

整体微调流程超参数

要了解整体微调流程的超参数设置,我们首先要知道什么是过拟合欠拟合现象:

过拟合与欠拟合

过拟合: 该模型会记住训练数据,但对其它领域的通识理解会变弱,相当于“学傻了”只知道微调的专业领域数据集种的知识,大模型的泛化能力和创造性大大降低。

欠拟合: 缺乏合适的学习参数而导致模型无法从训练数据中学习到知识,提问模型专业领域相关情况模型还是无法正确回答。

整体微调流程超参数详解

整体微调流程主要关注如下超参数:

1. learning_rate学习率:

定义模型权重在每个训练步骤中调整的程度。

  • 较高学习率

    : 更快的训练,减少过拟合,但过高的学习率会导致过拟合.

  • 较低学习率

    :更稳定的训练,可能需要更多的 epoch,也可能导致欠拟合.

  • 建议范围

    :1e-4 (0.0001) 至 5e-5 (0.00005)。

2. num_train_epochs训练轮数

模型训练专业数据的次数,设置训练轮数为3,模型会使用你的数据训练三个回合。

  • 推荐:

    虽然Unsloth推荐1-3 (超过 3 个通常不是最佳选择,除非你希望你的模型幻觉少得多且缺少相关领域创造性)。但结合自己工作实践我们采用专业领域训练还是要尽量避免大模型产生过多幻觉,我建议可以尝试1-50之间的值,超过50基本不是最好选择。

  • 较多Epochs

    :更好的学习但有更高的过拟合风险。

  • 较少Epochs

    :可能会导致模型欠拟合。

3. per_device_train_batch_size = 2

增加该值以提高 GPU 利用率,但要注意增加该值会导致训练速度变慢,显存资源足够可以适当调高该值。

4. gradient_accumulation_steps = 4

在不增加内存使用量的情况下模拟更大的批处理大小,显存资源足够可以适当调高该值。

使用Unsloth完成整体流程微调的代码如下:

pythonfrom trl import SFTTrainer
from transformers import TrainingArguments
from unsloth import is_bfloat16_supported

trainer = SFTTrainer(
    model=model,
    tokenizer=tokenizer,
    train_dataset=dataset,
    dataset_text_field="text",
    max_seq_length=max_seq_length,
    dataset_num_proc=2,
    args=TrainingArguments(
        per_device_train_batch_size=2,
        gradient_accumulation_steps=4,
        num_train_epochs = 3,
        warmup_steps=5,
        learning_rate=2e-4,
        fp16=not is_bfloat16_supported(),
        bf16=is_bfloat16_supported(),
        logging_steps=10,
        optim="adamw_8bit",
        weight_decay=0.01,
        lr_scheduler_type="linear",
        seed=3407,
        output_dir="outputs",
    ),
)

避免过拟合和欠拟合现象经验

避免过拟合:

  1. 降低学习率learning_rate
  2. 增加批量per_device_train_batch_size大小。
  3. 减少训练epoch的数量。
  4. 将数据集改写为ShareGPT格式
  5. 提高dropout rate以引入正则化。

避免欠拟合:

  1. 提高学习率learning_rate
  2. 增加训练epoch的数量。
  3. 提高Lora参数rlora_alphalora_alpha应至少等于rr通常在 4 -64 之间,对于较小的模型或者更复杂的数据集应该更大。

值得注意的是:微调没有单一的 “最佳” 方法,只有最佳实践。实验是找到最适合参数的关键。虽然Unsloth 默认参数是根据研究论文和过去实验数据的最佳实践,但有时我们需要自己尝试这些参数才能获得最佳匹配。

微调第五步:训练+评估

在训练时,Unsloth会打印一些数字日志,它表示训练损失,大家的目标是使训练损失尽可能接近 0.5!如果微调损失未达到 10.80.5,我们需要继续调整参数。微调模型不是一个确定性步骤,它往往需要我们不断调整上面介绍的参数,这就是大家所谓的“炼丹”过程。

如果大家发现损失变为 0,那说明你的模型过拟合了,需要降低epoch数量或者学习率learning_rate来避免过拟合。

在这里插入图片描述

模型评估阶段大家一般选取20%的训练数据作为测试集(这部分数据集不参与训练),运行微调后模型进行人工评估。大家也可以直接通过 Unsloth 启用评估,设置evaluation_steps = 100。但这个会增加Unsloth训练的时间。还有一种方法是使用自动评估工具,例如 EleutherAI 的 lm-evaluation-harness。不过切记自动化工具可能无法完全符合评估标准。

大家在评估时可以使用如下代码:

pythonFastLanguageModel.for_inference(model) # 开启推理模式
inputs = tokenizer([prompt_style.format(question, "")], return_tensors="pt").to("cuda") # promt_style是提示词模板(自行设置),问题替换为自己问题

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])

微调第六步:保存模型

trainer.train()运行完成后可以保存模型,Unsloth提供了多种保存模型的方法:

  1. 保存Lora适配器:只保存相对于原始模型增加的Lora参数(几百MB左右),不会融合新增加部分和原始模型。使用的代码是:
pyhtonmodel.save_pretrained("lora_model")
tokenier.save_pretrained("lora_model")
  1. 保存完整模型safetensors格式:一般情况下我们需要保存完整的模型,可以使用如下代码,保存后格式与modelscope和huggingface上模型格式类似,可使用vllm等框架部署推理服务。
pythonmodel.save_pretrained_merged("model", tokenizer, save_method = "merged_4bit",) #4位量化版
model.save_pretrained_merged("model", tokenizer, save_method = "merged_16bit",) #16位量化版
  1. 保存完整模型GGUF格式:这种格式适合采用Ollama部署,代码如下:
model.save_pretrained_gguf("dir", tokenizer, quantization_method = "q4_k_m") # q4量化版
model.save_pretrained_gguf("dir", tokenizer, quantization_method = "q8_0") # q8量化版
model.save_pretrained_gguf("dir", tokenizer, quantization_method = "f16") # float16版

以上就是Unsloth微调参数设置的全部经验内容啦!

总结

本篇分享我们基于Unsloth官方文档结合工作种微调经验,为大家提供了合适的参数选择范围,帮助大家从成百上千种参数组合中快速定位到最优组合,加速微调过程,让初学者也能简单快速上手大模型微调。还在等什么,赶紧按照分享建议的方案去微调属于你的专业领域大模型吧!

普通人如何抓住AI大模型的风口?

领取方式在文末

为什么要学习大模型?

目前AI大模型的技术岗位与能力培养随着人工智能技术的迅速发展和应用 , 大模型作为其中的重要组成部分 , 正逐渐成为推动人工智能发展的重要引擎 。大模型以其强大的数据处理和模式识别能力, 广泛应用于自然语言处理 、计算机视觉 、 智能推荐等领域 ,为各行各业带来了革命性的改变和机遇 。

目前,开源人工智能大模型已应用于医疗、政务、法律、汽车、娱乐、金融、互联网、教育、制造业、企业服务等多个场景,其中,应用于金融、企业服务、制造业和法律领域的大模型在本次调研中占比超过 30%。
在这里插入图片描述

随着AI大模型技术的迅速发展,相关岗位的需求也日益增加。大模型产业链催生了一批高薪新职业:

在这里插入图片描述

人工智能大潮已来,不加入就可能被淘汰。如果你是技术人,尤其是互联网从业者,现在就开始学习AI大模型技术,真的是给你的人生一个重要建议!

最后

如果你真的想学习大模型,请不要去网上找那些零零碎碎的教程,真的很难学懂!你可以根据我这个学习路线和系统资料,制定一套学习计划,只要你肯花时间沉下心去学习,它们一定能帮到你!

大模型全套学习资料领取

这里我整理了一份AI大模型入门到进阶全套学习包,包含学习路线+实战案例+视频+书籍PDF+面试题+DeepSeek部署包和技巧,需要的小伙伴文在下方免费领取哦,真诚无偿分享!!!
vx扫描下方二维码即可
加上后会一个个给大家发

在这里插入图片描述

部分资料展示

一、 AI大模型学习路线图

整个学习分为7个阶段
在这里插入图片描述
在这里插入图片描述

二、AI大模型实战案例

涵盖AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,皆可用。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

三、视频和书籍PDF合集

从入门到进阶这里都有,跟着老师学习事半功倍。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

四、LLM面试题

在这里插入图片描述
在这里插入图片描述

五、AI产品经理面试题

在这里插入图片描述

六、deepseek部署包+技巧大全

在这里插入图片描述

😝朋友们如果有需要的话,可以V扫描下方二维码联系领取~
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值