大语言模型常用微调与基于SFT微调DeepSeek R1指南

news2025/2/21 10:11:17

概述

大型语言模型(LLM,Large Language Model)的微调(Fine-tuning)是指在一个预训练模型的基础上,使用特定领域或任务的数据对模型进行进一步训练,以使其在该领域或任务上表现更好。微调是迁移学习的一种常见方法,能够显著提升模型在特定任务上的性能。在大型语言模型(LLM)的微调中,有几种常见的方法,包括 SFT(监督微调)LoRA(低秩适应)P-tuning v2 和 **Freeze

1.大语言模型微调

1.1 微调的工作原理

微调(Fine-tuning)是指在预训练模型的基础上,使用特定任务的标注数据对模型进行进一步训练,使其在该任务上表现更好。微调的核心思想是利用预训练模型已经学习到的通用语言表示,通过少量任务数据调整模型参数,使其适应特定任务。

微调的关键组件
  • 输入 (X)

    • 提供给模型的文本数据(例如,电影评论、问题、对话等)。
    • 对于文本生成任务,输入可能是一个问题或提示。
  • 目标 (Y)

    • 基于标注数据的预期输出(例如,情绪标签、聊天机器人响应、摘要文本等)。
    • 对于分类任务,目标可能是类别标签(如“积极”或“消极”)。
    • 对于生成任务,目标可能是完整的文本响应。
  • 损失函数

    • 衡量模型的预测与目标之间的差异。
    • 通过优化损失函数,模型逐渐调整参数以更好地拟合任务数据。
示例:IMDB 情绪分类
  • 输入 (X):电影评论,例如“这部电影的视觉效果很棒,但情节很弱。”
  • 目标 (Y):情绪标签,例如“积极”或“消极”。
  • 模型任务:根据输入文本预测正确的情绪标签。
示例:文本生成
  • 输入 (X):问题,例如“什么是人工智能?”
  • 目标 (Y):生成的响应,例如“人工智能是模拟人类智能的技术。”
  • 模型任务:根据输入问题生成正确的文本响应。

1.2 使用的损失函数:交叉熵损失

在语言模型的微调中,交叉熵损失(Cross-Entropy Loss) 是最常用的损失函数。它用于衡量模型预测的概率分布与真实目标分布之间的差异。

交叉熵损失的公式

对于语言模型,交叉熵损失的公式为:
Cross-Entropy Loss = − ∑ i = 1 N y i log ⁡ ( p i ) \text{Cross-Entropy Loss} = -\sum_{i=1}^{N} y_i \log(p_i) Cross-Entropy Loss=i=1Nyilog(pi)

其中:

  • y i y_i yi:目标分布(真实标签的 one-hot 编码)。
  • p i p_i pi:模型预测的概率分布。
  • N N N:词汇表的大小(对于分类任务,( N ) 是类别数)。

交叉熵损失的作用

  • 衡量预测与目标的差异
    • 当模型预测的概率分布与目标分布越接近时,交叉熵损失越小。
    • 当模型预测的概率分布与目标分布差异较大时,交叉熵损失越大。
  • 优化目标
    • 在训练过程中,通过反向传播和梯度下降,模型不断调整参数以最小化交叉熵损失。

示例:文本生成中的交叉熵损失

假设模型生成一个句子,每个词的概率分布如下:

  • 目标词:["I", "love", "AI"]
  • 模型预测的概率分布:
    • I: 0.9
    • love: 0.8
    • AI: 0.7

交叉熵损失计算如下:
t e x t L o s s = − ( log ⁡ ( 0.9 ) + log ⁡ ( 0.8 ) + log ⁡ ( 0.7 ) ) text{Loss} = -(\log(0.9) + \log(0.8) + \log(0.7)) textLoss=(log(0.9)+log(0.8)+log(0.7))

通过最小化损失,模型逐渐学会生成更准确的文本。

1.3 SFT(监督微调,Supervised Fine-Tuning)

