Spaces:
Runtime error
Runtime error
File size: 4,057 Bytes
e5158d5 a00fee9 e5158d5 a00fee9 e5158d5 a00fee9 6c2294e e5158d5 547bc5b e5158d5 6c2294e e5158d5 6c2294e e5158d5 6c2294e e5158d5 6c2294e e5158d5 6c2294e e5158d5 6bf2e25 e5158d5 6bf2e25 e5158d5 6c2294e e5158d5 6c2294e e5158d5 6c2294e e5158d5 6c2294e e5158d5 6c2294e e5158d5 6c2294e e5158d5 6c2294e e5158d5 6c2294e e5158d5 6c2294e e5158d5 6c2294e e5158d5 6c2294e e5158d5 6c2294e e5158d5 6c2294e e5158d5 6c2294e e5158d5 6c2294e e5158d5 6c2294e e5158d5 6c2294e e5158d5 a00fee9 6c2294e a00fee9 6c2294e a00fee9 e5158d5 6c2294e e5158d5 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | from pathlib import Path
import mlflow
import numpy as np
from datasets import load_from_disk
from seqeval.metrics import f1_score as seqeval_f1_score
from transformers import (
AutoModelForTokenClassification,
AutoTokenizer,
DataCollatorForTokenClassification,
Trainer,
TrainingArguments,
set_seed,
)
from absa.training.mlflow_utils import setup_mlflow
def compute_metrics(p):
"""Computes evaluation metrics (F1 score) for token classification.
Args:
p: EvalPrediction tuple containing predictions and labels.
Returns:
Dictionary with 'f1' key and its computed value.
"""
predictions, labels = p
predictions = np.argmax(predictions, axis=2)
label_map = {0: "O", 1: "B-ASP", 2: "I-ASP"}
true_predictions = [
[label_map[p] for (p, lbl) in zip(prediction, label) if lbl != -100]
for prediction, label in zip(predictions, labels)
]
true_labels = [
[label_map[lbl] for (p, lbl) in zip(prediction, label) if lbl != -100]
for prediction, label in zip(predictions, labels)
]
# Seqeval F1 handles span-level scoring
f1 = seqeval_f1_score(true_labels, true_predictions)
# Calculate macro F1 roughly from classification report if needed,
# but for NER, seqeval's micro-averaged F1 (which seqeval_f1_score returns) is standard span-F1
return {"f1": f1}
def main():
"""Main function to train and evaluate the aspect extraction model.
Loads tokenized dataset, initializes XLM-RoBERTa for token classification,
configures Trainer, executes training loop, evaluates on test set,
and logs results to MLflow.
"""
set_seed(42)
setup_mlflow()
dataset_path = Path("data/tokenized/absa_ner_dataset")
print(f"Loading dataset from {dataset_path}")
dataset = load_from_disk(str(dataset_path))
tokenizer = AutoTokenizer.from_pretrained("xlm-roberta-base")
data_collator = DataCollatorForTokenClassification(tokenizer=tokenizer)
label_map = {0: "O", 1: "B-ASP", 2: "I-ASP"}
model = AutoModelForTokenClassification.from_pretrained(
"xlm-roberta-base",
num_labels=len(label_map),
id2label=label_map,
label2id={v: k for k, v in label_map.items()},
)
output_dir = "models/aspect_extraction"
training_args = TrainingArguments(
output_dir=output_dir,
learning_rate=2e-5,
num_train_epochs=5,
per_device_train_batch_size=16,
per_device_eval_batch_size=16,
warmup_ratio=0.1,
weight_decay=0.01,
evaluation_strategy="epoch",
save_strategy="epoch",
metric_for_best_model="eval_f1",
load_best_model_at_end=True,
seed=42,
report_to="mlflow",
)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=dataset["train"],
eval_dataset=dataset["validation"],
tokenizer=tokenizer,
data_collator=data_collator,
compute_metrics=compute_metrics,
)
print("Training Aspect Extraction model...")
trainer.train()
print("Evaluating on test set...")
test_results = trainer.evaluate(dataset["test"], metric_key_prefix="test")
print(test_results)
best_model_path = Path(output_dir) / "best"
trainer.save_model(str(best_model_path))
print(f"Best model saved to {best_model_path}")
# Log test metric manually since trainer.train() only automatically logs eval metrics
# if report_to="mlflow" handles it, but test results we need to make sure are in the same run.
active_run = mlflow.active_run()
fallback_run_id = active_run.info.run_id if active_run else None
with mlflow.start_run(
run_id=(trainer.state.trial_params.get("mlflow_run_id") if trainer.state.trial_params else fallback_run_id)
) as run:
mlflow.log_metrics({"test_f1": test_results["test_f1"], "test_loss": test_results["test_loss"]})
print(f"Logged test metrics to run {run.info.run_id}")
if __name__ == "__main__":
main()
|