Spaces:
Runtime error
Runtime error
import io | |
import re | |
from typing import * | |
import pandas as pd | |
import streamlit as st | |
from pandas.api.types import is_bool_dtype, is_datetime64_any_dtype, is_numeric_dtype | |
GITHUB_URL = "https://github.com/RSTLess-research/" | |
NON_BENCHMARK_COLS = ["Publisher"] | |
def extract_table_and_format_from_markdown_text(markdown_table: str) -> pd.DataFrame: | |
"""Extracts a table from a markdown text and formats it as a pandas DataFrame. | |
Args: | |
text (str): Markdown text containing a table. | |
Returns: | |
pd.DataFrame: Table as pandas DataFrame. | |
""" | |
df = ( | |
pd.read_table(io.StringIO(markdown_table), sep="|", header=0, index_col=1) | |
.dropna(axis=1, how="all") # drop empty columns | |
.iloc[1:] # drop first row which is the "----" separator of the original markdown table | |
.sort_index(ascending=True) | |
.apply(lambda x: x.str.strip() if x.dtype == "object" else x) | |
.replace("", float("NaN")) | |
.astype(float, errors="ignore") | |
) | |
# remove whitespace from column names and index | |
df.columns = df.columns.str.strip() | |
df.index = df.index.str.strip() | |
df.index.name = df.index.name.strip() | |
return df | |
def extract_markdown_table_from_multiline(multiline: str, table_headline: str, next_headline_start: str = "#") -> str: | |
"""Extracts the markdown table from a multiline string. | |
Args: | |
multiline (str): content of README.md file. | |
table_headline (str): Headline of the table in the README.md file. | |
next_headline_start (str, optional): Start of the next headline. Defaults to "#". | |
Returns: | |
str: Markdown table. | |
Raises: | |
ValueError: If the table could not be found. | |
""" | |
# extract everything between the table headline and the next headline | |
table = [] | |
start = False | |
for line in multiline.split("\n"): | |
if line.startswith(table_headline): | |
start = True | |
elif line.startswith(next_headline_start): | |
start = False | |
elif start: | |
table.append(line + "\n") | |
if len(table) == 0: | |
raise ValueError(f"Could not find table with headline '{table_headline}'") | |
return "".join(table) | |
def remove_markdown_links(text: str) -> str: | |
"""Modifies a markdown text to remove all markdown links. | |
Example: [DISPLAY](LINK) to DISPLAY | |
First find all markdown links with regex. | |
Then replace them with: $1 | |
Args: | |
text (str): Markdown text containing markdown links | |
Returns: | |
str: Markdown text without markdown links. | |
""" | |
# find all markdown links | |
markdown_links = re.findall(r"\[([^\]]+)\]\(([^)]+)\)", text) | |
# remove link keep display text | |
for display, link in markdown_links: | |
text = text.replace(f"[{display}]({link})", display) | |
return text | |
def filter_dataframe_by_model_type(df: pd.DataFrame, model_type_column: str = 'Lang.', ignore_columns: List[str] = None) -> pd.DataFrame: | |
""" | |
Filter dataframe by the rows based on model type and by user-selected columns. | |
This function provides a user interface to select model types and columns for filtering a DataFrame. | |
Model types are dynamically derived from the column specified as 'model_type_column'. | |
Args: | |
df (pd.DataFrame): Original dataframe. | |
model_type_column (str): Column name that contains model types for filtering. | |
ignore_columns (list[str], optional): Columns to ignore when showing in column selection. Defaults to None. | |
Returns: | |
pd.DataFrame: Filtered dataframe. | |
""" | |
df = df.copy() | |
if ignore_columns is None: | |
ignore_columns = [] | |
# Streamlit UI Container | |
modification_container = st.container() | |
with modification_container: | |
# Selection for model types | |
unique_model_types = sorted(df[model_type_column].unique()) | |
selected_model_types = st.multiselect("Filter by model type:", unique_model_types) | |
# Filter dataframe by selected model types | |
if selected_model_types: | |
df = df[df[model_type_column].isin(selected_model_types)] | |
# Column selection excluding the model type column and any specified ignore columns | |
valid_columns = sorted(set(df.columns) - set(ignore_columns) - {model_type_column}) | |
selected_columns = st.multiselect("Filter by columns:", valid_columns) | |
# Filter dataframe to include only the selected columns plus the model type column | |
if selected_columns: | |
df = pd.DataFrame(df[[model_type_column] + selected_columns]) | |
return df | |
def filter_dataframe_by_row_and_columns(df: pd.DataFrame, ignore_columns: List[str] = None) -> pd.DataFrame: | |
""" | |
Filter dataframe by the rows and columns to display. | |
This does not select based on the values in the dataframe, but rather on the index and columns. | |
Modified from https://blog.streamlit.io/auto-generate-a-dataframe-filtering-ui-in-streamlit-with-filter_dataframe/ | |
Args: | |
df (pd.DataFrame): Original dataframe | |
ignore_columns (list[str], optional): Columns to ignore. Defaults to None. | |
Returns: | |
pd.DataFrame: Filtered dataframe | |
""" | |
df = df.copy() | |
if ignore_columns is None: | |
ignore_columns = [] | |
modification_container = st.container() | |
with modification_container: | |
to_filter_index = st.multiselect("Filter by model:", sorted(df.index)) | |
if to_filter_index: | |
df = pd.DataFrame(df.loc[to_filter_index]) | |
to_filter_columns = st.multiselect( | |
"Filter by benchmark:", sorted([c for c in df.columns if c not in ignore_columns]) | |
) | |
if to_filter_columns: | |
df = pd.DataFrame(df[ignore_columns + to_filter_columns]) | |
return df | |
def filter_dataframe_by_column_values(df: pd.DataFrame) -> pd.DataFrame: | |
""" | |
Filter dataframe by the values in the dataframe. | |
Modified from https://blog.streamlit.io/auto-generate-a-dataframe-filtering-ui-in-streamlit-with-filter_dataframe/ | |
Args: | |
df (pd.DataFrame): Original dataframe | |
Returns: | |
pd.DataFrame: Filtered dataframe | |
""" | |
df = df.copy() | |
modification_container = st.container() | |
with modification_container: | |
to_filter_columns = st.multiselect("Filter results on:", df.columns) | |
left, right = st.columns((1, 20)) | |
for column in to_filter_columns: | |
if is_bool_dtype(df[column]): | |
user_bool_input = right.checkbox(f"{column}", value=True) | |
df = df[df[column] == user_bool_input] | |
elif is_numeric_dtype(df[column]): | |
_min = float(df[column].min()) | |
_max = float(df[column].max()) | |
if (_min != _max) and pd.notna(_min) and pd.notna(_max): | |
step = 0.01 | |
user_num_input = right.slider( | |
f"Values for {column}:", | |
min_value=round(_min - step, 2), | |
max_value=round(_max + step, 2), | |
value=(_min, _max), | |
step=step, | |
) | |
df = df[df[column].between(*user_num_input)] | |
elif is_datetime64_any_dtype(df[column]): | |
user_date_input = right.date_input( | |
f"Values for {column}:", | |
value=( | |
df[column].min(), | |
df[column].max(), | |
), | |
) | |
if isinstance(user_date_input, Iterable) and len(user_date_input) == 2: | |
user_date_input_datetime = tuple(map(pd.to_datetime, user_date_input)) | |
start_date, end_date = user_date_input_datetime | |
df = df.loc[df[column].between(start_date, end_date)] | |
else: | |
selected_values = right.multiselect( | |
f"Values for {column}:", | |
sorted(df[column].unique()), | |
) | |
if selected_values: | |
df = df[df[column].isin(selected_values)] | |
return df | |
def setup_basic(): | |
title = "๐ Italian LLM-Leaderboard ๐ฎ๐น๐ค" | |
st.set_page_config( | |
page_title=title, | |
page_icon="๐๐ฎ๐น๐ค", | |
layout="wide", | |
) | |
st.title(title) | |
st.markdown( | |
"The Italian Open LLM Leaderboard published along with the paper _DanteLLM: Let's Push Italian LLM Research Forward!_ ๐ค๐ฎ๐น๐ (To be presented at: LREC-COLING 2024, May 20th-25th) \n" | |
) | |
def setup_leaderboard(readme: str): | |
leaderboard_table = extract_markdown_table_from_multiline(readme, table_headline="## Leaderboard") | |
leaderboard_table = remove_markdown_links(leaderboard_table) | |
df_leaderboard = extract_table_and_format_from_markdown_text(leaderboard_table) | |
st.markdown("## Leaderboard") | |
modify = st.checkbox("Add filters") | |
if modify: | |
df_leaderboard = filter_dataframe_by_row_and_columns(df_leaderboard, ignore_columns=NON_BENCHMARK_COLS) | |
df_leaderboard = filter_dataframe_by_column_values(df_leaderboard) | |
df_leaderboard = filter_dataframe_by_model_type(df_leaderboard) | |
df_leaderboard = df_leaderboard.sort_values(by=['Avg.'], ascending=False) | |
df_leaderboard["Rank"] = df_leaderboard["Avg."].rank(ascending=False) | |
# move rank at 0-th column | |
# Ensure 'Rank' is the first column | |
cols = ['Rank'] + [col for col in df_leaderboard.columns if col != 'Rank'] | |
df_leaderboard = df_leaderboard[cols] | |
#print(df_leaderboard.columns) | |
#df_leaderboard.reset_index(drop=True, inplace=True) | |
st.dataframe(df_leaderboard) | |
st.download_button( | |
"Download leaderboard as .html", | |
df_leaderboard.to_html().encode("utf-8"), | |
"leaderboard.html", | |
"text/html", | |
key="download-html", | |
) | |
st.download_button( | |
"Download leaderboard as .csv", | |
df_leaderboard.to_csv().encode("utf-8"), | |
"leaderboard.csv", | |
"text/csv", | |
key="download-csv", | |
) | |
def setup_benchmarks(readme: str): | |
benchmarks_table = extract_markdown_table_from_multiline(readme, table_headline="## Benchmarks") | |
df_benchmarks = extract_table_and_format_from_markdown_text(benchmarks_table) | |
st.markdown("## Covered Benchmarks") | |
selected_benchmark = st.selectbox("Select a benchmark to learn more:", df_benchmarks.index.unique()) | |
df_selected = df_benchmarks.loc[selected_benchmark] | |
text = [ | |
f"Name: {selected_benchmark}", | |
] | |
for key in df_selected.keys(): | |
text.append(f"{key}: {df_selected[key]} ") | |
st.markdown(" \n".join(text)) | |
def setup_sources(): | |
st.markdown("## Sources") | |
st.markdown( | |
"The results of this leaderboard are collected from the individual papers and published results of the model " | |
"authors. If you are interested in the sources of each individual reported model value, please visit the " | |
f"[llm-leaderboard]({GITHUB_URL}) repository." | |
) | |
def setup_disclaimer(): | |
st.markdown("## Authors") | |
st.markdown( | |
""" | |
- [Andrea Bacciu](https://www.linkedin.com/in/andreabacciu/)* (Work done prior joining Amazon) | |
- [Cesare Campagnano](https://www.linkedin.com/in/caesar-one/)* | |
- [Giovanni Trappolini](https://www.linkedin.com/in/giovanni-trappolini/) | |
- [Prof. Fabrizio Silvestri](https://www.linkedin.com/in/fabrizio-silvestri-a6b0391/) | |
\*Equal contribution | |
""" | |
) | |
st.markdown("## Ack") | |
st.markdown( | |
f"Special thanks to [llm-leaderboard](https://github.com/LudwigStumpp/llm-leaderboard) for the initial inspiration and codebase" | |
) | |
def setup_footer(): | |
st.markdown( | |
""" | |
--- | |
Made with โค๏ธ by the awesome open-source Italian community ๐ค๐ฎ๐น. | |
""" | |
) | |
def main(): | |
setup_basic() | |
with open("README.md", "r") as f: | |
readme = f.read() | |
setup_leaderboard(readme) | |
setup_benchmarks(readme) | |
setup_sources() | |
setup_disclaimer() | |
setup_footer() | |
if __name__ == "__main__": | |
main() |