What could be causing the poor metric results:
```
# Install Required Libraries
!pip install --upgrade transformers
!pip install datasets
!pip install evaluate
!pip install sacrebleu
!pip install bert_score

# Import Libraries
import evaluate
import torch
import random
import numpy as np
from transformers import (
    T5Tokenizer,
    T5ForConditionalGeneration,
    Seq2SeqTrainer,
    Seq2SeqTrainingArguments,
    DataCollatorForSeq2Seq
)
from datasets import load_dataset, concatenate_datasets
from bert_score import score as bert_score_func

# Set Seed for Reproducibility
def set_seed(seed):
    random.seed(seed)
    np.random.seed(seed)
    torch.manual_seed(seed)
    if torch.cuda.is_available():
        torch.cuda.manual_seed_all(seed)

set_seed(42)

# Load and Prepare the Dataset
dataset1 = load_dataset("danielv835/personal_finance_v0.2")

# Remove the 'rejected' column from dataset1
dataset1 = dataset1.remove_columns(['rejected'])

# Check Available Splits
print(dataset1)

# Load the tokenizer
tokenizer = T5Tokenizer.from_pretrained("google/flan-t5-base")

# Tokenization function with dynamic padding handled by data collator
def tokenize_function(examples):
    inputs = tokenizer(
        examples["context"],
        max_length=512,
        truncation=True,
        padding=False  # Disable padding here
    )
    labels = tokenizer(
        examples["chosen"],
        max_length=512,
        truncation=True,
        padding=False  # Disable padding here
    )
    inputs["labels"] = labels["input_ids"]
    return inputs

# Tokenize dataset1
tokenized_datasets1 = dataset1.map(
    tokenize_function,
    batched=True,
    batch_size=1000  # Adjust as needed
)

# Load the pre-trained FLAN-T5 model for conditional generation
tw_model = T5ForConditionalGeneration.from_pretrained("google/flan-t5-base")

# Define the data collator
data_collator = DataCollatorForSeq2Seq(
  tokenizer=tokenizer,
  model=tw_model,
  padding="longest",
  return_tensors="pt"
)

# Ensure the pad_token_id is set
if tw_model.config.pad_token_id is None:
    tw_model.config.pad_token_id = tokenizer.pad_token_id

# Define training arguments for the Trainer API
training_args = Seq2SeqTrainingArguments(
    output_dir="./trainer_wheel_model",    # Output directory for saving model checkpoints
    eval_strategy="epoch",                 # Evaluate at the end of every epoch
    learning_rate=3e-5,                    # Set model learning rate
    per_device_train_batch_size=2,         # Adjust batch size for your GPU/CPU
    per_device_eval_batch_size=1,
    gradient_accumulation_steps=2,         # Use gradient accumulation
    save_steps=500,                        # Save model every 500 steps
    save_total_limit=2,                    # Limit number of saved checkpoints
    logging_dir='./logs',                  # Directory for storing logs
    logging_steps=200,                     # Log every 200 steps
    num_train_epochs=1,                    # Number of training epochs
    fp16=False,                             # Disable mixed precision
    predict_with_generate=True,            # Generate predictions during evaluation
    generation_max_length=150,             # Maximum length of generated sequences
    generation_num_beams=5,                # Number of beams for beam search
)

# Load additional metrics from Hugging Face Evaluate library
sacrebleu_metric = evaluate.load("sacrebleu")
bertscore_metric = evaluate.load("bertscore")

# Define Exact Match (Custom Implementation)
def exact_match_score(preds, labels):
    return sum([int(p.strip() == l.strip()) for p, l in zip(preds, labels)]) / len(labels)

# Define F1 Score (Custom Implementation)
def f1_score_custom(preds, labels):
    f1_total = 0
    for p, l in zip(preds, labels):
        p_tokens = p.split()
        l_tokens = l.split()
        common = set(p_tokens) & set(l_tokens)
        if not common:
            f1_total += 0
        else:
            precision = len(common) / len(p_tokens)
            recall = len(common) / len(l_tokens)
            f1_total += 2 * precision * recall / (precision + recall)
    return f1_total / len(preds)

# Define the compute_metrics function
def compute_metrics(eval_pred):
    preds, labels = eval_pred

    # If logits are returned as a tuple, extract the first element
    if isinstance(preds, tuple):
        preds = preds[0]

    # Replace -100 in preds and the labels as we can't decode them
    preds = np.where(preds != -100, preds, tokenizer.pad_token_id)
    labels = np.where(labels != -100, labels, tokenizer.pad_token_id)

    # Decode the predicted tokens into text
    decoded_preds = tokenizer.batch_decode(preds, skip_special_tokens=True)
    decoded_labels = tokenizer.batch_decode(labels, skip_special_tokens=True)

    # Some simple post-processing
    decoded_preds = [pred.strip() for pred in decoded_preds]
    decoded_labels = [[label.strip()] for label in decoded_labels]  # SacreBLEU expects a list of references

    # Compute BLEU score using SacreBLEU metric
    bleu_result = sacrebleu_metric.compute(predictions=decoded_preds, references=decoded_labels)
    bleu_score = bleu_result["score"]

    # Flatten the decoded_labels for F1 and Exact Match computation
    flattened_labels = [label[0] for label in decoded_labels]

    # Compute Exact Match (EM) score
    em_score = exact_match_score(decoded_preds, flattened_labels)

    # Compute F1 Score
    f1_score = f1_score_custom(decoded_preds, flattened_labels)

    # Compute BERTScore (using pre-trained BERT embeddings)
    P, R, F1_bert = bert_score_func(decoded_preds, flattened_labels, lang="en", rescale_with_baseline=True)
    bert_f1_score = F1_bert.mean().item()  # Get the mean of the F1 BERTScore

    # Combine all metrics into a single dictionary
    result = {
        "bleu": bleu_score,
        "exact_match": em_score,
        "f1": f1_score,
        "bert_score_f1": bert_f1_score
    }

    return result

# Initialize the Trainer instance
trainer = Seq2SeqTrainer(
    model=tw_model,                        # Model to be trained
    args=training_args,                    # Training arguments
    train_dataset=tokenized_datasets1["train"],           # Training dataset
    eval_dataset=tokenized_datasets1["test"],             # Evaluation dataset
    data_collator=data_collator,           # Data collator for batching
    tokenizer=tokenizer,                   # Tokenizer for encoding/decoding
    compute_metrics=compute_metrics,       # Function to compute evaluation metrics
)

# Empty the cache before starting the training process
torch.cuda.empty_cache()

# Start training the model
print("Starting training...")
trainer.train()
print("Training completed!")
```
```
[14139/14139 3:14:09, Epoch 0/1]
Epoch	Training Loss	Validation Loss	Bleu	Exact Match	F1	Bert Score F1
0	3.091700	2.951736	2.492315	0.000000	0.087086	-0.087008
```