Fix gr.CheckboxGroup change event (#7915)

This commit is contained in:
Freddy Boulton 2024-04-03 07:19:58 -07:00 committed by GitHub
parent b729f10321
commit efd9524508
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 408 additions and 14 deletions

View File

@ -0,0 +1,6 @@
---
"@gradio/checkboxgroup": patch
"gradio": patch
---
fix:Fix gr.CheckboxGroup change event

View File

@ -1 +1 @@
{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: code_component"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "with gr.Blocks() as demo:\n", " gr.Code(\n", " value=\"\"\"def hello_world():\n", " return \"Hello, world!\"\n", " \n", "print(hello_world())\"\"\",\n", " language=\"python\",\n", " interactive=True,\n", " show_label=False,\n", " )\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5}
{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: code_component"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "from pathlib import Path\n", "\n", "demo = gr.Interface(\n", " lambda x: x,\n", " gr.Code(language=\"python\"),\n", " gr.Code(language=\"python\"),\n", " examples=[[(\"/Users/freddy/sources/gradio/demo/code_component/run.py\",)],\n", " [\"print('Hello, World!')\"],\n", " [(\"/Users/freddy/sources/gradio/demo/code/run.py\", )]]\n", ")\n", "\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5}

View File

@ -1,15 +1,15 @@
import gradio as gr
from pathlib import Path
with gr.Blocks() as demo:
gr.Code(
value="""def hello_world():
return "Hello, world!"
demo = gr.Interface(
lambda x: x,
gr.Code(language="python"),
gr.Code(language="python"),
examples=[[("/Users/freddy/sources/gradio/demo/code_component/run.py",)],
["print('Hello, World!')"],
[("/Users/freddy/sources/gradio/demo/code/run.py", )]]
)
print(hello_world())""",
language="python",
interactive=True,
show_label=False,
)
if __name__ == "__main__":
demo.launch()

View File

View File

@ -0,0 +1,87 @@
/* Hides the final AutoEvalColumn */
#llm-benchmark-tab-table table td:last-child,
#llm-benchmark-tab-table table th:last-child {
display: none;
}
/* Limit the width of the first AutoEvalColumn so that names don't expand too much */
table td:first-child,
table th:first-child {
max-width: 400px;
overflow: auto;
white-space: nowrap;
}
/* Full width space */
.gradio-container {
max-width: 95%!important;
}
/* Text style and margins */
.markdown-text {
font-size: 16px !important;
}
#models-to-add-text {
font-size: 18px !important;
}
#citation-button span {
font-size: 16px !important;
}
#citation-button textarea {
font-size: 16px !important;
}
#citation-button > label > button {
margin: 6px;
transform: scale(1.3);
}
#search-bar-table-box > div:first-child {
background: none;
border: none;
}
#search-bar {
padding: 0px;
}
.tab-buttons button {
font-size: 20px;
}
/* Filters style */
#filter_type{
border: 0;
padding-left: 0;
padding-top: 0;
}
#filter_type label {
display: flex;
}
#filter_type label > span{
margin-top: var(--spacing-lg);
margin-right: 0.5em;
}
#filter_type label > .wrap{
width: 103px;
}
#filter_type label > .wrap .wrap-inner{
padding: 2px;
}
#filter_type label > .wrap .wrap-inner input{
width: 1px
}
#filter-columns-type{
border:0;
padding:0.5;
}
#filter-columns-size{
border:0;
padding:0.5;
}
#box-filter > .form{
border: 0
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,244 @@
import gradio as gr
import pandas as pd
from pathlib import Path
abs_path = Path(__file__).parent.absolute()
df = pd.read_json(str(abs_path / "assets/leaderboard_data.json"))
invisible_df = df.copy()
COLS = [
"T",
"Model",
"Average ⬆️",
"ARC",
"HellaSwag",
"MMLU",
"TruthfulQA",
"Winogrande",
"GSM8K",
"Type",
"Architecture",
"Precision",
"Merged",
"Hub License",
"#Params (B)",
"Hub ❤️",
"Model sha",
"model_name_for_query",
]
ON_LOAD_COLS = [
"T",
"Model",
"Average ⬆️",
"ARC",
"HellaSwag",
"MMLU",
"TruthfulQA",
"Winogrande",
"GSM8K",
"model_name_for_query",
]
TYPES = [
"str",
"markdown",
"number",
"number",
"number",
"number",
"number",
"number",
"number",
"str",
"str",
"str",
"str",
"bool",
"str",
"number",
"number",
"bool",
"str",
"bool",
"bool",
"str",
]
NUMERIC_INTERVALS = {
"?": pd.Interval(-1, 0, closed="right"),
"~1.5": pd.Interval(0, 2, closed="right"),
"~3": pd.Interval(2, 4, closed="right"),
"~7": pd.Interval(4, 9, closed="right"),
"~13": pd.Interval(9, 20, closed="right"),
"~35": pd.Interval(20, 45, closed="right"),
"~60": pd.Interval(45, 70, closed="right"),
"70+": pd.Interval(70, 10000, closed="right"),
}
MODEL_TYPE = [str(s) for s in df["T"].unique()]
Precision = [str(s) for s in df["Precision"].unique()]
# Searching and filtering
def update_table(
hidden_df: pd.DataFrame,
columns: list,
type_query: list,
precision_query: str,
size_query: list,
query: str,
):
filtered_df = filter_models(hidden_df, type_query, size_query, precision_query)
filtered_df = filter_queries(query, filtered_df)
df = select_columns(filtered_df, columns)
return df
def search_table(df: pd.DataFrame, query: str) -> pd.DataFrame:
return df[(df["model_name_for_query"].str.contains(query, case=False))]
def select_columns(df: pd.DataFrame, columns: list) -> pd.DataFrame:
# We use COLS to maintain sorting
filtered_df = df[[c for c in COLS if c in df.columns and c in columns]]
return filtered_df
def filter_queries(query: str, filtered_df: pd.DataFrame) -> pd.DataFrame:
final_df = []
if query != "":
queries = [q.strip() for q in query.split(";")]
for _q in queries:
_q = _q.strip()
if _q != "":
temp_filtered_df = search_table(filtered_df, _q)
if len(temp_filtered_df) > 0:
final_df.append(temp_filtered_df)
if len(final_df) > 0:
filtered_df = pd.concat(final_df)
filtered_df = filtered_df.drop_duplicates(
subset=["Model", "Precision", "Model sha"]
)
return filtered_df
def filter_models(
df: pd.DataFrame,
type_query: list,
size_query: list,
precision_query: list,
) -> pd.DataFrame:
# Show all models
filtered_df = df
type_emoji = [t[0] for t in type_query]
filtered_df = filtered_df.loc[df["T"].isin(type_emoji)]
filtered_df = filtered_df.loc[df["Precision"].isin(precision_query + ["None"])]
numeric_interval = pd.IntervalIndex(
sorted([NUMERIC_INTERVALS[s] for s in size_query])
)
params_column = pd.to_numeric(df["#Params (B)"], errors="coerce")
mask = params_column.apply(lambda x: any(numeric_interval.contains(x)))
filtered_df = filtered_df.loc[mask]
return filtered_df
demo = gr.Blocks(css=str(abs_path / "assets/leaderboard_data.json"))
with demo:
gr.Markdown("""Test Space of the LLM Leaderboard""", elem_classes="markdown-text")
with gr.Tabs(elem_classes="tab-buttons") as tabs:
with gr.TabItem("🏅 LLM Benchmark", elem_id="llm-benchmark-tab-table", id=0):
with gr.Row():
with gr.Column():
with gr.Row():
search_bar = gr.Textbox(
placeholder=" 🔍 Search for your model (separate multiple queries with `;`) and press ENTER...",
show_label=False,
elem_id="search-bar",
)
with gr.Row():
shown_columns = gr.CheckboxGroup(
choices=COLS,
value=ON_LOAD_COLS,
label="Select columns to show",
elem_id="column-select",
interactive=True,
)
with gr.Column(min_width=320):
filter_columns_type = gr.CheckboxGroup(
label="Model types",
choices=MODEL_TYPE,
value=MODEL_TYPE,
interactive=True,
elem_id="filter-columns-type",
)
filter_columns_precision = gr.CheckboxGroup(
label="Precision",
choices=Precision,
value=Precision,
interactive=True,
elem_id="filter-columns-precision",
)
filter_columns_size = gr.CheckboxGroup(
label="Model sizes (in billions of parameters)",
choices=list(NUMERIC_INTERVALS.keys()),
value=list(NUMERIC_INTERVALS.keys()),
interactive=True,
elem_id="filter-columns-size",
)
leaderboard_table = gr.components.Dataframe(
value=df[ON_LOAD_COLS],
headers=ON_LOAD_COLS,
datatype=TYPES,
elem_id="leaderboard-table",
interactive=False,
visible=True,
column_widths=["2%", "33%"],
)
# Dummy leaderboard for handling the case when the user uses backspace key
hidden_leaderboard_table_for_search = gr.components.Dataframe(
value=invisible_df[COLS],
headers=COLS,
datatype=TYPES,
visible=False,
)
search_bar.submit(
update_table,
[
hidden_leaderboard_table_for_search,
shown_columns,
filter_columns_type,
filter_columns_precision,
filter_columns_size,
search_bar,
],
leaderboard_table,
)
for selector in [
shown_columns,
filter_columns_type,
filter_columns_precision,
filter_columns_size,
]:
selector.change(
update_table,
[
hidden_leaderboard_table_for_search,
shown_columns,
filter_columns_type,
filter_columns_precision,
filter_columns_size,
search_bar,
],
leaderboard_table,
queue=True,
)
if __name__ == "__main__":
demo.queue(default_concurrency_limit=40).launch()