SFT 是最常见的微调方法,通过在特定任务的标注数据上对预训练模型进行全参数微调。

特点

  • 全参数微调:更新模型的所有参数。
  • 适合场景:任务数据量较大,计算资源充足。
  • 优点:模型可以完全适应任务。
  • 缺点:计算成本高,显存占用大。

实现代码

from transformers import AutoTokenizer, AutoModelForSequenceClassification, Trainer, TrainingArguments
from datasets import load_dataset

# 加载预训练模型和分词器
model_name = "bert-base-uncased"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForSequenceClassification.from_pretrained(model_name, num_labels=2)

# 加载数据集
dataset = load_dataset("imdb")

# 数据预处理
def preprocess_function(examples):
    return tokenizer(examples["text"], truncation=True, padding="max_length", max_length=512)

tokenized_datasets = dataset.map(preprocess_function, batched=True)

# 设置训练参数
training_args = TrainingArguments(
    output_dir="./sft_results",
    evaluation_strategy="epoch",
    learning_rate=2e-5,
    per_device_train_batch_size=8,
    per_device_eval_batch_size=8,
    num_train_epochs=3,
    weight_decay=0.01,
    save_strategy="epoch",
    logging_dir="./logs",
)

# 定义 Trainer
trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=tokenized_datasets["train"],
    eval_dataset=tokenized_datasets["test"],
    tokenizer=tokenizer,
)

# 开始微调
trainer.train()

# 保存模型
model.save_pretrained("./sft-fine-tuned-model")
tokenizer.save_pretrained("./sft-fine-tuned-model")

1.4 LoRA(低秩适应,Low-Rank Adaptation)

LoRA 是一种高效的微调方法,通过低秩分解的方式微调模型参数,减少计算量和显存占用。

特点

  • 低秩分解:只微调模型的一部分参数(低秩矩阵)。
  • 适合场景:资源有限,但仍需高效微调。
  • 优点:参数效率高,显存占用低。
  • 缺点:需要额外的实现支持。

实现代码

使用 peft 库实现 LoRA:

pip install peft
from transformers import AutoTokenizer, AutoModelForSequenceClassification
from peft import get_peft_model, LoraConfig, TaskType
from datasets import load_dataset

# 加载预训练模型和分词器
model_name = "bert-base-uncased"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForSequenceClassification.from_pretrained(model_name, num_labels=2)

# 配置 LoRA
lora_config = LoraConfig(
    task_type=TaskType.SEQ_CLS,  # 任务类型
    r=8,  # 低秩矩阵的秩
    lora_alpha=32,  # 缩放因子
    lora_dropout=0.1,  # Dropout 概率
)

# 应用 LoRA
model = get_peft_model(model, lora_config)

# 加载数据集
dataset = load_dataset("imdb")

# 数据预处理
def preprocess_function(examples):
    return tokenizer(examples["text"], truncation=True, padding="max_length", max_length=512)

tokenized_datasets = dataset.map(preprocess_function, batched=True)

# 设置训练参数
training_args = TrainingArguments(
    output_dir="./lora_results",
    evaluation_strategy="epoch",
    learning_rate=2e-5,
    per_device_train_batch_size=8,
    per_device_eval_batch_size=8,
    num_train_epochs=3,
    weight_decay=0.01,
    save_strategy="epoch",
    logging_dir="./logs",
)

# 定义 Trainer
trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=tokenized_datasets["train"],
    eval_dataset=tokenized_datasets["test"],
    tokenizer=tokenizer,
)

# 开始微调
trainer.train()

# 保存模型
model.save_pretrained("./lora-fine-tuned-model")

1.5 P-tuning v2

P-tuning v2 是一种提示微调方法,通过优化提示(Prompt)来引导模型完成任务,而不改变模型参数。

