核心内容摘要
鸡鸡对鸡鸡
参考如何把你的 DeePseek-R1 微调为某个领域的专家今天我们一起来聊聊大模型的进阶使用“模型微调” 也就是较大 - 掘金看完就想试Unsloth打造个性化AI助手案例展示-CSDN博客unsloth 布署见unsloth 部署简单易上手版本-CSDN博客把基础模型下载到本地确定数据集的格式训练过程import os from unsloth import FastLanguageModel, is_bfloat16_supported from datasets import load_dataset import subprocess from trl import SFTTrainer,SFTConfig # 设置代理可选详见autodl参考文档 #
加载模型和 tokenizer model, tokenizer FastLanguageModel.from_pretrained( model_name/root/Qwen/Qwen2-
5B-Instruct, max_seq_length2048, dtypeNone, load_in_4bitTrue, ) #
添加 LoRAUnsloth 自动优化 model FastLanguageModel.get_peft_model( model, r32, # LoRA rank target_modules[q_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_proj, lm_head], lora_alpha64, lora_dropout
05, biasnone, use_gradient_checkpointingunsloth, # 更高效 random_state3407, ) #
加载数据集假设是 Alpaca 格式 dataset load_dataset(json, data_files/root/ft_data.json, splittrain) # load_dataset批量处理数据集 #
定义 formatting_func关键把结构化的 instruction/input/output 字段批量转换成模型能识别的对话格式文本 #更标准的写法和test的写法一致 def formatting_func(examples): outputs [] for i in range(len(examples[instruction])): instruction examples[instruction][i].strip() input_text examples[input][i].strip() if input in examples and examples[input][i] else output examples[output][i].strip() # 构造标准化 messages和推理时一致 messages [ {role: user, content: f{instruction}\n{input_text} if input_text else instruction}, {role: assistant, content: output} ] # 用 apply_chat_template 生成格式和推理时完全相同 text tokenizer.apply_chat_template( messages, tokenizeFalse, # 只生成文本不编码 add_generation_promptFalse # 训练时不需要加 assistant 生成提示符 ) outputs.append(text) return outputs#
使用 Unsloth 的 train 方法自动处理 packing、formatting 等 training_config SFTConfig( per_device_train_batch_size4, gradient_accumulation_steps2, warmup_steps10, max_steps100, learning_rate1e-4, logging_steps2, save_steps50, output_dir/root/my_qwen_assistant, optimadamw_8bit, seed3407, fp16False, bf16True, packingFalse, # 关闭打包与 Unsloth 无填充批处理兼容 remove_unused_columnsFalse, # 保留数据集字段避免格式化函数报错 ) trainer SFTTrainer( modelmodel, tokenizertokenizer, train_datasetdataset, formatting_funcformatting_func, # ←← Unsloth 的 SFTTrainer 要求这个 max_seq_length2048, dataset_num_proc2, packingFalse, argstraining_config, ) #
训练并保存 trainer_stats trainer.train() model.save_pretrained(my_qwen_assistant) tokenizer.save_pretrained(my_qwen_assistant)推理过程from peft import PeftModel from unsloth import FastLanguageModel, is_bfloat16_supported #
加载基础模型保持和训练一致的dtype/device_map base_model, tokenizer FastLanguageModel.from_pretrained( model_name/root/Qwen/Qwen2-
5B-Instruct, max_seq_length2048, dtypeNone, load_in_4bitTrue, ) #
加载LoRA适配器校验路径 lora_model_path /root/my_qwen_assistant # 校验LoRA权重是否存在 import os if not os.path.exists(lora_model_path): raise ValueError(fLoRA权重路径不存在{lora_model_path}) print(f成功加载LoRA权重{lora_model_path}) model PeftModel.from_pretrained(base_model, lora_model_path) model.eval() # 评估模式 #
推理仅用LoRA模型删除基础模型推理代码 messages [ {role: user, content: 项目名称xxxx一xxx二xxx。
三xxx。
。
。
} ] # 用和训练时一致的chat template生成输入 input_ids tokenizer.apply_chat_template( messages, tokenizeTrue, add_generation_promptTrue, return_tensorspt ).to(model.device) # 生成参数简化聚焦核心 outputs model.generate( input_idsinput_ids[input_ids], attention_mask input_ids[attention_mask], max_new_tokens800, do_sampleTrue, # 开启采样提升回复多样性 temperature