大型语言模型 (LLM) 是现代人工智能应用的主要组成部分,尤其是对于自然语言处理。它们具有有效处理和理解人类语言的潜力,其应用范围从虚拟助手和机器翻译到文本摘要和问答。
像 LangChain 这样的库促进了上述端到端AI应用程序的实现。
本文将解释训练大型语言模型的所有过程,从设置工作区到使用 Pytorch 2.0.1 进行最终实现,Pytorch 是一个动态且灵活的深度学习框架,可实现简单明了的模型实现。
先决条件
为了充分利用这些内容,重要的是要熟悉 Python 编程,对深度学习概念和转换器有基本的了解,并熟悉 Pytorch 框架。
在深入研究核心实现之前,我们需要安装并导入相关库。另外,需要注意的是,训练脚本的灵感来自 Hugging Face 的这个存储库。
库安装
安装过程详述如下:
首先,我们使用该语句在单个单元格中将安装命令作为 Jupyter Notebook 中的 bash 命令运行。
%%bash
- Trl:用于通过强化学习训练 transformer 语言模型。
- Peft 使用参数高效微调 (PEFT) 方法来实现对预训练模型的高效调整。
- Torch:一个广泛使用的开源机器学习库。
- 数据集:用于协助下载和加载许多常见的机器学习数据集。
Transformers:由 Hugging Face 开发的库,带有数千个预训练模型,用于各种基于文本的任务,例如分类、摘要和翻译。
css
pip -q install trl
pip -q install peft
pip -q install torch
pip -q install datasets
pip -q install transformers
现在,可以按如下方式导入这些模块:
javascript
import torch
from trl import SFTTrainer
from datasets import load_dataset
from peft import LoraConfig, get_peft_model, prepare_model_for_int8_training
from transformers import AutoModelForCausalLM, AutoTokenizer, TrainingArguments
数据加载和准备
Hugging Face 上免费提供的 alpaca 数据集将用于此插图。数据集有三个主要列:指令、输入和输出。这些列组合在一起以生成最终的文本列。
加载数据集的指令如下,提供感兴趣的数据集的名称,即:
tatsu-lab/alpaca
bash
train_dataset = load_dataset("tatsu-lab/alpaca", split="train")
print(train_dataset)
我们可以看到,生成的数据位于两个键的字典中:
- 特征:包含数据的主列
- num_rows:对应数据中的总行数

train_dataset 结构
前五行可以按照以下说明显示。首先,将字典转换为 pandas 数据帧,然后显示行。
scss
pandas_format = train_dataset.to_pandas()
display(pandas_format.head())

train_dataset 的前五行
为了更好地可视化,让我们打印有关前三行的信息,但在此之前,我们需要安装库以将每行的最大字数设置为 50。第一个 print 语句用 15 个破折号分隔每个块。
textwrap
scss
import textwrap
for index in range(3):
print("---"*15)
print("Instruction:
{}".format(textwrap.fill(pandas_format.iloc[index]["instruction"],
width=50)))
print("Output:
{}".format(textwrap.fill(pandas_format.iloc[index]["output"],
width=50)))
print("Text:
{}".format(textwrap.fill(pandas_format.iloc[index]["text"],
width=50)))

