主要解决的实际场景

例如支付客服,漫道云小助手,通过知识库()RAG无法达到预定的效果,需要微调解决问题

微调基础概念介绍

微调基本概念

所谓大模型微调,指的在已有的大规模预训练模型基础上,通过对标注数据进行训练,进一步优化模型的表现,以适应特定任务或场景的需求。不同于RAG或者Agent技术,通过搭建工作流来优化模型表现,微调是通过修改模型参数来优化模型能力,是一种能够让模型“永久”掌握某种能力的方法。

全量微调与高效微调

而从方法的大类上来划分,微调又可以划分为全量微调:带入全部数据进行微调,和高效微调:只带入部分数据进行微调。全量微调是一种算力消耗更大、但对模型的能力改造更为彻底的方法,而高效微调则更类似一种“四两拨千斤”的方法,通过修改模型部分参数,来调整模型整体能力。

模型微调的优劣势分析

尽管模型微调能够通过修改模型参数的方式,永久的修改模型的能力,但这其实是一把双刃剑,如果处理不当,很可能造成模型原始能力的灾难性遗忘、即会导致模型原始能力丢失,对于复杂模型尤其如此。而为了能够满足微调最初目标,必须小心谨慎的设计模型微调数据集和微调训练流程,并经过反复多次训练验证,得到一个最佳模型。

高效微调的应用场景

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

对话风格微调

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

知识灌注

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

推理能力提升

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

Agent能力(Function calling能力、或者MCP能力)提升

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

微调工具unsloth

unsloth 是一个专为大型语言模型(LLM)设计的动态量化与微调框架,旨在提高微调效率并减少显存占用。 它通过手动推导计算密集型数学步骤并手写 GPU 内核,实现了无需硬件更改即可显著加快训练速度。

主要功能点:

  • 高效微调: unsloth 通过深度优化,使 LLM 的微调速度提高 2-5 倍,显存使用量减少约 80%,且准确度无明显下降。
  • 广泛的模型支持: 目前支持的模型包括目前各类主流模型,用户可以根据需求适合的模型进行微调。
  • 兼容性: unsloth 与 HuggingFace态系统兼容,用户可以轻松将其与 traformers、peft、l 等库结合,实现模型的监督微调(SFT)和直接偏好优化(DPO),仅需修改模型的加载方式,无需对现有训练代码进行过多修改。
  • 内存优化: 通过 4 位和 16 位的 QLoRA/LoRA 微调,unsloth 显著了显存占用,使得在资源受限的环境中也能大的微调。

unsloth核心优势:

  • 显著提升微调效率: 相比传统方法,Unsloth采用独家4bit动态量化技术,能够在更短的时间内完成微调任务,节省时间成本。
  • 降低硬件要求: 通过优化显存使用,用户可以在显存较小的 GPU 上进行大模型的微调,降低了硬件门槛。
  • 开源免费: Unsloth 提供开源版本,用户可以在 Google Colab 或 Kaggle Notebooks 上免费试用,方便上手体验。

劣势

  • 动态量化的模型,无论是推理还是微调,只能单卡运行,这就使得其吞吐量有限,无法在一台物理机上实现多GPU并行从而扩大吞吐量。

Qwen3模型高效微调

Unsloth安装部署

conda create --name unsloth python=3.11
conda init
source ~/.bashrc
conda activate unsloth

#  然后在虚拟环境中安装Jupyter及Jupyter Kernel:
conda install jupyterlab
conda install ipykernel
python -m ipykernel install --user --name unsloth --display-name "Python unsloth"

# 然后使用如下命令安装Unsloth:
pip install --upgrade --force-reinstall --no-cache-dir unsloth unsloth_zoo

模型权重下载

pip install modelscope
modelscope download --model unsloth/Qwen3-32B-unsloth-bnb-4bit --local_dir ./Qwen3-32B-unsloth-bnb-4bit

完整操作流程

1.模型导入与调用流程

from unsloth import FastLanguageModel
import torch
max_seq_length = 8192
dtype = None
load_in_4bit = True
model, tokenizer = FastLanguageModel.from_pretrained(
    model_name = "./Qwen3-32B-unsloth-bnb-4bit",
    max_seq_length = max_seq_length,
    dtype = dtype,
    load_in_4bit = load_in_4bit,
)
model
tokenizer
gpu_stats = torch.cuda.get_device_properties(0)
start_gpu_memory = round(torch.cuda.max_memory_reserved() / 1024 / 1024 / 1024, 3)
max_memory = round(gpu_stats.total_memory / 1024 / 1024 / 1024, 3)
print(f"GPU = {gpu_stats.name}. Max memory = {max_memory} GB.")
print(f"{start_gpu_memory} GB of memory reserved.")

开启对话

messages = [
    {"role" : "user", "content" : "你好,好久不见!"}
]
text = tokenizer.apply_chat_template(
    messages,
    tokenize = False,
    add_generation_prompt = True, 
    enable_thinking = False, # 设置不思考
)
text
inputs = tokenizer(text, return_tensors="pt").to("cuda")
outputs = model.generate(
    input_ids=inputs.input_ids,
    attention_mask=inputs.attention_mask,
    max_new_tokens=max_seq_length,
    use_cache=True,
)
outputs
response = tokenizer.batch_decode(outputs)
response
response[0]
from datasets import load_dataset
reasoning_dataset = load_dataset("unsloth/OpenMathReasoning-mini", split = "cot")
non_reasoning_dataset = load_dataset("mlabonne/FineTome-100k", split = "train")
reasoning_dataset
reasoning_dataset[0]

微调数据集清洗

def generate_conversation(examples):
    problems  = examples["problem"]
    solutions = examples["generated_solution"]
    conversations = []
    for problem, solution in zip(problems, solutions):
        conversations.append([
            {"role" : "user",      "content" : problem},
            {"role" : "assistant", "content" : solution},
        ])
    return { "conversations": conversations, }
reasoning_dataset[0]
reasoning_data = reasoning_dataset.map(generate_conversation, batched = True)

总结

作者:张旭  创建时间:2025-07-02 16:57
最后编辑:张旭  更新时间:2025-08-15 15:21