在灾难推文分析场景上比较用 LoRA 微调 Roberta、Llama 2 和 Mistral 的过程及表现

引言

自然语言处理 (NLP) 领域的进展日新月异,你方唱罢我登场。因此,在实际场景中,针对特定的任务,我们经常需要对不同的语言模型进行比较,以寻找最适合的模型。本文主要比较 3 个模型: RoBERTa、Mistral-7B 及 Llama-2-7B。我们用它们来解决一个常见问题 —— 对灾难相关的推文进行分类。值得注意的是,Mistral 和 Llama 2 是 70 亿参数的大模型。相形之下,RoBERTa-large (355M 参数) 只是一个小模型,我们用它作为比较的基线。

本文,我们使用 PEFT (Parameter-Efficient Fine-Tuning,参数高效微调) 技术: LoRA (Low-Rank Adaptation,低秩适配) 来微调带序列分类任务头的预训练模型。LoRA 旨在显著减少可训参数量,同时保持强大的下游任务性能。

本文的主要目标是通过对 Hugging Face 的三个预训练模型进行 LoRA 微调,使之适用于序列分类任务。这三个预训练模型分别是: meta-llama/Llama-2-7b-hf、mistralai/Mistral-7B-v0.1 及 roberta-large。

使用的硬件

  • 节点数: 1

  • 每个节点的 GPU 数: 1

  • GPU 类型: A6000

  • GPU 显存: 48GB

目标

  • 使用 LoRA PEFT 方法对预训练 LLM 进行微调。

  • 了解如何使用 Hugging Face 的各种 API (transformers、peft 以及 datasets)。

  • 使用 Weights & Biases 进行超参调优以及实验日志记录。

软件依赖

datasets
evaluate
peft
scikit-learn
torch
transformers
wandb

注意: 要准确重现本文结果,请注意确保软件版本与 wandb 报告 的一致。

预训练模型

RoBERTa

RoBERTa (Robustly Optimized BERT Approach) 是 Meta AI 研究团队提出的改进版 BERT 模型。BERT 是一种基于 transformer 的语言模型,其基于自注意力机制对单词进行上下文感知的表征,并基于掩码语言模型目标进行训练。请注意,BERT 作为编码器模型,仅可用于自然语言理解任务 (例如序列分类和词元分类)。

RoBERTa 是一种流行的可微调模型,很适合作为我们实验的基线。欲了解更多信息,你可以查阅其 Hugging Face 模型卡。

Llama 2

Llama 2 (Large Language Model Meta AI) 是 Meta AI 推出的一系列大语言模型 (LLM),其模型大小各异,参数量从 70 亿到 650 亿不等。

Llama 2 是一种基于 transformer 解码器架构的自回归语言模型。Llama 2 接受单词序列作为输入,并基于滑动窗口迭代预测下一个词元,从而实现文本生成的功能。

Llama 2 的架构与 GPT-3 等模型略有不同。举几个例子,Llama 2 采用 SwiGLU 激活函数而不是 ReLU,另外其位置嵌入使用的是旋转位置嵌入而不是可训绝对位置嵌入。

最近发布的 Llama 2 还对架构进行了改进,其将支持的最大上下文长度扩展到 4096 个词元,并使用分组查询注意 (grouped-query attention,GQA) 解码机制来更好地利用长序列。

Mistral 7B

Mistral 7B v0.1 有 73 亿个参数,是 Mistral AI 推出的第一个 LLM。

Mistral 7B 架构使用的新技术主要有:

  • 滑窗注意力: 用基于滑动窗口的注意力替换完整注意力 (平方级计算成本),其中每个词元最多可以关注上一层的 4096 个词元 (线性计算成本)。这样,多层以后,Mistral 7B 的实际关注词元数会叠加,因此更高层的注意力实际关注的总历史词元数会超过 4096。

  • 分组查询注意力: Llama 2 也使用了该技术,其通过缓存先前解码的词元的键向量和值向量来优化推理过程 (减少处理时间)。

LoRA

PEFT (Parameter Efficient Fine-Tuning,参数高效微调) 包含 p-tuning、前缀微调 (prefix-tuning) 、IA3、适配器微调以及 LoRA 等一系列技术,其旨在通过仅微调大模型的一个小参数集,就能达到全模型微调的性能水平。

