Spaces:
Sleeping
Sleeping
File size: 11,978 Bytes
80aa351 bcf8ba9 80aa351 52415b9 bcf8ba9 80aa351 a159f5a 80aa351 39cd921 80aa351 bcf8ba9 39cd921 bcf8ba9 a159f5a bcf8ba9 80aa351 52415b9 bcf8ba9 52415b9 80aa351 bcf8ba9 80aa351 bcf8ba9 80aa351 bcf8ba9 80aa351 52415b9 80aa351 52415b9 80aa351 bcf8ba9 52415b9 80aa351 52415b9 bcf8ba9 80aa351 bcf8ba9 52415b9 80aa351 bcf8ba9 80aa351 bcf8ba9 80aa351 bcf8ba9 52415b9 bcf8ba9 52415b9 80aa351 a159f5a 39cd921 a159f5a 39cd921 a159f5a 39cd921 f38a125 80aa351 52415b9 80aa351 f38a125 b4d37bd f9428b4 b4d37bd 80aa351 b4d37bd 80aa351 bcf8ba9 b4d37bd bcf8ba9 52415b9 80aa351 bcf8ba9 b4d37bd bcf8ba9 52415b9 80aa351 52415b9 0a07f8a 52415b9 bcf8ba9 c8dd8d2 52415b9 bcf8ba9 39cd921 a159f5a 5254469 a159f5a 39cd921 a159f5a 52415b9 80aa351 bcf8ba9 80aa351 bcf8ba9 80aa351 bcf8ba9 80aa351 8dd872c 80aa351 bcf8ba9 80aa351 a159f5a |
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 |
from ast import literal_eval
from functools import lru_cache
from itertools import combinations
from pathlib import Path
from typing import List, Optional, Union
import gradio as gr
import numpy as np
import pandas as pd
from cytoolz import concat, frequencies, topk, unique
from datasets import load_dataset
pd.options.plotting.backend = "plotly"
def download_dataset():
return load_dataset(
"open-source-metrics/model-repos-stats",
split="train",
ignore_verifications=True,
)
def _clean_tags(tags: Optional[Union[str, List[str]]]):
try:
tags = literal_eval(tags)
if isinstance(tags, str):
return [tags]
if isinstance(tags, list):
return [tag for tag in tags if isinstance(tag, str)]
else:
return []
except (ValueError, SyntaxError):
return []
def _is_generated_from_tag(tags):
return any("generated" in tag for tag in tags)
def _parse_tags_for_generated(tags):
for tag in tags:
if "generated" in tag:
return tag
def prep_dataset():
ds = download_dataset()
df = ds.to_pandas()
df["languages"] = df["languages"].apply(_clean_tags)
df["datasets"] = df["datasets"].apply(_clean_tags)
df["tags"] = df["tags"].apply(_clean_tags)
df["has_languages"] = df.languages.apply(len) > 0
df["has_tags"] = df.tags.apply(len) > 0
df["has_dataset"] = df.datasets.apply(len) > 0
df["has_co2"] = df.co2.notnull()
df["has_co2"] = df.co2.apply(lambda x: x is not None)
df["has_license"] = df.license.notnull()
df["is_generated"] = df.tags.apply(_is_generated_from_tag)
df = df.drop(columns=["Unnamed: 0"])
df.to_parquet("data.parquet")
return df
def load_data():
return (
pd.read_parquet("data.parquet")
if Path("data.parquet").exists()
else prep_dataset()
)
def filter_df_by_library(filter="transformers"):
df = load_data()
return df[df["library"] == filter] if filter else df
@lru_cache()
def get_library_choices(min_freq: int = 50):
df = load_data()
library_counts = df.library.value_counts()
return library_counts[library_counts > min_freq].index.to_list()
@lru_cache()
def get_all_tags():
df = load_data()
tags = df["tags"].to_list()
return list(concat(tags))
@lru_cache()
def get_case_sensitive_duplicate_tags():
tags = get_all_tags()
unique_tags = unique(tags)
return [
tag_combo
for tag_combo in combinations(unique_tags, 2)
if tag_combo[0].lower() == tag_combo[1].lower()
]
def display_case_sensitive_duplicate_tags():
return pd.DataFrame(get_case_sensitive_duplicate_tags())
def get_number_of_tags(case_sensitive=True):
tags = set(get_all_tags())
if case_sensitive:
return f"Total number of case sensitive tags: {len(tags)}"
tags = {tag.lower() for tag in tags}
return f"Total number of case insensitive tags: {len(tags)}"
def tag_frequency(case_sensitive=True):
tags = get_all_tags()
if not case_sensitive:
tags = (tag.lower() for tag in tags)
tags_frequencies = dict(frequencies(tags))
df = pd.DataFrame.from_dict(
tags_frequencies, orient="index", columns=["Count"]
).sort_values(by="Count", ascending=False)
return df.reset_index()
def tag_frequency_by_library(library_filter):
df = filter_df_by_library(library_filter)
tags = concat(df["tags"])
tags = dict(frequencies(tags))
df = pd.DataFrame.from_dict(tags, orient="index", columns=["Count"]).sort_values(
by="Count", ascending=False
)
return df.reset_index()
def has_model_card_by_library(top_n):
df = load_data()
if top_n:
top_libs = df.library.value_counts().head(int(top_n)).index.to_list()
# min_thresh = df.library.value_counts()[:min_number].index.to_list()
df = df[df.library.isin(top_libs)]
return (
df.groupby("library")["has_text"]
.apply(lambda x: np.sum(x) / len(x))
.sort_values()
.plot.barh()
)
def model_card_length_by_library(top_n):
df = load_data()
if top_n:
top_libs = df.library.value_counts().head(int(top_n)).index.to_list()
# min_thresh = df.library.value_counts()[:min_number].index.to_list()
df = df[df.library.isin(top_libs)]
return df.groupby("library")["text_length"].describe().round().reset_index()
# df = df.groupby('library')['text_length'].describe().round().reset_index()
# df['library'] = df.library.apply(lambda library: f"[{library}](https://huggingface.co/models?library={library})")
# return df.to_markdown()
def metadata_coverage_by_library(metadata_field):
df = load_data()
return df.groupby("library")[metadata_field].mean().sort_values().plot.barh()
def metatadata_coverage_autogenerated_vs_test():
df = load_data()
subset_df = df[df["is_generated"]].copy(deep=True)
subset_df.reset_index()
return (
df.groupby("is_generated")[[c for c in df.columns if c.startswith("has")]]
.mean()
.transpose()
.round(6)
.reset_index()
.rename(
columns={
True: "From autogenerated",
False: "Not autogenerated",
"index": "Metadata/tag field",
}
)
)
def metadata_coverage_by_autogenerated(metadata_field):
df = load_data()
subset_df = df[df["is_generated"]].copy(deep=True)
subset_df.reset_index()
subset_df["autogenerated-from"] = subset_df.tags.apply(_parse_tags_for_generated)
return (
subset_df.groupby("autogenerated-from")[metadata_field]
.mean()
.sort_values()
.plot.barh()
)
def model_card_length_by_autogenerated():
df = load_data()
subset_df = df[df["is_generated"]].copy(deep=True)
subset_df.reset_index()
subset_df["autogenerated-from"] = subset_df.tags.apply(_parse_tags_for_generated)
return (
subset_df.groupby("autogenerated-from")["text_length"]
.describe()
.round()
.reset_index()
)
_ABSTRACT = """
tl;dr this dashboard aims to provide an overview of metadata associated with models hosted on the Hugging Face hub.
\n
Each tab of this dashboard focuses on a different aspect of model metadata on the hub.
Many of the tabs in the dashboard have a particular focus on the metadata coverage for different libraries in the hub.
"""
df = load_data()
top_n = df.library.value_counts().shape[0]
libraries = [library for library in df.library.unique() if library]
metadata_coverage_columns = [c for c in df.columns if c.startswith("has")]
with gr.Blocks() as demo:
gr.Markdown("# π€ Hub Metadata Explorer")
gr.Markdown(_ABSTRACT)
with gr.Tab("Tag frequencies"):
gr.Markdown(
"Tags are one of the key ways in which users may identify models which are of interest. This tab provides "
"some visualizations of tags across *all* models (regardless of library)"
)
with gr.Row():
gr.Markdown(
"The accordian below allows you to see the top tags for models on the hub (optionally making "
"tags case insensitive"
)
with gr.Row():
case_sensitive = gr.Checkbox(
True,
label="case sensitive",
)
mk = gr.Markdown()
case_sensitive.change(get_number_of_tags, [case_sensitive], mk, queue=False)
with gr.Accordion("Tag Frequencies", open=False):
df = gr.Dataframe()
case_sensitive.change(tag_frequency, [case_sensitive], df, queue=False)
with gr.Row():
gr.Markdown(
"Some tags are currently used with in cased or uncased forms i.e. 'translation' vs 'Translation'"
)
with gr.Row():
gr.Markdown(
f"Number of tags which are currently case sensitive {len(get_case_sensitive_duplicate_tags())}"
)
with gr.Row():
with gr.Accordion("View case sensitive tag pairs", open=False):
gr.Dataframe(display_case_sensitive_duplicate_tags())
with gr.Tab("Tags frequencies by library"):
gr.Markdown(
"The π€ hub hosts models from a wide range of machine learning libraries. These libraries use tags in "
"slightly different ways. The table below gives a breakdown of the most frequent tags for each library."
)
library_choice = gr.Dropdown(choices=libraries, label="select library")
df = gr.Dataframe()
library_choice.change(
tag_frequency_by_library, [library_choice], df, queue=False
)
with gr.Tab("Metadata coverage by library"):
gr.Markdown(
"Libraries hosting models on the Hugging Face hub take different approaches to "
"metadata i.e. some libraries automatically generate metadata for a model at the end of a "
"training run. These libraries may also have different types of users who take differing "
"approaches to creating metadata for models they share on the hub. The below chart allows you to "
"see which libraries have better coverage for key areas of model metadata. "
)
metadata_field = gr.Dropdown(choices=metadata_coverage_columns)
plot = gr.Plot()
metadata_field.change(
metadata_coverage_by_library, [metadata_field], plot, queue=False
)
with gr.Tab("Auto generated model cards"):
gr.Markdown(
"Some libraries/training frameworks automatically generate a model card when pushing models to "
"the hub. The below dataframe compares the metadata coverage across several tags for models "
"which are pushed with autogenerated model cards compared to those without. "
""
"**Note** this "
"breakdown relies on tags with `autogenerated` in them."
"As a result some model cards might be in the wrong category. "
)
gr.Dataframe(metatadata_coverage_autogenerated_vs_test())
with gr.Row():
metadata_field = gr.Dropdown(choices=metadata_coverage_columns)
plot = gr.Plot()
metadata_field.change(
metadata_coverage_by_autogenerated, [metadata_field], plot, queue=False
)
# )
# with gr.Row():
#
# # with gr.Column():
# # plot = gr.Plot()
# # min_lib_frequency.change(
# # model_card_length_by_autogenerated, [min_lib_frequency], plot, queue=False
# # )
# with gr.Column():
# gr.Markdown("Mean length of model card for autogenerated_from * model cards")
# df = gr.Dataframe(model_card_length_by_autogenerated)
with gr.Tab("Model Cards"):
gr.Markdown(
"""Model cards are a key component of metadata for a model. Model cards can include both
information created by a human i.e. outlining the goals behind the creation of the model and information
created by a training framework. This automatically generated information can contain information about
number of epochs, learning rate, weight decay etc. """
)
min_lib_frequency = gr.Slider(
minimum=1, maximum=top_n, value=10, label="filter by top n libraries"
)
with gr.Column():
plot = gr.Plot()
min_lib_frequency.change(
has_model_card_by_library, [min_lib_frequency], plot, queue=False
)
with gr.Column():
gr.Markdown("Mean length of model card by library")
df = gr.Dataframe()
min_lib_frequency.change(
model_card_length_by_library, [min_lib_frequency], df, queue=False
)
demo.launch()
|