如何训练/微调GPT-2/GPT-J模型以实现封闭域生成式问答?
封闭域生成式问答模型微调完整流程(基于GPT-2/GPT-J)
1. 数据准备与格式化
- 数据收集:针对医疗封闭域,整理结构化问答对(如病历咨询、医学科普问答),每条数据格式统一为:
问题:{你的问题} 回答:{对应回答},确保上下文连贯,适配GPT类模型的自回归生成逻辑。 - 数据清洗:剔除重复、无效(空回答、无关内容)的数据,统一文本格式(如规范医学术语、标点符号)。
- 数据集划分:按9:1比例拆分训练集与验证集,严格避免数据泄露。
2. 模型与Tokenizer加载
- 模型选择:
- GPT-2:轻量型模型,适合入门调试,资源需求低;
- GPT-J:参数量更大(6B),生成效果更优,需GPU显存≥16G(或启用梯度累积)。
- 加载代码示例:
from transformers import AutoModelForCausalLM, AutoTokenizer # 加载GPT-2 model_name = "gpt2" # 若加载GPT-J,替换为 "EleutherAI/gpt-j-6B" # model_name = "EleutherAI/gpt-j-6B" model = AutoModelForCausalLM.from_pretrained(model_name) tokenizer = AutoTokenizer.from_pretrained(model_name) # GPT系列默认无pad token,用eos token替代 tokenizer.pad_token = tokenizer.eos_token tokenizer.padding_side = "left" # 适配左向注意力机制
3. 数据预处理
- 格式化单条数据:将问答对拼接为模型可接受的输入文本,例如:
def format_data(example): return f"问题:{example['question']} 回答:{example['answer']}" - 批量Tokenization:
def tokenize_function(examples): texts = [format_data(example) for example in examples] return tokenizer(texts, truncation=True, max_length=512, padding="max_length") # 假设你的数据集是Huggingface Dataset格式 tokenized_train_dataset = train_dataset.map(tokenize_function, batched=True) tokenized_val_dataset = val_dataset.map(tokenize_function, batched=True) # 设置标签(自回归任务标签与输入id一致) tokenized_train_dataset.set_format("torch", columns=["input_ids", "attention_mask", "input_ids"]) tokenized_val_dataset.set_format("torch", columns=["input_ids", "attention_mask", "input_ids"])
4. 模型微调
- 配置训练参数:
from transformers import TrainingArguments, Trainer training_args = TrainingArguments( output_dir="./medical_gpt_finetuned", # 模型保存目录 num_train_epochs=3, # 训练轮数 per_device_train_batch_size=4, # 单设备批次大小,GPT-J可设为2并启用梯度累积 per_device_eval_batch_size=4, learning_rate=2e-5, # 学习率,GPT类模型通常用1e-5~3e-5 gradient_accumulation_steps=4, # 梯度累积,等效增大批次大小 logging_steps=100, save_steps=500, evaluation_strategy="epoch", # 每轮结束评估 fp16=True, # 启用混合精度训练,需GPU支持 weight_decay=0.01, ) - 启动训练:
trainer = Trainer( model=model, args=training_args, train_dataset=tokenized_train_dataset, eval_dataset=tokenized_val_dataset, ) trainer.train()
5. 推理与生成
- 加载微调后模型:
model = AutoModelForCausalLM.from_pretrained("./medical_gpt_finetuned") - 生成回答示例:
def generate_answer(question): prompt = f"问题:{question} 回答:" inputs = tokenizer(prompt, return_tensors="pt").to(model.device) outputs = model.generate( **inputs, max_new_tokens=128, # 生成回答的最大长度 temperature=0.7, # 控制随机性,值越低越确定 top_p=0.9, # 核采样,过滤低概率token do_sample=True, pad_token_id=tokenizer.eos_token_id, ) return tokenizer.decode(outputs[0], skip_special_tokens=True) # 测试 print(generate_answer("高血压患者日常饮食需要注意什么?"))
6. 优化与迭代
- 数据增强:若数据量不足,可通过同义词替换、医学文本回译、领域知识库扩充等方式增加样本;
- Prompt优化:在输入前添加领域身份提示,例如
"你是一名专业的内科医生,精准回答以下医疗问题:问题:XXX 回答:",提升生成内容的专业性; - 模型评估:用BLEU、ROUGE指标量化生成质量,同时结合人工评估检查回答的医学准确性,避免生成错误信息。
内容的提问来源于stack exchange,提问作者Aayush Shah
相关产品推荐
相关产品推荐