LoRA (Low-Rank Adaptation,低阶适配) 的方法与添加适配层类似。其主要目标是减少模型的可训参数量。LoRA 的主要做法是冻结预训练权重,仅更新一个新增的低秩矩阵。

04df2e428b36597331ff5b6802f24741.png

环境设置

RoBERTa 支持的最大序列长度为 512,为公平起见,对所有模型,我们统一设定 MAX_LEN=512

MAX_LEN = 512
roberta_checkpoint = "roberta-large"
mistral_checkpoint = "mistralai/Mistral-7B-v0.1"
llama_checkpoint = "meta-llama/Llama-2-7b-hf"

数据准备

数据加载

从 Hugging Face 加载数据集:

from datasets import load_dataset
dataset = load_dataset("mehdiiraqui/twitter_disaster")

将数据集分为训练集和验证集,同时加载测试集:

from datasets import Dataset
# 将数据集的训练集划分为训练集和验证集
data = dataset['train'].train_test_split(train_size=0.8, seed=42)
# 把划分而得的测试集重命名为验证集
data['val'] = data.pop("test")
# 将原数据集的测试集仍作为测试集
data['test'] = dataset['test']

以下是数据集概览:

DatasetDict({
    train: Dataset({
        features: ['id', 'keyword', 'location', 'text', 'target'],
        num_rows: 6090
    })
    val: Dataset({
        features: ['id', 'keyword', 'location', 'text', 'target'],
        num_rows: 1523
    })
    test: Dataset({
        features: ['id', 'keyword', 'location', 'text', 'target'],
        num_rows: 3263
    })
})

首先,检查一下数据分布:

import pandas as pd

data['train'].to_pandas().info()
data['test'].to_pandas().info()
  • 训练集

RangeIndex: 7613 entries, 0 to 7612
Data columns (total 5 columns):
 # Column Non-Null Count Dtype
--- ------ -------------- -----
 0 id 7613 non-null int64
 1 keyword 7552 non-null object
 2 location 5080 non-null object
 3 text 7613 non-null object
 4 target 7613 non-null int64
dtypes: int64(2), object(3)
memory usage: 297.5+ KB
  • 测试集

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 3263 entries, 0 to 3262
Data columns (total 5 columns):
 # Column Non-Null Count Dtype
--- ------ -------------- -----
 0 id 3263 non-null int64
 1 keyword 3237 non-null object
 2 location 2158 non-null object
 3 text 3263 non-null object
 4 target 3263 non-null int64
dtypes: int64(2), object(3)
memory usage: 127.6+ KB

训练集中标签分布情况:

target
0 4342
1 3271
Name: count, dtype: int64

由于类别不平衡,我们计算一下正负类权重,以用于稍后的损失计算:

pos_weights = len(data['train'].to_pandas()) / (2 * data['train'].to_pandas().target.value_counts()[1])
neg_weights = len(data['train'].to_pandas()) / (2 * data['train'].to_pandas().target.value_counts()[0])

计算出的权重为:

POS_WEIGHT, NEG_WEIGHT = (1.1637114032405993, 0.8766697374481806)

接着,我们计算文本序列的最大长度:

# 字符数
max_char = data['train'].to_pandas()['text'].str.len().max()
# 词数
max_words = data['train'].to_pandas()['text'].str.split().str.len().max()
The maximum number of characters is 152.
The maximum number of words is 31.

数据处理

以一条训练数据为例:

data['train'][0]
{'id': 5285,
 'keyword': 'fear',
 'location': 'Thibodaux, LA',
 'text': 'my worst fear. https://t.co/iH8UDz8mq3',
 'target': 0}

该数据中包括关键字、位置和推文。为了简单起见,我们选择 text 特征作为 LLM 的唯一输入。

本阶段的目标是为 LLM 微调准备所需的 Hugging Face 格式的训练集、验证集和测试集。然后是定义用于训练的词元数据集,使用合适的分词器将 text 特征转换为词元 id 和注意力掩码序列这两个张量。由于每个模型都有其特定的分词器,因此我们需要生成三个不同的数据集,每个模型一个。

我们首先定义 RoBERTa 模型的数据加载器:

  • 加载与分词:

