译者 | 布加迪
审校 | 重楼
在最近一年半的时间里,自然语言处理(NLP)领域发生了显著的变化,这主要得益于AI target=_blank class=infotextkey>OpenAI的GPT系列等大语言模型(LLM)的兴起。
这些功能强大的模型已彻底改变了我们处理自然语言任务的方法,在翻译、情绪分析和文本自动生成等方面提供了前所未有的能力。它们理解和生成类似人类的文本的能力已带来了曾经被认为无法实现的可能性。
然而,尽管这些模型具有出色的能力,但训练它们的过程却充满了挑战,比如需要投入大量的时间和资金。这时候,微调LLM就体现出了其重要性。
通过细化这些预训练的模型以更好地适应特定的应用环境或领域,我们就可以显著提高它们处理特定任务的性能。这一步不仅提高了它们的质量,还扩大了它们在一系列广泛领域的用途。
本文旨在将这个过程分解为七个简单步骤,以便使任何LLM针对特定任务进行微调。
LLM是机器学习算法的一个特殊类别,旨在根据前一个单词提供的上下文预测序列中的下一个单词。这些模型建立在Transformers架构上,这是机器学习技术领域的一大突破,在谷歌的《你需要的就是注意力》文章中作了首次解释。
GPT(生成式预训练Transformer)之类的模型就是已经暴露于大量文本数据的预训练语言模型。这种广泛的训练使它们得以掌握语言使用的基本规则,包括如何将单词组合成连贯的句子。
这些模型的一个关键优势在于,它们不仅能够理解自然语言,还能够根据提供的输入生成酷似人类写作的文本。
那么其最大的优点是什么呢?那就是这些模型已经通过API向大众开放。
微调是指选择一个预训练的模型,并通过使用特定领域的数据集进一步训练来改进它的过程。
大多数LLM模型有很好的自然语言技能和通用知识性能,但在处理特定的面向任务的问题时差强人意。微调过程提供了一种方法,可以提升模型处理特定问题的性能,同时降低计算费用,无需从头开始构建模型。
简而言之,模型经过微调后,针对特定任务拥有更好的性能,使其在实际应用中更有效、更通用。这个过程对于改进现有模型以处理特定的任务或领域至关重要。
不妨通过如下七个步骤微调一个实际模型来举例说明这个概念。
假设我们想要推断任何文本的情绪,决定试用GPT-2来完成这样的任务。
我敢肯定,我们很快就会发现它在这方面做得很差,这并不奇怪。然后,一个自然而然的问题浮现在脑海中:我们可以做些什么来改善其性能?
当然,答案是我们可以!
使用含有推文及相应情绪的数据集训练来自Hugging Face Hub的预训练GPT-2模型,充分利用微调的效果,以便提高性能。
所以,我们的最终目标是拥有一个善于从文本中推断情绪的模型。
第二步是选择什么模型作为基本模型。在本文例子中,我们已经选择了模型:GPT-2。所以我们要对它进行一些简单的微调。
始终记住要选择适合您任务的模型。
我们已有了模型和主要任务,现在需要一些数据来处理。
不过别担心,Hugging Face已经把一切都安排好了!
这时候,它的数据集库有了用武之地。
在这个例子中,我们将充分利用Hugging Face数据集库来导入一个数据集,其中的推文被标记为相应的情绪(积极的、中立的或消极的)。
from datasets import load_dataset
dataset = load_dataset("mteb/tweet_sentiment_extraction")
df = pd.DataFrame(dataset['train'])
数据看起来就像这样:
现在我们有了模型和数据集来对其进行微调。因此,接下来的合理步骤是加载分词器。由于LLM使用token(而不是单词!!),我们需要分词器将数据发送到我们的模型。
通过利用map方法对整个数据集进行分词处理,我们很容易做到这一点。
from transformers import GPT2Tokenizer
# Loading the dataset to train our model
dataset = load_dataset("mteb/tweet_sentiment_extraction")
tokenizer = GPT2Tokenizer.from_pretrained("gpt2")
tokenizer.pad_token = tokenizer.eos_token
def tokenize_function(examples):
return tokenizer(examples["text"], padding="max_length", truncatinotallow=True)
tokenized_datasets = dataset.map(tokenize_function, batched=True)
为了提高我们的处理性能,生成两个较小的子集:
Small_train_dataset = tokenized_datasets["train"].shuffle(seed=42).select(range(1000))
Small_eval_dataset = tokenized_datasets["test"].shuffle(seed=42).select(range(1000))
一旦我们有了要使用的数据集,就加载我们的模型,并指定预期标签的数量。您可以从推文的情绪数据集知道有三种可能的标签:
from transformers import GPT2ForSequenceClassification
model = GPT2ForSequenceClassification.from_pretrained("gpt2", num_labels=3)
Transformers库提供了一个名为“Trainer”的类,它可以优化我们模型的训练和评估。因此,在实际训练开始之前,我们需要定义一个函数来评估经过微调的模型。
import evaluate
metric = evaluate.load("accuracy")
def compute_metrics(eval_pred):
logits, labels = eval_pred
predictions = np.argmax(logits, axis=-1)
return metric.compute(predictinotallow=predictions, references=labels)
最后一步是微调模型。为此,我们将一起设置训练参数与评估策略,并执行Trainer对象。
要执行Trainer对象,我们只需使用train()命令。
from transformers import TrainingArguments, Trainer
training_args = TrainingArguments(
output_dir="test_trainer",
#evaluation_strategy="epoch",
per_device_train_batch_size=1, # Reduce batch size here
per_device_eval_batch_size=1, # Optionally, reduce for evaluation as well
gradient_accumulation_steps=4
)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=small_train_dataset,
eval_dataset=small_eval_dataset,
compute_metrics=compute_metrics,
)
trainer.train()
一旦我们的模型经过微调,我们使用测试集来评估其性能。trainer对象已经包含了经过优化的evaluate()方法。
import evaluate
trainer.evaluate()
这就是对任何LLM进行微调的基本过程。
另外请记住,微调LLM的过程对计算资源的要求很高,因此您的本地计算机可能没有足够的能力来进行微调。
如今,针对特定任务对预训练的大语言模型(比如GPT)进行微调对于改进LLM在特定领域的性能至关重要。它使我们得以利用LLM的自然语言能力,同时提高它们的效率和定制方面的潜力,使这个过程易于访问且具有成本效益。
如果遵循这七个简单的步骤:从选择正确的模型和数据集到训练和评估微调模型,我们可以在特定领域实现卓越的模型性能。
如果想要查看完整代码,可以在我的大语言模型Github代码库中找到:https://github.com/rfeers/large-language-models/blob/main/7%20Steps%20to%20Fine-Tune%20LLMs.ipynb。
原文标题:7 Steps to Mastering Large Language Model Fine-tuning,作者:Josep Ferrer