当前位置: 首页 > news >正文

基于AutoDL V100微调DeepSeek Coder 6.7B (2)

1.工具准备

  • transformers:用于加载和训练大模型。
  • peft:用于低秩适配(LoRA)训练方法。
  • datasets:加载JSON数据集。

Transformers:

AutoTokenizer:自动加载与模型对应的 分词器(Tokenizer),用于将文本转化为模型输入(input_ids等)。

AutoModelForCausalLM:加载支持“因果语言建模(Causal Language Modeling)”的预训练模型。

TrainingArguments:配置训练参数,如 batch size、learning rate、日志保存间隔等。

Trainer:Hugging Face 提供的高层封装的训练器,支持微调、评估、保存模型等功能。

DataCollatorForLanguageModeling:对训练数据进行批处理(collate),用于语言建模任务。

BitsAndBytesConfig:配置 模型量化参数,比如是否启用4bit、使用哪种量化方式(如 NF4)。

Peft:

prepare_model_for_kbit_training:在使用量化模型训练前,对模型进行预处理。

LoraConfig:定义 LoRA 微调的配置参数。

get_peft_model:将 LoRA 模块集成到原始模型中,只训练极少量 LoRA 参数,其余参数保持冻结。这样可以在不破坏预训练能力的基础上,快速微调模型以适应新任务。

TaskType:定义你的微调任务类型,这里使用SEQ_2_SEQ_LM(序列到序列任务,用于翻译、摘要等)

摘自文档
任务类型 (TaskType)说明常用模型示例
CAUSAL_LM因果语言建模(自回归),用于文本生成任务GPT、DeepSeek、LLaMA、Mistral
SEQ_2_SEQ_LM序列到序列任务(编码器-解码器),用于翻译、摘要等T5、BART、FLAN-T5
TOKEN_CLSToken 级别分类,如命名实体识别 NERBERT、RoBERTa
SEQ_CLS序列分类任务,如情感分析、文本分类BERT、RoBERTa
QUESTION_ANSWERING提问-回答任务,如阅读理解(SQuAD)BERT、RoBERTa
IMAGE_CLASSIFICATION图像分类任务ViT、ConvNeXt 等视觉模型
MULTIPLE_CHOICE多选题任务,如 SWAG、RACEBERT、RoBERTa
OBJECT_DETECTION目标检测(用于视觉模型)YOLO、DETR 等
VISION2TEXT图文生成,如图像字幕生成(Image Captioning)BLIP、ViLT
FEATURE_EXTRACTION特征提取(不常用)任意模型提取中间层表示

2.模型准备

(1)模型量化:

模型量化是指将模型中使用的数值精度从高精度降低为低精度的方法,以减少模型的计算需求和内存占用,常用于部署大模型到资源受限的设备或加速推理/训练过程。

常见量化类型
类型精度特点适用场景
FP1616-bit float减少内存使用,支持GPU原生计算微调、推理
INT88-bit int内存和速度显著下降,准确率略损推理部署、移动设备
4-bit(NF4)4-bit float-like极限压缩,结合QLoRA使用,保留准确性参数高效微调(QLoRA)

在这里为了降低训练成本选择使用NF4 

bnb_config = BitsAndBytesConfig(load_in_4bit=True, #开启四位量化bnb_4bit_quant_type="nf4", #使用NormalFloat4量化格式(高精度)bnb_4bit_use_double_quant=True, #启用double quantization(二次压缩,更有空间)bnb_4bit_compute_dtype=torch.float16   # 前向计算时使用 float16 精度(兼顾精度与速度)
)

加载Tokenizer(分词器):将自然语言文本编码为模型输入的token(input_ids)

tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)

参数说明:

model_path:模型文件夹或HuggingFace模型名。

trust_remote_code:允许加载自定义模型或 tokenizer 结构(DeepSeek 等大模型常用)。

加载并量化模型