from transformers import AutoTokenizer
roberta_tokenizer = AutoTokenizer.from_pretrained(roberta_checkpoint, add_prefix_space=True)

注意: RoBERTa 分词器经过训练已将空格视为词元的一部分。因此,如果句子的第一个单词前面没有空格,则其编码会有所不同。为了确保第一个单词包含空格,我们设置 add_prefix_space=True 。同时,为了保持三个模型的预处理一致,我们将 Llama 2 和 Mistral 7B 的相应参数也设为 True

  • 定义每条数据的预处理函数:

def roberta_preprocessing_function(examples):
    return roberta_tokenizer(examples['text'], truncation=True, max_length=MAX_LEN)

将预处理函数应用于训练数据集的第一条数据,我们得到了分词后的输入 ( input_ids ) 及其注意力掩码:

roberta_preprocessing_function(data['train'][0])
{'input_ids': [0, 127, 2373, 2490, 4, 1205, 640, 90, 4, 876, 73, 118, 725, 398, 13083, 329, 398, 119, 1343, 246, 2], 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]}
  • 现在,将预处理函数应用于整个数据集:

col_to_delete = ['id', 'keyword','location', 'text']
# 删除不需要的列,并应用预处理函数
roberta_tokenized_datasets = data.map(roberta_preprocessing_function, batched=True, remove_columns=col_to_delete)
# 按照 HuggingFace 的要求,将 `target` 列  重命名为 `label` 列
roberta_tokenized_datasets = roberta_tokenized_datasets.rename_column("target", "label")
# 数据集格式设为 "torch"
roberta_tokenized_datasets.set_format("torch")

注意: 我们从数据中删除了不需要的列: idkeywordlocationtext 。删除 text 的原因是我们已经将其转换为输入 id 和注意力掩码:

分词后的训练数据集中的数据如下:

roberta_tokenized_datasets['train'][0]
{'label': tensor(0),
 'input_ids': tensor([ 0, 127, 2373, 2490, 4, 1205, 640, 90, 4, 876,
            73, 118, 725, 398, 13083, 329, 398, 119, 1343, 246,
             2]),
 'attention_mask': tensor([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1])}
  • 为了生成训练 batch 数据,我们还需要对给定 batch 中的序列进行填充,以使 batch 中所有序列的长度都等于本 batch 最长序列的长度。为此,我们使用了 DataCollatorWithPadding 类:

# 数据整理器将所有数据统一填充至 batch 内最长序列的长度
from transformers import DataCollatorWithPadding
roberta_data_collator = DataCollatorWithPadding(tokenizer=roberta_tokenizer)

用相同的流程为 Mistral 7B 和 Llama 2 模型准备数据:

注意 Llama 2 和 Mistral 7B 没有默认的 pad_token_id ,我们将其设为 eos_token_id

  • Mistral 7B:

# 加载 Mistral 7B 分词器
from transformers import AutoTokenizer, DataCollatorWithPadding
mistral_tokenizer = AutoTokenizer.from_pretrained(mistral_checkpoint, add_prefix_space=True)
mistral_tokenizer.pad_token_id = mistral_tokenizer.eos_token_id
mistral_tokenizer.pad_token = mistral_tokenizer.eos_token

def mistral_preprocessing_function(examples):
    return mistral_tokenizer(examples['text'], truncation=True, max_length=MAX_LEN)

mistral_tokenized_datasets = data.map(mistral_preprocessing_function, batched=True, remove_columns=col_to_delete)
mistral_tokenized_datasets = mistral_tokenized_datasets.rename_column("target", "label")
mistral_tokenized_datasets.set_format("torch")

# 序列填充
mistral_data_collator = DataCollatorWithPadding(tokenizer=mistral_tokenizer)
  • Llama 2:

# 加载 Llama 2 分词器
from transformers import AutoTokenizer, DataCollatorWithPadding
llama_tokenizer = AutoTokenizer.from_pretrained(llama_checkpoint, add_prefix_space=True)
llama_tokenizer.pad_token_id = llama_tokenizer.eos_token_id
llama_tokenizer.pad_token = llama_tokenizer.eos_token

def llama_preprocessing_function(examples):
    return llama_tokenizer(examples['text'], truncation=True, max_length=MAX_LEN)

