news 2026/7/17 21:34:41

微调生成特定写作风格助手

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
微调生成特定写作风格助手

参考

如何把你的 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参考文档 # 1. 加载模型和 tokenizer model, tokenizer = FastLanguageModel.from_pretrained( model_name="/root/Qwen/Qwen2-1.5B-Instruct", max_seq_length=2048, dtype=None, load_in_4bit=True, ) # 2. 添加 LoRA(Unsloth 自动优化) model = FastLanguageModel.get_peft_model( model, r=32, # LoRA rank target_modules=["q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj", "lm_head"], lora_alpha=64, lora_dropout=0.05, bias="none", use_gradient_checkpointing="unsloth", # 更高效 random_state=3407, ) # 3. 加载数据集(假设是 Alpaca 格式) dataset = load_dataset("json", data_files="/root/ft_data.json", split="train") # load_dataset批量处理数据集 # 4. 定义 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, tokenize=False, # 只生成文本,不编码 add_generation_prompt=False # 训练时不需要加 assistant 生成提示符 ) outputs.append(text) return outputs
# 5. 使用 Unsloth 的 train 方法(自动处理 packing、formatting 等) training_config = SFTConfig( per_device_train_batch_size=4, gradient_accumulation_steps=2, warmup_steps=10, max_steps=100, learning_rate=1e-4, logging_steps=2, save_steps=50, output_dir="/root/my_qwen_assistant", optim="adamw_8bit", seed=3407, fp16=False, bf16=True, packing=False, # 关闭打包,与 Unsloth 无填充批处理兼容 remove_unused_columns=False, # 保留数据集字段,避免格式化函数报错 ) trainer = SFTTrainer( model=model, tokenizer=tokenizer, train_dataset=dataset, formatting_func=formatting_func, # ←← Unsloth 的 SFTTrainer 要求这个 max_seq_length=2048, dataset_num_proc=2, packing=False, args=training_config, ) # 6. 训练并保存 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 # 1. 加载基础模型(保持和训练一致的dtype/device_map) base_model, tokenizer = FastLanguageModel.from_pretrained( model_name="/root/Qwen/Qwen2-1.5B-Instruct", max_seq_length=2048, dtype=None, load_in_4bit=True, ) # 2. 加载LoRA适配器(校验路径) lora_model_path = "/root/my_qwen_assistant" # 校验LoRA权重是否存在 import os if not os.path.exists(lora_model_path): raise ValueError(f"LoRA权重路径不存在:{lora_model_path}") print(f"成功加载LoRA权重:{lora_model_path}") model = PeftModel.from_pretrained(base_model, lora_model_path) model.eval() # 评估模式 # 3. 推理(仅用LoRA模型,删除基础模型推理代码) messages = [ {"role": "user", "content": "项目名称:xxxx;一,xxx,二,xxx。三,xxx。。。"} ] # 用和训练时一致的chat template生成输入 input_ids = tokenizer.apply_chat_template( messages, tokenize=True, add_generation_prompt=True, return_tensors="pt" ).to(model.device) # 生成参数(简化,聚焦核心) outputs = model.generate( input_ids=input_ids["input_ids"], attention_mask = input_ids["attention_mask"], max_new_tokens=800, do_sample=True, # 开启采样,提升回复多样性 temperature=0.7, top_p=0.95, repetition_penalty=1.1, pad_token_id=tokenizer.eos_token_id, eos_token_id=tokenizer.eos_token_id, ) # 解码输出 response = tokenizer.decode(outputs[0][input_ids["input_ids"].shape[1]:], skip_special_tokens=True) print("LoRA模型推理结果:") print(response.strip()) #(可选)验证基础模型结果(对比用) base_model.eval() outputs_base = base_model.generate( input_ids=input_ids["input_ids"], attention_mask = input_ids["attention_mask"], max_new_tokens=800, do_sample=True, temperature=0.7, top_p=0.95, repetition_penalty=1.1, pad_token_id=tokenizer.eos_token_id, eos_token_id=tokenizer.eos_token_id, ) response_base = tokenizer.decode(outputs_base[0][input_ids["input_ids"].shape[1]:], skip_special_tokens=True) print("\n基础模型推理结果:") print(response_base.strip())
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/15 6:39:09

ScalingLaws-2022-Chinchilla-2:既然Dₒₚₜ/Nₒₚₜ≈20,为什么LLaMA系列用的D/N远大于20【Chinchilla比例:每个参数大约对应20个token】

“每个参数大约对应 20 个 token”(常被叫作 Chinchilla 比例)并不是一条“宇宙定律”。 你看到 LLaMA 系列的 token/参数 比值远大于 20,核心原因是:他们优化的目标、约束条件、以及用来拟合的“最优前沿(frontier)”都变了。 尤其从 Llama 3 开始,论文里甚至明确承认…

作者头像 李华
网站建设 2026/7/15 8:13:33

HTTP Content-Type

HTTP Content-Type 引言 HTTP协议中的Content-Type头字段是Web服务器与客户端之间进行数据交换的重要机制。它定义了服务器发送给客户端数据的类型,允许浏览器或其他客户端应用程序正确地处理和展示这些数据。本文将详细介绍HTTP Content-Type的用途、类型以及在实际应用中的…

作者头像 李华
网站建设 2026/7/15 4:18:06

VSCode 下如何检查 Vue 项目中未使用的依赖?

VSCode 下如何检查 Vue 项目中未使用的依赖? 文章目录 VSCode 下如何检查 Vue 项目中未使用的依赖?1. 使用 depcheck 工具(推荐)安装和使用:配置(可选): 2. 使用 npm-check 工具3. V…

作者头像 李华
网站建设 2026/7/17 16:07:59

SSM计算机毕设之基于ssm的网上手机商城系统基于SSM的手机商城(完整前后端代码+说明文档+LW,调试定制等)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华
网站建设 2026/7/17 15:06:14

开题报告 雅韵古诗词系统python爬虫

目录 雅韵古诗词系统Python爬虫简介爬虫技术实现要点数据处理与存储反爬策略应对应用场景扩展 项目技术支持可定制开发之功能亮点源码获取详细视频演示 :文章底部获取博主联系方式!同行可合作 雅韵古诗词系统Python爬虫简介 雅韵古诗词系统是一个基于Py…

作者头像 李华
网站建设 2026/7/17 9:36:41

SSM计算机毕设之基于SSM的疫情健康上报管理系统行程上报、健康上报(完整前后端代码+说明文档+LW,调试定制等)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华