news 2026/6/6 10:44:43

极简LLM入门指南6

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
极简LLM入门指南6

【LLM实操系列06】模型微调:用100条数据打造专属AI

开始微调之前,建议先完成第02篇(环境配置)和第03篇(模型基础)的学习。
硬件方面,你需要至少8GB GPU显存(使用QLoRA可降至6GB)。
理论方面,了解Transformer基本架构会有帮助(第01篇有介绍)。

5分钟理解微调

什么时候需要微调?

defneed_finetuning():"""判断是否需要微调"""if"特定领域术语多"and"Prompt优化无效":return"需要微调"elif"需要特定输出格式"and"Few-shot效果差":return"需要微调"elif"隐私数据不能用API":return"需要微调"else:return"继续优化Prompt"

微调 vs 其他方案(选择指南)

方案成本效果适用场景参考章节
Prompt工程一般通用任务第04篇
RAG知识问答第05篇
微调最好专属任务本篇
从头训练极高-不推荐-

LoRA:高效微调神器

原理:只训练少量参数

# 传统微调:训练所有参数(7B = 70亿参数)# LoRA微调:只训练0.1%参数(7M参数)# LoRA数学原理# W_new = W_original + ΔW# ΔW = A × B (A和B是小矩阵)

15分钟跑通LoRA

# pip install transformers peft datasets accelerate bitsandbytesfromtransformersimport(AutoModelForCausalLM,AutoTokenizer,TrainingArguments,Trainer)frompeftimportLoraConfig,get_peft_model,TaskTypeimporttorch# 1. 加载基座模型(以Qwen为例)model_name="Qwen/Qwen2.5-1.5B"# 小模型,适合测试model=AutoModelForCausalLM.from_pretrained(model_name,torch_dtype=torch.float16,device_map="auto")tokenizer=AutoTokenizer.from_pretrained(model_name)# 2. 配置LoRAlora_config=LoraConfig(task_type=TaskType.CAUSAL_LM,r=8,# LoRA秩,越大效果越好但越慢lora_alpha=16,# LoRA缩放参数lora_dropout=0.1,# Dropout比例target_modules=["q_proj","v_proj"],# 要微调的层)# 3. 创建PEFT模型model=get_peft_model(model,lora_config)model.print_trainable_parameters()# 输出: trainable params: 4,194,304 || all params: 1,544,454,144 || trainable%: 0.27# 4. 准备数据defprepare_data():"""准备训练数据"""# 格式:instruction-output对data=[{"instruction":"翻译成英文:你好世界","output":"Hello World"},{"instruction":"生成SQL:查询年龄大于18的用户","output":"SELECT * FROM users WHERE age > 18"}]returndatadefformat_prompt(example):"""格式化训练样本"""prompt=f"""<|im_start|>user{example['instruction']}<|im_end|> <|im_start|>assistant{example['output']}<|im_end|>"""return{"text":prompt}# 5. 训练training_args=TrainingArguments(output_dir="./lora_model",num_train_epochs=3,per_device_train_batch_size=4,gradient_accumulation_steps=4,warmup_steps=100,logging_steps=10,save_strategy="epoch",learning_rate=1e-4,fp16=True,)trainer=Trainer(model=model,args=training_args,train_dataset=train_dataset,tokenizer=tokenizer,)trainer.train()

QLoRA:4bit量化微调

显存对比

# 模型大小对比configs={"全精度":{"7B模型":"28GB显存","可行性":"A100"},"LoRA":{"7B模型":"16GB显存","可行性":"3090/4090"},"QLoRA":{"7B模型":"6GB显存","可行性":"2080Ti"},# ← 推荐}

QLoRA实现

fromtransformersimportBitsAndBytesConfig# QLoRA配置:4bit量化bnb_config=BitsAndBytesConfig(load_in_4bit=True,bnb_4bit_compute_dtype=torch.float16,bnb_4bit_quant_type="nf4",bnb_4bit_use_double_quant=True,)# 加载4bit模型model=AutoModelForCausalLM.from_pretrained(model_name,quantization_config=bnb_config,device_map="auto")# 准备训练frompeftimportprepare_model_for_kbit_training model=prepare_model_for_kbit_training(model)# 应用LoRAmodel=get_peft_model(model,lora_config)# 现在可以在6GB显存上微调7B模型!