llama_tokenized_datasets = data.map(llama_preprocessing_function, batched=True, remove_columns=col_to_delete)
llama_tokenized_datasets = llama_tokenized_datasets.rename_column("target", "label")
llama_tokenized_datasets.set_format("torch")

# 序列填充
llama_data_collator = DataCollatorWithPadding(tokenizer=llama_tokenizer)

至此,我们已经准备好了分词后的数据集,下一节我们将讨论如何加载预训练 LLM 检查点以及如何设置 LoRA 权重。

模型

RoBERTa

为分类任务加载 RoBERTa 检查点

我们使用 Hugging Face AutoModelForSequenceClassification 类加载带有序列分类头的预训练 RoBERTa 模型:

from transformers import AutoModelForSequenceClassification
roberta_model = AutoModelForSequenceClassification.from_pretrained(roberta_checkpoint, num_labels=2)
RoBERTa 分类器的 LoRA 设置

我们为 RoBERTa 分类器设置 LoRA 参数:

  • TaskType: 序列分类

  • r(rank): 分解矩阵的秩

  • lora_alpha: 用于对习得权重进行缩放的 alpha 参数。LoRA 论文建议将 alpha 固定为 16

  • lora_dropout: LoRA 层的 Dropout 概率

  • bias: 是否向 LoRA 层添加偏置

以下代码使用了 LoRA 论文 的推荐设置。后文 我们还将用 wandb 对这些超参进行调优。

from peft import get_peft_model, LoraConfig, TaskType
roberta_peft_config = LoraConfig(
    task_type=TaskType.SEQ_CLS, r=2, lora_alpha=16, lora_dropout=0.1, bias="none",
)
roberta_model = get_peft_model(roberta_model, roberta_peft_config)
roberta_model.print_trainable_parameters()

可以看到,可训参数量仅占 RoBERTa 模型参数量的 0.64%:

trainable params: 2,299,908 || all params: 356,610,052 || trainable%: 0.6449363911929212

Mistral

为分类任务加载检查点

加载带有序列分类头的预训练 Mistral-7B 模型:

from transformers import AutoModelForSequenceClassification
import torch
mistral_model =  AutoModelForSequenceClassification.from_pretrained(
  pretrained_model_name_or_path=mistral_checkpoint,
  num_labels=2,
  device_map="auto"
)

设置填充词元 id,因为 Mistral 7B 没有默认填充词元。

mistral_model.config.pad_token_id = mistral_model.config.eos_token_id
Mistral 7B 分类器的 LoRA 设置

对 Mistral 7B 模型而言,我们需要指定 target_modules (我们将其指定为注意力模块的查询向量映射层和值向量映射层):

from peft import get_peft_model, LoraConfig, TaskType

mistral_peft_config = LoraConfig(
    task_type=TaskType.SEQ_CLS, r=2, lora_alpha=16, lora_dropout=0.1, bias="none",
    target_modules=[
        "q_proj",
        "v_proj",
    ],
)

mistral_model = get_peft_model(mistral_model, mistral_peft_config)
mistral_model.print_trainable_parameters()

可训参数量仅占 Mistral 模型参数量的 0.024%:

trainable params: 1,720,320 || all params: 7,112,380,416 || trainable%: 0.02418768259540745

Llama 2

为分类任务加载检查点

加载带有序列分类头的预训练 Llama 2 模型。

from transformers import AutoModelForSequenceClassification
import torch
llama_model =  AutoModelForSequenceClassification.from_pretrained(
  pretrained_model_name_or_path=llama_checkpoint,
  num_labels=2,
  device_map="auto",
  offload_folder="offload",
  trust_remote_code=True
)

设置填充词元 id,因为 Llama 2 没有默认填充词元。

llama_model.config.pad_token_id = llama_model.config.eos_token_id
Llama 2 分类器的 LoRA 设置

使用与 Mistral 相同的 LoRA 参数:

from peft import get_peft_model, LoraConfig, TaskType
llama_peft_config = LoraConfig(
    task_type=TaskType.SEQ_CLS, r=16, lora_alpha=16, lora_dropout=0.05, bias="none",
    target_modules=[
        "q_proj",
        "v_proj",
    ],
)

llama_model = get_peft_model(llama_model, llama_peft_config)
llama_model.print_trainable_parameters()

