CoolFace
Apppublic

AMR-KELEG/MLADI

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
app.py327 linesDownload Raw Back to root
1import os2import subprocess3import streamlit as st4 5import datasets6from tqdm import tqdm7from transformers import AutoModelForSequenceClassification, AutoTokenizer8 9from constants import DIALECTS_WITH_LABELS10from inspect import getmembers, isfunction11import eval_utils12import utils13import numpy as np14import pandas as pd15from sklearn.metrics import accuracy_score, f1_score, recall_score, precision_score16 17from huggingface_hub import HfApi18 19api = HfApi()20 21st.set_page_config(layout="wide")22st.title("MLADI Leaderboard")23st.write(24    "The Multi-label Arabic Dialect Identification (MLADI) leaderboard serves as a public interface for benchmarking ADI "25    "models using an 'extended version' of the NADI 2024 test set, "26    "the first multi-label country-level ADI dataset.\n\n"27    "๐Ÿ”œ More information can be found through the following paper: [Revisiting Common Assumptions about Arabic Dialects in NLP](https://arxiv.org/abs/2505.21816)\n\n"28)29 30SHARED_TASK_TEAMS = {31    "Elyadata": "https://aclanthology.org/2024.arabicnlp-1.85/",32    "NLP_DI": "https://aclanthology.org/2024.arabicnlp-1.82/",33    "dzNlp": "https://aclanthology.org/2024.arabicnlp-1.84/",34}35tab1, tab2 = st.tabs(["Leaderboard", "Submit a Model"])36with tab1:37    # Load the labels38    dataset_name = os.environ["DATASET_NAME"]39    dataset = datasets.load_dataset(dataset_name)["test"]40    labels = {dialect: dataset[dialect] for dialect in DIALECTS_WITH_LABELS}41 42    print("Loaded the labels, no. of samples:", len(dataset))43 44    # Load the models' predictions45    try:46        model_predictions_rows = datasets.load_dataset(47            os.environ["PREDICTIONS_DATASET_NAME"]48        )["train"]49 50    except Exception as e:51        st.info(f"Error in loading the results!")52        print(e)53        model_predictions_rows = []54 55    if model_predictions_rows:56        # TODO: Store these metrics in a separate dataset!57        evaluation_metrics = []58        for row in model_predictions_rows:59            # Evaluate the models60            accuracy_scores = {}61            f1_scores = {}62            recall_scores = {}63            precision_scores = {}64            predictions = row["predictions"]65 66            if not row["status"] == "completed":67                continue68 69            for dialect in DIALECTS_WITH_LABELS:70                y_true = labels[dialect]71                y_pred = [dialect in prediction for prediction in predictions]72                accuracy = accuracy_score(y_true, y_pred)73                f1 = f1_score(y_true, y_pred)74                recall = recall_score(y_true, y_pred)75                precision = precision_score(y_true, y_pred)76 77                accuracy_scores[dialect] = accuracy78                f1_scores[dialect] = f179                recall_scores[dialect] = recall80                precision_scores[dialect] = precision81 82            macro_avg_accuracy = np.mean(list(accuracy_scores.values()))83            macro_avg_f1 = np.mean(list(f1_scores.values()))84            macro_avg_recall = np.mean(list(recall_scores.values()))85            macro_avg_precision = np.mean(list(precision_scores.values()))86 87            evaluation_metrics.append(88                {89                    "Model Name": row["model_name"],90                    "Accuracy": macro_avg_accuracy,91                    "Recall": macro_avg_recall,92                    "Precision": macro_avg_precision,93                    "F1 score": macro_avg_f1,94                    "Inference Method": row["inference_function"],95                    "URL": f"https://huggingface.co/{row['model_name']}"96                    if ("shared task team" not in row["model_name"])97                    else SHARED_TASK_TEAMS[row["model_name"].split(" (")[0]],98                    "Commit ID": row["commit_id"][:5]99                    if ("shared task team" not in row["model_name"])100                    else "N/A",101                }102            )103 104        if evaluation_metrics:105            results_df = pd.DataFrame(evaluation_metrics).sort_values(106                "F1 score", ascending=False107            )108            results_df["Rank"] = range(1, len(results_df) + 1)109 110            results_df = results_df[111                [112                    "Rank",113                    "Model Name",114                    "F1 score",115                    "Precision",116                    "Recall",117                    "Accuracy",118                    "Inference Method",119                    "URL",120                    "Commit ID",121                ]122            ]123            st.data_editor(124                results_df,125                column_config={126                    "URL": st.column_config.LinkColumn("URL", required=False),127                },128                hide_index=True,129            )130            st.write("Note: The metrics are macro-averaged across all 11 dialects.")131 132        with st.expander("Click for more information."):133            inference_functions_names = [134                func_name for func_name, _ in getmembers(eval_utils, isfunction)135            ]136            # Show the docstring of the inference functions137            inference_functions_docstring = [138                getattr(eval_utils, func).__doc__ for func in inference_functions_names139            ]140 141            inference_functions_df = pd.DataFrame(142                {143                    "Method": inference_functions_names,144                    "Description": inference_functions_docstring,145                }146            )147            st.markdown("## Inference Methods' Descriptions", unsafe_allow_html=True)148            st.markdown(149                inference_functions_df.to_markdown(index=False), unsafe_allow_html=True150            )151 152            with open("leaderboard_info.md", "r") as f:153                MARKDOWN_TEXT = f.read()154            st.markdown(MARKDOWN_TEXT)155            st.markdown("For any inquiries, please do not hesistate to contact me: https://amr-keleg.github.io/")156 157        with st.expander("Cite this leaderboard!"):158            st.write(159                """160                Please cite the following paper in which we introduced the NADI 2024 evaluation sets:161                ```162                @inproceedings{keleg-etal-2025-revisiting,163                    title = "Revisiting Common Assumptions about Arabic Dialects in NLP",164                    author = "Keleg, Amr  and165                    Goldwater, Sharon  and166                    Magdy, Walid",167                    booktitle = "Proceedings of the 63rd Annual Meeting of the Association for Computational Linguistics",168                    month = july,169                    year = "2025",170                    address = "Vienna, Austria",171                    publisher = "Association for Computational Linguistics",172                }173 174                @inproceedings{abdul-mageed-etal-2024-nadi,175                    title = "{NADI} 2024: The Fifth Nuanced {A}rabic Dialect Identification Shared Task",176                    author = "Abdul-Mageed, Muhammad  and177                    Keleg, Amr  and178                    Elmadany, AbdelRahim  and179                    Zhang, Chiyu  and180                    Hamed, Injy  and181                    Magdy, Walid  and182                    Bouamor, Houda  and183                    Habash, Nizar",184                    editor = "Habash, Nizar  and185                    Bouamor, Houda  and186                    Eskander, Ramy  and187                    Tomeh, Nadi  and188                    Abu Farha, Ibrahim  and189                    Abdelali, Ahmed  and190                    Touileb, Samia  and191                    Hamed, Injy  and192                    Onaizan, Yaser  and193                    Alhafni, Bashar  and194                    Antoun, Wissam  and195                    Khalifa, Salam  and196                    Haddad, Hatem  and197                    Zitouni, Imed  and198                    AlKhamissi, Badr  and199                    Almatham, Rawan  and200                    Mrini, Khalil",201                    booktitle = "Proceedings of The Second Arabic Natural Language Processing Conference",202                    month = aug,203                    year = "2024",204                    address = "Bangkok, Thailand",205                    publisher = "Association for Computational Linguistics",206                    url = "https://aclanthology.org/2024.arabicnlp-1.79",207                    doi = "10.18653/v1/2024.arabicnlp-1.79",208                    pages = "709--728",209                }210                ```211                """212            )213 214    # Evaluate the models queued215    if model_predictions_rows:216        models_to_be_evaluated = []217        models_in_progress = []218 219        for row in model_predictions_rows:220            if row["status"] == "queued":221                models_to_be_evaluated.append(row)222            elif row["status"] == "in_progress":223                models_in_progress.append(row)224 225        for model in models_in_progress:226            # Check if the evaluation is staled for more than a day!227            timestamp = model["last_updated_timestamp"]228            if utils.current_seconds_time() - timestamp > 86400:229                utils.update_model_queue(230                    repo_id=os.environ["PREDICTIONS_DATASET_NAME"],231                    model_name=model["model_name"],232                    commit_id=model["commit_id"],233                    inference_function=model["inference_function"],234                    status="queued",235                )236                print(f"Model {model['model_name']} is staled for more than a day.")237                models_to_be_evaluated.append(model)238                models_in_progress.remove(model)239 240        if models_in_progress == []:241            for row in models_to_be_evaluated:242                # Evaluate the model243                subprocess.Popen(244                    [245                        "python",246                        "background_inference.py",247                        row["model_name"],248                        row["commit_id"],249                        row["inference_function"],250                    ]251                )252                print(f"Started the evaluation of {row['model_name']}.")253 254with tab2:255    model_name = st.text_input("Enter a model's name on HF")256    model_revision = st.text_input(257        "Enter a model's revision on HF (commit id, or branch name)",258        placeholder="main",259        value="main",260    )261    inference_functions_names = [262        func_name for func_name, _ in getmembers(eval_utils, isfunction)263    ]264    inference_function = st.selectbox(265        "Inference Method",266        inference_functions_names,267    )268 269    # TODO: Allow modifying the adhoc threshold values of the different inference methods270 271    # Show the docstring of the inference functions272    inference_functions_docstring = [273        getattr(eval_utils, func).__doc__ for func in inference_functions_names274    ]275 276    inference_functions_df = pd.DataFrame(277        {278            "Method": inference_functions_names,279            "Description": inference_functions_docstring,280        }281    )282    with st.expander("Check the inference methods' short descriptions"):283        st.markdown(284            inference_functions_df.to_markdown(index=False), unsafe_allow_html=True285        )286        st.write(287            "Note: We are happy to discuss adding new custom inference methods for your models."288        )289 290    if model_name and model_revision and inference_function:291        # Get the model's commit id292        commit_id = api.list_repo_commits(model_name, revision=model_revision)[293            0294        ].commit_id295 296        model_predictions_rows = datasets.load_dataset(297            os.environ["PREDICTIONS_DATASET_NAME"]298        )["train"]299 300        # Check if the model is already in the leaderboard301        model_exists = any(302            [303                row["model_name"] == model_name304                and row["commit_id"] == commit_id305                and row["inference_function"] == inference_function306                for row in model_predictions_rows307            ]308        )309 310        if not model_exists:311            # Add the model to the evaluation queue312            utils.update_model_queue(313                repo_id=os.environ["PREDICTIONS_DATASET_NAME"],314                model_name=model_name,315                commit_id=commit_id,316                inference_function=inference_function,317                status="queued",318            )319            st.info(320                f"The evaluation of the model {model_name} is queued for processing."321            )322 323        else:324            st.info(325                f"The model {model_name} has already submitted to the leaderboard before."326            )327