一、核心场景定义文本动作提取输入注意事项数据输出固定格式、固定字段的 JSON训练方式32B 大模型生成标注 → 蒸馏到 7B模型Qwen-7B-Chat LoRA输出要求字段不能错、格式不能乱、不能少 key领域适配性识别电力检修专属动作。二、代码2.1测试训练import torch from datasets import load_dataset from transformers import ( AutoModelForCausalLM, AutoTokenizer, TrainingArguments, Trainer, DataCollatorForLanguageModeling ) from peft import LoraConfig, get_peft_model, TaskType import os import json # 1. 基础配置 BASE_MODEL_PATH Qwen/Qwen-7B-Chat DATA_PATH operation_samples.jsonl #数据集 OUTPUT_DIR ./operation_extract_7b DEVICE cuda if torch.cuda.is_available() else cpu BATCH_SIZE 2 LEARNING_RATE 3e-5 EPOCHS 4 # 2. 数据预处理 tokenizer AutoTokenizer.from_pretrained(BASE_MODEL_PATH, trust_remote_codeTrue) tokenizer.pad_token tokenizer.eos_token def preprocess_function(examples): texts [] for input_text, output_text in zip(examples[input], examples[output]): # 【关键】固定指令让模型学习结构化抽取 prompt f|im_start|user 从以下电网操作票中提取操作步骤输出严格为JSON格式不要多余说明 操作票内容{input_text}|im_end| |im_start|assistant {output_text}|im_end| texts.append(prompt) tokenized tokenizer( texts, truncationTrue, max_length1024, paddingmax_length, return_tensorspt#输出tensor字典 ) tokenized[labels] tokenized[input_ids].clone() return tokenized # 加载数据 dataset load_dataset(json, data_filesDATA_PATH)[train] tokenized_dataset dataset.map(preprocess_function, batchedTrue, remove_columnsdataset.column_names) data_collator DataCollatorForLanguageModeling(tokenizertokenizer, mlmFalse) #把padding填充的数据设置为-100避免训练到后面的数据 # 3. LoRA配置 model AutoModelForCausalLM.from_pretrained( BASE_MODEL_PATH, torch_dtypetorch.float16, device_mapauto, trust_remote_codeTrue ) lora_config LoraConfig( task_typeTaskType.CAUSAL_LM, r8,#低秩矩阵维度 lora_alpha32,#缩放因子 target_modules[c_attn, c_proj],#loRA训练配置层 #target_modules[c_attn, c_proj, w1, w2] lora_dropout0.05, biasnone, ) model get_peft_model(model, lora_config)#将loRA参数注入模型 model.print_trainable_parameters() # 4. 训练 training_args TrainingArguments( output_dirOUTPUT_DIR, per_device_train_batch_sizeBATCH_SIZE, learning_rateLEARNING_RATE, num_train_epochsEPOCHS, logging_steps10, save_steps100, fp16True, gradient_accumulation_steps4, save_total_limit2, report_tonone, ) trainer Trainer( modelmodel, argstraining_args, train_datasettokenized_dataset, data_collatordata_collator, ) trainer.train() model.save_pretrained(os.path.join(OUTPUT_DIR, final))#参数保存下次load tokenizer.save_pretrained(os.path.join(OUTPUT_DIR, final)) #把当前配置好的分词器包含词表、特殊符号、padding/truncation 规则等完整保存到指定文件夹 # 5. 推理专门适配你的JSON结构 def predict_operation(text): model_path os.path.join(OUTPUT_DIR, final)#model.loads m AutoModelForCausalLM.from_pretrained(model_path, torch_dtypetorch.float16, device_mapauto, trust_remote_codeTrue) t AutoTokenizer.from_pretrained(model_path, trust_remote_codeTrue) prompt f|im_start|user 从以下电网操作票中提取操作步骤输出严格为JSON格式不要多余说明 操作票内容{text}|im_end| |im_start|assistant inputs t(prompt, return_tensorspt).to(DEVICE) outputs m.generate( **inputs, max_new_tokens512, temperature0.05, # 极低温度保证格式稳定 top_p0.8, do_sampleFalse, eos_token_idt.eos_token_id, ) res t.decode(outputs[0], skip_special_tokensTrue) res res.split(assistant)[-1].strip() # 自动校验JSON保证可用 try: return json.loads(res) except: return {data: []} # 测试 if __name__ __main__: test_text 操作A设备按正常方式复电。 result predict_operation(test_text) print(json.dumps(result, ensure_asciiFalse, indent2))2.2 拓展get_peft_model接收一个基础预训练模型和一个配置对象返回一个配置好的、可训练的 PEFT 模型。PeftModel封装了基础模型和可训练的适配器参数。用于前向传播、保存、加载、合并权重等。PeftConfig用于保存特定方法如 LoRA的配置。LoraConfigLoRA 方法的配置。指定在哪些层target_modules添加 LoRA 适配器以及秩r、缩放因子lora_alpha等关键参数。PromptTuningConfig提示调优方法的配置。主要指定可学习软提示的长度num_virtual_tokens。PrefixTuningConfig前缀调优方法的配置。在模型每一层的输入前添加可学习的连续前缀向量。三、基于PPO算法的再训练「再训练过程中」每一轮迭代实时打分更新模型参数import torch import json import os from trl import PPOTrainer, PPOConfig, AutoModelForCausalLMWithValueHead from transformers import AutoTokenizer from peft import PeftModel # 1. 加载基础模型 BASE_MODEL_PATH Qwen/Qwen-7B-Chat LORA_PATH ./operation_extract_7b/final # 你训练好的SFT-LoRA权重 DEVICE cuda if torch.cuda.is_available() else cpu # 加载基础模型LoRA权重 base_model AutoModelForCausalLM.from_pretrained( BASE_MODEL_PATH, torch_dtypetorch.float16, device_mapauto, trust_remote_codeTrue ) model PeftModel.from_pretrained(base_model, LORA_PATH) # 包装成带价值头的模型RL需要价值头评估奖励 model AutoModelForCausalLMWithValueHead.from_pretrained(model, torch_dtypetorch.float16) tokenizer AutoTokenizer.from_pretrained(LORA_PATH, trust_remote_codeTrue) tokenizer.pad_token tokenizer.eos_token # 2. 定义奖励函数 def calculate_reward(json_str, ground_truth): 计算奖励值 参数 json_str: 模型生成的JSON字符串 ground_truth: 真实标注用于内容准确评分 返回 total_reward: 总奖励值0~11 return total_reward # 3. PPO配置 训练器初始化 ppo_config PPOConfig( batch_size1, # RL批次更小避免显存溢出 learning_rate1e-6, # RL学习率远低于SFT防止模型震荡 log_withnone, mini_batch_size1, gradient_accumulation_steps4, ) # 初始化PPO训练器 ppo_trainer PPOTrainer( modelmodel, configppo_config, tokenizertokenizer, ) # 4. RL再训练 def rl_finetune(sample): sample格式{input: , ground_truth: 真实JSON} # 步骤1构建Prompt和SFT一致 prompt f|im_start|user 从以下提取操作步骤输出严格为JSON格式不要多余说明 内容{sample[input]}|im_end| |im_start|assistant inputs tokenizer(prompt, return_tensorspt).to(DEVICE) input_ids inputs[input_ids] # 步骤2模型生成JSON当前策略 generation_kwargs { max_new_tokens: 512, temperature: 0.05, do_sample: False, } response ppo_trainer.generate(input_ids, **generation_kwargs) response_text tokenizer.decode(response[0], skip_special_tokensTrue).split(assistant)[-1].strip() # 步骤3计算奖励 reward calculate_reward(response_text, sample[ground_truth]) reward_tensor torch.tensor([reward], deviceDEVICE) # 转张量供PPO使用 # 步骤4PPO更新模型 stats ppo_trainer.step([input_ids[0]], [response[0]], [reward_tensor]) return stats, reward # 测试RL迭代 test_sample { input: 操作A站按正常方式复电。, ground_truth: {data: [{seq: 1, action: 复电, object: {name: A站}}]} } # 迭代 for i in range(10): stats, reward rl_finetune(test_sample) print(f第{i1}轮RL训练奖励值{reward:.2f}) # 5. 保存RL优化后的模型 model.save_pretrained(./operation_extract_7b_rl) tokenizer.save_pretrained(./operation_extract_7b_rl)
LLM训练基本代码学习-文本动作提取训练思路
一、核心场景定义文本动作提取输入注意事项数据输出固定格式、固定字段的 JSON训练方式32B 大模型生成标注 → 蒸馏到 7B模型Qwen-7B-Chat LoRA输出要求字段不能错、格式不能乱、不能少 key领域适配性识别电力检修专属动作。二、代码2.1测试训练import torch from datasets import load_dataset from transformers import ( AutoModelForCausalLM, AutoTokenizer, TrainingArguments, Trainer, DataCollatorForLanguageModeling ) from peft import LoraConfig, get_peft_model, TaskType import os import json # 1. 基础配置 BASE_MODEL_PATH Qwen/Qwen-7B-Chat DATA_PATH operation_samples.jsonl #数据集 OUTPUT_DIR ./operation_extract_7b DEVICE cuda if torch.cuda.is_available() else cpu BATCH_SIZE 2 LEARNING_RATE 3e-5 EPOCHS 4 # 2. 数据预处理 tokenizer AutoTokenizer.from_pretrained(BASE_MODEL_PATH, trust_remote_codeTrue) tokenizer.pad_token tokenizer.eos_token def preprocess_function(examples): texts [] for input_text, output_text in zip(examples[input], examples[output]): # 【关键】固定指令让模型学习结构化抽取 prompt f|im_start|user 从以下电网操作票中提取操作步骤输出严格为JSON格式不要多余说明 操作票内容{input_text}|im_end| |im_start|assistant {output_text}|im_end| texts.append(prompt) tokenized tokenizer( texts, truncationTrue, max_length1024, paddingmax_length, return_tensorspt#输出tensor字典 ) tokenized[labels] tokenized[input_ids].clone() return tokenized # 加载数据 dataset load_dataset(json, data_filesDATA_PATH)[train] tokenized_dataset dataset.map(preprocess_function, batchedTrue, remove_columnsdataset.column_names) data_collator DataCollatorForLanguageModeling(tokenizertokenizer, mlmFalse) #把padding填充的数据设置为-100避免训练到后面的数据 # 3. LoRA配置 model AutoModelForCausalLM.from_pretrained( BASE_MODEL_PATH, torch_dtypetorch.float16, device_mapauto, trust_remote_codeTrue ) lora_config LoraConfig( task_typeTaskType.CAUSAL_LM, r8,#低秩矩阵维度 lora_alpha32,#缩放因子 target_modules[c_attn, c_proj],#loRA训练配置层 #target_modules[c_attn, c_proj, w1, w2] lora_dropout0.05, biasnone, ) model get_peft_model(model, lora_config)#将loRA参数注入模型 model.print_trainable_parameters() # 4. 训练 training_args TrainingArguments( output_dirOUTPUT_DIR, per_device_train_batch_sizeBATCH_SIZE, learning_rateLEARNING_RATE, num_train_epochsEPOCHS, logging_steps10, save_steps100, fp16True, gradient_accumulation_steps4, save_total_limit2, report_tonone, ) trainer Trainer( modelmodel, argstraining_args, train_datasettokenized_dataset, data_collatordata_collator, ) trainer.train() model.save_pretrained(os.path.join(OUTPUT_DIR, final))#参数保存下次load tokenizer.save_pretrained(os.path.join(OUTPUT_DIR, final)) #把当前配置好的分词器包含词表、特殊符号、padding/truncation 规则等完整保存到指定文件夹 # 5. 推理专门适配你的JSON结构 def predict_operation(text): model_path os.path.join(OUTPUT_DIR, final)#model.loads m AutoModelForCausalLM.from_pretrained(model_path, torch_dtypetorch.float16, device_mapauto, trust_remote_codeTrue) t AutoTokenizer.from_pretrained(model_path, trust_remote_codeTrue) prompt f|im_start|user 从以下电网操作票中提取操作步骤输出严格为JSON格式不要多余说明 操作票内容{text}|im_end| |im_start|assistant inputs t(prompt, return_tensorspt).to(DEVICE) outputs m.generate( **inputs, max_new_tokens512, temperature0.05, # 极低温度保证格式稳定 top_p0.8, do_sampleFalse, eos_token_idt.eos_token_id, ) res t.decode(outputs[0], skip_special_tokensTrue) res res.split(assistant)[-1].strip() # 自动校验JSON保证可用 try: return json.loads(res) except: return {data: []} # 测试 if __name__ __main__: test_text 操作A设备按正常方式复电。 result predict_operation(test_text) print(json.dumps(result, ensure_asciiFalse, indent2))2.2 拓展get_peft_model接收一个基础预训练模型和一个配置对象返回一个配置好的、可训练的 PEFT 模型。PeftModel封装了基础模型和可训练的适配器参数。用于前向传播、保存、加载、合并权重等。PeftConfig用于保存特定方法如 LoRA的配置。LoraConfigLoRA 方法的配置。指定在哪些层target_modules添加 LoRA 适配器以及秩r、缩放因子lora_alpha等关键参数。PromptTuningConfig提示调优方法的配置。主要指定可学习软提示的长度num_virtual_tokens。PrefixTuningConfig前缀调优方法的配置。在模型每一层的输入前添加可学习的连续前缀向量。三、基于PPO算法的再训练「再训练过程中」每一轮迭代实时打分更新模型参数import torch import json import os from trl import PPOTrainer, PPOConfig, AutoModelForCausalLMWithValueHead from transformers import AutoTokenizer from peft import PeftModel # 1. 加载基础模型 BASE_MODEL_PATH Qwen/Qwen-7B-Chat LORA_PATH ./operation_extract_7b/final # 你训练好的SFT-LoRA权重 DEVICE cuda if torch.cuda.is_available() else cpu # 加载基础模型LoRA权重 base_model AutoModelForCausalLM.from_pretrained( BASE_MODEL_PATH, torch_dtypetorch.float16, device_mapauto, trust_remote_codeTrue ) model PeftModel.from_pretrained(base_model, LORA_PATH) # 包装成带价值头的模型RL需要价值头评估奖励 model AutoModelForCausalLMWithValueHead.from_pretrained(model, torch_dtypetorch.float16) tokenizer AutoTokenizer.from_pretrained(LORA_PATH, trust_remote_codeTrue) tokenizer.pad_token tokenizer.eos_token # 2. 定义奖励函数 def calculate_reward(json_str, ground_truth): 计算奖励值 参数 json_str: 模型生成的JSON字符串 ground_truth: 真实标注用于内容准确评分 返回 total_reward: 总奖励值0~11 return total_reward # 3. PPO配置 训练器初始化 ppo_config PPOConfig( batch_size1, # RL批次更小避免显存溢出 learning_rate1e-6, # RL学习率远低于SFT防止模型震荡 log_withnone, mini_batch_size1, gradient_accumulation_steps4, ) # 初始化PPO训练器 ppo_trainer PPOTrainer( modelmodel, configppo_config, tokenizertokenizer, ) # 4. RL再训练 def rl_finetune(sample): sample格式{input: , ground_truth: 真实JSON} # 步骤1构建Prompt和SFT一致 prompt f|im_start|user 从以下提取操作步骤输出严格为JSON格式不要多余说明 内容{sample[input]}|im_end| |im_start|assistant inputs tokenizer(prompt, return_tensorspt).to(DEVICE) input_ids inputs[input_ids] # 步骤2模型生成JSON当前策略 generation_kwargs { max_new_tokens: 512, temperature: 0.05, do_sample: False, } response ppo_trainer.generate(input_ids, **generation_kwargs) response_text tokenizer.decode(response[0], skip_special_tokensTrue).split(assistant)[-1].strip() # 步骤3计算奖励 reward calculate_reward(response_text, sample[ground_truth]) reward_tensor torch.tensor([reward], deviceDEVICE) # 转张量供PPO使用 # 步骤4PPO更新模型 stats ppo_trainer.step([input_ids[0]], [response[0]], [reward_tensor]) return stats, reward # 测试RL迭代 test_sample { input: 操作A站按正常方式复电。, ground_truth: {data: [{seq: 1, action: 复电, object: {name: A站}}]} } # 迭代 for i in range(10): stats, reward rl_finetune(test_sample) print(f第{i1}轮RL训练奖励值{reward:.2f}) # 5. 保存RL优化后的模型 model.save_pretrained(./operation_extract_7b_rl) tokenizer.save_pretrained(./operation_extract_7b_rl)