可训参数量仅占 Llama 2 模型参数量的 0.12%:

trainable params: 8,404,992 || all params: 6,615,748,608 || trainable%: 0.1270452143516515

至此,我们定义了用于训练的词元数据集及 LoRA 设置。下面,我们介绍如何使用 Hugging Face 的 Trainer 类启动训练。

设置 Trainer

评估指标

首先,我们定义用于对三个模型的性能进行比较的指标: F1 分数、召回率、精确度和准确度:

import evaluate
import numpy as np

def compute_metrics(eval_pred):
    # HF `evaluate` 包已支持我们所要的所有指标
    precision_metric = evaluate.load("precision")
    recall_metric = evaluate.load("recall")
    f1_metric= evaluate.load("f1")
    accuracy_metric = evaluate.load("accuracy")

    logits, labels = eval_pred
    # eval_pred 是模型返回的预测值和实际值元组
    predictions = np.argmax(logits, axis=-1)
    precision = precision_metric.compute(predictions=predictions, references=labels)["precision"]
    recall = recall_metric.compute(predictions=predictions, references=labels)["recall"]
    f1 = f1_metric.compute(predictions=predictions, references=labels)["f1"]
    accuracy = accuracy_metric.compute(predictions=predictions, references=labels)["accuracy"]

    # `Trainer` 要求将指标组织为一个字典,其键为指标名,值为分数。
    return {"precision": precision, "recall": recall, "f1-score": f1, 'accuracy': accuracy}

基于加权损失的自定义 Trainer

前文提到,数据集正负类分布并不平衡。因此,我们用加权交叉熵损失来训练模型以解决这个问题。Trainer 类本身的实现中不支持自定义损失,因为它期望直接从模型的输出中获取损失。

因此,我们需要定义一个自定义的 WeightedCELossTrainer ,以重写 compute_loss 方法,该方法可以根据模型的预测和标签计算加权交叉熵损失:

from transformers import Trainer

class WeightedCELossTrainer(Trainer):
    def compute_loss(self, model, inputs, return_outputs=False):
        labels = inputs.pop("labels")
        # Get model's predictions
        outputs = model(**inputs)
        logits = outputs.get("logits")
        # Compute custom loss
        loss_fct = torch.nn.CrossEntropyLoss(weight=torch.tensor([neg_weights, pos_weights], device=model.device, dtype=logits.dtype))
        loss = loss_fct(logits.view(-1, self.model.config.num_labels), labels.view(-1))
        return (loss, outputs) if return_outputs else loss

Trainer 设置

我们为三个模型分别设置训练超参及训练器。

RoBERTa

第一步,把模型搬到 GPU 设备上。

roberta_model = roberta_model.cuda()
roberta_model.device()

It will print the following:

device(type='cuda', index=0)

然后,设置训练超参:

from transformers import TrainingArguments

lr = 1e-4
batch_size = 8
num_epochs = 5

training_args = TrainingArguments(
    output_dir="roberta-large-lora-token-classification",
    learning_rate=lr,
    lr_scheduler_type= "constant",
    warmup_ratio= 0.1,
    max_grad_norm= 0.3,
    per_device_train_batch_size=batch_size,
    per_device_eval_batch_size=batch_size,
    num_train_epochs=num_epochs,
    weight_decay=0.001,
    evaluation_strategy="epoch",
    save_strategy="epoch",
    load_best_model_at_end=True,
    report_to="wandb",
    fp16=False,
    gradient_checkpointing=True,
)

最后,我们将模型、训练超参和词元数据集一起作为参数来实例化一个 RoBERTa 训练器:

roberta_trainer = WeightedCELossTrainer(
    model=roberta_model,
    args=training_args,
    train_dataset=roberta_tokenized_datasets['train'],
    eval_dataset=roberta_tokenized_datasets["val"],
    data_collator=roberta_data_collator,
    compute_metrics=compute_metrics
)
Mistral-7B

与 RoBERTa 类似,我们用如下代码初始化 WeightedCELossTrainer :

from transformers import TrainingArguments, Trainer

mistral_model = mistral_model.cuda()

lr = 1e-4
batch_size = 8
num_epochs = 5

