Сравнение производительности LLM-моделей глубокий анализ Roberta, Llama 2 и Mistral для анализа твитов о бедствиях с помощью Lora
Сравнение эффективности LLM-моделей Roberta, Llama 2 и Mistral для анализа твитов о бедствиях, используя Lora
- Сравнение производительности LLM: погружение в Роберту, Лама 2 и Мистраль для анализа через LoRA
Введение
В быстром мире обработки естественного языка (NLP) мы часто оказываемся в ситуации сравнения различных языковых моделей, чтобы определить, какая из них лучше всего подходит для конкретных задач. В этом блоге мы сравниваем три модели: RoBERTa, Mistral-7b и Llama-2-7b. Мы использовали их для решения общей проблемы – классификации твитов о бедствиях. Важно отметить, что модели Mistral и Llama 2 являются большими моделями с 7 миллиардами параметров. В отличие от них, RoBERTa-large (355 миллионов параметров) является относительно меньшей моделью, используемой в качестве базового уровня для исследовательского сравнительного анализа.
В этом блоге мы использовали технику PEFT (Parameter-Efficient Fine-Tuning): LoRA (Low-Rank Adaptation of Large Language Models) для настройки предварительно обученной модели на задачу классификации последовательностей. LoRA разработана для значительного снижения количества обучаемых параметров при сохранении высокой производительности на задачах последующего использования.
Основная цель этого блога – реализовать настройку метода LoRA fine-tuning для задач классификации последовательностей, используя три предварительно обученные модели от Hugging Face: meta-llama/Llama-2-7b-hf, mistralai/Mistral-7B-v0.1 и roberta-large.
Используемое оборудование
- Количество узлов: 1
- Количество графических процессоров на узел: 1
- Тип графического процессора: A6000
- Объем памяти графического процессора: 48 ГБ
Цели
- Реализовать настройку предварительно обученных LLM с использованием методов LoRA PEFT.
- Научиться использовать API HuggingFace (transformers, peft и datasets).
- Настроить настройку гиперпараметров и журналирование экспериментов с использованием Weights & Biases.
Зависимости
datasetsevaluatepeftscikit-learntorchtransformerswandb
Примечание: Для воспроизведения отчетных результатов, пожалуйста, проверьте закрепленные версии в отчетах wandb.
- GPT-4 против Zephyr-7b-beta Который следует использовать?
- Разгадывая аномалии во временных рядах 1/4
- Цифровой художник Стивен Танг демонстрирует современный стиль ‘In the NVIDIA Studio’ на этой неделе
Предварительно обученные модели
RoBERTa
RoBERTa (Robustly Optimized BERT Approach) – это усовершенствованная вариант модели BERT, предложенная исследовательской группой Meta AI. BERT является моделью на основе трансформера с использованием механизмов само-внимания для контекстныx представлений слов и обучена с использованием задачи маскированной языковой модели. Обратите внимание, что BERT – это только модель-кодировщик, используемая для задач понимания естественного языка (таких как классификация последовательностей и классификация токенов).
RoBERTa – популярная модель для настройки и подходящая в качестве базового уровня для наших экспериментов. Для получения дополнительной информации вы можете проверить модель Hugging Face карты.
Llama 2
Модели Llama 2, что означает Large Language Model Meta AI, принадлежат к семье больших языковых моделей (LLMs), представленных Meta AI. Модели Llama 2 имеют различный размер, с количеством параметров от 7 миллиардов до 65 миллиардов.
“`html
Llama 2 – это авторегрессионная языковая модель, основанная на архитектуре декодера трансформера. Для генерации текста Llama 2 обрабатывает последовательность слов в качестве входных данных и последовательно предсказывает следующий символ с помощью скользящего окна. Архитектура Llama 2 немного отличается от моделей, таких как GPT-3. Например, Llama 2 использует функцию активации SwiGLU вместо ReLU и предпочитает вращающиеся позиционные эмбеддинги вместо абсолютных позиционных эмбеддингов, которые можно обучать.
Недавно выпущенная модель Llama 2 внесла некоторые улучшения в архитектуру для более эффективной работы с очень длинными последовательностями, увеличивая длину контекста до 4096 токенов и используя группированное внимание при декодировании (GQA).
Mistral 7B
Mistral 7B v0.1 с 7,3 миллиардами параметров – первая модель LLM, представленная компанией Mistral AI. Основные новые техники, используемые в архитектуре Mistral 7B, включают:
- Внимание со скользящим окном: замена полного внимания (с квадратной вычислительной сложностью) на внимание со скользящим окном, где каждый токен может обращаться не более чем к 4096 токенам предыдущего слоя (с линейной вычислительной сложностью). Этот механизм позволяет Mistral 7B обрабатывать более длинные последовательности, где более высокие слои могут иметь доступ к исторической информации за пределами размера окна из 4096 токенов.
- Группированное внимание к запросу: используется также в модели Llama 2, эта техника оптимизирует процесс вывода (сокращает время обработки), кэшируя векторы ключей и значений для ранее расшифрованных токенов в последовательности.
LoRA
PEFT, Parameter Efficient Fine-Tuning, это набор техник (p-tuning, prefix-tuning, IA3, Adapters и LoRA), разработанных для точной настройки больших моделей с помощью гораздо меньшего набора обучаемых параметров, сохраняя при этом уровень производительности, обычно достигаемый полной настройкой.
LoRA, Low-Rank Adaptation, это метод PEFT, который подобен слоям адаптеров. Его основная цель – сократить количество обучаемых параметров модели. Операция LoRA заключается в обучении матрицы обновлений низкого ранга при замороженных предобученных весах.
Настройка
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)
# Переименование стандартного раздела "test" в "validation"
data['val'] = data.pop("test")
# Преобразование тестового набора данных в формат HuggingFace dataset и добавление его в первый набор данных
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 pddata['train'].to_pandas().info()data['test'].to_pandas().info()
- Набор данных для обучения
RangeIndex: 7613 записей, с 0 по 7612Data 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 записей, с 0 по 3262Data 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
Распределение целевой переменной в наборе данных для обучения
target0 43421 3271Name: 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()
Максимальное количество символов составляет 152.Максимальное количество слов составляет 31.
Обработка данных
Давайте рассмотрим пример одной строки обучающих данных:
data['train'][0]
{'id': 5285, 'keyword': 'fear', 'location': 'Thibodaux, LA', 'text': 'my worst fear. https://t.co/iH8UDz8mq3', 'target': 0}
Данные включают ключевое слово, местоположение и текст твита. В целях простоты мы выбираем признак text
как единственный вход для LLM.
На этом этапе мы подготовили наборы данных для обучения, валидации и тестирования в формате HuggingFace, ожидаемом предобученными LLM. Следующим шагом является определение токенизированного набора данных для обучения с использованием соответствующего токенизатора для преобразования признака text
в два тензора последовательности идентификаторов токенов и масок внимания. Поскольку каждая модель имеет свой собственный токенизатор, нам потребуется определить три разных набора данных.
Начнем с определения загрузчика данных для RoBERTa:
- Загрузить токенизатор:
from transformers import AutoTokenizerroberta_tokenizer = AutoTokenizer.from_pretrained(roberta_checkpoint, add_prefix_space=True)
Примечание: Токенизатор RoBERTa был обучен таким образом, чтобы он рассматривал пробелы как часть токена. В результате первое слово предложения кодируется по-разному, если оно не предшествует пробелу. Чтобы обеспечить наличие пробела в первом слове, мы устанавливаем add_prefix_space=True
. Кроме того, чтобы сохранить последовательную предобработку для всех трех моделей, мы устанавливаем параметр ‘True’ для Llama 2 и Mistral 7b.
- Определите функцию предобработки для преобразования одной строки в dataframe:
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)# Переименовать целевую переменную в 'label' согласно стандартам HugginFace
roberta_tokenized_datasets = roberta_tokenized_datasets.rename_column("target", "label")# Установить формат torch
roberta_tokenized_datasets.set_format("torch")
Примечание: мы удалили ненужные столбцы из наших данных: id, keyword, location и text. Мы удалили текст, потому что мы уже преобразовали его в идентификаторы входа и маску внимания:
Мы можем взглянуть на наш токенизированный обучающий набор данных:
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])}
- Для формирования обучающих пакетов нам также необходимо заполнить строки данной партии до максимальной длины, найденной в этой партии. Для этого мы будем использовать класс
DataCollatorWithPadding
:
# Коллатор данных для заполнения пакета примеров до максимальной длины внутри пакета
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")# Data collator for padding a batch of examples to the maximum length seen in the batchmistral_data_collator = DataCollatorWithPadding(tokenizer=mistral_tokenizer)
- Llama 2:
# Загрузка Llama 2 Tokenizerfrom transformers import AutoTokenizer, DataCollatorWithPaddingllama_tokenizer = AutoTokenizer.from_pretrained(llama_checkpoint, add_prefix_space=True)llama_tokenizer.pad_token_id = llama_tokenizer.eos_token_idllama_tokenizer.pad_token = llama_tokenizer.eos_tokendef 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 для задачи классификации
Мы загружаем предварительно обученную модель RoBERTa с головой классификации последовательностей с использованием класса Hugging Face AutoModelForSequenceClassification
:
from transformers import AutoModelForSequenceClassification roberta_model = AutoModelForSequenceClassification.from_pretrained(roberta_checkpoint, num_labels=2)
Настройка LoRA для классификатора RoBERTa
Мы импортируем конфигурацию LoRa и устанавливаем некоторые параметры для классификатора RoBERTa:
- Тип задачи: Классификация последовательностей
- r(rank): Ранк для наших матриц разложения
- lora_alpha: Параметр Alpha для масштабирования изучаемых весов. Статья LoRA рекомендует установить alpha равным 16
- lora_dropout: Вероятность отключения слоев LoRA
- bias: Добавлять ли смещение к слоям LoRA
Ниже приведен код, использующий значения, рекомендованные в статье о LoRa. В следующем разделе мы будем настраивать гиперпараметры этих параметров при помощи wandb
.
from peft import get_peft_model, LoraConfig, TaskTyperoberta_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()
Мы можем видеть, что количество обучаемых параметров составляет всего 0,64% от параметров модели RoBERTa:
trainable params: 2,299,908 || all params: 356,610,052 || trainable%: 0.6449363911929212
Mistral
Загрузка чекпоинтов для модели классификации Mistral-7B
Давайте загрузим предварительно обученную модель Mistral-7B с головой классификации последовательностей:
from transformers import AutoModelForSequenceClassificationimport torchmistral_model = AutoModelForSequenceClassification.from_pretrained( pretrained_model_name_or_path=mistral_checkpoint, num_labels=2, device_map="auto")
Для Mistral 7B нам нужно добавить идентификатор заполнения, так как он не определен по умолчанию.
mistral_model.config.pad_token_id = mistral_model.config.eos_token_id
Настройка LoRA для классификатора Mistral 7B
Для модели 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()
Количество обучаемых параметров представляет всего 0,024% от параметров модели Mistral:
trainable params: 1,720,320 || all params: 7,112,380,416 || trainable%: 0.02418768259540745
Лама 2
Загрузка чекпоинтов для режима классификации
Давайте загрузим предварительно обученную модель Лама 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
)
Для Лама 2 нам нужно добавить идентификатор заполнения как он не определен по умолчанию.
llama_model.config.pad_token_id = llama_model.config.eos_token_id
Подготовка LoRa для классификатора Лама 2
Мы определяем LoRa для Лама 2 с теми же параметрами, что и для Mistral:
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()
Количество обучаемых параметров представляет всего 0,12% от параметров модели Лама 2:
trainable params: 8,404,992 || all params: 6,615,748,608 || trainable%: 0.1270452143516515
На этом этапе мы определили токенизированный набор данных для обучения, а также настройки LLMs с использованием слоев LoRa. В следующем разделе будет рассмотрено, как осуществить обучение с использованием класса Trainer
из HuggingFace.
Настройка тренера
Метрики оценки
Сначала мы определяем метрики производительности, которые будем использовать для сравнения трех моделей: F1-оценка, полнота, точность и точность:
import evaluate
import numpy as np
def compute_metrics(eval_pred):
# Все метрики уже определены в пакете evaluate от HF
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"]
# Тренер ожидает словарь, в котором ключи - названия метрик, а значения - оценки.
return {"precision": precision, "recall": recall, "f1-score": f1, 'accuracy': accuracy}
Пользовательский тренер для взвешенной потери
Как уже упоминалось в начале статьи, у нас несбалансированное распределение между положительными и отрицательными классами. Нам нужно обучать наши модели с использованием взвешенной кросс-энтропийной потери для учета этого. Класс Trainer
не поддерживает предоставление пользовательской потери, так как ожидается, что потеря будет получена непосредственно из выходов модели.
Итак, нам нужно определить нашу собственную WeightedCELossTrainer
, переопределив метод compute_loss
, чтобы вычислить взвешенную кросс-энтропийную потерю на основе предсказаний модели и входных меток:
from transformers import Trainerclass WeightedCELossTrainer(Trainer): def compute_loss(self, model, inputs, return_outputs=False): labels = inputs.pop("labels") # Получить предсказания модели outputs = model(**inputs) logits = outputs.get("logits") # Вычислить пользовательскую потерю 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
Настройка тренера
Давайте установим параметры обучения и тренера для трех моделей.
RoBERTa
Первый важный шаг – переместить модели на устройство GPU для обучения.
roberta_model = roberta_model.cuda()roberta_model.device()
Это выведет следующее:
device(type='cuda', index=0)
Затем устанавливаем параметры обучения:
from transformers import TrainingArgumentslr = 1e-4batch_size = 8num_epochs = 5training_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=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)
Mistral-7B
Аналогично RoBERTa, мы инициализируем WeightedCELossTrainer
следующим образом:
from transformers import TrainingArguments, Trainermistral_model = mistral_model.cuda()lr = 1e-4batch_size = 8num_epochs = 5training_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 большая, и ее веса не могут поместиться в память одного GPU (48 ГБ) с полной точностью float32.
Llama 2
Аналогично Mistral 7B, мы определяем тренера следующим образом:
from transformers import TrainingArguments, Trainerllama_model = llama_model.cuda()lr = 1e-4batch_size = 8num_epochs = 5training_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)
Настройка гиперпараметров
Мы использовали API Wandb Sweep для запуска настройки гиперпараметров с использованием стратегии Байесовского поиска (30 запусков). Настроенные гиперпараметры следующие.
Дополнительную информацию можно найти в отчете эксперимента Wandb в разделе resources sections.
Результаты
Заключение
В этом блоге мы сравнили производительность трех больших языковых моделей (LLM) – RoBERTa, Mistral 7b и Llama 2 – для классификации твитов о бедствии с использованием LoRa. Из результатов производительности видно, что RoBERTa превосходит Mistral 7B и Llama 2 с большим отрывом. Это возникает вопрос о том, действительно ли нам нужна сложная и большая LLM для задач такого рода, как бинарная классификация коротких последовательностей?
Одно из основных уроков, которые мы можем извлечь из этого исследования, заключается в том, что нужно учитывать специфические требования проекта, доступные ресурсы и потребности в производительности при выборе модели LLM.
Кроме того, для относительно простых задач предсказания с короткими последовательностями базовые модели, такие как RoBERTa, остаются конкурентоспособными.
Наконец, мы показываем, что метод LoRa можно применять как к моделям кодировщика (RoBERTa), так и к моделям декодировщика (Llama 2 и Mistral 7B).
Ресурсы
-
Кодовый скрипт можно найти в следующем Github проекте.
-
Вы можете проверить результаты поиска гиперпараметров в отчетах Weight&Bias: