针对特定任务对 Llama 2 进行微调

微调是一种定制预训练大型语言模型 (LLM) 以更好地完成特定任务的过程。微调 Llama 2 是一种调整预训练模型参数以提高其在特定任务或数据集上的性能的过程。此过程可用于使 Llama 2 适应各种任务。

本章介绍了迁移学习微调技术的概念,以及如何微调 Llama以完成不同任务的示例。

了解迁移学习

迁移学习是机器学习的一种应用,其中在较大语料库上进行预训练的模型可以适应相关任务,但规模要小得多。它不是从头开始训练模型,这在计算上既昂贵又耗时,而是建立在模型在更大的语料库上已经获得的知识之上。

以 Llama 为例:它已在大量文本数据上进行了预训练。我们将使用迁移学习;我们将在小得多的数据集上对其进行微调,以完成非常不同的 NLP 任务:例如,情绪分析、文本分类或问答。

迁移学习的主要优势

  • 节省时间 − 微调所需的时间比从原始数据集训练模型要少得多。
  • 改进的泛化 − 预训练的模型已经掌握了通用语言模式,这些模式对一系列自然语言处理应用程序都很有用。
  • 数据效率 −微调可以使模型即使在较小的数据集上也能保持高效。

微调技术

微调 Llama 或任何其他大型语言模型是一个针对任务微调模型参数的过程。有几种微调技术:

完整模型微调

这会更新模型每一层的参数。不过,它确实使用了大量计算,并且对于特定任务的性能来说可能会更好。

from transformers import LlamaForSequenceClassification, Trainer, TrainingArguments
from datasets import load_dataset

# 加载 tokenizer(假设您需要定义 tokenizer)
from transformers import LlamaTokenizer
tokenizer = LlamaTokenizer.from_pretrained("meta-Llama/Llama-2-7b-chat-hf")

# 加载数据集
dataset = load_dataset("imdb")

# 预处理数据集
def preprocess_function(examples):
    return tokenizer(examples['text'], padding="max_length", truncation=True)

tokenized_dataset = dataset.map(preprocess_function, batched=True)

# 设置训练参数
training_args = TrainingArguments(
    output_dir="./results",
    evaluation_strategy="epoch",
    per_device_train_batch_size=8,
    per_device_eval_batch_size=8,
    num_train_epochs=3,
    weight_decay=0.01
)

model = LlamaForSequenceClassification.from_pretrained("meta-Llama/Llama-2-7b-chat-hf", num_labels=2)

# 训练器初始化
trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=tokenized_dataset["train"],
    eval_dataset=tokenized_dataset["test"]
)

# 微调模型
trainer.train()

Output

Epoch 1/3
Training Loss: 0.1345, Evaluation Loss: 0.1523
Epoch 2/3
Training Loss: 0.0821, Evaluation Loss: 0.1042
Epoch 3/3
Training Loss: 0.0468, Evaluation Loss: 0.0879

层冻结

仅冻结模型的所有最后层,并且前面的层"冻结"。它主要在您想要节省内存使用量和训练时间时应用。如果它更接近预训练数据,则此技术很有价值。

# 冻结除分类器层之外的所有层
for param in model.base_model.parameters():
    param.requires_grad = False
     # 现在,仅对分类器层进行微调
trainer.train()

学习率调整

其他方法包括尝试调整学习率作为微调方法。学习率较低时效果更好,因为微调时对预先学习的知识造成的干扰最小。

training_args = TrainingArguments(
    output_dir="./results",
    learning_rate=2e-5,  
# 微调学习速度慢
    num_train_epochs=3,
    evaluation_strategy="epoch"
)

基于提示的微调

它采用精心设计的提示,影响模型执行特定任务,而无需更新模型的权重。它在零样本和少样本学习的所有类型的任务中都具有很高的实用性。

其他任务的微调示例

让我们来看一些微调 Llama 模型的真实示例 −

1. 情绪分析的微调

广义上讲,情绪分析将文本输入分为以下类别之一,这些类别表示文本的性质是积极的、消极的还是中性的。对 Llama 进行微调可能比理解不同文本输入背后的情感更为出色。

来自 transformers 导入 LlamaForSequenceClassification、Trainer、TrainingArguments、LlamaTokenizer
来自 datasets 导入 load_dataset
来自 huggingface_hub 导入 login

access_token_read = "<输入 token>"

# 使用 Hugging Face Hub 进行身份验证
login(token=access_token_read)

# 加载 tokenizer
tokenizer = LlamaTokenizer.from_pretrained("meta-Llama/Llama-2-7b-chat-hf")

# 下载情绪分析数据集
dataset = load_dataset("yelp_polarity")

# 预处理数据集
def preprocess_function(examples):
    return tokenizer(examples['text'], padding="max_length", truncation=True)