training_args = TrainingArguments(
    output_dir="mistral-lora-token-classification",
    learning_rate=lr,
    lr_scheduler_type= "constant",
    warmup_ratio= 0.1,
    max_grad_norm= 0.3,
    per_device_train_batch_size=batch_size,
    per_device_eval_batch_size=batch_size,
    num_train_epochs=num_epochs,
    weight_decay=0.001,
    evaluation_strategy="epoch",
    save_strategy="epoch",
    load_best_model_at_end=True,
    report_to="wandb",
    fp16=True,
    gradient_checkpointing=True,
)

mistral_trainer = WeightedCELossTrainer(
    model=mistral_model,
    args=training_args,
    train_dataset=mistral_tokenized_datasets['train'],
    eval_dataset=mistral_tokenized_datasets["val"],
    data_collator=mistral_data_collator,
    compute_metrics=compute_metrics
)

注意,我们需要将 fp16 设为 True 以启用半精度训练。主要原因是 Mistral-7B 很大,如果使用 fp32 精度,其权重无法放进单块 GPU 的显存 (48GB) 中。

Llama 2

与 Mistral 7B 类似,我们用如下代码定义训练器:

from transformers import TrainingArguments, Trainer

llama_model = llama_model.cuda()

lr = 1e-4
batch_size = 8
num_epochs = 5
training_args = TrainingArguments(
    output_dir="llama-lora-token-classification",
    learning_rate=lr,
    lr_scheduler_type= "constant",
    warmup_ratio= 0.1,
    max_grad_norm= 0.3,
    per_device_train_batch_size=batch_size,
    per_device_eval_batch_size=batch_size,
    num_train_epochs=num_epochs,
    weight_decay=0.001,
    evaluation_strategy="epoch",
    save_strategy="epoch",
    load_best_model_at_end=True,
    report_to="wandb",
    fp16=True,
    gradient_checkpointing=True,
)

llama_trainer = WeightedCELossTrainer(
    model=llama_model,
    args=training_args,
    train_dataset=llama_tokenized_datasets['train'],
    eval_dataset=llama_tokenized_datasets["val"],
    data_collator=llama_data_collator,
    compute_metrics=compute_metrics
)

超参调优

我们用 Wandb Sweep API 通过贝叶斯搜索策略来进行超参调优 (30 次运行),待调优的超参搜索空间如下:

方法指标lora_alphalora_biaslora_dropoutlora_ranklrmax_length
bayes目标: maximize分布: categorical分布: categorical分布: uniform分布: categorical分布: uniform分布: categorical

目标名: eval/f1-score取值集合:
-16    
-32    
-64
取值集合: None-最大值: 0.1  
-最小值: 0
取值集合:      
-4  
-8    
-16    
-32
-最大值: 2e-04
-最小值: 1e-05
取值集合: 512

欲了解更多信息,可以查看 资源 一节中的 Wandb 实验报告。

结果

模型F1 分数训练时间内存消耗可训参数量
RoBERTa0.8077538 秒GPU1: 9.1 GB
GPU2: 8.3 GB
0.64%
Mistral 7B0.73642030 秒GPU1: 29.6 Gb
GPU2: 29.5 GB
0.024%
Llama 20.76382052 秒GPU1: 35 GB
GPU2: 33.9 GB
0.12%

总结

本文我们用 LoRA 对三个大语言模型 (LLM) (RoBERTa、Mistral 7B 及 Llama 2) 针对灾难推文分类任务进行微调。从性能结果来看,RoBERTa 的性能大幅优于 Mistral 7B 和 Llama 2。这就提出了一个问题: 我们是否真的需要一个大而复杂的 LLM 来完成诸如短序列二分类这样的简单任务?

一个重要的启示是,在选择要使用的 LLM 模型时应该考虑具体的项目要求、可用资源和性能需求。

此外,对于针对短序列的相对 简单 的预测任务,小的基础模型 (例如 RoBERTa) 仍然具有竞争力。

最后,我们还通过例子展示了 LoRA 方法的通用性,其既可应用于编码器 (RoBERTa) 模型,还可应用于解码器 (Llama 2 及 Mistral 7B) 模型。

资源

  1. 本文代码均已在该 Github 项目。

  2. 下面是各模型的 Wandb 超参调优实验报告:

  • RoBERTa

  • Mistral 7B

  • Llama 2