特点

  • 提示优化:通过可学习的提示向量引导模型。
  • 适合场景:少样本学习,资源有限。
  • 优点:无需修改模型参数,显存占用低。
  • 缺点:需要设计提示模板。

实现代码

使用 openprompt 库实现 P-tuning v2:

pip install openprompt
from openprompt import PromptDataLoader, PromptForClassification
from openprompt.plms import load_plm
from openprompt.prompts import ManualTemplate
from openprompt.prompts import ManualVerbalizer
from datasets import load_dataset

# 加载预训练模型
plm, tokenizer, model_config, WrapperClass = load_plm("bert", "bert-base-uncased")

# 加载数据集
dataset = load_dataset("imdb")

# 定义提示模板
template = ManualTemplate(
    text='{"placeholder":"text_a"} It was {"mask"}',
    tokenizer=tokenizer,
)

# 定义标签词映射
verbalizer = ManualVerbalizer(
    classes=["negative", "positive"],
    label_words={
        "negative": ["bad"],
        "positive": ["good"],
    },
    tokenizer=tokenizer,
)

# 定义 Prompt 模型
prompt_model = PromptForClassification(
    plm=plm,
    template=template,
    verbalizer=verbalizer,
)

# 数据加载器
dataloader = PromptDataLoader(
    dataset=dataset["train"],
    tokenizer=tokenizer,
    template=template,
    max_seq_length=512,
)

# 训练(伪代码,需补充优化器和训练循环)
for batch in dataloader:
    logits = prompt_model(batch)
    # 计算损失并更新模型

1.6 Freeze 微调

Freeze 微调是指冻结模型的大部分参数,只微调部分层(如分类头)。

特点

  • 参数冻结:只微调模型的最后几层。
  • 适合场景:资源有限,任务数据量较小。
  • 优点:计算成本低,显存占用少。
  • 缺点:模型适应能力有限。

实现代码

from transformers import AutoTokenizer, AutoModelForSequenceClassification, Trainer, TrainingArguments
from datasets import load_dataset

# 加载预训练模型和分词器
model_name = "bert-base-uncased"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForSequenceClassification.from_pretrained(model_name, num_labels=2)

# 冻结模型的大部分参数
for param in model.bert.parameters():
    param.requires_grad = False

# 加载数据集
dataset = load_dataset("imdb")

# 数据预处理
def preprocess_function(examples):
    return tokenizer(examples["text"], truncation=True, padding="max_length", max_length=512)

tokenized_datasets = dataset.map(preprocess_function, batched=True)

# 设置训练参数
training_args = TrainingArguments(
    output_dir="./freeze_results",
    evaluation_strategy="epoch",
    learning_rate=2e-5,
    per_device_train_batch_size=8,
    per_device_eval_batch_size=8,
    num_train_epochs=3,
    weight_decay=0.01,
    save_strategy="epoch",
    logging_dir="./logs",
)

# 定义 Trainer
trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=tokenized_datasets["train"],
    eval_dataset=tokenized_datasets["test"],
    tokenizer=tokenizer,
)

# 开始微调
trainer.train()

# 保存模型
model.save_pretrained("./freeze-fine-tuned-model")
tokenizer.save_pretrained("./freeze-fine-tuned-model")

1.7 总结

方法特点适用场景优点缺点
SFT全参数微调数据量大,资源充足完全适应任务计算成本高
LoRA低秩分解,部分参数微调资源有限参数效率高,显存占用低需要额外实现
P-tuning提示优化,不修改模型参数少样本学习显存占用低需要设计提示模板
Freeze冻结大部分参数,微调部分层资源有限,数据量小计算成本低模型适应能力有限

2.DeepSeek微调

DeepSeek LLM 是一个强大的开源语言模型,但为了最大限度地发挥其在特定应用中的潜力,微调是必不可少的。
在这里插入图片描述

2.1 使用数据子集