model = AutoModelForCausalLM.from_pretrained(model_path,quantization_config=bnb_config,     # 应用上面定义的 4-bit 量化配置device_map="auto",                  # 自动将模型切分分配到可用设备(多卡/单卡)trust_remote_code=True              # 信任远程自定义代码(必须对非标准结构模型)
)

参数说明:

model_path:模型文件夹。

quantization_config:使用设置好的量化配置。

device_map:自动将模型加载到 GPU,适用于多个 GPU 或 AutoDL 的环境。

trust_remote_code:(同上)

准备模型进行QLoRA微调

model = prepare_model_for_kbit_training(model)

 第五步:配置模型行为(防OOM、启用梯度检查点)

model.config.use_cache = False
model.config.gradient_checkpointing = True

use_cache=false:禁用生成缓存,防止训练时出现 CUDA OOM(显存溢出)错误。

gradient_checkpointing=Ture:启梯度检查点(节省显存),以牺牲部分计算时间换取更低显存占用。

(2)LoRA 微调的配置参数

使用peft当中的Lora_config工具定义LoRA配置。

lora_config = LoraConfig(r=8,lora_alpha=16,target_modules=["q_proj", "v_proj"],lora_dropout=0.05,bias="none",task_type=TaskType.SEQ_2_SEQ_LM
)

LoRA原理:

模型在Transformer的过程公式为:y=Wx

其中y为输出,W为大模型参数矩阵,x为大模型的输入。

因此W是一个R^{d_{out} \times d_{in}}的矩阵。

LoRA是通过冻结W使输出为y=Wx +\alpha \cdot BA \cot x

其中BA分别为为R^{d_{out}\times d_{r}},R^{d_r\times d_{in}}的矩阵。那么训练所需要调整的参数就从d_{out}\times d_{in},被降低到(d_{in}+d_{out})\times d_r

这段代码中的r就是A和B的秩;lora_alpha是放大因子,用于对 LoRA 分支的输出进行线性缩放;Target_modules=["q_proj","v_proj"]表示在注意力模块“query”和“value”投影层插入LoRA结构;LoRA_dropout正则化防止过拟合,只对LoRA分支起作用;bias表示bias是否参与训练;task_type训练任务类型,这里使用Peft的TaskType.SEQ_2_SEQ_LM

加载lora_config

model = get_peft_model(model, lora_config)

(3)格式化训练样本

构造对话模板:

def format_prompt(example):return f"<|user|>\n{example['instruction']}\n<|assistant|>\n{example['output']}"

将一条样本中的 "instruction"(用户提问)和 "output"(模型期望输出)按照对话形式拼接,形成最终的训练输入 prompt。

分词并设置标签

def tokenize(example):prompt = format_prompt(example)result = tokenizer(prompt, truncation=True, padding="max_length", max_length=512)result["labels"] = result["input_ids"].copy()return result

首先构造对话模板之后使用Transformer的AutoTokenizer对Prompt分词并编码。

tokenizer的参数对模型微调的影响
参数含义对训练的影响
truncation=True超出最大长度时截断🔹 防止超长输入导致报错
🔹 但可能 丢失重要信息
padding="max_length"填充到固定长度🔹 提高 batch 对齐效率
🔹 太多 padding 会浪费显存,降低有效 token 比例
max_length=512最长 token 数🔹 控制模型处理的最大上下文范围
🔹 过短可能截断回答,过长显存压力大
return_tensors="pt"返回 PyTorch 张量用于直接输入模型(微调常设在 Trainer 内处理)
return_attention_mask=True是否返回 attention mask🔹 让模型忽略 padding 区域,非常重要,否则会学错位置

通常一个token对应一个中文字符或者更多。512个token通常对应500-600个中文字符,对应一篇法律文书摘要通常是足够的。 

将原本的数据token化处理并移除原始字段,并作为用于模型训练的tokenized数据集。

tokenized_dataset = dataset.map(tokenize, remove_columns=dataset.column_names)

3.模型训练参数

training_args = TrainingArguments(output_dir="../lora/output",per_device_train_batch_size=1,gradient_accumulation_steps=16,num_train_epochs=4,learning_rate=2e-4,fp16=True,bf16=False,logging_steps=10,save_steps=200,save_total_limit=2,report_to="none",
)