View File

@ -0,0 +1,51 @@
import { test, expect } from "@gradio/tootils";
test("Search bar filters dataframe correctly.", async ({ page }) => {
await page.getByTestId("textbox").fill("yam-peleg");
await page.getByTestId("textbox").press("Enter");
await expect(
page
.getByRole("button", { name: "yam-peleg/Experiment26-7B", exact: true })
.first()
).toBeInViewport();
});
test("Column selection adds columns to the dataframe.", async ({ page }) => {
await expect(
page
.locator("#leaderboard-table svelte-virtual-table-viewport")
.getByRole("button", { name: "Type" })
).not.toBeInViewport();
await page.getByLabel("Type").check();
await expect(
page
.locator("#leaderboard-table svelte-virtual-table-viewport")
.getByRole("button", { name: "Type" })
).toBeInViewport();
});
test("Column selection removes columns to the dataframe.", async ({ page }) => {
await expect(
page
.locator("#leaderboard-table svelte-virtual-table-viewport")
.getByRole("button", { name: "ARC" })
).toBeInViewport();
await page.getByLabel("ARC", { exact: true }).uncheck();
await expect(
page
.locator("#leaderboard-table svelte-virtual-table-viewport")
.getByRole("button", { name: "ARC" })
).not.toBeInViewport();
});
test("Model Types Checkbox filters models from the table", async ({ page }) => {
await expect(
page.getByRole("button", { name: "Qwen/Qwen-72B", exact: true }).first()
).not.toBeInViewport();
await page.getByLabel("🔶").uncheck();
await page.getByLabel("💬").uncheck();
await page.getByLabel("🤝").uncheck();
await expect(
page.getByRole("button", { name: "Qwen/Qwen-72B", exact: true }).first()
).toBeInViewport();
});