在资源有限的硬件上微调像 DeepSeek LLM 这样的大型语言模型时,在完整数据集(例如,具有 25,000 个样本的 IMDB)上进行训练可能会导致过多的训练时间和 GPU 内存问题。

  • 选择一个子集:500 个样本用于训练,100 个样本用于评估。
  • 保持代表性:该子集保留了足够的多样性以实现合理的性能。

使用较小的数据集可以加快实验速度,同时有效地展示微调概念。对于生产级微调,应在更强大的基础设施上使用更大的数据集。

2.2 安装所需的库

首先,安装必要的依赖项:

pip install -U torch transformers datasets accelerate peft bitsandbytes

2.3 使用 4 位量化加载模型

使用 4 位量化使大型模型与有限的 GPU 内存兼容:

from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
from peft import LoraConfig, get_peft_model

model_name = "deepseek-ai/deepseek-llm-7b-base"
# Configure 4-bit quantization
bnb_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_compute_dtype=torch.float16  # Use float16 for faster computation
)
# Load tokenizer and model
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
    model_name, 
    quantization_config=bnb_config, 
    device_map="auto"
)
# Apply LoRA for memory-efficient fine-tuning
lora_config = LoraConfig(
    r=8,  # Low-rank adaptation size
    lora_alpha=32,
    target_modules=["q_proj", "v_proj"],  # Apply LoRA to attention layers
    lora_dropout=0.05,
    bias="none"
)
model = get_peft_model(model, lora_config)
model.print_trainable_parameters()
print(" DeepSeek LLM Loaded with LoRA and 4-bit Precision!")

2.4 使用 Hugging Face 数据集进行训练

为了进行微调,需要一个高质量的数据集。 Hugging Face 提供对各种数据集的访问:

选择数据集

对于此示例,让我们使用 IMDB 数据集对 DeepSeek LLM 进行情绪分类微调:

from datasets import load_dataset

# Load dataset
dataset = load_dataset("imdb")

预处理数据集

将文本转换为模型的标记化输入:

def tokenize_function(examples):
    inputs = tokenizer(
        examples["text"], 
        truncation=True, 
        padding="max_length", 
        max_length=512
    )
    inputs["labels"] = inputs["input_ids"].copy()
    return inputs

tokenized_datasets = dataset.map(tokenize_function, batched=True)
# Subset the dataset for faster experimentation
small_train_dataset = tokenized_datasets["train"].shuffle(seed=42).select(range(500))
small_test_dataset = tokenized_datasets["test"].shuffle(seed=42).select(range(100))
# Print a sample tokenized entry
print("Tokenized Sample:")
print(small_train_dataset[0])

3.LoRA(低秩自适应)

LoRA(低秩自适应)是一种旨在通过以下方式使 DeepSeek LLM 等大型模型的微调更加节省内存的技术:

  • 冻结模型的大部分权重。
  • 在关键层(例如注意层)中引入低秩可训练矩阵。

这大大减少了可训练参数的数量,同时保持了模型的性能。LoRA 可以在资源受限的硬件(例如 Colab GPU)上微调大型语言模型。

#4.代码演练:微调 DeepSeek LLM

首先设置训练参数:

from transformers import TrainingArguments, Trainer

training_args = TrainingArguments(
    output_dir="./results",
    evaluation_strategy="epoch",
    learning_rate=3e-4,  # Lower learning rate for LoRA fine-tuning
    per_device_train_batch_size=1,  # Reduce batch size for memory efficiency
    gradient_accumulation_steps=8,  # Simulate larger batch size
    num_train_epochs=0.5,
    weight_decay=0.01,
    save_strategy="epoch",
    logging_dir="./logs",
    logging_steps=50,
    fp16=True,  # Mixed precision training
)

初始化训练器:

trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=small_train_dataset,
    eval_dataset=small_test_dataset,
)
print("🚀 Trainer Initialized!")

开始微调:

print("🚀 Starting Fine-Tuning...")
trainer.train()

保存微调模型:

