Spaces:
Runtime error
Runtime error
Commit
·
8076d2b
1
Parent(s):
34aa785
remove unecessary files , update tasks fux bug on tasks mapping in get_leaderboard df
Browse files- app.py +1 -1
- src/about.py +9 -7
- src/display/formatting.py +2 -2
- src/evaluator/tsac.py +0 -133
- src/evaluators/madar_tun.py +0 -108
- src/leaderboard/read_evals.py +1 -1
- src/populate.py +2 -0
app.py
CHANGED
|
@@ -84,7 +84,7 @@ def init_leaderboard(dataframe):
|
|
| 84 |
|
| 85 |
### Space initialisation
|
| 86 |
try:
|
| 87 |
-
print(
|
| 88 |
|
| 89 |
print(f"EVAL_REQUESTS_PATH: {EVAL_REQUESTS_PATH}")
|
| 90 |
print(f"EVAL_RESULTS_PATH: {EVAL_RESULTS_PATH}")
|
|
|
|
| 84 |
|
| 85 |
### Space initialisation
|
| 86 |
try:
|
| 87 |
+
print("\n=== Starting space initialization ===")
|
| 88 |
|
| 89 |
print(f"EVAL_REQUESTS_PATH: {EVAL_REQUESTS_PATH}")
|
| 90 |
print(f"EVAL_RESULTS_PATH: {EVAL_RESULTS_PATH}")
|
src/about.py
CHANGED
|
@@ -9,13 +9,15 @@ class Task:
|
|
| 9 |
|
| 10 |
|
| 11 |
class Tasks(Enum):
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
|
|
|
|
|
|
| 19 |
|
| 20 |
NUM_FEWSHOT = 0 # Change with your few shot
|
| 21 |
# ---------------------------------------------------
|
|
|
|
| 9 |
|
| 10 |
|
| 11 |
class Tasks(Enum):
|
| 12 |
+
sentiment_analysis = Task("tunis-ai/tsac", "Sentiment Analysis", "Accuracy (Sentiment Analysis) ⬆️")
|
| 13 |
+
normalization = Task("tunis-ai/MADAR-TUN", "Normalization", "Normalization F1 ⬆️")
|
| 14 |
+
transliteration = Task("tunis-ai/MADAR-TUN", "Transliteration", "Transliteration F1 ⬆️")
|
| 15 |
+
# sentiment_f1 = Task("fbougares/tsac", "macro_f1", "Macro-F1 (TSAC) ⬆️")
|
| 16 |
+
# ner_f1 = Task("arbml/tunisian_ner", "entity_f1", "Entity F1 (NER) ⬆️")
|
| 17 |
+
# coverage = Task("arbml/Tunisian_Dialect_Corpus", "coverage", "Corpus Coverage % ⬆️")
|
| 18 |
+
# arabizi_robustness = Task("tunis-ai/arabizi_eval", "arabizi_f1", "Arabizi Robustness F1 ⬆️")
|
| 19 |
+
# code_switch = Task("tunis-ai/codeswitch_eval", "accuracy", "Code-Switch Accuracy ⬆️")
|
| 20 |
+
# typo_robustness = Task("tunis-ai/typo_eval", "f1_drop", "Typo Robustness Drop % ⬇️")
|
| 21 |
|
| 22 |
NUM_FEWSHOT = 0 # Change with your few shot
|
| 23 |
# ---------------------------------------------------
|
src/display/formatting.py
CHANGED
|
@@ -20,8 +20,8 @@ def styled_message(message):
|
|
| 20 |
|
| 21 |
|
| 22 |
def has_no_nan_values(df, columns):
|
| 23 |
-
print(df.columns)
|
| 24 |
-
print(columns)
|
| 25 |
return df[columns].notna().all(axis=1)
|
| 26 |
|
| 27 |
|
|
|
|
| 20 |
|
| 21 |
|
| 22 |
def has_no_nan_values(df, columns):
|
| 23 |
+
# print(df.columns)
|
| 24 |
+
# print(columns)
|
| 25 |
return df[columns].notna().all(axis=1)
|
| 26 |
|
| 27 |
|
src/evaluator/tsac.py
DELETED
|
@@ -1,133 +0,0 @@
|
|
| 1 |
-
import torch
|
| 2 |
-
from datasets import load_dataset
|
| 3 |
-
import traceback
|
| 4 |
-
import time
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
def evaluate_tsac_sentiment(model, tokenizer, device):
|
| 8 |
-
"""Evaluate model on TSAC sentiment analysis task"""
|
| 9 |
-
try:
|
| 10 |
-
print("\n=== Starting TSAC sentiment evaluation ===")
|
| 11 |
-
print(f"Current device: {device}")
|
| 12 |
-
|
| 13 |
-
# Load and preprocess dataset
|
| 14 |
-
print("\nLoading and preprocessing TSAC dataset...")
|
| 15 |
-
dataset = load_dataset("fbougares/tsac", split="test", trust_remote_code=True)
|
| 16 |
-
dataset = dataset.select(range(10)) # Only evaluate on 200 samples
|
| 17 |
-
|
| 18 |
-
# print(f"Dataset size: {len(dataset)} examples")
|
| 19 |
-
|
| 20 |
-
def preprocess(examples):
|
| 21 |
-
return tokenizer(
|
| 22 |
-
examples['sentence'],
|
| 23 |
-
padding=True,
|
| 24 |
-
truncation=True,
|
| 25 |
-
max_length=512,
|
| 26 |
-
return_tensors=None
|
| 27 |
-
)
|
| 28 |
-
print(dataset.column_names)
|
| 29 |
-
dataset = dataset.map(preprocess, batched=True)
|
| 30 |
-
dataset.set_format(type='torch', columns=['input_ids', 'attention_mask', 'target'])
|
| 31 |
-
|
| 32 |
-
# Check first example
|
| 33 |
-
first_example = dataset[0]
|
| 34 |
-
print("\nFirst example details:")
|
| 35 |
-
print(f"Input IDs shape: {first_example['input_ids'].shape}")
|
| 36 |
-
print(f"Attention mask shape: {first_example['attention_mask'].shape}")
|
| 37 |
-
print(f"Target: {first_example['target']}")
|
| 38 |
-
|
| 39 |
-
model.eval()
|
| 40 |
-
print(f"\nModel class: {model.__class__.__name__}")
|
| 41 |
-
print(f"Model device: {next(model.parameters()).device}")
|
| 42 |
-
|
| 43 |
-
with torch.no_grad():
|
| 44 |
-
predictions = []
|
| 45 |
-
targets = []
|
| 46 |
-
|
| 47 |
-
# Create DataLoader with batch size 16
|
| 48 |
-
from torch.utils.data import DataLoader
|
| 49 |
-
|
| 50 |
-
# Define a custom collate function
|
| 51 |
-
def collate_fn(batch):
|
| 52 |
-
input_ids = torch.stack([sample['input_ids'] for sample in batch])
|
| 53 |
-
attention_mask = torch.stack([sample['attention_mask'] for sample in batch])
|
| 54 |
-
targets = torch.stack([sample['target'] for sample in batch])
|
| 55 |
-
return {
|
| 56 |
-
'input_ids': input_ids,
|
| 57 |
-
'attention_mask': attention_mask,
|
| 58 |
-
'target': targets
|
| 59 |
-
}
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
dataloader = DataLoader(
|
| 64 |
-
dataset,
|
| 65 |
-
batch_size=16,
|
| 66 |
-
shuffle=False,
|
| 67 |
-
collate_fn=collate_fn
|
| 68 |
-
)
|
| 69 |
-
|
| 70 |
-
for i, batch in enumerate(dataloader):
|
| 71 |
-
if i % 10 == 0 :
|
| 72 |
-
print("\nProcessing first batch...")
|
| 73 |
-
print(f"Batch keys: {list(batch.keys())}")
|
| 74 |
-
print(f"Target shape: {batch['target'].shape}")
|
| 75 |
-
|
| 76 |
-
inputs = {k: v.to(device) for k, v in batch.items() if k != 'target'}
|
| 77 |
-
target = batch['target'].to(device)
|
| 78 |
-
before = time.time()
|
| 79 |
-
outputs = model(**inputs)
|
| 80 |
-
# print(f"\nBatch {i} output type: {type(outputs)}")
|
| 81 |
-
|
| 82 |
-
# Handle different model output formats
|
| 83 |
-
if isinstance(outputs, dict):
|
| 84 |
-
# print(f"Output keys: {list(outputs.keys())}")
|
| 85 |
-
if 'logits' in outputs:
|
| 86 |
-
logits = outputs['logits']
|
| 87 |
-
elif 'prediction_logits' in outputs:
|
| 88 |
-
logits = outputs['prediction_logits']
|
| 89 |
-
else:
|
| 90 |
-
raise ValueError(f"Unknown output format. Available keys: {list(outputs.keys())}")
|
| 91 |
-
elif isinstance(outputs, tuple):
|
| 92 |
-
print(f"Output tuple length: {len(outputs)}")
|
| 93 |
-
logits = outputs[0]
|
| 94 |
-
else:
|
| 95 |
-
logits = outputs
|
| 96 |
-
|
| 97 |
-
# print(f"Logits shape: {logits.shape}")
|
| 98 |
-
|
| 99 |
-
# For sequence classification, we typically use the [CLS] token's prediction
|
| 100 |
-
if len(logits.shape) == 3: # [batch_size, sequence_length, num_classes]
|
| 101 |
-
logits = logits[:, 0, :] # Take the [CLS] token prediction
|
| 102 |
-
|
| 103 |
-
# print(f"Final logits shape: {logits.shape}")
|
| 104 |
-
|
| 105 |
-
batch_predictions = logits.argmax(dim=-1).cpu().tolist()
|
| 106 |
-
batch_targets = target.cpu().tolist()
|
| 107 |
-
|
| 108 |
-
predictions.extend(batch_predictions)
|
| 109 |
-
targets.extend(batch_targets)
|
| 110 |
-
|
| 111 |
-
if i % 10 == 0:
|
| 112 |
-
print("\nFirst batch predictions:")
|
| 113 |
-
print(f"Predictions: {batch_predictions[:5]}")
|
| 114 |
-
print(f"Targets: {batch_targets[:5]}")
|
| 115 |
-
|
| 116 |
-
print(f"\nTotal predictions: {len(predictions)}")
|
| 117 |
-
print(f"Total targets: {len(targets)}")
|
| 118 |
-
|
| 119 |
-
# Calculate accuracy
|
| 120 |
-
correct = sum(p == t for p, t in zip(predictions, targets))
|
| 121 |
-
total = len(predictions)
|
| 122 |
-
accuracy = correct / total if total > 0 else 0.0
|
| 123 |
-
|
| 124 |
-
print(f"\nEvaluation results:")
|
| 125 |
-
print(f"Correct predictions: {correct}")
|
| 126 |
-
print(f"Total predictions: {total}")
|
| 127 |
-
print(f"Accuracy: {accuracy:.4f}")
|
| 128 |
-
|
| 129 |
-
return {"fbougares/tsac": accuracy}
|
| 130 |
-
except Exception as e:
|
| 131 |
-
print(f"\n=== Error in TSAC evaluation: {str(e)} ===")
|
| 132 |
-
print(f"Full traceback: {traceback.format_exc()}")
|
| 133 |
-
raise e
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/evaluators/madar_tun.py
DELETED
|
@@ -1,108 +0,0 @@
|
|
| 1 |
-
import torch
|
| 2 |
-
from datasets import load_dataset
|
| 3 |
-
# from transformers import AutoTokenizer, AutoModel
|
| 4 |
-
from sklearn.metrics import accuracy_score
|
| 5 |
-
# import argparse
|
| 6 |
-
import warnings
|
| 7 |
-
warnings.filterwarnings("ignore")
|
| 8 |
-
|
| 9 |
-
def load_and_prepare_data():
|
| 10 |
-
"""Load MADAR-TUN and prepare normalization & transliteration pairs."""
|
| 11 |
-
print("Loading MADAR-TUN dataset...")
|
| 12 |
-
ds = load_dataset("tunis-ai/MADAR-TUN", split="train")
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
valid_examples = [
|
| 16 |
-
ex for ex in ds
|
| 17 |
-
if ex["arabish"] != "<eos>"
|
| 18 |
-
and ex["words"] != "<eos>"
|
| 19 |
-
and ex["lem"] != "<eos>"
|
| 20 |
-
and ex["arabish"] is not None
|
| 21 |
-
and ex["arabish"].strip()
|
| 22 |
-
and ex["words"] is not None
|
| 23 |
-
and ex["words"].strip()
|
| 24 |
-
and ex["lem"] is not None
|
| 25 |
-
and ex["lem"].strip()
|
| 26 |
-
]
|
| 27 |
-
|
| 28 |
-
print(f"Loaded {len(valid_examples)} valid token entries.")
|
| 29 |
-
|
| 30 |
-
# Build unique pairs (deduplicate)
|
| 31 |
-
norm_pairs = {} # arabish -> canonical lemma
|
| 32 |
-
trans_pairs = {} # arabish <-> arabic
|
| 33 |
-
|
| 34 |
-
for ex in valid_examples:
|
| 35 |
-
arabizi = ex["arabish"]
|
| 36 |
-
arabic = ex["words"]
|
| 37 |
-
lemma = ex["lem"]
|
| 38 |
-
|
| 39 |
-
# For normalization: use lemma as canonical form
|
| 40 |
-
if arabizi not in norm_pairs:
|
| 41 |
-
norm_pairs[arabizi] = lemma
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
if arabizi not in trans_pairs:
|
| 45 |
-
trans_pairs[arabizi] = arabic
|
| 46 |
-
|
| 47 |
-
print(f"Normalization pairs: {len(norm_pairs)}")
|
| 48 |
-
print(f"Transliteration pairs: {len(trans_pairs)}")
|
| 49 |
-
|
| 50 |
-
return norm_pairs, trans_pairs
|
| 51 |
-
|
| 52 |
-
def evaluate_word_classification(model, tokenizer, word_pairs, device, task_name):
|
| 53 |
-
"""
|
| 54 |
-
Evaluate word-level classification (normalization or transliteration).
|
| 55 |
-
Treats it as closed-vocabulary classification via embedding similarity.
|
| 56 |
-
"""
|
| 57 |
-
words = list(word_pairs.keys())
|
| 58 |
-
targets = list(word_pairs.values())
|
| 59 |
-
|
| 60 |
-
# Build target vocabulary
|
| 61 |
-
unique_targets = sorted(set(targets))
|
| 62 |
-
target_to_id = {t: i for i, t in enumerate(unique_targets)}
|
| 63 |
-
_target_ids = [target_to_id[t] for t in targets]
|
| 64 |
-
|
| 65 |
-
print(f"\n[{task_name}] Vocabulary size: {len(unique_targets)}")
|
| 66 |
-
print(f"[{task_name}] Evaluation samples: {len(words)}")
|
| 67 |
-
|
| 68 |
-
# Get embeddings for all target forms
|
| 69 |
-
print(f"[{task_name}] Encoding target vocabulary...")
|
| 70 |
-
target_encodings = tokenizer(
|
| 71 |
-
unique_targets,
|
| 72 |
-
padding=True,
|
| 73 |
-
truncation=True,
|
| 74 |
-
max_length=32,
|
| 75 |
-
return_tensors="pt"
|
| 76 |
-
).to(device)
|
| 77 |
-
|
| 78 |
-
with torch.no_grad():
|
| 79 |
-
target_embeds = model(**target_encodings).last_hidden_state[:, 0] # [V, H]
|
| 80 |
-
|
| 81 |
-
# Predict for each input word
|
| 82 |
-
predictions = []
|
| 83 |
-
batch_size = 32
|
| 84 |
-
|
| 85 |
-
print(f"[{task_name}] Predicting...")
|
| 86 |
-
for i in range(0, len(words), batch_size):
|
| 87 |
-
batch_words = words[i:i+batch_size]
|
| 88 |
-
inputs = tokenizer(
|
| 89 |
-
batch_words,
|
| 90 |
-
padding=True,
|
| 91 |
-
truncation=True,
|
| 92 |
-
max_length=32,
|
| 93 |
-
return_tensors="pt"
|
| 94 |
-
).to(device)
|
| 95 |
-
|
| 96 |
-
with torch.no_grad():
|
| 97 |
-
word_embeds = model(**inputs).last_hidden_state[:, 0] # [B, H]
|
| 98 |
-
logits = torch.matmul(word_embeds, target_embeds.T) # [B, V]
|
| 99 |
-
preds = logits.argmax(dim=1).cpu().tolist()
|
| 100 |
-
predictions.extend(preds)
|
| 101 |
-
|
| 102 |
-
# Map back to target IDs
|
| 103 |
-
true_labels = [target_to_id[t] for t in targets]
|
| 104 |
-
|
| 105 |
-
acc = accuracy_score(true_labels, predictions)
|
| 106 |
-
print(f"[{task_name}] Accuracy: {acc:.4f}")
|
| 107 |
-
return acc
|
| 108 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/leaderboard/read_evals.py
CHANGED
|
@@ -33,7 +33,7 @@ class EvalResult:
|
|
| 33 |
try:
|
| 34 |
with open(json_filepath) as fp:
|
| 35 |
data = json.load(fp)
|
| 36 |
-
|
| 37 |
# Extract model information from the JSON data
|
| 38 |
full_model_name = data.get('model')
|
| 39 |
org_and_model = full_model_name.split("/", 1)
|
|
|
|
| 33 |
try:
|
| 34 |
with open(json_filepath) as fp:
|
| 35 |
data = json.load(fp)
|
| 36 |
+
print(data)
|
| 37 |
# Extract model information from the JSON data
|
| 38 |
full_model_name = data.get('model')
|
| 39 |
org_and_model = full_model_name.split("/", 1)
|
src/populate.py
CHANGED
|
@@ -12,8 +12,10 @@ from src.leaderboard.read_evals import get_raw_eval_results
|
|
| 12 |
def get_leaderboard_df(results_path: str, requests_path: str, cols: list, benchmark_cols: list) -> pd.DataFrame:
|
| 13 |
"""Creates a dataframe from all the individual experiment results"""
|
| 14 |
raw_data = get_raw_eval_results(results_path, requests_path)
|
|
|
|
| 15 |
all_data_json = [v.to_dict() for v in raw_data]
|
| 16 |
df = pd.DataFrame.from_records(all_data_json)
|
|
|
|
| 17 |
if df.empty:
|
| 18 |
print("No evaluation results found. Returning empty DataFrame with correct columns.")
|
| 19 |
return pd.DataFrame(columns=cols)
|
|
|
|
| 12 |
def get_leaderboard_df(results_path: str, requests_path: str, cols: list, benchmark_cols: list) -> pd.DataFrame:
|
| 13 |
"""Creates a dataframe from all the individual experiment results"""
|
| 14 |
raw_data = get_raw_eval_results(results_path, requests_path)
|
| 15 |
+
# print(raw_data)
|
| 16 |
all_data_json = [v.to_dict() for v in raw_data]
|
| 17 |
df = pd.DataFrame.from_records(all_data_json)
|
| 18 |
+
# print(df)
|
| 19 |
if df.empty:
|
| 20 |
print("No evaluation results found. Returning empty DataFrame with correct columns.")
|
| 21 |
return pd.DataFrame(columns=cols)
|