共计 8218 个字符,预计需要花费 21 分钟才能阅读完成。
踏上人工智能的演变之旅和自然语言解决 (NLP) 畛域获得的惊人提高。一眨眼的功夫,人工智能曾经崛起,塑造了咱们的世界。训练大型语言模型的微小影响彻底改变了 NLP,彻底改变了咱们的技术交互。工夫回到 2017 年,这是一个以“注意力就是你所须要的”为标记的关键时刻,开创性的“Transformer”架构诞生了。该架构当初形成了 NLP 的基石,是每个大型语言模型配方中不可代替的成分 – 包含驰名的 ChatGPT。
设想一下轻松生成连贯、上下文丰盛的文本 – 这就是 GPT-3 等模型的魔力。作为聊天机器人、翻译和内容生成的弱小力量,它们的辉煌源于架构以及预训练和训练的简单舞蹈。咱们行将发表的文章将深入研究这首交响曲,揭示利用大型语言模型执行工作背地的艺术性,利用预训练和训练的动静二重奏来达到杰出的成果。与咱们一起揭开这些改革技术的神秘面纱!
学习指标
·理解构建 LLM 申请的不同办法。
·学习特征提取、层训练和适配器办法等技术。
·应用 Huggingface 转换器库在上游工作上训练 LLM。
入门
LLM 代表大型语言模型。LLM 是深度学习模型,旨在了解类人文本的含意并执行各种工作,例如情感剖析、语言建模(下一个词预测)、文本生成、文本摘要等等。他们承受了大量文本数据的训练。
咱们每天都在应用基于这些 LLM 的应用程序,甚至没有意识到这一点。Google 将 BERT(Transformers 双向编码器示意)用于各种利用,例如查问实现、了解查问上下文、输入更相干和更精确的搜寻后果、语言翻译等。
这些模型建设在深度学习技术、深度神经网络和自注意力等先进技术的根底上。他们承受大量文本数据的训练,以学习语言的模式、构造和语义。
因为这些模型是在宽泛的数据集上进行训练的,因而须要大量的工夫和资源来训练它们,并且从头开始训练它们是没有意义的。
咱们能够通过一些技术间接应用这些模型来实现特定工作。那么让咱们具体讨论一下它们。
构建 LLM 申请的不同办法概述
咱们在日常生活中常常看到令人兴奋的 LLM 申请。您想晓得如何构建 LLM 申请吗?以下是构建 LLM 申请的 3 种办法:
- 利用 Scratch 训练大语言模型
- 训练大型语言模型
- 提醒
1、利用 Scratch 训练大语言模型
人们常常对这两个术语感到困惑:训练和微调 LLM。这两种技术的工作形式类似,即扭转模型参数,但训练指标不同。
从头开始培训 LLM 也称为预培训。预训练是一种在大量未标记文本上训练大型语言模型的技术。但问题是,“咱们如何在未标记的数据上训练模型,而后冀望模型精确地预测数据?”。这就是“自我监督学习”的概念。在自监督学习中,模型会覆盖一个单词,并尝试借助后面的单词来预测下一个单词。例如,假如咱们有一句话:“我是一名数据科学家”。
该模型能够依据这句话创立本人的标记数据,例如:
这被称为下一个工作预测,由 MLM(掩码语言模型)实现。BERT,一种屏蔽语言模型,应用这种技术来预测屏蔽词。咱们能够将传销视为“填空”概念,其中模型预测哪些单词能够填入空白。
预测下一个单词的办法有多种,但在本文中,咱们只探讨 BERT,即 MLM。BERT 能够查看后面和前面的单词来了解句子的上下文并预测屏蔽词。
2、训练大型语言模型
训练是调整模型的参数,使其适宜执行特定工作。模型通过预训练后,会进行训练,或者简略地说,训练它来执行特定工作,例如情感剖析、文本生成、查找文档相似性等。咱们不用在特定的环境上再次训练模型。大文本;相同,咱们应用经过训练的模型来执行咱们想要执行的工作。咱们将在本文前面具体探讨如何训练大型语言模型。
因而,作为预训练的高级概述,它只是模型学习预测文本中下一个单词的技术。
3、提醒
提醒是所有 3 种技术中最简略的,但也有点辣手。它波及为模型提供一个上下文(提醒),模型依据该上下文执行工作。能够将其视为具体教孩子书中的一章,对解释十分审慎,而后要求他们解决与该章相干的问题。
就 LLM 而言,以 ChatGPT 为例;咱们设置一个上下文并要求模型依照阐明来解决给定的问题。
假如我心愿 ChatGPT 只问我一些无关变形金刚的面试问题。为了取得更好的体验和精确的输入,您须要设置适当的上下文并给出具体的工作形容。
示例:我是一名领有两年教训的数据科学家,目前正在某某公司筹备面试。我喜爱解决问题,目前正在应用最先进的 NLP 模型。我理解最新的趋势和技术。问我对于 Transformer 模型的十分辣手的问题,这个公司的面试官能够依据公司以前的教训来问。问我十个问题并给出问题的答案。
您提醒的越具体和具体,后果就越好。最乏味的局部是您能够从模型自身生成提醒,而后增加个人风格或所需的信息。
理解不同地训练技术
传统上训练模型的办法有多种,不同的办法取决于您想要解决的具体问题。让咱们探讨训练模型的技术。
传统上有 3 种办法能够对 LLM 进行训练。
1、特征提取
人们应用这种技术从给定文本中提取特色,然而为什么咱们要从给定文本中提取嵌入呢?答案很简略。因为计算机无法了解文本,因而须要有一种文本的示意模式,以便咱们能够用来执行各种工作。一旦咱们提取嵌入,它们就可能执行情感剖析、辨认文档相似性等工作。在特征提取中,咱们锁定模型的骨干层,这意味着咱们不会更新这些层的参数;仅更新分类器层的参数。分类器层波及全连贯层。
2、全模型训练
顾名思义,咱们在该技术中在自定义数据集上训练每个模型层特定数量的期间。咱们依据新的自定义数据集调整模型中所有层的参数。这能够进步模型对数据和咱们想要执行的特定工作的准确性。思考到训练大型语言模型中有数十亿个参数,计算成本很高,并且须要大量工夫来训练模型。
3、基于适配器的训练
基于适配器的训练是一个绝对较新的概念,其中将额定的随机初始化层或模块增加到网络中,而后针对特定工作进行训练。在这种技术中,模型的参数不受烦扰,或者咱们能够说模型的参数没有扭转或调整。相同,适配器层参数是经过训练的。该技术有助于以计算无效的形式调整模型。
施行:在上游工作上训练 BERT
当初咱们晓得了训练技术,让咱们应用 BERT 对 IMDB 电影评论进行情感剖析。BERT 是一种大型语言模型,联合了转换器层并且仅蕴含编码器。谷歌开发了它,并已证实在各种工作上体现良好。BERT 有不同的大小和变体,例如 BERT-base-uncased、BERT Large、RoBERTa、LegalBERT 等等。
1、BERT 模型进行情感剖析
咱们应用 BERT 模型对 IMDB 电影评论进行情感剖析。如需收费应用 GPU,倡议应用 Google Colab。让咱们通过加载一些重要的库来开始训练。
因为 BERT(编码器的双向编码器示意)基于 Transformer,因而第一步是在咱们的环境中装置 Transformer。
!pip 装置变压器
让咱们加载一些库,这些库将帮忙咱们加载 BERT 模型所需的数据、对加载的数据进行标记、加载咱们将用于分类的模型、执行训练 - 测试 - 宰割、加载 CSV 文件以及其余一些性能。
import pandas as pd
import numpy as np
import os
from sklearn.model_selection import train_test_split
import torch
import torch.nn as nn
from transformers import BertTokenizer, BertModel
为了更快的计算,咱们必须将设施从 CPU 更改为 GPU
device = torch.device("cuda")
下一步是加载数据集并查看数据集中的前 5 条记录。
df = pd.read_csv('/content/drive/MyDrive/movie.csv')
df.head()
咱们将把数据集分成训练集和验证集。您还能够将数据拆分为训练集、验证集和测试集,但为了简略起见,我只是将数据集拆分为训练集和验证集。
x_train, x_val, y_train, y_val = train_test_split(df.text, df.label, random_state = 42, test_size = 0.2, stratify = df.label)
2、导入并加载 BERT 模型
让咱们导入并加载 BERT 模型和分词器。
from transformers.models.bert.modeling_bert import BertForSequenceClassification
# import BERT-base pretrained model
BERT = BertModel.from_pretrained('bert-base-uncased')
# Load the BERT tokenizer
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
咱们将应用分词器将文本转换为最大长度为 250 的标记,并在须要时进行填充和截断。
train_tokens = tokenizer.batch_encode_plus(x_train.tolist(), max_length = 250, pad_to_max_length=True, truncation=True)
val_tokens = tokenizer.batch_encode_plus(x_val.tolist(), max_length = 250, pad_to_max_length=True, truncation=True)
分词器返回一个字典,其中蕴含三个键值对,其中蕴含 input_ids,它们是与特定单词相干的标记;token_type_ids,它是辨别输出的不同段或局部的整数列表。Attention_mask 批示要关注哪个标记。
将这些值转换为张量
train_ids = torch.tensor(train_tokens['input_ids'])
train_masks = torch.tensor(train_tokens['attention_mask'])
train_label = torch.tensor(y_train.tolist())
val_ids = torch.tensor(val_tokens['input_ids'])
val_masks = torch.tensor(val_tokens['attention_mask'])
val_label = torch.tensor(y_val.tolist())
加载 TensorDataset 和 DataLoaders 以进一步预处理数据并使其适宜模型。
from torch.utils.data import TensorDataset, DataLoader
train_data = TensorDataset(train_ids, train_masks, train_label)
val_data = TensorDataset(val_ids, val_masks, val_label)
train_loader = DataLoader(train_data, batch_size = 32, shuffle = True)
val_loader = DataLoader(val_data, batch_size = 32, shuffle = True)
咱们的工作是应用分类器解冻 BERT 的参数,而后在自定义数据集上训练这些层。那么,让咱们解冻模型的参数。
for param in BERT.parameters():
param.requires_grad = False
当初,咱们必须为咱们增加的层定义前向和后向传递。BERT 模型将充当特征提取器,而咱们必须明确定义分类的前向和后向传递。
class Model(nn.Module):
def __init__(self, bert):
super(Model, self).__init__()
self.bert = bert
self.dropout = nn.Dropout(0.1)
self.relu = nn.ReLU()
self.fc1 = nn.Linear(768, 512)
self.fc2 = nn.Linear(512, 2)
self.softmax = nn.LogSoftmax(dim=1)
def forward(self, sent_id, mask):
# Pass the inputs to the model
outputs = self.bert(sent_id, mask)
cls_hs = outputs.last_hidden_state[:, 0, :]
x = self.fc1(cls_hs)
x = self.relu(x)
x = self.dropout(x)
x = self.fc2(x)
x = self.softmax(x)
return x
让咱们将模型移至 GPU
model = Model(BERT)
# push the model to GPU
model = model.to(device)
3、定义优化器
# optimizer from hugging face transformers
from transformers import AdamW
# define the optimizer
optimizer = AdamW(model.parameters(),lr = 1e-5)
到目前为止,咱们曾经预处理了数据集并定义了咱们的模型。当初是训练模型的时候了。咱们必须编写代码来训练和评估模型。
火车性能:
def train():
model.train()
total_loss, total_accuracy = 0, 0
total_preds = []
for step, batch in enumerate(train_loader):
# Move batch to GPU if available
batch = [item.to(device) for item in batch]
sent_id, mask, labels = batch
# Clear previously calculated gradients
optimizer.zero_grad()
# Get model predictions for the current batch
preds = model(sent_id, mask)
# Calculate the loss between predictions and labels
loss_function = nn.CrossEntropyLoss()
loss = loss_function(preds, labels)
# Add to the total loss
total_loss += loss.item()
# Backward pass and gradient update
loss.backward()
optimizer.step()
# Move predictions to CPU and convert to numpy array
preds = preds.detach().cpu().numpy()
# Append the model predictions
total_preds.append(preds)
# Compute the average loss
avg_loss = total_loss / len(train_loader)
# Concatenate the predictions
total_preds = np.concatenate(total_preds, axis=0)
# Return the average loss and predictions
return avg_loss, total_preds
4、评估函数
def evaluate():
model.eval()
total_loss, total_accuracy = 0, 0
total_preds = []
for step, batch in enumerate(val_loader):
# Move batch to GPU if available
batch = [item.to(device) for item in batch]
sent_id, mask, labels = batch
# Clear previously calculated gradients
optimizer.zero_grad()
# Get model predictions for the current batch
preds = model(sent_id, mask)
# Calculate the loss between predictions and labels
loss_function = nn.CrossEntropyLoss()
loss = loss_function(preds, labels)
# Add to the total loss
total_loss += loss.item()
# Backward pass and gradient update
loss.backward()
optimizer.step()
# Move predictions to CPU and convert to numpy array
preds = preds.detach().cpu().numpy()
# Append the model predictions
total_preds.append(preds)
# Compute the average loss
avg_loss = total_loss / len(val_loader)
# Concatenate the predictions
total_preds = np.concatenate(total_preds, axis=0)
# Return the average loss and predictions
return avg_loss, total_preds
咱们当初将应用这些函数来训练模型:
# set initial loss to infinite
best_valid_loss = float('inf')
#defining epochs
epochs = 5
# empty lists to store training and validation loss of each epoch
train_losses=[]
valid_losses=[]
#for each epoch
for epoch in range(epochs):
print('\n Epoch {:} / {:}'.format(epoch + 1, epochs))
#train model
train_loss, _ = train()
#evaluate model
valid_loss, _ = evaluate()
#save the best model
if valid_loss < best_valid_loss:
best_valid_loss = valid_loss
torch.save(model.state_dict(), 'saved_weights.pt')
# append training and validation loss
train_losses.append(train_loss)
valid_losses.append(valid_loss)
print(f'\nTraining Loss: {train_loss:.3f}')
print(f'Validation Loss: {valid_loss:.3f}')
当初你就失去了它。您能够应用经过训练的模型来推断您抉择的任何数据或文本。
论断
本文探讨了训练大型语言模型 (LLM) 的世界及其对自然语言解决 (NLP) 的重大影响。探讨预训练过程,其中 LLM 应用自我监督学习对大量未标记文本进行训练。咱们还深入研究了训练,其中波及针对特定工作和提醒调整事后训练的模型,其中为模型提供上下文以生成相干输入。此外,咱们还钻研了不同的训练技术,例如特征提取、残缺模型训练和基于适配器的训练。大型语言模型曾经彻底改变了 NLP,并持续推动各种应用程序的提高。
常见问题
Q1:像 BERT 这样的大型语言模型 (LLM) 如何在没有明确标签的状况下了解文本的含意?
A:LLM 采纳自我监督学习技术,例如掩码语言模型,依据四周单词的上下文预测下一个单词,从而无效地从未标记的文本创立标记数据。
Q2:训练大型语言模型的目标是什么?
A:训练容许 LLM 通过调整其参数来适应特定工作,使它们适宜情感剖析、文本生成或文档相似性工作。它建设在模型的事后训练的常识之上。
Q3:LLM 中的提醒有何意义?
A:提醒波及向 LLM 提供背景或阐明以生成相干输入。用户能够通过设置特定的提醒来疏导模型依据给定的上下文答复问题、生成文本或执行特定工作。