trainer.save_model("./fine_tuned_deepseek")
tokenizer.save_pretrained("./fine_tuned_deepseek")
print("Fine-Tuned Model Saved Successfully!")

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2301100.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

聚焦地灾防治,助力城市地质安全风险防控

城市是人类社会发展的重要载体,承载着经济繁荣、文化交流和人口聚集等重要功能。然而,由于城市建设过程中地质条件复杂,地质灾害风险隐患存在,城市地质安全等问题日益突出,引起人们的广泛关注。为保障城市发展的安全和…

为什么WP建站更适合于谷歌SEO优化?

在当今数字时代,建立一个网站似乎变得容易,但要构建一个真正能够带来流量和订单的网站却并非易事。特别是在谷歌SEO优化方面,不同的建站程序在SEO支持方面的效果差异显著。对于希望提升搜索引擎表现的用户来说,WordPress无疑是最佳…

用deepseek学大模型08-长短时记忆网络 (LSTM)

deepseek.com 从入门到精通长短时记忆网络(LSTM),着重介绍的目标函数,损失函数,梯度下降 标量和矩阵形式的数学推导,pytorch真实能跑的代码案例以及模型,数据, 模型应用场景和优缺点,及如何改进解决及改进方法数据推导…

(蓝桥杯——10. 小郑做志愿者)洛斯里克城志愿者问题详解

题目背景 小郑是一名大学生,她决定通过做志愿者来增加自己的综合分。她的任务是帮助游客解决交通困难的问题。洛斯里克城是一个六朝古都,拥有 N 个区域和古老的地铁系统。地铁线路覆盖了树形结构上的某些路径,游客会询问两个区域是否可以通过某条地铁线路直达,以及有多少条…

小胡说技书博客分类(部分目录):服务治理、数据治理与安全治理对比表格

文章目录 一、对比表格二、目录2.1 服务2.2 数据2.3 安全 一、对比表格 下表从多个维度对服务治理、数据治理和安全治理进行详细对比,为读者提供一个直观而全面的参考框架。 维度服务治理数据治理安全治理定义对软件开发全流程、应用交付及API和接口管理进行规范化…

开源模型应用落地-DeepSeek-R1-Distill-Qwen-7B-LoRA微调-LLaMA-Factory-单机单卡-V100(一)

一、前言 如今,大语言模型领域热闹非凡,各种模型不断涌现。DeepSeek-R1-Distill-Qwen-7B 模型凭借其出色的效果和性能,吸引了众多开发者的目光。而 LLaMa-Factory 作为强大的微调工具,能让模型更好地满足个性化需求。 在本篇中&am…

uni-app发起网络请求的三种方式

uni.request(OBJECT) 发起网络请求 具体参数可查看官方文档uni-app data:请求的参数; header:设置请求的 header,header 中不能设置 Referer; method:请求方法; timeout:超时时间,单位 ms&a…

EasyRTC:智能硬件适配,实现多端音视频互动新突破

一、智能硬件全面支持,轻松跨越平台障碍 EasyRTC 采用前沿的智能硬件适配技术,无缝对接 Windows、macOS、Linux、Android、iOS 等主流操作系统,并全面拥抱 WebRTC 标准。这一特性确保了“一次开发,多端运行”的便捷性&#xff0c…

LeetCode1287