数据准备最佳实践

1. 数据格式

# 方式1:指令微调格式instruction_data={"instruction":"任务描述","input":"输入内容(可选)","output":"期望输出"}# 方式2:对话格式conversation_data={"conversations":[{"from":"human","value":"用户问题"},{"from":"assistant","value":"助手回答"}]}# 方式3:纯文本续写text_data={"text":"这是一段完整的文本..."}

2. 数据处理工具

classDataProcessor:"""数据预处理工具"""def__init__(self,tokenizer,max_length=512):self.tokenizer=tokenizer self.max_length=max_lengthdefprocess_dataset(self,raw_data):"""处理数据集"""processed=[]foriteminraw_data:# 构建对话text=self.format_conversation(item)# 分词tokens=self.tokenizer(text,max_length=self.max_length,truncation=True,padding="max_length",return_tensors="pt")processed.append({"input_ids":tokens["input_ids"][0],"attention_mask":tokens["attention_mask"][0],"labels":tokens["input_ids"][0]# 自回归训练})returnprocesseddefformat_conversation(self,item):"""格式化为模型输入"""# Qwen格式returnf"""<|im_start|>system You are a helpful assistant.<|im_end|> <|im_start|>user{item['instruction']}<|im_end|> <|im_start|>assistant{item['output']}<|im_end|>"""defvalidate_data(self,dataset):"""数据质量检查"""issues=[]foridx,iteminenumerate(dataset):# 检查长度iflen(item['text'])>self.max_length*4:# 估算issues.append(f"样本{idx}过长")# 检查格式ifnotitem.get('instruction'):issues.append(f"样本{idx}缺少instruction")returnissues

3. 数据增强

defaugment_data(original_data):"""数据增强技巧"""augmented=[]foriteminoriginal_data:# 1. 原始样本augmented.append(item)# 2. 改写instructionrephrased={"instruction":f"请{item['instruction']}","output":item['output']}augmented.append(rephrased)# 3. 添加思维链cot_version={"instruction":item['instruction'],"output":f"让我思考一下。{item['output']}"}augmented.append(cot_version)returnaugmented

训练监控与评估

实时监控

fromtransformersimportTrainerCallbackimportwandbclassTrainingMonitor(TrainerCallback):"""训练监控回调"""defon_log(self,args,state,control,logs=None,**kwargs):iflogs:# 打印关键指标print(f"Step{state.global_step}: Loss={logs.get('loss',0):.4f}")# 上传到wandb(可选)ifwandb.run:wandb.log(logs)defon_epoch_end(self,args,state,control,**kwargs):# 每个epoch结束后评估print(f"Epoch{state.epoch}completed")

评估指标

defevaluate_model(model,test_data):"""模型评估"""fromrougeimportRougefrombert_scoreimportscore predictions=[]references=[]foritemintest_data:# 生成预测input_text=item['instruction']pred=model.generate(input_text,max_length=100)predictions.append(pred)references.append(item['output'])# ROUGE分数rouge=Rouge()rouge_scores=rouge.get_scores(predictions,references,avg=True)# BERTScoreP,R,F1=score(predictions,references,lang="zh")return{"rouge":rouge_scores,"bertscore":{"P":P.mean(),"R":R.mean(),"F1":F1.mean()}}

部署微调模型

1. 合并LoRA权重

frompeftimportPeftModel# 加载基座模型base_model=AutoModelForCausalLM.from_pretrained(model_name)# 加载LoRA权重model=PeftModel.from_pretrained(base_model,"./lora_model")# 合并权重merged_model=model.merge_and_unload()# 保存完整模型merged_model.save_pretrained("./final_model")tokenizer.save_pretrained("./final_model")

2. 量化部署

# GGUF格式(用于llama.cpp/Ollama)fromtransformersimportAutoModelForCausalLMimporttorch# 转换为GGUFmodel=AutoModelForCausalLM.from_pretrained("./final_model")model.save_pretrained("./gguf_model",safe_serialization=True)# 使用llama.cpp量化# python convert.py ./final_model --outfile model.gguf# ./quantize model.gguf model_q4_k_m.gguf q4_k_m

3. API服务

fromfastapiimportFastAPIfrompydanticimportBaseModel app=FastAPI()# 加载模型model=AutoModelForCausalLM.from_pretrained("./final_model")tokenizer=AutoTokenizer.from_pretrained("./final_model")classQuery(BaseModel):text:strmax_length:int=100@app.post("/generate")asyncdefgenerate(query:Query):inputs=tokenizer(query.text,return_tensors="pt")outputs=model.generate(**inputs,max_length=query.max_length)response=tokenizer.decode(outputs[0],skip_special_tokens=True)return{"response":response}

成本与效果对比

方法数据量训练时间显存效果提升
Prompt000基准
Few-shot5-1000+10%
LoRA100-1K1-4小时16GB+30%
QLoRA100-1K2-6小时6GB+25%
全量微调10K+1-7天80GB+35%

调试技巧

# 常见问题快速诊断defdiagnose_training_issues():checks={"Loss不下降":["检查学习率(试试1e-4到5e-5)","增加训练轮数","检查数据格式"],"显存爆炸":["减小batch_size","使用gradient_accumulation_steps","启用gradient_checkpointing"],"效果不好":["增加LoRA rank (r=8→16)","增加训练数据","调整lora_alpha"],"推理错误":["检查tokenizer配置","确认special tokens","验证prompt模板"]}returnchecks
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/5 9:16:49

Wan2.2-T2V-5B + GPU算力租赁:打造高性价比视频生成方案

Wan2.2-T2V-5B GPU算力租赁&#xff1a;打造高性价比视频生成方案 你有没有试过&#xff0c;在深夜灵光一闪&#xff0c;想为新品牌做个宣传短片&#xff0c;却卡在“找人拍太贵、外包周期太长”上&#xff1f;又或者作为独立开发者&#xff0c;手握创意却因一张A100显卡的价格…

作者头像 李华
网站建设 2026/6/5 22:57:30

轮流停电,末日来临!美国数据中心崩溃

由于德克萨斯州拥有丰富的能源资源和良好的营商环境&#xff0c;因此吸引了大量的数据中心需求。北美电力公司表示&#xff0c;这些数据中心可能会在极端冬季风暴期间加剧电力供应短缺。2021年的一场冬季风暴迫使德克萨斯州电网运营商ERCOT下令轮流停电&#xff0c;防止电网系统…

作者头像 李华
网站建设 2026/6/6 7:46:43

AutoGPT与RAG技术融合探索:增强知识检索准确性的新路径

AutoGPT与RAG技术融合探索&#xff1a;增强知识检索准确性的新路径 在AI智能体日益深入现实场景的今天&#xff0c;一个核心挑战逐渐浮现&#xff1a;如何让大模型既具备自主决策能力&#xff0c;又能精准获取动态、可信的知识&#xff1f;传统聊天机器人依赖用户步步引导&…

作者头像 李华
网站建设 2026/6/3 23:16:09

保持单线程工作状态

在职场每个人每天都有很多事情&#xff0c;但是要把这些事情都做好的办法&#xff0c;其实不是一下子做多个事情&#xff0c;而是&#xff1a;一次做一件事情&#xff0c;把这件事情做好&#xff0c;做完再做下一件事情。心理学家卡尔纽波特提出了“深度工作”的概念&#xff0…

作者头像 李华
网站建设 2026/6/6 5:37:11

24、Oracle数据库中PERIOD类型的使用与时间性识别

Oracle数据库中PERIOD类型的使用与时间性识别 1. 时间属性与事务时间 在就业合同的例子中,原则上雇佣日期限制了合同的有效性。但数据并非恰好在有效性起始点加载到数据库中,因此事务时间是系统管理的DATE或TIMESTAMP值,表示插入点。根据设置,事务时间可意味着插入操作时…

作者头像 李华