mirror of
https://github.com/wassname/peft.git
synced 2026-09-24 13:40:15 +08:00
17 KiB
17 KiB
In [1]:
from transformers import AutoModelForSeq2SeqLM
from pet import get_pet_config,get_pet_model, get_pet_model_state_dict
import torch
from datasets import load_dataset
import os
os.environ["TOKENIZERS_PARALLELISM"] = "false"
os.environ["CUDA_VISIBLE_DEVICES"] = "3"
from transformers import AutoTokenizer
from torch.utils.data import DataLoader
from transformers import default_data_collator,get_linear_schedule_with_warmup
from tqdm import tqdm
from datasets import load_dataset
device = "cuda"
model_name_or_path = "t5-large"
tokenizer_name_or_path = "t5-large"
config = {
"pet_type":"PREFIX_TUNING",
"task_type":"SEQ_2_SEQ_LM",
"num_virtual_tokens": 20
}
checkpoint_name = "financial_sentiment_analysis_prefix_tuning_v1.pt"
text_column = "sentence"
label_column = "text_label"
max_length=128
lr = 1e-2
num_epochs = 5
batch_size=8
In [ ]:
# creating model
pet_config = get_pet_config(config)
model = AutoModelForSeq2SeqLM.from_pretrained(model_name_or_path)
model = get_pet_model(model, pet_config)
model.print_trainable_parameters()
modelIn [3]:
# loading dataset
dataset = load_dataset("financial_phrasebank", 'sentences_allagree')
dataset = dataset["train"].train_test_split(test_size=0.1)
dataset["validation"] = dataset["test"]
del(dataset["test"])
classes = dataset["train"].features["label"].names
dataset = dataset.map(
lambda x: {"text_label": [classes[label] for label in x["label"]]},
batched=True,
num_proc=1,
)
dataset["train"][0]Out [3]:
/home/sourab/miniconda3/envs/ml/lib/python3.10/site-packages/huggingface_hub/utils/_deprecation.py:97: FutureWarning: Deprecated argument(s) used in 'dataset_info': token. Will not be supported from version '0.12'. warnings.warn(message, FutureWarning) Found cached dataset financial_phrasebank (/home/sourab/.cache/huggingface/datasets/financial_phrasebank/sentences_allagree/1.0.0/550bde12e6c30e2674da973a55f57edde5181d53f5a5a34c1531c53f93b7e141)
0%| | 0/1 [00:00<?, ?it/s]
0%| | 0/3 [00:00<?, ?ba/s]
0%| | 0/1 [00:00<?, ?ba/s]
{'sentence': 'ADPnews - Feb 5 , 2010 - Finnish real estate investor Sponda Oyj HEL : SDA1V said today that it slipped to a net loss of EUR 81.5 million USD 11.8 m in 2009 from a profit of EUR 29.3 million in 2008 .',
'label': 0,
'text_label': 'negative'}In [4]:
# data preprocessing
tokenizer = AutoTokenizer.from_pretrained(model_name_or_path)
def preprocess_function(examples):
inputs = examples[text_column]
targets = examples[label_column]
model_inputs = tokenizer(inputs, max_length=max_length, padding="max_length", truncation=True, return_tensors="pt")
labels = tokenizer(targets, max_length=2, padding="max_length", truncation=True, return_tensors="pt")
labels = labels["input_ids"]
labels[labels==tokenizer.pad_token_id] = -100
model_inputs["labels"] = labels
return model_inputs
processed_datasets = dataset.map(
preprocess_function,
batched=True,
num_proc=1,
remove_columns=dataset["train"].column_names,
load_from_cache_file=False,
desc="Running tokenizer on dataset",
)
train_dataset = processed_datasets["train"]
eval_dataset = processed_datasets["validation"]
train_dataloader = DataLoader(
train_dataset, shuffle=True, collate_fn=default_data_collator, batch_size=batch_size, pin_memory=True
)
eval_dataloader = DataLoader(eval_dataset, collate_fn=default_data_collator, batch_size=batch_size, pin_memory=True)
Downloading: 0%| | 0.00/792k [00:00<?, ?B/s]
Downloading: 0%| | 0.00/1.39M [00:00<?, ?B/s]
/home/sourab/transformers/src/transformers/models/t5/tokenization_t5_fast.py:156: FutureWarning: This tokenizer was incorrectly instantiated with a model max length of 512 which will be corrected in Transformers v5. For now, this behavior is kept to avoid breaking backwards compatibility when padding/encoding with `truncation is True`. - Be aware that you SHOULD NOT rely on t5-large automatically truncating your input to 512 when padding/encoding. - If you want to encode/pad to sequences longer than 512 you can either instantiate this tokenizer with `model_max_length` or pass `max_length` when encoding/padding. - To avoid this warning, please instantiate this tokenizer with `model_max_length` set to your preferred value. warnings.warn(
Running tokenizer on dataset: 0%| | 0/3 [00:00<?, ?ba/s]
Running tokenizer on dataset: 0%| | 0/1 [00:00<?, ?ba/s]
In [5]:
# optimizer and lr scheduler
optimizer = torch.optim.AdamW(model.parameters(), lr=lr)
lr_scheduler = get_linear_schedule_with_warmup(
optimizer=optimizer,
num_warmup_steps=0,
num_training_steps=(len(train_dataloader) * num_epochs),
)
In [6]:
# training and evaluation
model = model.to(device)
for epoch in range(num_epochs):
model.train()
total_loss = 0
for step, batch in enumerate(tqdm(train_dataloader)):
batch = {k: v.to(device) for k, v in batch.items()}
outputs = model(**batch)
loss = outputs.loss
total_loss += loss.detach().float()
loss.backward()
optimizer.step()
lr_scheduler.step()
optimizer.zero_grad()
model.eval()
eval_loss = 0
eval_preds = []
for step, batch in enumerate(tqdm(eval_dataloader)):
batch = {k: v.to(device) for k, v in batch.items()}
with torch.no_grad():
outputs = model(**batch)
loss = outputs.loss
eval_loss += loss.detach().float()
eval_preds.extend(tokenizer.batch_decode(torch.argmax(outputs.logits, -1).detach().cpu().numpy(), skip_special_tokens=True))
eval_epoch_loss = eval_loss/len(train_dataloader)
eval_ppl = torch.exp(eval_epoch_loss)
train_epoch_loss = total_loss/len(eval_dataloader)
train_ppl = torch.exp(train_epoch_loss)
print(f"{epoch=}: {train_ppl=} {train_epoch_loss=} {eval_ppl=} {eval_epoch_loss=}")
100%|█████████████████████████████████████████████████████████████| 255/255 [00:20<00:00, 12.27it/s] 100%|███████████████████████████████████████████████████████████████| 29/29 [00:01<00:00, 17.32it/s]
epoch=0: train_ppl=tensor(2697769., device='cuda:0') train_epoch_loss=tensor(14.8079, device='cuda:0') eval_ppl=tensor(1.0089, device='cuda:0') eval_epoch_loss=tensor(0.0089, device='cuda:0')
100%|█████████████████████████████████████████████████████████████| 255/255 [00:19<00:00, 12.75it/s] 100%|███████████████████████████████████████████████████████████████| 29/29 [00:01<00:00, 17.33it/s]
epoch=1: train_ppl=tensor(2.9475, device='cuda:0') train_epoch_loss=tensor(1.0809, device='cuda:0') eval_ppl=tensor(1.0072, device='cuda:0') eval_epoch_loss=tensor(0.0072, device='cuda:0')
100%|█████████████████████████████████████████████████████████████| 255/255 [00:20<00:00, 12.71it/s] 100%|███████████████████████████████████████████████████████████████| 29/29 [00:01<00:00, 17.31it/s]
epoch=2: train_ppl=tensor(2.0588, device='cuda:0') train_epoch_loss=tensor(0.7221, device='cuda:0') eval_ppl=tensor(1.0055, device='cuda:0') eval_epoch_loss=tensor(0.0054, device='cuda:0')
100%|█████████████████████████████████████████████████████████████| 255/255 [00:20<00:00, 12.70it/s] 100%|███████████████████████████████████████████████████████████████| 29/29 [00:01<00:00, 17.32it/s]
epoch=3: train_ppl=tensor(1.7939, device='cuda:0') train_epoch_loss=tensor(0.5844, device='cuda:0') eval_ppl=tensor(1.0063, device='cuda:0') eval_epoch_loss=tensor(0.0063, device='cuda:0')
100%|█████████████████████████████████████████████████████████████| 255/255 [00:19<00:00, 13.01it/s] 100%|███████████████████████████████████████████████████████████████| 29/29 [00:01<00:00, 17.33it/s]
epoch=4: train_ppl=tensor(1.7740, device='cuda:0') train_epoch_loss=tensor(0.5732, device='cuda:0') eval_ppl=tensor(1.0062, device='cuda:0') eval_epoch_loss=tensor(0.0061, device='cuda:0')
In [7]:
# print accuracy
correct =0
total = 0
for pred,true in zip(eval_preds, dataset["validation"]["text_label"]):
if pred.strip()==true.strip():
correct+=1
total+=1
accuracy = correct/total*100
print(f"{accuracy=} % on the evaluation dataset")
print(f"{eval_preds[:10]=}")
print(f"{dataset['validation']['text_label'][:10]=}")accuracy=96.47577092511013 % on the evaluation dataset eval_preds[:10]=['neutral', 'neutral', 'neutral', 'negative', 'neutral', 'neutral', 'neutral', 'neutral', 'positive', 'positive'] dataset['validation']['text_label'][:10]=['neutral', 'neutral', 'neutral', 'negative', 'neutral', 'neutral', 'neutral', 'neutral', 'positive', 'positive']
In [8]:
# saving model
state_dict = get_pet_model_state_dict(model)
torch.save(state_dict, checkpoint_name)
print(state_dict){'prompt_embeddings': tensor([[-0.3165, -0.8389, 0.3262, ..., -1.5049, -1.6963, 0.3444],
[-1.8359, 1.1936, 1.0483, ..., 0.6197, -0.4452, 0.5844],
[-0.6027, 0.3246, -1.5601, ..., -0.3645, 0.2329, 0.3402],
...,
[-1.9525, -0.5035, 0.8474, ..., 0.4793, -0.0789, -0.9305],
[-1.9741, 0.5242, -2.0594, ..., -0.7970, -0.4889, 2.7323],
[ 0.9355, -0.2714, 0.4610, ..., 0.2692, -1.5801, -1.6405]])}
In [9]:
!du -h $checkpoint_name3,8M financial_sentiment_analysis_prefix_tuning_v1.pt
In [ ]: