ToB企服应用市场:ToB评测及商务社交产业平台

标题: 大语言模型训练的全过程:预训练、微调、RLHF [打印本页]

作者: 天津储鑫盛钢材现货供应商    时间: 2024-11-8 03:05
标题: 大语言模型训练的全过程:预训练、微调、RLHF
一、 大语言模型的训练过程



二、 预训练

2.1、 预训练数据

目的:构建一个多样化、高质量的预训练语料库,为模型提供语言知识

2.2、 模型架构选择

目标:界说大语言模型的结构,包罗层数、隐藏单位大小、注意力头数等。
选择模型类型:根据任务选择模型架构,比方:

超参设计:

初始化计谋:接纳适合深度网络的参数初始化方法(如Xavier、He初始化)以制止梯度消失或爆炸。
2.3、训练前预备

目标:配置训练硬件和分布式计算环境,优化数据加载和模型更新效率。

2.4、 正式训练

目标:根据语言建模任务界说训练目标,使用反向流传优化模型参数。

2.5、 评估与验证

目标:评估模型在验证集上的表现,确保模型未出现过拟合或欠拟合。

2.6、 后处理与保存

目标:对训练好的模型举行优化和保存,方便后续使用和摆设。

2.7、 模型摆设

目标:将训练好的模型集成到应用中,提供生成或理解任务的服务。


三、 指令微调

3.1、微调数据

微调模型时使用的数据类型应与目标应用场景细密相关,数据的详细类型取决于任务要求。以下是几种常见的微调数据类型及示例:
  1. {
  2.   "question": "如何重置我的密码?",
  3.   "answer": "请前往设置页面,选择“安全设置”,然后点击“重置密码”按钮,按提示操作即可。"
  4. },
  5. {
  6.   "question": "你们的退款政策是什么?",
  7.   "answer": "在购买后的30天内,符合条件的订单可申请全额退款。"
  8. }
复制代码
  1. [
  2.   {"role": "user", "content": "你们的营业时间是几点?"},
  3.   {"role": "assistant", "content": "我们每天早上9点到晚上9点营业,周末时间相同。"}
  4. ],
  5. [
  6.   {"role": "user", "content": "今天有什么优惠活动?"},
  7.   {"role": "assistant", "content": "本周有会员双倍积分活动,消费满100元还可享9折优惠。"}
  8. ]
复制代码
  1. {
  2.   "text": "这个产品的质量真差,下次不会再买了!",
  3.   "label": "负面"
  4. },
  5. {
  6.   "text": "客服服务很好,很满意!",
  7.   "label": "正面"
  8. }
复制代码
  1. {
  2.   "prompt": "请写一封申请信用卡的邮件",
  3.   "completion": "尊敬的银行工作人员:\n您好!我想申请一张信用卡,希望能获得适合我的信用额度。感谢您的帮助!"
  4. },
  5. {
  6.   "prompt": "产品描述:请简要描述这款运动手表的功能",
  7.   "completion": "这款运动手表具有心率监测、GPS定位、步数计算和防水功能,是运动爱好者的理想选择。"
  8. }
复制代码
  1. {
  2.   "instruction": "给出3个关于如何提高生产力的建议。",
  3.   "output": [
  4.     "每天制定一个合理的工作计划。",
  5.     "避免长时间分心,集中精力处理手头任务。",
  6.     "使用任务管理工具追踪进度。"
  7.   ]
  8. },
  9. {
  10.   "instruction": "解释一下什么是机器学习。",
  11.   "output": "机器学习是一种让计算机通过数据自动学习和改进的方法,不需要人为编程。"
  12. }
复制代码
  1. {
  2.   "entity": "爱因斯坦",
  3.   "facts": [
  4.     {"fact": "出生日期", "value": "1879年3月14日"},
  5.     {"fact": "国籍", "value": "德国"},
  6.     {"fact": "主要成就", "value": "相对论"}
  7.   ]
  8. },
  9. {
  10.   "entity": "太阳系",
  11.   "facts": [
  12.     {"fact": "行星数量", "value": "8"},
  13.     {"fact": "最大行星", "value": "木星"},
  14.     {"fact": "距银河系中心的距离", "value": "约2.7万光年"}
  15.   ]
  16. }
