一、 大语言模型的训练过程
- 预训练阶段:PT(Pre training)。使用公开数据颠末预训练得到预训练模型,预训练模型具备语言的初步理解;训练周期比力长;
- 微调阶段1:SFT(指令微调/有监督微调)。如果想要预训练模型在某个垂直范畴(金融、法律、电商等)有更好的知识储备,就必要使用人工标注的QA问答对举行有监督的微调训练,从而得到精调模型;训练周期较短;
- 微调阶段2:对齐/强化训练。精调模型的输出并不是全部都令人满意的,我们还必要让模型知道复兴的接受度。可以在运行日志中收集对齐数据,包罗【问题,接受的复兴,不接受的复兴】,再举行对齐训练,得到最后可使用的模型;
二、 预训练
2.1、 预训练数据
目的:构建一个多样化、高质量的预训练语料库,为模型提供语言知识
- 数据来源:从公开的数据集(如Common Crawl、Wikipedia、BooksCorpus)中获取文本数据。确保数据包罗多种类型(如对话、消息、小说、百科等),以提高模型的实用性;
- 数据洗濯:去除HTML标签、无意义字符、重复句子等。洗濯过程中要特殊注意去掉垃圾数据,以保证语料库的质量;
- 分词与标记化:将数据按单词或子词举行分割。大部门大语言模型使用子词级别的标记化算法(如BPE、WordPiece、SentencePiece),因为它可以提高词汇表覆盖度并淘汰OOV(Out of Vocabulary)词的出现;
- 词汇表生成:根据分词后的语料生成词汇表。词汇表大小根据模型大小调整,通常在3万到5万之间;
- 数据格式:将标记化的数据保存成方便训练的格式(如TFRecord、HDF5),同时包罗输入和输出标记以供训练时使用;
2.2、 模型架构选择
目标:界说大语言模型的结构,包罗层数、隐藏单位大小、注意力头数等。
选择模型类型:根据任务选择模型架构,比方:
- GPT类(自回归):适合顺序生成任务:聊天;
- BERT类(自编码):适合文本理解任务:实体定名;
- T5、BART等(编码-解码):兼顾生成和理解任务。
超参设计:
- 层数:通常在6层到24层,甚至更多;
- 隐藏层维度:常见的选择是512、1024、2048等;
- 注意力头数:可以选4、8、16头等,头数越多注意力计算越细致;
- 词嵌入层和位置嵌入层:在每个输入标记中嵌入位置编码,用于资助模型理解序列顺序。
初始化计谋:接纳适合深度网络的参数初始化方法(如Xavier、He初始化)以制止梯度消失或爆炸。
2.3、训练前预备
目标:配置训练硬件和分布式计算环境,优化数据加载和模型更新效率。
- 硬件配置:大模型训练必要大量计算资源,发起使用多GPU集群或TPU集群;确保显存充足容纳模型参数和批量数据。
- 分布式训练:接纳数据并行或模型并行计谋(如Megatron-LM、DeepSpeed)以提拔训练速度。要确保数据加载的高效性和装备间的通信速度。
- 优化器选择:一般选择Adam或AdamW优化器,针对大模型训练的优化方法(如LAMB、LARS)也可以提高效率。
- 学习率调度:选择符合的学习率调度计谋,如Warmup、Cosine Decay、Polynomial Decay等;在训练初期接纳小学习率,以稳定模型更新。
2.4、 正式训练
目标:根据语言建模任务界说训练目标,使用反向流传优化模型参数。
- 丧失函数:大多数大语言模型的预训练目标是自回归语言建模或添补式语言建模,两者都依赖于交叉熵丧失函数 (Cross-Entropy Loss) 来优化模型参数,计算模型猜测的概率分布和目标分布之间的偏差。
- 梯度累积:对于大模型,可以使用梯度累积来模仿更大的批次,从而节流显存开销。
- 混合精度训练:接纳FP16(半精度浮点数)举行训练,低落内存占用并加速计算。
- 监控与日志记录:记录训练丧失、精度、学习率、梯度大小等;可以借助TensorBoard或WandB监控训练希望。
- 定期保存检查点:定期保存模型检查点,确保即使训练中断也可以从最新进度规复。
2.5、 评估与验证
目标:评估模型在验证集上的表现,确保模型未出现过拟合或欠拟合。
- 验证集构建:从原始语料中划分出一部门作为验证集,保持数据分布与训练集一致。
- 评估指标:使用困惑度(Perplexity,PPL)等指标,评估模型生成内容的连贯性和正确性。
- 调优超参数:根据验证集上的表现,调治学习率、批次大小、正则化等超参数。
2.6、 后处理与保存
目标:对训练好的模型举行优化和保存,方便后续使用和摆设。
- 模型剪枝与量化:通过模型剪枝(去除冗余参数)和量化(如8位或混合精度量化)来淘汰模型大小、提拔推理效率。
- 保存模型:将训练好的模型权重、词汇表等保存成可加载格式(如PyTorch的.pt或TensorFlow的SavedModel格式)。
- 模型测试:在现实下游任务上测试模型生成和理解能力,确保模型可以在推理时高效工作
2.7、 模型摆设
目标:将训练好的模型集成到应用中,提供生成或理解任务的服务。
- 推理优化:通过ONNX、TensorRT等工具优化推理速度,低落延迟。
- 摆设平台:可以选择摆设在云平台(如AWS、GCP)、本地服务器或边沿装备,根据应用场景选择符合的架构。
三、 指令微调
3.1、微调数据
微调模型时使用的数据类型应与目标应用场景细密相关,数据的详细类型取决于任务要求。以下是几种常见的微调数据类型及示例:
- {
- "question": "如何重置我的密码?",
- "answer": "请前往设置页面,选择“安全设置”,然后点击“重置密码”按钮,按提示操作即可。"
- },
- {
- "question": "你们的退款政策是什么?",
- "answer": "在购买后的30天内,符合条件的订单可申请全额退款。"
- }
复制代码- [
- {"role": "user", "content": "你们的营业时间是几点?"},
- {"role": "assistant", "content": "我们每天早上9点到晚上9点营业,周末时间相同。"}
- ],
- [
- {"role": "user", "content": "今天有什么优惠活动?"},
- {"role": "assistant", "content": "本周有会员双倍积分活动,消费满100元还可享9折优惠。"}
- ]
复制代码- {
- "text": "这个产品的质量真差,下次不会再买了!",
- "label": "负面"
- },
- {
- "text": "客服服务很好,很满意!",
- "label": "正面"
- }
复制代码
- 生成任务数据:实用于内容生成、择要生成、翻译等任务
- {
- "prompt": "请写一封申请信用卡的邮件",
- "completion": "尊敬的银行工作人员:\n您好!我想申请一张信用卡,希望能获得适合我的信用额度。感谢您的帮助!"
- },
- {
- "prompt": "产品描述:请简要描述这款运动手表的功能",
- "completion": "这款运动手表具有心率监测、GPS定位、步数计算和防水功能,是运动爱好者的理想选择。"
- }
复制代码
- 指令式数据:实用于对话式AI助理、智能客服、内容推荐
- {
- "instruction": "给出3个关于如何提高生产力的建议。",
- "output": [
- "每天制定一个合理的工作计划。",
- "避免长时间分心,集中精力处理手头任务。",
- "使用任务管理工具追踪进度。"
- ]
- },
- {
- "instruction": "解释一下什么是机器学习。",
- "output": "机器学习是一种让计算机通过数据自动学习和改进的方法,不需要人为编程。"
- }
复制代码
- 知识图谱或事实数据:实用于事实问答体系、知识性内容生成
- {
- "entity": "爱因斯坦",
- "facts": [
- {"fact": "出生日期", "value": "1879年3月14日"},
- {"fact": "国籍", "value": "德国"},
- {"fact": "主要成就", "value": "相对论"}
- ]
- },
- {
- "entity": "太阳系",
- "facts": [
- {"fact": "行星数量", "value": "8"},
- {"fact": "最大行星", "value": "木星"},
- {"fact": "距银河系中心的距离", "value": "约2.7万光年"}
- ]
- }
复制代码 3.2、任务类型、丧失函数、评估指标
任务类型:
- 生成任务:如对话生成、文章续写等,模型的目标是生成连贯的文本。
- 分类任务:如情感分析、意图识别等,模型必要在每个输入上输出特定类别。
- 问答任务:针对用户提出的问题,生成相关答复。
丧失函数选择:
- 交叉熵丧失:分类任务通常使用交叉熵丧失,评估模型生成的词分布与目标词的匹配度。
- KL散度:通常用于生成模型,评估两个概率分布的相似性;
- 定制丧失:如果有特定需求,也可以根据任务要求设计丧失函数,增加正则化或加权方式等。
评估指标:
- 困惑度 (Perplexity, PPL):实用于生成任务,评估生成文本的质量。
- 正确率 (Accuracy):实用于分类任务,评估标签猜测的正确度。
- BLEU/ROUGE:实用于文本生成任务,评估生成文本与参考文本的相似度。
- F1、召回率:实用于多分类或不平衡数据任务,问答任务或情感分析任务。
3.3、代码
- import torch
- from transformers import AutoTokenizer, AutoModelForCausalLM, Trainer, TrainingArguments
- from datasets import load_dataset, Dataset
- # Step 1: 加载预训练模型和分词器
- model_name = "your_pretrained_model" # 预训练模型名称
- tokenizer = AutoTokenizer.from_pretrained(model_name)
- model = AutoModelForCausalLM.from_pretrained(model_name)
- # Step 2: 加载私域数据集(假设为JSON格式)
- # 私域数据的格式为 [{"input": "input text", "target": "target text"}]
- data_path = "path_to_your_data.json" # 数据文件路径
- raw_datasets = load_dataset("json", data_files=data_path)
- # Step 3: 数据预处理
- def preprocess_function(examples):
- # 将输入和目标文本编码为模型可以理解的token形式
- inputs = tokenizer(examples['input'], padding="max_length", truncation=True, max_length=128)
- targets = tokenizer(examples['target'], padding="max_length", truncation=True, max_length=128)
-
- # 创建labels,将target部分作为训练目标
- inputs["labels"] = targets["input_ids"]
- return inputs
- # 使用map函数对数据集进行预处理
- tokenized_datasets = raw_datasets.map(preprocess_function, batched=True)
- # Step 4: 配置训练参数
- training_args = TrainingArguments(
- output_dir="./finetuned_model", # 模型保存路径
- evaluation_strategy="epoch",
- learning_rate=5e-5,
- per_device_train_batch_size=8,
- per_device_eval_batch_size=8,
- num_train_epochs=3,
- weight_decay=0.01,
- logging_dir="./logs",
- logging_steps=10,
- save_strategy="epoch",
- save_total_limit=2,
- )
- # Step 5: 初始化Trainer并微调模型
- trainer = Trainer(
- model=model,
- args=training_args,
- train_dataset=tokenized_datasets['train'],
- eval_dataset=tokenized_datasets['test'] if 'test' in tokenized_datasets else None,
- )
- # 开始训练
- trainer.train()
- # Step 6: 保存微调后的模型
- model.save_pretrained("./finetuned_model")
- tokenizer.save_pretrained("./finetuned_model")
- print("模型微调完成并保存至 ./finetuned_model")
复制代码 四、 人类反馈强化学习RLHF
人类反馈强化学习(RLHF, Reinforcement Learning from Human Feedback)
- 目的:是使用人类反馈强化模型对话的质量和合规性,使其答复更自然、正确且符合伦理,也叫嘉奖模型训练或强化学习过程。
- 方法:构建嘉奖模型并使用它来调整生成模型的输出。通常涉及三个步骤:人类生成数据反馈、嘉奖模型训练、PPO算法(计谋优化)训练。
- 工具:必要一定的标注职员提供人类反馈,OpenAI等方法中使用PPO(Proximal Policy Optimization)算法。
4.1、 人类生成数据反馈
- 采样生成数据:模仿真实的对话场景,让预训练模型根据预设任务和指令生成多条不同的复兴。
- 构建评分体系:创建尺度的评分准则,常见的评价维度包罗:正确性、相关性、自然性、简介性,让人类标注员从多个维度来评价模型输出的质量,可以用分数(如1-5分)或“优劣”排序来标注。
- 优选与排序:要求标注员对多个模型输出举行排序,以选择最符适用户期望的复兴。可以接纳成对比力的方式,即给定两条复兴,让标注员选择较好的一个。
示例 1:问答任务
- 输入:
- “火星与地球相比有何不同?”
- 模型输出:
- 火星的重力比地球低、气温更低,且大气主要由二氧化碳组成。
- 火星是一个有红色表面的星球,但地球有生命和大量水。
- 火星比地球小,没有适合人类生存的大气。
- 人类反馈:
- 准确性:输出 1 得分 5/5,输出 2 得分 3/5,输出 3 得分 4/5。
- 相关性:输出 1 得分 5/5,输出 2 得分 2/5(提及地球和水,但无关主题),输出 3 得分 4/5。
- 排序:1 > 3 > 2
复制代码 示例 2:情感分析任务
- 输入:
- “我觉得这次旅行很糟糕,遇到的每件事都令人失望。”
- 模型输出:
- 情感:负面
- 情感:正面
- 情感:中性
- 人类反馈:
- 准确性:输出 1 得分 5/5(准确反映了消极情绪),输出 2 得分 1/5(与情感明显不符),输出 3 得分 2/5(偏离原意)。
- 排序:1 > 3 > 2
复制代码 示例 3:产品推荐任务
- 输入:
- “我在寻找一款轻便耐用的旅行背包,有推荐吗?”
- 模型输出:
- 建议选择30L的轻便背包,款式多样且适合短途旅行。
- 推荐X品牌的登山包,非常耐用且轻便。
- 旅行背包款式众多,推荐考虑容积和耐用性。
- 人类反馈:
- 准确性:输出 2 得分 5/5(具体推荐了品牌),输出 1 得分 4/5(描述具体,但无品牌推荐),输出 3 得分 3/5(没有实际推荐)。
- 排序:2 > 1 > 3
复制代码 4.2、嘉奖模型训练
数据预备:嘉奖模型的数据一般有三个部门:输入、输出、评分的格式,比方如下数据:
- # 示例数据格式
- training_data = [
- {"input": "火星与地球相比有何不同?",
- "outputs": [
- {"response": "火星的重力比地球低...", "score": 5},
- {"response": "火星是一个有红色表面...", "score": 3},
- {"response": "火星比地球小,没有适合人类生存...", "score": 4}
- ]},
- {"input": "我觉得这次旅行很糟糕,遇到的每件事都令人失望。",
- "outputs": [
- {"response": "情感:负面", "score": 5},
- {"response": "情感:正面", "score": 1},
- {"response": "情感:中性", "score": 2}
- ]},
- # 更多样例...
- ]
复制代码 构建嘉奖模型:嘉奖模型通常基于预训练语言模型(如GPT、BERT),并在其基础上添加一个嘉奖猜测层。这个层的输出是模型对给定输入-输出对的评分猜测。
- import torch
- from transformers import AutoModelForSequenceClassification, AutoTokenizer
- # 使用预训练模型作为奖励模型基础
- model_name = "bert-base-uncased" # 可根据需求选择模型
- model = AutoModelForSequenceClassification.from_pretrained(model_name, num_labels=1) # 设置单一输出(奖励分数)
- tokenizer = AutoTokenizer.from_pretrained(model_name)
复制代码 预备训练数据,生成嘉奖分数,将输入和模型输出对举行标记转换,以训练嘉奖模型猜测分数。
- def preprocess_data(training_data):
- inputs, scores = [], []
- for item in training_data:
- input_text = item["input"]
- for output in item["outputs"]:
- response = output["response"]
- score = output["score"]
- # 将输入和输出连接,作为奖励模型的输入
- combined_input = f"输入: {input_text} 输出: {response}"
- inputs.append(combined_input)
- scores.append(score)
- return inputs, scores
- # 生成输入文本和奖励分数
- inputs, scores = preprocess_data(training_data)
- # 进行tokenization
- tokenized_inputs = tokenizer(inputs, padding=True, truncation=True, return_tensors="pt")
- labels = torch.tensor(scores).float() # 奖励分数标签
复制代码 训练嘉奖模型:通过监督学习训练嘉奖模型,使其猜测的嘉奖分数与人类评分接近。丧失函数可以接纳均方偏差(MSE),因为我们希望嘉奖模型的输出值与人类评分之间的偏差最小
- from torch.utils.data import DataLoader, TensorDataset
- from transformers import AdamW
- # 创建DataLoader
- dataset = TensorDataset(tokenized_inputs["input_ids"], tokenized_inputs["attention_mask"], labels)
- dataloader = DataLoader(dataset, batch_size=8, shuffle=True)
- # 设置优化器
- optimizer = AdamW(model.parameters(), lr=5e-5)
- # 训练循环
- model.train()
- epochs = 3
- for epoch in range(epochs):
- total_loss = 0
- for batch in dataloader:
- input_ids, attention_mask, label = batch
- outputs = model(input_ids=input_ids, attention_mask=attention_mask, labels=label)
- loss = outputs.loss
- total_loss += loss.item()
-
- # 反向传播和参数更新
- loss.backward()
- optimizer.step()
- optimizer.zero_grad()
-
- print(f"Epoch {epoch + 1} - Loss: {total_loss / len(dataloader)}")
复制代码 嘉奖模型训练完成后,将其应用到生成模型的强化学习环节。比方,通过强化学习算法(如PPO)更新生成模型,使其生成的输出逐渐朝着嘉奖模型给高分的方向优化。详细来说,生成模型每次生成输出后,嘉奖模型会评估输出质量,生成模型根据嘉奖反馈调整生成计谋,从而生成更加符合人类偏好的内容
4.3、 PPO算法(计谋优化)训练
代码步骤概述:
- 设置生成模型和嘉奖模型:加载生成模型(如GPT)和嘉奖模型(可以是微调过的BERT)。
- 实现PPO训练:为生成模型的输出提供嘉奖反馈。
- 更新生成模型:根据嘉奖值和计谋更新生成模型。
设置生成模型和嘉奖模型
- import torch
- from transformers import AutoTokenizer, AutoModelForCausalLM, AutoModelForSequenceClassification
- # 加载生成模型(例如,GPT-2)
- gen_model_name = "gpt2"
- gen_model = AutoModelForCausalLM.from_pretrained(gen_model_name)
- gen_tokenizer = AutoTokenizer.from_pretrained(gen_model_name)
- # 加载已经训练好的奖励模型(例如,BERT)
- reward_model_name = "bert-base-uncased" # 根据实际选择
- reward_model = AutoModelForSequenceClassification.from_pretrained(reward_model_name)
- reward_tokenizer = AutoTokenizer.from_pretrained(reward_model_name)
复制代码 界说嘉奖函数
嘉奖函数用于评估生成模型的输出质量。将输入文本和生成的相应传递给嘉奖模型,得到分数并作为嘉奖信号返回。
- def compute_reward(input_text, generated_text):
- # 将输入和输出拼接成奖励模型的输入格式
- combined_input = f"输入: {input_text} 输出: {generated_text}"
-
- # 对拼接输入进行tokenization
- inputs = reward_tokenizer(combined_input, return_tensors="pt", truncation=True, padding=True)
-
- # 通过奖励模型计算分数(输出的logits用于评分)
- with torch.no_grad():
- reward_score = reward_model(**inputs).logits.squeeze().item()
-
- return reward_score
复制代码 训练循环 - PPO 更新
通过计谋梯度方法逐步更新生成模型的参数,PPO的关键点:
- 嘉奖计算:使用嘉奖模型给生成的文本打分,分数越高代表生成效果越好。
- 上风计算:在PPO中,我们用嘉奖减去当前计谋的log_probs均值,来估计计谋的相对上风。
- 计谋更新:PPO主要通过限定更新步长来制止计谋的剧烈变革,通常通过上风函数和log概率的乘积来调整生成模型的计谋。
- from transformers import AdamW
- import numpy as np
- # 超参数设置
- ppo_epochs = 5
- batch_size = 8
- learning_rate = 5e-5
- # 优化器
- optimizer = AdamW(gen_model.parameters(), lr=learning_rate)
- # PPO训练过程
- gen_model.train()
- for epoch in range(ppo_epochs):
- for batch in range(batch_size):
- # Step 1: 采样输入
- input_text = "火星与地球相比有何不同?" # 示例输入,可以改成实际数据的batch
- input_ids = gen_tokenizer(input_text, return_tensors="pt").input_ids
- # Step 2: 生成输出
- generated_outputs = gen_model.generate(input_ids, max_length=50)
- generated_text = gen_tokenizer.decode(generated_outputs[0], skip_special_tokens=True)
- # Step 3: 计算奖励
- reward = compute_reward(input_text, generated_text)
- # Step 4: 计算PPO损失
- outputs = gen_model(input_ids=input_ids, labels=generated_outputs)
- logits = outputs.logits
- log_probs = torch.nn.functional.log_softmax(logits, dim=-1)
- # 计算优势函数(假设reward即优势)
- # 可以加入熵正则化项来鼓励探索
- advantages = reward - log_probs.mean().item()
- # 计算损失
- ppo_loss = -advantages * log_probs.mean()
- ppo_loss.backward()
- # 参数更新
- optimizer.step()
- optimizer.zero_grad()
- print(f"Epoch {epoch + 1}/{ppo_epochs} - PPO Loss: {ppo_loss.item()}")
复制代码 这份代码是一个根本的实现,可以进一步在以下方面举行改进:
- 批量化处理:为提高效率,使用批量数据举行生成和嘉奖计算。
- 熵正则化:加入熵项,以鼓励探索、提拔生成模型的多样性。
- 上风函数:接纳更加复杂的上风计算方法,如引入值函数基线,进一步提高PPO训练的稳定性。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |