Spaces:
Runtime error
Runtime error
Benjamin Bossan
commited on
Commit
·
2174ccd
1
Parent(s):
d3818ef
Add special fields for skops template
Browse files- It's now possible to enter metrics in text area
- It's now possible to toggle model diagram
edit.py
CHANGED
|
@@ -37,6 +37,7 @@ from skops.card._model_card import PlotSection, split_subsection_names
|
|
| 37 |
|
| 38 |
from utils import iterate_key_section_content, process_card_for_rendering
|
| 39 |
from tasks import (
|
|
|
|
| 40 |
AddSectionTask,
|
| 41 |
AddFigureTask,
|
| 42 |
DeleteSectionTask,
|
|
@@ -279,33 +280,107 @@ def add_download_model_card_button():
|
|
| 279 |
)
|
| 280 |
|
| 281 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 282 |
def edit_input_form():
|
| 283 |
if "task_state" not in st.session_state:
|
| 284 |
st.session_state.task_state = TaskState()
|
| 285 |
|
| 286 |
with st.sidebar:
|
| 287 |
-
|
| 288 |
-
|
| 289 |
-
|
| 290 |
-
|
| 291 |
-
|
| 292 |
-
|
| 293 |
-
st.button(name, on_click=undo_last, disabled=undo_disabled, help=tip)
|
| 294 |
-
with col_1:
|
| 295 |
-
name = f"REDO ({len(st.session_state.task_state.undone_list)})"
|
| 296 |
-
tip = "Redo the last undone edit"
|
| 297 |
-
st.button(name, on_click=redo_last, disabled=redo_disabled, help=tip)
|
| 298 |
-
with col_2:
|
| 299 |
-
tip = "Undo all edits"
|
| 300 |
-
st.button("Reset", on_click=reset_model_card, help=tip)
|
| 301 |
-
|
| 302 |
-
col_0, col_1, *_ = st.columns([2, 2, 2, 2])
|
| 303 |
-
with col_0:
|
| 304 |
-
add_download_model_card_button()
|
| 305 |
-
with col_1:
|
| 306 |
-
tip = "Start over from scratch (lose all progress)"
|
| 307 |
-
st.button("Delete", on_click=delete_model_card, help=tip)
|
| 308 |
|
|
|
|
| 309 |
if "model_card" in st.session_state:
|
| 310 |
display_sections(st.session_state.model_card)
|
| 311 |
|
|
|
|
| 37 |
|
| 38 |
from utils import iterate_key_section_content, process_card_for_rendering
|
| 39 |
from tasks import (
|
| 40 |
+
AddMetricsTask,
|
| 41 |
AddSectionTask,
|
| 42 |
AddFigureTask,
|
| 43 |
DeleteSectionTask,
|
|
|
|
| 280 |
)
|
| 281 |
|
| 282 |
|
| 283 |
+
def display_edit_buttons():
|
| 284 |
+
# first row: undo + redo + reset
|
| 285 |
+
col_0, col_1, col_2, *_ = st.columns([2, 2, 2, 2])
|
| 286 |
+
undo_disabled = not bool(st.session_state.task_state.done_list)
|
| 287 |
+
redo_disabled = not bool(st.session_state.task_state.undone_list)
|
| 288 |
+
with col_0:
|
| 289 |
+
name = f"UNDO ({len(st.session_state.task_state.done_list)})"
|
| 290 |
+
tip = "Undo the last edit"
|
| 291 |
+
st.button(name, on_click=undo_last, disabled=undo_disabled, help=tip)
|
| 292 |
+
with col_1:
|
| 293 |
+
name = f"REDO ({len(st.session_state.task_state.undone_list)})"
|
| 294 |
+
tip = "Redo the last undone edit"
|
| 295 |
+
st.button(name, on_click=redo_last, disabled=redo_disabled, help=tip)
|
| 296 |
+
with col_2:
|
| 297 |
+
tip = "Undo all edits"
|
| 298 |
+
st.button("Reset", on_click=reset_model_card, help=tip)
|
| 299 |
+
|
| 300 |
+
# second row: download + delete
|
| 301 |
+
col_0, col_1, *_ = st.columns([2, 2, 2, 2])
|
| 302 |
+
with col_0:
|
| 303 |
+
add_download_model_card_button()
|
| 304 |
+
with col_1:
|
| 305 |
+
tip = "Start over from scratch (lose all progress)"
|
| 306 |
+
st.button("Delete", on_click=delete_model_card, help=tip)
|
| 307 |
+
|
| 308 |
+
|
| 309 |
+
def _update_model_diagram():
|
| 310 |
+
val = st.session_state.get("special_model_diagram", True)
|
| 311 |
+
model_card = st.session_state.model_card
|
| 312 |
+
model_card.model_diagram = val
|
| 313 |
+
|
| 314 |
+
# TODO: this may no longer be necesssary once this issue is solved:
|
| 315 |
+
# https://github.com/skops-dev/skops/issues/292
|
| 316 |
+
if val:
|
| 317 |
+
model_card.add_model_plot()
|
| 318 |
+
else:
|
| 319 |
+
model_card.delete("Model description/Training Procedure/Model Plot")
|
| 320 |
+
|
| 321 |
+
|
| 322 |
+
def _parse_metrics(metrics: str) -> dict[str, str | float]:
|
| 323 |
+
# parse metrics from text area, one per line, into a dict
|
| 324 |
+
metrics_table = {}
|
| 325 |
+
for line in metrics.splitlines():
|
| 326 |
+
line = line.strip()
|
| 327 |
+
val: str | float
|
| 328 |
+
name, _, val = line.partition("=")
|
| 329 |
+
try:
|
| 330 |
+
# try to coerce to float but don't error if it fails
|
| 331 |
+
val = float(val.strip())
|
| 332 |
+
except ValueError:
|
| 333 |
+
pass
|
| 334 |
+
metrics_table[name.strip()] = val
|
| 335 |
+
return metrics_table
|
| 336 |
+
|
| 337 |
+
|
| 338 |
+
def _update_metrics():
|
| 339 |
+
metrics = st.session_state.get("special_metrics_text", {})
|
| 340 |
+
model_card = st.session_state.model_card
|
| 341 |
+
metrics_table = _parse_metrics(metrics)
|
| 342 |
+
|
| 343 |
+
# check if any change
|
| 344 |
+
if metrics_table == model_card._metrics:
|
| 345 |
+
return
|
| 346 |
+
|
| 347 |
+
task = AddMetricsTask(model_card, metrics_table)
|
| 348 |
+
st.session_state.task_state.add(task)
|
| 349 |
+
|
| 350 |
+
|
| 351 |
+
def display_skops_special_fields():
|
| 352 |
+
st.checkbox(
|
| 353 |
+
"Show model diagram",
|
| 354 |
+
value=True,
|
| 355 |
+
on_change=_update_model_diagram,
|
| 356 |
+
key="special_model_diagram",
|
| 357 |
+
)
|
| 358 |
+
|
| 359 |
+
with st.expander("Add metrics"):
|
| 360 |
+
with st.form("special_metrics", clear_on_submit=False):
|
| 361 |
+
st.text_area(
|
| 362 |
+
"Add one metric per line, e.g. 'accuracy = 0.9'",
|
| 363 |
+
key="special_metrics_text",
|
| 364 |
+
)
|
| 365 |
+
st.form_submit_button(
|
| 366 |
+
"Update",
|
| 367 |
+
on_click=_update_metrics,
|
| 368 |
+
)
|
| 369 |
+
|
| 370 |
+
|
| 371 |
def edit_input_form():
|
| 372 |
if "task_state" not in st.session_state:
|
| 373 |
st.session_state.task_state = TaskState()
|
| 374 |
|
| 375 |
with st.sidebar:
|
| 376 |
+
# TOP ROW BUTTONS
|
| 377 |
+
display_edit_buttons()
|
| 378 |
+
|
| 379 |
+
# SHOW SPECIAL FIELDS IF SKOPS TEMPLATE WAS USED
|
| 380 |
+
if st.session_state.get("model_card_type", "") == "skops":
|
| 381 |
+
display_skops_special_fields()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 382 |
|
| 383 |
+
# SHOW EDITABLE SECTIONS
|
| 384 |
if "model_card" in st.session_state:
|
| 385 |
display_sections(st.session_state.model_card)
|
| 386 |
|
start.py
CHANGED
|
@@ -107,6 +107,7 @@ def create_skops_model_card() -> None:
|
|
| 107 |
metadata = card.metadata_from_config(hf_path)
|
| 108 |
model_card = card.Card(model=st.session_state.model, metadata=metadata)
|
| 109 |
st.session_state.model_card = model_card
|
|
|
|
| 110 |
|
| 111 |
|
| 112 |
def create_empty_model_card() -> None:
|
|
@@ -117,6 +118,7 @@ def create_empty_model_card() -> None:
|
|
| 117 |
)
|
| 118 |
model_card.add(**{"Untitled": "[More Information Needed]"})
|
| 119 |
st.session_state.model_card = model_card
|
|
|
|
| 120 |
|
| 121 |
|
| 122 |
def create_hf_model_card() -> None:
|
|
@@ -128,6 +130,7 @@ def create_hf_model_card() -> None:
|
|
| 128 |
path = hf_hub_download(repo_id, "README.md")
|
| 129 |
model_card = card.parse_modelcard(path)
|
| 130 |
st.session_state.model_card = model_card
|
|
|
|
| 131 |
|
| 132 |
|
| 133 |
def start_input_form():
|
|
|
|
| 107 |
metadata = card.metadata_from_config(hf_path)
|
| 108 |
model_card = card.Card(model=st.session_state.model, metadata=metadata)
|
| 109 |
st.session_state.model_card = model_card
|
| 110 |
+
st.session_state.model_card_type = "skops"
|
| 111 |
|
| 112 |
|
| 113 |
def create_empty_model_card() -> None:
|
|
|
|
| 118 |
)
|
| 119 |
model_card.add(**{"Untitled": "[More Information Needed]"})
|
| 120 |
st.session_state.model_card = model_card
|
| 121 |
+
st.session_state.model_card_type = "empty"
|
| 122 |
|
| 123 |
|
| 124 |
def create_hf_model_card() -> None:
|
|
|
|
| 130 |
path = hf_hub_download(repo_id, "README.md")
|
| 131 |
model_card = card.parse_modelcard(path)
|
| 132 |
st.session_state.model_card = model_card
|
| 133 |
+
st.session_state.model_card_type = "loaded"
|
| 134 |
|
| 135 |
|
| 136 |
def start_input_form():
|
tasks.py
CHANGED
|
@@ -208,3 +208,24 @@ class UpdateFigureTask(Task):
|
|
| 208 |
|
| 209 |
self.path.unlink(missing_ok=True)
|
| 210 |
section.content = self.old_data
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 208 |
|
| 209 |
self.path.unlink(missing_ok=True)
|
| 210 |
section.content = self.old_data
|
| 211 |
+
|
| 212 |
+
|
| 213 |
+
class AddMetricsTask(Task):
|
| 214 |
+
"""Add new metrics"""
|
| 215 |
+
|
| 216 |
+
def __init__(
|
| 217 |
+
self,
|
| 218 |
+
model_card: card.Card,
|
| 219 |
+
metrics: dict[str, str | int | float],
|
| 220 |
+
) -> None:
|
| 221 |
+
self.model_card = model_card
|
| 222 |
+
self.old_metrics = model_card._metrics.copy()
|
| 223 |
+
self.new_metrics = metrics
|
| 224 |
+
|
| 225 |
+
def do(self) -> None:
|
| 226 |
+
self.model_card._metrics.clear()
|
| 227 |
+
self.model_card.add_metrics(**self.new_metrics)
|
| 228 |
+
|
| 229 |
+
def undo(self) -> None:
|
| 230 |
+
self.model_card._metrics.clear()
|
| 231 |
+
self.model_card.add_metrics(**self.old_metrics)
|