复制代码
3.2、任务类型、丧失函数、评估指标

任务类型:
丧失函数选择:

评估指标:

3.3、代码

  1. import torch
  2. from transformers import AutoTokenizer, AutoModelForCausalLM, Trainer, TrainingArguments
  3. from datasets import load_dataset, Dataset
  4. # Step 1: 加载预训练模型和分词器
  5. model_name = "your_pretrained_model"  # 预训练模型名称
  6. tokenizer = AutoTokenizer.from_pretrained(model_name)
  7. model = AutoModelForCausalLM.from_pretrained(model_name)
  8. # Step 2: 加载私域数据集(假设为JSON格式)
  9. # 私域数据的格式为 [{"input": "input text", "target": "target text"}]
  10. data_path = "path_to_your_data.json"  # 数据文件路径
  11. raw_datasets = load_dataset("json", data_files=data_path)
  12. # Step 3: 数据预处理
  13. def preprocess_function(examples):
  14.     # 将输入和目标文本编码为模型可以理解的token形式
  15.     inputs = tokenizer(examples['input'], padding="max_length", truncation=True, max_length=128)
  16.     targets = tokenizer(examples['target'], padding="max_length", truncation=True, max_length=128)
  17.    
  18.     # 创建labels,将target部分作为训练目标
  19.     inputs["labels"] = targets["input_ids"]
  20.     return inputs
  21. # 使用map函数对数据集进行预处理
  22. tokenized_datasets = raw_datasets.map(preprocess_function, batched=True)
  23. # Step 4: 配置训练参数
  24. training_args = TrainingArguments(
  25.     output_dir="./finetuned_model",  # 模型保存路径
  26.     evaluation_strategy="epoch",
  27.     learning_rate=5e-5,
  28.     per_device_train_batch_size=8,
  29.     per_device_eval_batch_size=8,
  30.     num_train_epochs=3,
  31.     weight_decay=0.01,
  32.     logging_dir="./logs",
  33.     logging_steps=10,
  34.     save_strategy="epoch",
  35.     save_total_limit=2,
  36. )
  37. # Step 5: 初始化Trainer并微调模型
  38. trainer = Trainer(
  39.     model=model,
  40.     args=training_args,
  41.     train_dataset=tokenized_datasets['train'],
  42.     eval_dataset=tokenized_datasets['test'] if 'test' in tokenized_datasets else None,
  43. )
  44. # 开始训练
  45. trainer.train()
  46. # Step 6: 保存微调后的模型
  47. model.save_pretrained("./finetuned_model")
  48. tokenizer.save_pretrained("./finetuned_model")
  49. print("模型微调完成并保存至 ./finetuned_model")
复制代码

四、 人类反馈强化学习RLHF

人类反馈强化学习(RLHF, Reinforcement Learning from Human Feedback)

4.1、 人类生成数据反馈

示例 1:问答任务
  1. 输入:
  2. “火星与地球相比有何不同?”
  3. 模型输出:
  4. 火星的重力比地球低、气温更低,且大气主要由二氧化碳组成。
  5. 火星是一个有红色表面的星球,但地球有生命和大量水。
  6. 火星比地球小,没有适合人类生存的大气。
  7. 人类反馈:
  8. 准确性:输出 1 得分 5/5,输出 2 得分 3/5,输出 3 得分 4/5。
  9. 相关性:输出 1 得分 5/5,输出 2 得分 2/5(提及地球和水,但无关主题),输出 3 得分 4/5。
  10. 排序:1 > 3 > 2
复制代码
示例 2:情感分析任务
  1. 输入:
  2. “我觉得这次旅行很糟糕,遇到的每件事都令人失望。”
  3. 模型输出:
  4. 情感:负面
  5. 情感:正面
  6. 情感:中性
  7. 人类反馈:
  8. 准确性:输出 1 得分 5/5(准确反映了消极情绪),输出 2 得分 1/5(与情感明显不符),输出 3 得分 2/5(偏离原意)。
  9. 排序:1 > 3 > 2