🤗 宝子们可以戳 阅读原文 查看文中所有的外部链接哟!


英文原文: https://hf.co/blog/Lora-for-sequence-classification-with-Roberta-Llama-Mistral

原文作者: Mehdi Iraqi

译者: Matrix Yao (姚伟峰),英特尔深度学习工程师,工作方向为 transformer-family 模型在各模态数据上的应用及大规模模型的训练推理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/262843.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于javaWeb的長安智慧医疗管理系统设计与实现论文

長安智慧医疗管理系统 摘 要&#xff1a;如今社会上各行各业&#xff0c;都在用属于自己专用的软件来进行工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。互联网的发展&#xff0c;离不开一些新的技术&#xff0c;而新技术的产生往往是为了解决…

Shell 脚本应用(三)

使用 for 循环语句 for语句的结构 使用for循环语句时&#xff0c;需要指定一个变量及可能的取值列表&#xff0c;针对每个不同的取值重复执行相同 的命令序列&#xff0c;直到变量值用完退出循环。在这里&#xff0c;“取值列表”称为for语句的执行条件&#xff0c;其中包括多…

makefile例子

1、目录结构 2、文件 2.1、 test.h extern void test(void); 2.2 、test.c #include <stdio.h>void test(void) {printf("Hello world!\n"); }2.3 、main.c #include "test.h"int main(void) {test();return 0; }2.4、makefile TEST_DIR : $(s…

ai学习笔记-入门

目录 一、人工智能是什么&#xff1f;可以做什么&#xff1f; 人工智能(Artificial Intelligence): 人工智能的技术发展路线&#xff1a; 产业发展驱动因素&#xff1a;数据、算力、算法 二、人工智能这个工具的使用原理入门 神经网络⭕数学基础 1.神经网络的生物表示 …

SpringMVC:执行原理详解、配置文件和注解开发实现 SpringMVC

文章目录 SpringMVC - 01一、概述二、SpringMVC 执行原理三、使用配置文件实现 SpringMVC四、使用注解开发实现 SpringMVC1. 步骤2. 实现 五、总结注意&#xff1a; SpringMVC - 01 一、概述 SpringMVC 官方文档&#xff1a;点此进入 有关 MVC 架构模式的内容见之前的笔记&a…

小红书kos和kop有什么区别,营销玩法有哪些

相信熟悉媒介传播的朋友&#xff0c;对于kol和koc都不陌生。但随着平台的发展和市场的进步&#xff0c;又出现了kos和kop。那么小红书kos和kop有什么区别&#xff0c;营销玩法有哪些&#xff1f; 一、什么是kos和kop KOS&#xff0c;全称叫做Key Opinion Sales&#xff0c;意思…

安装 PyCharm 2021.1 保姆级教程

作者&#xff1a;billy 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 前言 目前能下载到的最新版本是 PyCharm 2021.1。 请注意对应 Python 的版本&#xff1a; Python 2: 2.7Python 3: >3.6, <3.11…

APEX后台弱密码增强改造出现的问题及解决方法

为了加强APEX后台密码的安全性和可靠性&#xff0c;对其进行弱密码改造&#xff0c;通过改写登录函数&#xff0c;判断密码可靠性&#xff0c;在密码不符合条件&#xff08;密码长度必须大于8位小于16位&#xff0c;其包含数字、大小写字母与特殊符号&#xff09;时跳转到密码修…

网络基础篇【网线的制作,OSI七层模型,集线器和交换机的介绍,路由器的介绍与设置】

目录 一、网线制作 1.1 工具介绍 1.1.1网线 1.1.2 网线钳 1.1.3 水晶头 1.1.4 网线测试仪 二、OSI七层模型 2.1 简介 2.2 OSI模型层次介绍 2.2.1 结构图 2.2.2 数据传输过程 2.3 相关网站 二、集线器 2.1 介绍 2.2 适用场景 三、交换机 3.1 介绍 3.2 适用场景…

Linux(二)常用命令

文章目录 一、文件管理命令1.1 chmod1.2 chown1.3 cat1.4 cp1.5 find1.6 head1.7 tail1.8 less1.9 more1.10 mv1.11 rm1.12 touch1.13 vim1.14 >和>>1.15 scp1.16 ln1.17 怎么用命令查看日志 二、文档管理命令2.1 grep2.2 wc2.3 echo 三、磁盘管理命令3.1 cd3.2 df3.3…