tokenized_dataset = dataset.map(preprocess_function, batched=True)

# 下载预先训练的 Llama 进行分类
model = LlamaForSequenceClassification.from_pretrained("meta-Llama/Llama-2-7b-chat-hf", num_labels=2)

# 训练参数
training_args = TrainingArguments(
    output_dir="./results",
    learning_rate=2e-5,
    per_device_train_batch_size=8,
    per_device_eval_batch_size=8,
    num_train_epochs=3,
    weight_decay=0.01,
)

# 初始化训练器
trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=tokenized_dataset["train"],
    eval_dataset=tokenized_dataset["test"]
)

# 针对情绪分析微调模型
trainer.train()

输出

Epoch 1/3
Training Loss: 0.2954, Evaluation Loss: 0.3121
Epoch 2/3
Training Loss: 0.1786, Evaluation Loss: 0.2245
Epoch 3/3
Training Loss: 0.1024, Evaluation Loss: 0.1893

2. 问答微调

微调模型还支持它从文本生成简短且相关的问题答案。

from transformers import LlamaForQuestionAnswering、Trainer、TrainingArguments、LlamaTokenizer
from datasets import load_dataset
from huggingface_hub import login

access_token_read = "<Enter token>"

# 使用 Hugging Face Hub 进行身份验证
login(token=access_token_read)

# 加载 tokenizer
tokenizer = LlamaTokenizer.from_pretrained("meta-Llama/Llama-2-7b-chat-hf")

# 加载 SQuAD 数据集以进行问答
dataset = load_dataset("squad")

# 预处理数据集
def preprocess_function(examples):
    return tokenizer(
        examples['question'],
        examples['context'],
        truncation=True,
        padding="max_length", 	# 根据需要调整填充
        max_length=512 			# 根据需要调整 max_length
    )

tokenized_dataset = dataset.map(preprocess_function, batched=True)

# 加载预先训练过的 Llama 进行问答
model = LlamaForQuestionAnswering.from_pretrained("meta-Llama/Llama-2-7b-chat-hf")

# 训练参数
training_args = TrainingArguments(
    output_dir="./results",
    learning_rate=3e-5,
    per_device_train_batch_size=8,
    per_device_eval_batch_size=8,
    num_train_epochs=3,
    weight_decay=0.01,
)

# 初始化训练器
trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=tokenized_dataset["train"],
    eval_dataset=tokenized_dataset["validation"]
)

# 在问答上微调模型
trainer.train()

输出

Epoch 1/3
Training Loss: 1.8234, Eval. Loss: 1.5243
Epoch 2/3
Training Loss: 1.3451, Eval. Loss: 1.2212
Epoch 3/3
Training Loss: 1.0152, Eval. Loss: 1.0435

3. 文本生成微调

Llama 可以进行微调以增强其文本生成能力,可用于故事生成、对话系统甚至创意写作等应用。

from transformers import LlamaForCausalLM, Trainer, TrainingArguments, LlamaTokenizer
from datasets import load_dataset
from huggingface_hub import login

access_token_read = "<Enter token>"

login(token=access_token_read)

# 加载 tokenizer
tokenizer = LlamaTokenizer.from_pretrained("meta-Llama/Llama-2-7b-chat-hf")

# 加载用于文本生成的数据集
dataset = load_dataset("wikitext", "wikitext-2-raw-v1")

# 预处理数据集
def preprocess_function(examples):
    return tokenizer(examples['text'], padding="max_length", truncation=True)

tokenized_dataset = dataset.map(preprocess_function, batched=True)

# 加载预先训练的 Llama 模型进行因果语言建模
model = LlamaForCausalLM.from_pretrained("meta-Llama/Llama-2-7b-chat-hf")

# 训练参数
training_args = TrainingArguments(
    output_dir="./results",
    learning_rate=5e-5,
    per_device_train_batch_size=8,
    per_device_eval_batch_size=8,
    num_train_epochs=3,
    weight_decay=0.01,
)

# 初始化训练器
trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=tokenized_dataset["train"],
    eval_dataset=tokenized_dataset["validation"],
)

# 微调模型以生成文本
trainer.train()

输出

Epoch 1/3
Training Loss: 2.9854, Eval Loss: 2.6452
Epoch 2/3
Training Loss: 2.5423, Eval Loss: 2.4321
Epoch 3/3
Training Loss: 2.2356, Eval Loss: 2.1987

总结

事实上,对某些特定任务(无论是情绪分析、问答还是文本生成)上的 Llama 进行微调,都展示了迁移学习的强大功能。换句话说,从一些大型预训练模型开始,微调允许使用最少的数据和计算量针对特定用例进行定制。本章介绍了一些技术和示例,以展示 Llama 的多功能性,从而提供了可能方便适应多种不同 NLP 挑战的实践步骤。