模型训练原理简述:

损失评估:计算模型预测结果与真实结果之间的差距,不同类型的任务对应不同的损失函数,在文本摘要生成任务中,模型的目标是根据输入一段简洁、准确的文字。这个任务属于序列到序列生成(Seq2Seq自回归语言建模(Causal LM),损失函数通常用于衡量生成文本与参考摘要的差异。交叉熵损失(Cross Entropy Loss)。模型按 token 逐个生成摘要,预测每个位置上的 token 的概率分布,交叉熵用于评估预测概率与真实 token 的偏差:Loss=-\sum_{i=1}^{T}logP \{ y_i|y_{<t},x\}

反向传播:在经历了模型预测,并根据预测结果以及损失函数计算出损失后,需要对不同的权重计算损失函数的梯度。再通过修改学习率更新权重,进而优化模型训练的参数

参数解释:

per_device_train_batch_size:每个设备每一批载入多少条数据。越小越节省资源。

gradient_accumulation_steps=k:每k步更新一次权重,常用于显存较小的环境,比如训练大模型时节省显存。越大越节省资源。

num_train_epochs:训练轮数,指完整的遍历数据的次数。过大可能过拟合且消耗资源,过下训练结果较差但节省资源。

learning_rate:学习率,用于更新权重,过大容易过大过小都容易浪费计算资源(过大步长过长越过最低点,太小靠近损失最低点过慢)

fp/bp16:启用混合精度训练,使用 16 位浮动精度(bfloat16/float16)来加速训练。

logging_steps (k):每k步打印一次训练日志。

save_steps(k):每k步保存一次模型,(避免训练中断时丢失进度。)

save_total_limit (2):设置最多保留的检查点数。

report_to ("none"):指定训练日志报告的目标平台。

数据处理器:

data_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer,mlm=False
)

 data_collator是用于处理和批处理输入数据的工具,特别是在训练语言模型时。

DataCollatorForLanguageModeling 是 Hugging Face Transformers 库中用于语言模型训练的一个类。它会将一个批次的文本样本合并成一个批次并进行适当的处理,尤其是对于处理输入文本(例如将其转换为模型的输入格式)非常重要。

tokenizer用于指定tokenizer,mlm指定是否使用 Masked Language Modeling (MLM),即是否使用遮盖语言建模任务。False:表示这是一个 Causal Language Modeling(因果语言建模)任务。在因果语言建模中,模型的目标是预测下一个单词或 token,通常用于自回归的语言模型。

开始训练:

trainer = Trainer(model=model, #加载模型args=training_args, #加载训练参数train_dataset=tokenized_dataset, #加载训练数据data_collator=data_collator, #加载数据整理器
)trainer.train() #开始训练

总结

以上就是模型训练需要的相关知识,总的来说主要需要设置的参数Lora的参数以及训练参数,Lora参数的目的在于在训练的过程中降低GPU负荷。训练参数的目的在于加速训练速度以及影响训练的效果过低和过高都会影响模型训练速度以及模型的训练效果。最终将所有的参数载入到peft的trainer当中进行训练即可。