JMeter常见配置及常见问题修改

一、设置JMeter默认打开字体 1、进入安装目录&#xff1a;apache-jmeter-x.x.x\bin\ 2、找到 jmeter.properties&#xff0c;打开。 3、搜索“ languageen ”&#xff0c;前面带有“#”号.。 4、去除“#”号&#xff0c;并修改为&#xff1a;languagezh_CN 或 直接新增一行&…

MySQL增删改查(查询)

White graces&#xff1a;个人主页 &#x1f649;专栏推荐:Java入门知识&#x1f649; &#x1f649; 内容推荐:《MySQL增删改查(增加)》&#x1f649; &#x1f439;今日诗词:八百虎贲踏江去,十万吴兵丧胆还&#x1f439; ⛳️点赞 ☀️收藏⭐️关注&#x1f4ac;卑微小博主…

网络技术基础与计算思维实验教程_4.1_PSTN和以太网互连实验

实验内容 实验目的 实验原理 关键命令说明 实验步骤 构建以太网 工作区中放置路由器 交换机 PC机 直通线互连PC0和交换机 交换机和路由器 构建PSTN 放置PSTN 放置PC 为路由器安装modem 打开电源 再为终端安装modem 单击路由器选择图形配置 这个IP地址将成为PC0的默认网关地…

时间序列分析

常用数据集 2.monash数据集 官网链接 我们的存储库包含30个数据集&#xff0c;包括公开可用的时间序列数据集(不同格式)和由我们管理的数据集。 DatasetDomainNo: of SeriesMin. LengthMax. LengthCompetitionMultivariateDownloadSourceM1Multiple100115150YesNoYearly Quart…

配置MUX VLAN示例(接入层设备)

一、组网需求 在企业网络中&#xff0c;企业所有员工都可以访问企业的服务器。但对于企业来说&#xff0c;希望企业内部部分员工之间可以互相交流&#xff0c;而部分员工之间是隔离的&#xff0c;不能够互相访问。为了解决上述问题&#xff0c;可在连接终端的交换机上部署MUX …

keil 5 : Error: L6218E: Undefined symbol 问题解决方法小记

1.路径已添加但依旧包找不到定义的错误,这里找不到的是DFP包中的函数 2.点击Manage Run-Time Environment->打开Device->ATC Driver->勾选SPI&#xff08;找到你未定义函数所在的DFP包中的模块&#xff09; 3.编译后&#xff0c;点击Open definition会成功跳转到函数…

ansible的脚本------playbook剧本

playbook组成部分&#xff1a; 1.task 任务&#xff1a;包含要在目标主机上执行的操作&#xff0c;使用模块定义这些操作。每个都是一个模块的调用。2.variables 变量&#xff1a;存储和传递数据。变量可以自定义&#xff0c;可以在playbook当中定义为全局变量&#xff0c;也可…

用C爬取人人文库并分析实现免积分下载资料

最近有个学妹学习遇到问题&#xff0c;想要的学习资料都在文库中&#xff0c;因为资料太多太杂&#xff0c;想要一篇篇找太难了&#xff0c;主要是太浪费精力了。因此&#xff0c;听说这个事情我能解决&#xff0c;立马找到我&#xff0c;给我一杯奶茶就把我收买了&#xff0c;…

4. 可用性

文章目录 4. 第4章 可用性4.1. 可用性一般场景4.2. 可用性策略故障检测&#xff08;Detect Faults&#xff09;故障恢复&#xff08;Recover from Faults &#xff09;故障预防&#xff08;Prevent Faults&#xff09; 4.3. 基于策略的可用性调查表4.4. 可用性模式4.5. 扩展阅读…

云渲染Blender怎么用 Blender云渲染设置教程

作为一个免费且开源的三维创作套件&#xff0c;Blender为独立艺术家和小规模的创意团队提供了一个功能丰富的平台&#xff0c;涵盖了从建模、雕刻到动力学模拟、动画和高级渲染的全套工作流程。随着其支持的特效和视觉质量的不断提升&#xff0c;Blender项目的渲染耗时也显著增…