天天看點

「人工智能」大型語言模型 (LLM) 初學者指南

作者:架構思考

踏上人工智能的演變之旅和自然語言處理(NLP) 領域取得的驚人進步。一眨眼的功夫,人工智能已經崛起,塑造了我們的世界。訓練大型語言模型的巨大影響徹底改變了 NLP,徹底改變了我們的技術互動。時間回到 2017 年,這是一個以“注意力就是你所需要的”為标志的關鍵時刻,開創性的“Transformer”架構誕生了。該架構現在構成了 NLP 的基石,是每個大型語言模型配方中不可替代的成分 - 包括著名的 ChatGPT。

「人工智能」大型語言模型 (LLM) 初學者指南

想象一下輕松生成連貫、上下文豐富的文本 - 這就是 GPT-3 等模型的魔力。作為聊天機器人、翻譯和内容生成的強大力量,它們的輝煌源于架構以及預訓練和訓練的複雜舞蹈。我們即将發表的文章将深入研究這首交響曲,揭示利用大型語言模型執行任務背後的藝術性,利用預訓練和訓練的動态二重奏來達到出色的效果。與我們一起揭開這些變革技術的神秘面紗!

學習目标

  • 了解建構 LLM 申請的不同方法。
  • 學習特征提取、層訓練和擴充卡方法等技術。
  • 使用 Huggingface 轉換器庫在下遊任務上訓練 LLM。

入門

LLM 代表大型語言模型。LLM 是深度學習模型,旨在了解類人文本的含義并執行各種任務,例如情感分析、語言模組化(下一個詞預測)、文本生成、文本摘要等等。他們接受了大量文本資料的訓練。

我們每天都在使用基于這些LLM的應用程式,甚至沒有意識到這一點。Google 将 BERT(Transformers 雙向編碼器表示)用于各種應用,例如查詢完成、了解查詢上下文、輸出更相關和更準确的搜尋結果、語言翻譯等。

這些模型建立在深度學習技術、深度神經網絡和自注意力等先進技術的基礎上。他們接受大量文本資料的訓練,以學習語言的模式、結構和語義。

由于這些模型是在廣泛的資料集上進行訓練的,是以需要大量的時間和資源來訓練它們,并且從頭開始訓練它們是沒有意義的。

我們可以通過一些技術直接使用這些模型來完成特定任務。那麼讓我們詳細讨論一下它們。

一、建構LLM申請的不同方法概述

我們在日常生活中經常看到令人興奮的LLM申請。您想知道如何建構 LLM 申請嗎?以下是建構 LLM 申請的 3 種方法:

  1. 利用 Scratch 訓練大語言模型
  2. 訓練大型語言模型
  3. 提示

1.1 利用 Scratch 訓練大語言模型

人們經常對這兩個術語感到困惑:訓練和微調LLM。這兩種技術的工作方式相似,即改變模型參數,但訓練目标不同。

從頭開始教育訓練LLM也稱為預教育訓練。預訓練是一種在大量未标記文本上訓練大型語言模型的技術。但問題是,“我們如何在未标記的資料上訓練模型,然後期望模型準确地預測資料?”。這就是“自我監督學習”的概念。在自監督學習中,模型會掩蓋一個單詞,并嘗試借助前面的單詞來預測下一個單詞。例如,假設我們有一句話:“我是一名資料科學家”。

該模型可以根據這句話建立自己的标記資料,例如:

「人工智能」大型語言模型 (LLM) 初學者指南

這被稱為下一個工作預測,由 MLM(掩碼語言模型)完成。BERT,一種屏蔽語言模型,使用這種技術來預測屏蔽詞。我們可以将傳銷視為“填空”概念,其中模型預測哪些單詞可以填入空白。

預測下一個單詞的方法有多種,但在本文中,我們隻讨論 BERT,即 MLM。BERT 可以檢視前面和後面的單詞來了解句子的上下文并預測屏蔽詞。

是以,作為預訓練的進階概述,它隻是模型學習預測文本中下一個單詞的技術。