复制代码
示例 3:产品推荐任务
  1. 输入:
  2. “我在寻找一款轻便耐用的旅行背包,有推荐吗?”
  3. 模型输出:
  4. 建议选择30L的轻便背包,款式多样且适合短途旅行。
  5. 推荐X品牌的登山包,非常耐用且轻便。
  6. 旅行背包款式众多,推荐考虑容积和耐用性。
  7. 人类反馈:
  8. 准确性:输出 2 得分 5/5(具体推荐了品牌),输出 1 得分 4/5(描述具体,但无品牌推荐),输出 3 得分 3/5(没有实际推荐)。
  9. 排序:2 > 1 > 3
复制代码
4.2、嘉奖模型训练

数据预备:嘉奖模型的数据一般有三个部门:输入、输出、评分的格式,比方如下数据:
  1. # 示例数据格式
  2. training_data = [
  3.     {"input": "火星与地球相比有何不同?",
  4.      "outputs": [
  5.          {"response": "火星的重力比地球低...", "score": 5},
  6.          {"response": "火星是一个有红色表面...", "score": 3},
  7.          {"response": "火星比地球小,没有适合人类生存...", "score": 4}
  8.      ]},
  9.     {"input": "我觉得这次旅行很糟糕,遇到的每件事都令人失望。",
  10.      "outputs": [
  11.          {"response": "情感:负面", "score": 5},
  12.          {"response": "情感:正面", "score": 1},
  13.          {"response": "情感:中性", "score": 2}
  14.      ]},
  15.     # 更多样例...
  16. ]
复制代码
构建嘉奖模型:嘉奖模型通常基于预训练语言模型(如GPT、BERT),并在其基础上添加一个嘉奖猜测层。这个层的输出是模型对给定输入-输出对的评分猜测。
  1. import torch
  2. from transformers import AutoModelForSequenceClassification, AutoTokenizer
  3. # 使用预训练模型作为奖励模型基础
  4. model_name = "bert-base-uncased"  # 可根据需求选择模型
  5. model = AutoModelForSequenceClassification.from_pretrained(model_name, num_labels=1)  # 设置单一输出(奖励分数)
  6. tokenizer = AutoTokenizer.from_pretrained(model_name)
复制代码
预备训练数据,生成嘉奖分数,将输入和模型输出对举行标记转换,以训练嘉奖模型猜测分数。
  1. def preprocess_data(training_data):
  2.     inputs, scores = [], []
  3.     for item in training_data:
  4.         input_text = item["input"]
  5.         for output in item["outputs"]:
  6.             response = output["response"]
  7.             score = output["score"]
  8.             # 将输入和输出连接,作为奖励模型的输入
  9.             combined_input = f"输入: {input_text} 输出: {response}"
  10.             inputs.append(combined_input)
  11.             scores.append(score)
  12.     return inputs, scores
  13. # 生成输入文本和奖励分数
  14. inputs, scores = preprocess_data(training_data)
  15. # 进行tokenization
  16. tokenized_inputs = tokenizer(inputs, padding=True, truncation=True, return_tensors="pt")
  17. labels = torch.tensor(scores).float()  # 奖励分数标签
复制代码
训练嘉奖模型:通过监督学习训练嘉奖模型,使其猜测的嘉奖分数与人类评分接近。丧失函数可以接纳均方偏差(MSE),因为我们希望嘉奖模型的输出值与人类评分之间的偏差最小
  1. from torch.utils.data import DataLoader, TensorDataset
  2. from transformers import AdamW
  3. # 创建DataLoader
  4. dataset = TensorDataset(tokenized_inputs["input_ids"], tokenized_inputs["attention_mask"], labels)
  5. dataloader = DataLoader(dataset, batch_size=8, shuffle=True)
  6. # 设置优化器
  7. optimizer = AdamW(model.parameters(), lr=5e-5)
  8. # 训练循环
  9. model.train()
  10. epochs = 3
  11. for epoch in range(epochs):
  12.     total_loss = 0
  13.     for batch in dataloader:
  14.         input_ids, attention_mask, label = batch
  15.         outputs = model(input_ids=input_ids, attention_mask=attention_mask, labels=label)
  16.         loss = outputs.loss
  17.         total_loss += loss.item()
  18.         
  19.         # 反向传播和参数更新
  20.         loss.backward()
  21.         optimizer.step()
  22.         optimizer.zero_grad()
  23.         
  24.     print(f"Epoch {epoch + 1} - Loss: {total_loss / len(dataloader)}")