import os
os.environ["PYTORCH_CUDA_ALLOC_CONF"] = "max_split_size_mb:128"import torch
torch.cuda.empty_cache()
torch.cuda.ipc_collect()from datasets import load_dataset
from transformers import (AutoTokenizer,AutoModelForCausalLM,TrainingArguments,Trainer,DataCollatorForLanguageModeling,BitsAndBytesConfig
)
from peft import (get_peft_model,prepare_model_for_kbit_training,LoraConfig,TaskType
)# ========== 基础配置 ==========
model_path = "model/deepseek-coder-6.7b-base"
data_path = "data/finetune_data.jsonl"# ========== 量化 & 加载模型 ==========
bnb_config = BitsAndBytesConfig(load_in_4bit=True, #开启四位量化bnb_4bit_quant_type="nf4", #使用NormalFloat4量化格式(高精度)bnb_4bit_use_double_quant=True, #启用double quantization(二次压缩,更有空间)bnb_4bit_compute_dtype=torch.float16   # 前向计算时使用 float16 精度(兼顾精度与速度)
)
)tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(model_path,quantization_config=bnb_config,device_map="auto",trust_remote_code=True
)model = prepare_model_for_kbit_training(model)
model.config.use_cache = False
model.config.gradient_checkpointing = True# ========== 配置 LoRA ==========
lora_config = LoraConfig(r=8,lora_alpha=16,target_modules=["q_proj", "v_proj"],lora_dropout=0.05,bias="none",task_type=TaskType.SEQ_2_SEQ_LM
)
model = get_peft_model(model, lora_config)# ========== 加载数据 ==========
dataset = load_dataset("json", data_files=data_path)["train"]def format_prompt(example):return f"<|user|>\n{example['instruction']}\n<|assistant|>\n{example['output']}"def tokenize(example):prompt = format_prompt(example)result = tokenizer(prompt, truncation=True, padding="max_length", max_length=512)result["labels"] = result["input_ids"].copy()return resulttokenized_dataset = dataset.map(tokenize, remove_columns=dataset.column_names)# ========== 训练参数 ==========
training_args = TrainingArguments(output_dir="../lora/output",per_device_train_batch_size=1,gradient_accumulation_steps=16,num_train_epochs=4,learning_rate=2e-4,fp16=True,bf16=False,logging_steps=10,save_steps=200,save_total_limit=2,report_to="none",
)# ========== 数据整理器 ==========
data_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer,mlm=False
)# ========== 开始训练 ==========
trainer = Trainer(model=model,args=training_args,train_dataset=tokenized_dataset,data_collator=data_collator,
)trainer.train()# ========== 保存模型 ==========
model.save_pretrained("lora/output")
tokenizer.save_pretrained("lora/output")

相关文章:

  • 智体OS-V3.7重大发布:智体管家2.0、ai-docs知识库2.0、mcphost支持千款MCP-server、氛围电商或知识库电商模板、智体轻聊网页版
  • Java 多线程基础:Thread 类详解
  • 【Sqlalchemy Model转换成Pydantic Model示例】
  • 【含文档+PPT+源码】基于SSM的电影数据挖掘与分析可视化系统设计与实现
  • 嵌入式学习笔记 - 关于STM32 SPI控制器读取以及写入时,标志位TXE, RXNE的变化
  • Leetcode 3530. Maximum Profit from Valid Topological Order in DAG
  • C#实现对达索(Dassault)SolidWorks中3D图纸转化为手机可直接查看预览图纸格式
  • 扣子流程图批量导入飞书多维表格
  • springboot 框架把 resources下的zip压缩包, springboot 项目启动后解压到项目根目录工具类
  • 域对齐是什么
  • 基于STM32、HAL库的ATECC608B安全验证及加密芯片驱动程序设计
  • Kotlin-高阶函数,Lambda表达式,内联函数
  • Spring Boot × K8s 监控实战-集成 Prometheus 与 Grafana
  • 在开发板上如何处理curl: (60) SSL certificate problem
  • openssl_error_string() 不要依赖错误信息作为逻辑判断
  • C语言复习笔记--数据在内存中的存储
  • 【LLM】解析RAG增强检索技术:原理、实现与应用
  • 23种设计模式-行为型模式之解释器模式(Java版本)
  • 光谱共焦位移传感器的优势有哪些?
  • 洛谷题解 | CF111C Petya and Spiders
  • 五一假期上海地铁部分线路将延时运营,这些调整请查收
  • 五一“拼假”催热超长假期,热门酒店民宿一房难求
  • 浙江官宣:五一假期,没电、没气、没油车辆全部免费拖离高速
  • 泽连斯基承认乌情报部门刺杀俄军高官
  • 黄仁勋访华期间表示希望继续与中国合作,贸促会回应
  • 上海超万套保租房供应高校毕业生,各项目免押、打折等优惠频出