1.2 訓練大型語言模型

訓練是調整模型的參數,使其适合執行特定任務。模型經過預訓練後,會進行訓練,或者簡單地說,訓練它來執行特定任務,例如情感分析、文本生成、查找文檔相似性等。我們不必在特定的環境上再次訓練模型。大文本;相反,我們使用經過訓練的模型來執行我們想要執行的任務。我們将在本文後面詳細讨論如何訓練大型語言模型。

「人工智能」大型語言模型 (LLM) 初學者指南

1.3 提示

提示是所有 3 種技術中最簡單的,但也有點棘手。它涉及為模型提供一個上下文(提示),模型根據該上下文執行任務。可以将其視為詳細教孩子書中的一章,對解釋非常謹慎,然後要求他們解決與該章相關的問題。

就 LLM 而言,以 ChatGPT 為例;我們設定一個上下文并要求模型按照說明來解決給定的問題。

假設我希望 ChatGPT 隻問我一些有關變形金剛的面試問題。為了獲得更好的體驗和準确的輸出,您需要設定适當的上下文并給出詳細的任務描述。

示例:我是一名擁有兩年經驗的資料科學家,目前正在某某公司準備面試。我喜歡解決問題,目前正在使用最先進的 NLP 模型。我了解最新的趨勢和技術。問我關于Transformer模型的非常棘手的問題,這個公司的面試官可以根據公司以前的經驗來問。問我十個問題并給出問題的答案。

您提示的越詳細和具體,結果就越好。最有趣的部分是您可以從模型本身生成提示,然後添加個人風格或所需的資訊。

二、了解不同地訓練技術

傳統上訓練模型的方法有多種,不同的方法取決于您想要解決的具體問題。讓我們讨論訓練模型的技術。

傳統上有 3 種方法可以對 LLM 進行訓練。

2.1 特征提取

人們使用這種技術從給定文本中提取特征,但是為什麼我們要從給定文本中提取嵌入呢?答案很簡單。由于計算機無法了解文本,是以需要有一種文本的表示形式,以便我們可以用來執行各種任務。一旦我們提取嵌入,它們就能夠執行情感分析、識别文檔相似性等任務。在特征提取中,我們鎖定模型的主幹層,這意味着我們不會更新這些層的參數;僅更新分類器層的參數。分類器層涉及全連接配接層。

「人工智能」大型語言模型 (LLM) 初學者指南

2.2 全模型訓練

顧名思義,我們在該技術中在自定義資料集上訓練每個模型層特定數量的時期。我們根據新的自定義資料集調整模型中所有層的參數。這可以提高模型對資料和我們想要執行的特定任務的準确性。考慮到訓練大型語言模型中有數十億個參數,計算成本很高,并且需要大量時間來訓練模型。

2.3 基于擴充卡的訓練

「人工智能」大型語言模型 (LLM) 初學者指南

基于擴充卡的訓練是一個相對較新的概念,其中将額外的随機初始化層或子產品添加到網絡中,然後針對特定任務進行訓練。在這種技術中,模型的參數不受幹擾,或者我們可以說模型的參數沒有改變或調整。相反,擴充卡層參數是經過訓練的。該技術有助于以計算有效的方式調整模型。

三、實施:在下遊任務上訓練 BERT

現在我們知道了訓練技術,讓我們使用 BERT 對 IMDB 電影評論進行情感分析。BERT 是一種大型語言模型,結合了轉換器層并且僅包含編碼器。谷歌開發了它,并已證明在各種任務上表現良好。BERT 有不同的大小和變體,例如 BERT-base-uncased、BERT Large、RoBERTa、LegalBERT 等等。

「人工智能」大型語言模型 (LLM) 初學者指南

3.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)           

3.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.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           

3.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提供背景或說明以生成相關輸出。使用者可以通過設定特定的提示來引導模型根據給定的上下文回答問題、生成文本或執行特定任務。

文章來源:MomodelAI_https://mp.weixin.qq.com/s/bXvIRlxM28aSffKBYCgjGg

繼續閱讀