大模型微调实战:从预训练到LoRA微调全攻略
大模型微调实战从预训练到LoRA微调全攻略大语言模型LLM的预训练阶段消耗海量数据和算力但直接用于特定业务场景往往效果欠佳。模型微调Fine-tuning通过在下游任务数据上继续训练让模型掌握特定领域的知识和输出风格。本文系统梳理从全参数微调到高效参数微调PEFT的完整技术路径并给出可运行的PyTorch代码实战。一、大模型训练的生命周期在深入微调之前我们先理解大模型从诞生到落地的完整训练流程| 阶段 | 目标 | 数据量 | 计算资源 | 典型时长 | |------|------|--------|---------|---------| |预训练Pre-training| 学习通用语言知识和世界常识 | 万亿级token | 数千GPU/TPU | 数周至数月 | |持续预训练Continual Pre-training| 注入领域知识如法律、医疗 | 百亿级token | 数百GPU | 数天至数周 | |指令微调SFT| 学习对话格式和遵循指令 | 十万至百万级样本 | 数十至数百GPU | 数小时至数天 | |对齐训练RLHF/DPO| 对齐人类偏好和价值观 | 数万偏好对 | 数十GPU | 数天 | |推理部署Inference| 服务线上请求 | - | 根据QPS配置 | 持续运行 |微调的核心定位大多数企业和开发者处于指令微调阶段使用预训练好的开源模型如Llama、ChatGLM、Qwen在自有数据上调整模型行为。二、全参数微调Full Fine-tuning2.1 原理与适用场景全参数微调更新模型的所有权重参数让模型最大程度地适应下游任务。其优势是上限高能充分挖掘模型潜力劣势是显存占用巨大且每个任务都需要保存完整的模型副本。以Llama-2-7B为例全参数微调需要模型权重约14GBFP16优化器状态AdamW约28GB动量二阶矩梯度约14GB激活值随batch size和序列长度变化约10-30GB总计至少需要约70GB显存单卡A10080GB刚好满载。2.2 全参数微调代码示例import torch from transformers import ( AutoModelForCausalLM, AutoTokenizer, TrainingArguments, Trainer, DataCollatorForSeq2Seq ) from datasets import load_dataset # 加载模型与分词器 model_name meta-llama/Llama-2-7b-hf model AutoModelForCausalLM.from_pretrained( model_name, torch_dtypetorch.bfloat16, device_mapauto # 自动分配到多卡 ) tokenizer AutoTokenizer.from_pretrained(model_name) tokenizer.pad_token tokenizer.eos_token # 设置填充token # 加载数据集以Alpaca格式为例 dataset load_dataset(tatsu-lab/alpaca, splittrain[:10000]) def preprocess_function(examples): 构建指令-输出格式的训练样本 prompts [] for instruction, input_text, output in zip( examples[instruction], examples[input], examples[output] ): if input_text: prompt f### Instruction:\n{instruction}\n\n### Input:\n{input_text}\n\n### Response:\n{output} else: prompt f### Instruction:\n{instruction}\n\n### Response:\n{output} prompts.append(prompt) # 分词并截断 model_inputs tokenizer( prompts, max_length512, truncationTrue, paddingmax_length ) # 标签与输入相同用于因果语言建模 model_inputs[labels] model_inputs[input_ids].copy() return model_inputs # 数据预处理 tokenized_dataset dataset.map( preprocess_function, batchedTrue, remove_columnsdataset.column_names ) # 训练配置 training_args TrainingArguments( output_dirquo