View File

@ -25,6 +25,7 @@
export let loading_status: LoadingStatus;
export let interactive = true;
export let old_value = value.slice();
function toggle_choice(choice: string | number): void {
if (value.includes(choice)) {
@ -37,7 +38,10 @@
$: disabled = !interactive;
$: value && gradio.dispatch("change");
$: if (JSON.stringify(old_value) !== JSON.stringify(value)) {
old_value = value;
gradio.dispatch("change");
}
</script>
<Block

View File

@ -124,7 +124,7 @@ describe("Values", () => {
});
test("changing the component value updates the checkboxes", async () => {
const { getByLabelText, debug, component } = await render(CheckboxGroup, {
const { getByLabelText, component } = await render(CheckboxGroup, {
value: [],
label: "Dropdown",
choices: [
@ -143,7 +143,6 @@ describe("Values", () => {
expect(item_three).not.toBeChecked();
component.value = [1, 3];
expect(item_one).toBeChecked();
expect(item_two).not.toBeChecked();
expect(item_three).toBeChecked();

View File

@ -30,6 +30,7 @@ def copy_all_demos(source_dir: str, dest_dir: str):
"kitchen_sink",
"kitchen_sink_random",
"matrix_transpose",
"mini_leaderboard",
"model3D",
"native_plots",
"reverse_audio",