复制代码
嘉奖模型训练完成后,将其应用到生成模型的强化学习环节。比方,通过强化学习算法(如PPO)更新生成模型,使其生成的输出逐渐朝着嘉奖模型给高分的方向优化。详细来说,生成模型每次生成输出后,嘉奖模型会评估输出质量,生成模型根据嘉奖反馈调整生成计谋,从而生成更加符合人类偏好的内容
4.3、 PPO算法(计谋优化)训练

代码步骤概述:
设置生成模型和嘉奖模型
  1. import torch
  2. from transformers import AutoTokenizer, AutoModelForCausalLM, AutoModelForSequenceClassification
  3. # 加载生成模型(例如,GPT-2)
  4. gen_model_name = "gpt2"
  5. gen_model = AutoModelForCausalLM.from_pretrained(gen_model_name)
  6. gen_tokenizer = AutoTokenizer.from_pretrained(gen_model_name)
  7. # 加载已经训练好的奖励模型(例如,BERT)
  8. reward_model_name = "bert-base-uncased"  # 根据实际选择
  9. reward_model = AutoModelForSequenceClassification.from_pretrained(reward_model_name)
  10. reward_tokenizer = AutoTokenizer.from_pretrained(reward_model_name)
复制代码
界说嘉奖函数
嘉奖函数用于评估生成模型的输出质量。将输入文本和生成的相应传递给嘉奖模型,得到分数并作为嘉奖信号返回。
  1. def compute_reward(input_text, generated_text):
  2.     # 将输入和输出拼接成奖励模型的输入格式
  3.     combined_input = f"输入: {input_text} 输出: {generated_text}"
  4.    
  5.     # 对拼接输入进行tokenization
  6.     inputs = reward_tokenizer(combined_input, return_tensors="pt", truncation=True, padding=True)
  7.    
  8.     # 通过奖励模型计算分数(输出的logits用于评分)
  9.     with torch.no_grad():
  10.         reward_score = reward_model(**inputs).logits.squeeze().item()
  11.    
  12.     return reward_score
复制代码
训练循环 - PPO 更新
通过计谋梯度方法逐步更新生成模型的参数,PPO的关键点:

  1. from transformers import AdamW
  2. import numpy as np
  3. # 超参数设置
  4. ppo_epochs = 5
  5. batch_size = 8
  6. learning_rate = 5e-5
  7. # 优化器
  8. optimizer = AdamW(gen_model.parameters(), lr=learning_rate)
  9. # PPO训练过程
  10. gen_model.train()
  11. for epoch in range(ppo_epochs):
  12.     for batch in range(batch_size):
  13.         # Step 1: 采样输入
  14.         input_text = "火星与地球相比有何不同?"  # 示例输入,可以改成实际数据的batch
  15.         input_ids = gen_tokenizer(input_text, return_tensors="pt").input_ids
  16.         # Step 2: 生成输出
  17.         generated_outputs = gen_model.generate(input_ids, max_length=50)
  18.         generated_text = gen_tokenizer.decode(generated_outputs[0], skip_special_tokens=True)
  19.         # Step 3: 计算奖励
  20.         reward = compute_reward(input_text, generated_text)
  21.         # Step 4: 计算PPO损失
  22.         outputs = gen_model(input_ids=input_ids, labels=generated_outputs)
  23.         logits = outputs.logits
  24.         log_probs = torch.nn.functional.log_softmax(logits, dim=-1)
  25.         # 计算优势函数(假设reward即优势)
  26.         # 可以加入熵正则化项来鼓励探索
  27.         advantages = reward - log_probs.mean().item()
  28.         # 计算损失
  29.         ppo_loss = -advantages * log_probs.mean()
  30.         ppo_loss.backward()
  31.         # 参数更新
  32.         optimizer.step()
  33.         optimizer.zero_grad()
  34.     print(f"Epoch {epoch + 1}/{ppo_epochs} - PPO Loss: {ppo_loss.item()}")
复制代码
这份代码是一个根本的实现,可以进一步在以下方面举行改进:


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4