前三行的详细信息
模型训练
在继续训练模型之前,我们需要设置一些先决条件:
-
**预训练模型:**我们将使用预训练的模型 Salesforce/xgen-7b-8k-base,该模型可在 Hugging Face 上使用。Salesforce 训练了这一系列名为 XGen-7B 的 7B LLM,对高达 8K 的序列进行了标准的密集关注,最高可达 1.5T 代币。
-
分词器: 这是训练数据上的标记化任务所必需的。加载预训练模型和分词器的代码如下:
pretrained_model_name = "Salesforce/xgen-7b-8k-base" model = AutoModelForCausalLM.from_pretrained(pretrained_model_name, torch_dtype=torch.bfloat16) tokenizer = AutoTokenizer.from_pretrained(pretrained_model_name, trust_remote_code=True)
训练配置
训练需要一些训练参数和配置,下面定义了两个重要的配置对象,一个是 TrainingArguments 的实例,一个是 LoraConfig 模型的实例,最后是 SFTTrainer 模型。
训练参数
这用于定义模型训练的参数。
在此特定场景中,我们首先使用属性定义将存储训练模型的目标,然后再定义其他超参数,例如优化方法等。
output_dir``learning rate``number of epochs
ini
model_training_args = TrainingArguments(
output_dir="xgen-7b-8k-base-fine-tuned",
per_device_train_batch_size=4,
optim="adamw_torch",
logging_steps=80,
learning_rate=2e-4,
warmup_ratio=0.1,
lr_scheduler_type="linear",
num_train_epochs=1,
save_strategy="epoch"
)
LoRAConfig
此方案使用的主要参数是 LoRA 中低秩转换矩阵的秩,该矩阵设置为 16。然后,LoRA 中其他参数的比例因子设置为 32。
此外,辍学率为 0.05,这意味着在训练期间将忽略 5% 的输入单元。最后,由于我们正在处理一种常见的语言建模,因此使用属性初始化任务。
CAUSAL_LM
SFTTrainer
这旨在使用训练数据、标记器和其他信息(如上述模型)来训练模型。
由于我们使用的是训练数据中的文本字段,因此查看分布非常重要,以帮助设置给定序列中的最大标记数。
scss
import matplotlib.pyplot as plt
pandas_format['text_length'] = pandas_format['text'].apply(len)
plt.figure(figsize=(10,6))
plt.hist(pandas_format['text_length'], bins=50, alpha=0.5, color='g')
plt.title('Distribution of Length of Text')
plt.xlabel('Length of Text')
plt.ylabel('Frequency')
plt.grid(True)
plt.show()

文本列长度的分布
根据上面的观察,我们可以看到大多数文本的长度在 0 到 1000 之间。此外,我们可以在下面看到,只有 4.5% 的文本文档的长度大于 1024。
scss
mask = pandas_format['text_length'] > 1024
percentage = (mask.sum() / pandas_format['text_length'].count()) * 100
print(f"The percentage of text documents with a length greater than 1024 is: {percentage}%")

然后,我们将序列中的最大标记数设置为 1024,以便任何超过此长度的文本都会被截断。
ini
SFT_trainer = SFTTrainer(
model=model,
train_dataset=train_dataset,
dataset_text_field="text",
max_seq_length=1024,
tokenizer=tokenizer,
args=model_training_args,
packing=True,
peft_config=lora_peft_config,
)
训练执行
满足所有先决条件后,我们现在可以按如下方式运行模型的训练过程:
ini
tokenizer.pad_token = tokenizer.eos_token
model.resize_token_embeddings(len(tokenizer))
model = prepare_model_for_int8_training(model)
model = get_peft_model(model, lora_peft_config)
training_args = model_training_args
trainer = SFT_trainer
trainer.train()
值得一提的是,这种训练是在带有 GPU 的云环境中进行的,这使得整个训练过程更快。但是,在本地计算机上进行训练需要更多时间才能完成。
让我们了解上面的代码片段中发生了什么:
- tokenizer.pad_token = tokenizer.eos_token:将填充标记设置为与句尾标记相同。
- **model.resize_token_embeddings(len(tokenizer))):**调整模型的标记嵌入层的大小,以匹配标记器词汇表的长度。
- model = prepare_model_for_int8_training(model):准备模型以 INT8 精度进行训练,可能执行量化。
- model = get_peft_model(model, lora_peft_config):根据 PEFT 配置调整给定模型。
- training_args = model_training_args:将预定义的训练参数分配给 training_args。
- trainer = SFT_trainer:将 SFTTrainer 实例分配给变量 trainer。
- trainer.train():根据提供的规范触发模型的训练过程。
结论
本文提供了使用 PyTorch 训练大型语言模型的明确指南。从数据集准备开始,它演练了准备先决条件、设置训练器以及最后运行训练过程的步骤。
尽管它使用了特定的数据集和预训练模型,但对于任何其他兼容选项,该过程应该大致相同。现在您已经了解如何训练 LLM,您可以利用这些知识为各种 NLP 任务训练其他复杂的模型。