LeetCode1287 目录 题目描述示例思路分析代码段代码逐行讲解复杂度分析总结的知识点整合总结 题目描述 给定一个非递减的整数数组 arr,其中有一个元素恰好出现超过数组长度的 25%。请你找到并返回这个元素。 示例 示例 1 输入: arr [1, 2, 2, 6, 6, 6, 6, 7,…

深度学习笔记之自然语言处理(NLP)

深度学习笔记之自然语言处理(NLP) 在行将开学之时,我将开始我的深度学习笔记的自然语言处理部分,这部分内容是在前面基础上开展学习的,且目前我的学习更加倾向于通识。自然语言处理部分将包含《动手学深度学习》这本书的第十四章&#xff0c…

自动化测试框架搭建-单次接口执行-三部曲

目的 判断接口返回值和提前设置的预期是否一致,从而判断本次测试是否通过 代码步骤设计 第一步:前端调用后端已经写好的POST接口,并传递参数 第二步:后端接收到参数,组装并请求指定接口,保存返回 第三…

DeepSeek R1生成图片总结2(虽然本身是不能直接生成图片,但是可以想办法利用别的工具一起实现)

DeepSeek官网 目前阶段,DeepSeek R1是不能直接生成图片的,但可以通过优化文本后转换为SVG或HTML代码,再保存为图片。另外,Janus-Pro是DeepSeek的多模态模型,支持文生图,但需要本地部署或者使用第三方工具。…

ESP32 ESP-IDF TFT-LCD(ST7735 128x160) LVGL基本配置和使用

ESP32 ESP-IDF TFT-LCD(ST7735 128x160) LVGL基本配置和使用 📍项目地址:https://github.com/lvgl/lv_port_esp32参考文章:https://blog.csdn.net/chentuo2000/article/details/126668088https://blog.csdn.net/p1279030826/article/details/…

【笔记】LLM|Ubuntu22服务器极简本地部署DeepSeek+联网使用方式

2025/02/18说明:2月18日~2月20日是2024年度博客之星投票时间,走过路过可以帮忙点点投票吗?我想要前一百的实体证书,经过我严密的计算只要再拿到60票就稳了。一人可能会有多票,Thanks♪(・ω・)&am…

Linux的基础指令和环境部署,项目部署实战(下)

目录 上一篇:Linxu的基础指令和环境部署,项目部署实战(上)-CSDN博客 1. 搭建Java部署环境 1.1 apt apt常用命令 列出所有的软件包 更新软件包数据库 安装软件包 移除软件包 1.2 JDK 1.2.1. 更新 1.2.2. 安装openjdk&am…

数值积分:通过复合梯形法计算

在物理学和工程学中,很多问题都可以通过数值积分来求解,特别是当我们无法得到解析解时。数值积分是通过计算积分区间内离散点的函数值来近似积分的结果。在这篇博客中,我将讨论如何使用 复合梯形法 来进行数值积分,并以一个简单的…

【Java计算机毕业设计】基于SSM+VUE保险公司管理系统数据库源代码+LW文档+开题报告+答辩稿+部署教程+代码讲解

源代码数据库LW文档(1万字以上)开题报告答辩稿 部署教程代码讲解代码时间修改教程 一、开发工具、运行环境、开发技术 开发工具 1、操作系统:Window操作系统 2、开发工具:IntelliJ IDEA或者Eclipse 3、数据库存储&#xff1a…

C#之上位机开发---------C#通信库及WPF的简单实践

〇、上位机,分层架构 界面层 要实现的功能: 展示数据 获取数据 发送数据 数据层 要实现的功能: 转换数据 打包数据 存取数据 通信层 要实现的功能: 打开连接 关闭连接 读取数据 写入数据 实体类 作用: 封装数据…

仿 Sora 之形,借物理模拟之技绘视频之彩

来自麻省理工学院、斯坦福大学、哥伦比亚大学以及康奈尔大学的研究人员携手开源了一款创新的3D交互视频模型——PhysDreamer(以下简称“PD”)。PD与OpenAI旗下的Sora相似,能够借助物理模拟技术来生成视频,这意味着PD所生成的视频蕴…

RedisTemplate存储含有特殊字符解决

ERROR信息: 案发时间: 2025-02-18 01:01 案发现场: UserServiceImpl.java 嫌疑人: stringRedisTemplate.opsForValue().set(SystemConstants.LOGIN_CODE_PREFIX phone, code, Duration.ofMinutes(3L)); // 3分钟过期作案动机: stringRedisTemplate继承了Redistemplate 使用的…