inoki-giskard commited on
Commit
3573a39
1 Parent(s): 970a44b

Format with black and fix import

Browse files
app.py CHANGED
@@ -1,10 +1,11 @@
 
 
1
 
2
  import gradio as gr
3
- import atexit
4
- from app_text_classification import get_demo as get_demo_text_classification
5
  from app_leaderboard import get_demo as get_demo_leaderboard
 
6
  from run_jobs import start_process_run_job, stop_thread
7
- import threading
8
 
9
  if threading.current_thread() is not threading.main_thread():
10
  t = threading.current_thread()
@@ -14,7 +15,7 @@ try:
14
  get_demo_text_classification(demo)
15
  with gr.Tab("Leaderboard"):
16
  get_demo_leaderboard()
17
-
18
  start_process_run_job()
19
 
20
  demo.queue(max_size=100)
@@ -24,5 +25,3 @@ try:
24
  except Exception:
25
  print("stop background thread")
26
  stop_thread()
27
-
28
-
 
1
+ import atexit
2
+ import threading
3
 
4
  import gradio as gr
5
+
 
6
  from app_leaderboard import get_demo as get_demo_leaderboard
7
+ from app_text_classification import get_demo as get_demo_text_classification
8
  from run_jobs import start_process_run_job, stop_thread
 
9
 
10
  if threading.current_thread() is not threading.main_thread():
11
  t = threading.current_thread()
 
15
  get_demo_text_classification(demo)
16
  with gr.Tab("Leaderboard"):
17
  get_demo_leaderboard()
18
+
19
  start_process_run_job()
20
 
21
  demo.queue(max_size=100)
 
25
  except Exception:
26
  print("stop background thread")
27
  stop_thread()
 
 
app_leaderboard.py CHANGED
@@ -1,8 +1,11 @@
1
- import gradio as gr
2
- import datasets
3
  import logging
 
 
 
 
4
  from fetch_utils import check_dataset_and_get_config, check_dataset_and_get_split
5
 
 
6
  def get_records_from_dataset_repo(dataset_id):
7
  dataset_config = check_dataset_and_get_config(dataset_id)
8
 
@@ -15,83 +18,115 @@ def get_records_from_dataset_repo(dataset_id):
15
  df = ds.to_pandas()
16
  return df
17
  except Exception as e:
18
- logging.warning(f"Failed to load dataset {dataset_id} with config {dataset_config}: {e}")
 
 
19
  return None
20
 
 
21
  def get_model_ids(ds):
22
  logging.info(f"Dataset {ds} column names: {ds['model_id']}")
23
- models = ds['model_id'].tolist()
24
  # return unique elements in the list model_ids
25
  model_ids = list(set(models))
26
  return model_ids
27
 
 
28
  def get_dataset_ids(ds):
29
  logging.info(f"Dataset {ds} column names: {ds['dataset_id']}")
30
- datasets = ds['dataset_id'].tolist()
31
  dataset_ids = list(set(datasets))
32
  return dataset_ids
33
 
 
34
  def get_types(ds):
35
  # set types for each column
36
  types = [str(t) for t in ds.dtypes.to_list()]
37
- types = [t.replace('object', 'markdown') for t in types]
38
- types = [t.replace('float64', 'number') for t in types]
39
- types = [t.replace('int64', 'number') for t in types]
40
  return types
41
 
 
42
  def get_display_df(df):
43
  # style all elements in the model_id column
44
  display_df = df.copy()
45
  columns = display_df.columns.tolist()
46
- if 'model_id' in columns:
47
- display_df['model_id'] = display_df['model_id'].apply(lambda x: f'<p href="https://huggingface.co/{x}" style="color:blue">🔗{x}</p>')
 
 
48
  # style all elements in the dataset_id column
49
- if 'dataset_id' in columns:
50
- display_df['dataset_id'] = display_df['dataset_id'].apply(lambda x: f'<p href="https://huggingface.co/datasets/{x}" style="color:blue">🔗{x}</p>')
 
 
51
  # style all elements in the report_link column
52
- if 'report_link' in columns:
53
- display_df['report_link'] = display_df['report_link'].apply(lambda x: f'<p href="{x}" style="color:blue">🔗{x}</p>')
 
 
54
  return display_df
55
 
 
56
  def get_demo():
57
- records = get_records_from_dataset_repo('ZeroCommand/test-giskard-report')
58
 
59
  model_ids = get_model_ids(records)
60
  dataset_ids = get_dataset_ids(records)
61
 
62
  column_names = records.columns.tolist()
63
- default_columns = ['model_id', 'dataset_id', 'total_issues', 'report_link']
64
- default_df = records[default_columns] # extract columns selected
65
  types = get_types(default_df)
66
- display_df = get_display_df(default_df) # the styled dataframe to display
67
 
68
  with gr.Row():
69
- task_select = gr.Dropdown(label='Task', choices=['text_classification', 'tabular'], value='text_classification', interactive=True)
70
- model_select = gr.Dropdown(label='Model id', choices=model_ids, interactive=True)
71
- dataset_select = gr.Dropdown(label='Dataset id', choices=dataset_ids, interactive=True)
72
-
 
 
 
 
 
 
 
 
 
73
  with gr.Row():
74
- columns_select = gr.CheckboxGroup(label='Show columns', choices=column_names, value=default_columns, interactive=True)
 
 
 
 
 
75
 
76
  with gr.Row():
77
  leaderboard_df = gr.DataFrame(display_df, datatype=types, interactive=False)
78
-
79
- @gr.on(triggers=[model_select.change, dataset_select.change, columns_select.change, task_select.change],
80
- inputs=[model_select, dataset_select, columns_select, task_select],
81
- outputs=[leaderboard_df])
 
 
 
 
 
 
 
82
  def filter_table(model_id, dataset_id, columns, task):
83
  # filter the table based on task
84
- df = records[(records['task'] == task)]
85
  # filter the table based on the model_id and dataset_id
86
  if model_id:
87
- df = records[(records['model_id'] == model_id)]
88
  if dataset_id:
89
- df = records[(records['dataset_id'] == dataset_id)]
90
 
91
  # filter the table based on the columns
92
  df = df[columns]
93
  types = get_types(df)
94
  display_df = get_display_df(df)
95
- return (
96
- gr.update(value=display_df, datatype=types, interactive=False)
97
- )
 
 
 
1
  import logging
2
+
3
+ import datasets
4
+ import gradio as gr
5
+
6
  from fetch_utils import check_dataset_and_get_config, check_dataset_and_get_split
7
 
8
+
9
  def get_records_from_dataset_repo(dataset_id):
10
  dataset_config = check_dataset_and_get_config(dataset_id)
11
 
 
18
  df = ds.to_pandas()
19
  return df
20
  except Exception as e:
21
+ logging.warning(
22
+ f"Failed to load dataset {dataset_id} with config {dataset_config}: {e}"
23
+ )
24
  return None
25
 
26
+
27
  def get_model_ids(ds):
28
  logging.info(f"Dataset {ds} column names: {ds['model_id']}")
29
+ models = ds["model_id"].tolist()
30
  # return unique elements in the list model_ids
31
  model_ids = list(set(models))
32
  return model_ids
33
 
34
+
35
  def get_dataset_ids(ds):
36
  logging.info(f"Dataset {ds} column names: {ds['dataset_id']}")
37
+ datasets = ds["dataset_id"].tolist()
38
  dataset_ids = list(set(datasets))
39
  return dataset_ids
40
 
41
+
42
  def get_types(ds):
43
  # set types for each column
44
  types = [str(t) for t in ds.dtypes.to_list()]
45
+ types = [t.replace("object", "markdown") for t in types]
46
+ types = [t.replace("float64", "number") for t in types]
47
+ types = [t.replace("int64", "number") for t in types]
48
  return types
49
 
50
+
51
  def get_display_df(df):
52
  # style all elements in the model_id column
53
  display_df = df.copy()
54
  columns = display_df.columns.tolist()
55
+ if "model_id" in columns:
56
+ display_df["model_id"] = display_df["model_id"].apply(
57
+ lambda x: f'<p href="https://huggingface.co/{x}" style="color:blue">🔗{x}</p>
58
+ ')
59
  # style all elements in the dataset_id column
60
+ if "dataset_id" in columns:
61
+ display_df["dataset_id"] = display_df["dataset_id"].apply(
62
+ lambda x: f'<p href="https://huggingface.co/datasets/{x}" style="color:blue">🔗{x}</p>
63
+ ')
64
  # style all elements in the report_link column
65
+ if "report_link" in columns:
66
+ display_df["report_link"] = display_df["report_link"].apply(
67
+ lambda x: f'<p href="{x}" style="color:blue">🔗{x}</p>'
68
+ )
69
  return display_df
70
 
71
+
72
  def get_demo():
73
+ records = get_records_from_dataset_repo("ZeroCommand/test-giskard-report")
74
 
75
  model_ids = get_model_ids(records)
76
  dataset_ids = get_dataset_ids(records)
77
 
78
  column_names = records.columns.tolist()
79
+ default_columns = ["model_id", "dataset_id", "total_issues", "report_link"]
80
+ default_df = records[default_columns] # extract columns selected
81
  types = get_types(default_df)
82
+ display_df = get_display_df(default_df) # the styled dataframe to display
83
 
84
  with gr.Row():
85
+ task_select = gr.Dropdown(
86
+ label="Task",
87
+ choices=["text_classification", "tabular"],
88
+ value="text_classification",
89
+ interactive=True,
90
+ )
91
+ model_select = gr.Dropdown(
92
+ label="Model id", choices=model_ids, interactive=True
93
+ )
94
+ dataset_select = gr.Dropdown(
95
+ label="Dataset id", choices=dataset_ids, interactive=True
96
+ )
97
+
98
  with gr.Row():
99
+ columns_select = gr.CheckboxGroup(
100
+ label="Show columns",
101
+ choices=column_names,
102
+ value=default_columns,
103
+ interactive=True,
104
+ )
105
 
106
  with gr.Row():
107
  leaderboard_df = gr.DataFrame(display_df, datatype=types, interactive=False)
108
+
109
+ @gr.on(
110
+ triggers=[
111
+ model_select.change,
112
+ dataset_select.change,
113
+ columns_select.change,
114
+ task_select.change,
115
+ ],
116
+ inputs=[model_select, dataset_select, columns_select, task_select],
117
+ outputs=[leaderboard_df],
118
+ )
119
  def filter_table(model_id, dataset_id, columns, task):
120
  # filter the table based on task
121
+ df = records[(records["task"] == task)]
122
  # filter the table based on the model_id and dataset_id
123
  if model_id:
124
+ df = records[(records["model_id"] == model_id)]
125
  if dataset_id:
126
+ df = records[(records["dataset_id"] == dataset_id)]
127
 
128
  # filter the table based on the columns
129
  df = df[columns]
130
  types = get_types(df)
131
  display_df = get_display_df(df)
132
+ return gr.update(value=display_df, datatype=types, interactive=False)
 
 
app_legacy.py CHANGED
@@ -1,22 +1,31 @@
1
- import gradio as gr
2
- import datasets
3
- import huggingface_hub
4
  import os
5
- import time
6
  import subprocess
7
- import logging
8
-
9
- import json
10
 
 
 
 
11
  from transformers.pipelines import TextClassificationPipeline
12
 
13
- from text_classification import check_column_mapping_keys_validity, text_classification_fix_column_mapping
14
- from io_utils import read_scanners, write_scanners, read_inference_type, write_inference_type, convert_column_mapping_to_json
15
- from wordings import CONFIRM_MAPPING_DETAILS_MD, CONFIRM_MAPPING_DETAILS_FAIL_MD
 
 
 
 
 
 
 
 
 
 
 
 
 
16
 
17
- HF_REPO_ID = 'HF_REPO_ID'
18
- HF_SPACE_ID = 'SPACE_ID'
19
- HF_WRITE_TOKEN = 'HF_WRITE_TOKEN'
20
 
21
  def check_model(model_id):
22
  try:
@@ -26,6 +35,7 @@ def check_model(model_id):
26
 
27
  try:
28
  from transformers import pipeline
 
29
  ppl = pipeline(task=task, model=model_id)
30
 
31
  return model_id, ppl
@@ -55,55 +65,70 @@ def check_dataset(dataset_id, dataset_config="default", dataset_split="test"):
55
  return dataset_id, None, None
56
  return dataset_id, dataset_config, dataset_split
57
 
58
- def try_validate(m_id, ppl, dataset_id, dataset_config, dataset_split, column_mapping='{}'):
 
 
 
59
  # Validate model
60
  if m_id is None:
61
- gr.Warning('Model is not accessible. Please set your HF_TOKEN if it is a private model.')
 
 
62
  return (
63
- gr.update(interactive=False), # Submit button
64
- gr.update(visible=True), # Loading row
65
- gr.update(visible=False), # Preview row
66
- gr.update(visible=False), # Model prediction input
67
- gr.update(visible=False), # Model prediction preview
68
- gr.update(visible=False), # Label mapping preview
69
- gr.update(visible=False), # feature mapping preview
70
  )
71
  if isinstance(ppl, Exception):
72
  gr.Warning(f'Failed to load model": {ppl}')
73
  return (
74
- gr.update(interactive=False), # Submit button
75
- gr.update(visible=True), # Loading row
76
- gr.update(visible=False), # Preview row
77
- gr.update(visible=False), # Model prediction input
78
- gr.update(visible=False), # Model prediction preview
79
- gr.update(visible=False), # Label mapping preview
80
- gr.update(visible=False), # feature mapping preview
81
  )
82
 
83
  # Validate dataset
84
- d_id, config, split = check_dataset(dataset_id=dataset_id, dataset_config=dataset_config, dataset_split=dataset_split)
 
 
 
 
85
 
86
  dataset_ok = False
87
  if d_id is None:
88
- gr.Warning(f'Dataset "{dataset_id}" is not accessible. Please set your HF_TOKEN if it is a private dataset.')
 
 
89
  elif isinstance(config, list):
90
- gr.Warning(f'Dataset "{dataset_id}" does not have "{dataset_config}" config. Please choose a valid config.')
 
 
91
  config = gr.update(choices=config, value=config[0])
92
  elif isinstance(split, list):
93
- gr.Warning(f'Dataset "{dataset_id}" does not have "{dataset_split}" split. Please choose a valid split.')
 
 
94
  split = gr.update(choices=split, value=split[0])
95
  else:
96
  dataset_ok = True
97
 
98
  if not dataset_ok:
99
  return (
100
- gr.update(interactive=False), # Submit button
101
- gr.update(visible=True), # Loading row
102
- gr.update(visible=False), # Preview row
103
- gr.update(visible=False), # Model prediction input
104
- gr.update(visible=False), # Model prediction preview
105
- gr.update(visible=False), # Label mapping preview
106
- gr.update(visible=False), # feature mapping preview
107
  )
108
 
109
  # TODO: Validate column mapping by running once
@@ -115,55 +140,94 @@ def try_validate(m_id, ppl, dataset_id, dataset_config, dataset_split, column_ma
115
  except Exception:
116
  column_mapping = {}
117
 
118
- column_mapping, prediction_input, prediction_result, id2label_df, feature_df = \
119
- text_classification_fix_column_mapping(column_mapping, ppl, d_id, config, split)
 
 
 
 
 
 
 
120
 
121
  column_mapping = json.dumps(column_mapping, indent=2)
122
 
123
  if prediction_result is None and id2label_df is not None:
124
- gr.Warning('The model failed to predict with the first row in the dataset. Please provide feature mappings in "Advance" settings.')
 
 
125
  return (
126
- gr.update(interactive=False), # Submit button
127
- gr.update(visible=False), # Loading row
128
- gr.update(CONFIRM_MAPPING_DETAILS_MD, visible=True), # Preview row
129
- gr.update(value=f'**Sample Input**: {prediction_input}', visible=True), # Model prediction input
130
- gr.update(visible=False), # Model prediction preview
131
- gr.update(value=id2label_df, visible=True, interactive=True), # Label mapping preview
132
- gr.update(value=feature_df, visible=True, interactive=True), # feature mapping preview
 
 
 
 
 
 
133
  )
134
  elif id2label_df is None:
135
- gr.Warning('The prediction result does not conform the labels in the dataset. Please provide label mappings in "Advance" settings.')
 
 
136
  return (
137
- gr.update(interactive=False), # Submit button
138
- gr.update(visible=False), # Loading row
139
- gr.update(CONFIRM_MAPPING_DETAILS_MD, visible=True), # Preview row
140
- gr.update(value=f'**Sample Input**: {prediction_input}', visible=True), # Model prediction input
141
- gr.update(value=prediction_result, visible=True), # Model prediction preview
142
- gr.update(visible=True, interactive=True), # Label mapping preview
143
- gr.update(visible=True, interactive=True), # feature mapping preview
 
 
 
 
144
  )
145
 
146
- gr.Info("Model and dataset validations passed. Your can submit the evaluation task.")
 
 
147
 
148
  return (
149
- gr.update(interactive=True), # Submit button
150
- gr.update(visible=False), # Loading row
151
- gr.update(CONFIRM_MAPPING_DETAILS_MD, visible=True), # Preview row
152
- gr.update(value=f'**Sample Input**: {prediction_input}', visible=True), # Model prediction input
153
- gr.update(value=prediction_result, visible=True), # Model prediction preview
154
- gr.update(value=id2label_df, visible=True, interactive=True), # Label mapping preview
155
- gr.update(value=feature_df, visible=True, interactive=True), # feature mapping preview
 
 
 
 
 
 
156
  )
157
 
158
 
159
- def try_submit(m_id, d_id, config, split, id2label_mapping_dataframe, feature_mapping_dataframe, local):
 
 
 
 
 
 
 
 
160
  label_mapping = {}
161
  for i, label in id2label_mapping_dataframe["Model Prediction Labels"].items():
162
  label_mapping.update({str(i): label})
163
-
164
  feature_mapping = {}
165
  for i, feature in feature_mapping_dataframe["Dataset Features"].items():
166
- feature_mapping.update({feature_mapping_dataframe["Model Input Features"][i]: feature})
 
 
167
 
168
  # TODO: Set column mapping for some dataset such as `amazon_polarity`
169
 
@@ -171,18 +235,30 @@ def try_submit(m_id, d_id, config, split, id2label_mapping_dataframe, feature_ma
171
  command = [
172
  "python",
173
  "cli.py",
174
- "--loader", "huggingface",
175
- "--model", m_id,
176
- "--dataset", d_id,
177
- "--dataset_config", config,
178
- "--dataset_split", split,
179
- "--hf_token", os.environ.get(HF_WRITE_TOKEN),
180
- "--discussion_repo", os.environ.get(HF_REPO_ID) or os.environ.get(HF_SPACE_ID),
181
- "--output_format", "markdown",
182
- "--output_portal", "huggingface",
183
- "--feature_mapping", json.dumps(feature_mapping),
184
- "--label_mapping", json.dumps(label_mapping),
185
- "--scan_config", "../config.yaml",
 
 
 
 
 
 
 
 
 
 
 
 
186
  ]
187
 
188
  eval_str = f"[{m_id}]<{d_id}({config}, {split} set)>"
@@ -196,12 +272,16 @@ def try_submit(m_id, d_id, config, split, id2label_mapping_dataframe, feature_ma
196
  )
197
  result = evaluator.wait()
198
 
199
- logging.info(f"Finished local evaluation exit code {result} on {eval_str}: {time.time() - start:.2f}s")
 
 
200
 
201
- gr.Info(f"Finished local evaluation exit code {result} on {eval_str}: {time.time() - start:.2f}s")
 
 
202
  else:
203
  gr.Info("TODO: Submit task to an endpoint")
204
-
205
  return gr.update(interactive=True) # Submit button
206
 
207
 
@@ -224,56 +304,82 @@ def get_demo():
224
  return gr.Dropdown(splits, value=splits[0], visible=True)
225
  except Exception as e:
226
  # Dataset may not exist
227
- gr.Warning(f"Failed to load dataset {dataset_id} with config {dataset_config}: {e}")
228
- pass
229
-
 
230
  def clear_column_mapping_tables():
231
  return [
232
  gr.update(CONFIRM_MAPPING_DETAILS_FAIL_MD, visible=True),
233
  gr.update(value=[], visible=False, interactive=True),
234
  gr.update(value=[], visible=False, interactive=True),
235
  ]
236
-
237
- def gate_validate_btn(model_id, dataset_id, dataset_config, dataset_split, id2label_mapping_dataframe=None, feature_mapping_dataframe=None):
238
- column_mapping = '{}'
 
 
 
 
 
 
 
239
  _, ppl = check_model(model_id=model_id)
240
 
241
  if id2label_mapping_dataframe is not None:
242
- labels = convert_column_mapping_to_json(id2label_mapping_dataframe.value, label="data")
243
- features = convert_column_mapping_to_json(feature_mapping_dataframe.value, label="text")
 
 
 
 
244
  column_mapping = json.dumps({**labels, **features}, indent=2)
245
 
246
  if check_column_mapping_keys_validity(column_mapping, ppl) is False:
247
- gr.Warning('Label mapping table has invalid contents. Please check again.')
248
- return (gr.update(interactive=False),
249
- gr.update(CONFIRM_MAPPING_DETAILS_FAIL_MD, visible=True),
250
- gr.update(),
251
- gr.update(),
252
- gr.update(),
253
- gr.update(),
254
- gr.update())
 
 
255
  else:
256
  if model_id and dataset_id and dataset_config and dataset_split:
257
- return try_validate(model_id, ppl, dataset_id, dataset_config, dataset_split, column_mapping)
 
 
 
 
 
 
 
258
  else:
259
- return (gr.update(interactive=False),
260
- gr.update(visible=True),
261
- gr.update(visible=False),
262
- gr.update(visible=False),
263
- gr.update(visible=False),
264
- gr.update(visible=False),
265
- gr.update(visible=False))
 
 
 
266
  with gr.Row():
267
  gr.Markdown(CONFIRM_MAPPING_DETAILS_MD)
268
  with gr.Row():
269
  run_local = gr.Checkbox(value=True, label="Run in this Space")
270
- use_inference = read_inference_type('./config.yaml') == 'hf_inference_api'
271
  run_inference = gr.Checkbox(value=use_inference, label="Run with Inference API")
272
-
273
  with gr.Row():
274
- selected = read_scanners('./config.yaml')
275
- scan_config = selected + ['data_leakage']
276
- scanners = gr.CheckboxGroup(choices=scan_config, value=selected, label='Scan Settings', visible=True)
 
 
277
 
278
  with gr.Row():
279
  model_id_input = gr.Textbox(
@@ -286,75 +392,154 @@ def get_demo():
286
  placeholder="tweet_eval",
287
  )
288
  with gr.Row():
289
- dataset_config_input = gr.Dropdown(label='Dataset Config', visible=False)
290
- dataset_split_input = gr.Dropdown(label='Dataset Split', visible=False)
291
-
292
  with gr.Row(visible=True) as loading_row:
293
- gr.Markdown('''
 
294
  <p style="text-align: center;">
295
  🚀🐢Please validate your model and dataset first...
296
  </p>
297
- ''')
298
-
 
299
  with gr.Row(visible=False) as preview_row:
300
- gr.Markdown('''
 
301
  <h1 style="text-align: center;">
302
  Confirm Pre-processing Details
303
  </h1>
304
  Base on your model and dataset, we inferred this label mapping and feature mapping. <b>If the mapping is incorrect, please modify it in the table below.</b>
305
- ''')
306
-
 
307
  with gr.Row():
308
- id2label_mapping_dataframe = gr.DataFrame(label="Preview of label mapping", interactive=True, visible=False)
309
- feature_mapping_dataframe = gr.DataFrame(label="Preview of feature mapping", interactive=True, visible=False)
 
 
 
 
310
  with gr.Row():
311
- example_input = gr.Markdown('Sample Input: ', visible=False)
312
-
313
  with gr.Row():
314
- example_labels = gr.Label(label='Model Prediction Sample', visible=False)
315
-
316
  run_btn = gr.Button(
317
  "Get Evaluation Result",
318
  variant="primary",
319
  interactive=False,
320
  size="lg",
321
  )
322
-
323
- model_id_input.blur(clear_column_mapping_tables, outputs=[id2label_mapping_dataframe, feature_mapping_dataframe])
324
 
 
 
 
 
325
 
326
- dataset_id_input.blur(check_dataset_and_get_config, dataset_id_input, dataset_config_input)
327
- dataset_id_input.submit(check_dataset_and_get_config, dataset_id_input, dataset_config_input)
 
 
 
 
328
 
329
  dataset_config_input.change(
330
- check_dataset_and_get_split,
331
- inputs=[dataset_config_input, dataset_id_input],
332
- outputs=[dataset_split_input])
333
-
334
- dataset_id_input.blur(clear_column_mapping_tables, outputs=[id2label_mapping_dataframe, feature_mapping_dataframe])
335
- # model_id_input.blur(gate_validate_btn,
336
- # inputs=[model_id_input, dataset_id_input, dataset_config_input, dataset_split_input],
 
 
 
 
337
  # outputs=[run_btn, loading_row, preview_row, example_input, example_labels, id2label_mapping_dataframe, feature_mapping_dataframe])
338
- # dataset_id_input.blur(gate_validate_btn,
339
- # inputs=[model_id_input, dataset_id_input, dataset_config_input, dataset_split_input],
340
- # outputs=[run_btn, loading_row, preview_row, example_input, example_labels, id2label_mapping_dataframe, feature_mapping_dataframe])
341
- dataset_config_input.change(gate_validate_btn,
342
- inputs=[model_id_input, dataset_id_input, dataset_config_input, dataset_split_input],
343
- outputs=[run_btn, loading_row, preview_row, example_input, example_labels, id2label_mapping_dataframe, feature_mapping_dataframe])
344
- dataset_split_input.change(gate_validate_btn,
345
- inputs=[model_id_input, dataset_id_input, dataset_config_input, dataset_split_input],
346
- outputs=[run_btn, loading_row, preview_row, example_input, example_labels, id2label_mapping_dataframe, feature_mapping_dataframe])
347
- id2label_mapping_dataframe.input(gate_validate_btn,
348
- inputs=[model_id_input, dataset_id_input, dataset_config_input, dataset_split_input, id2label_mapping_dataframe, feature_mapping_dataframe],
349
- outputs=[run_btn, loading_row, preview_row, example_input, example_labels, id2label_mapping_dataframe, feature_mapping_dataframe])
350
- feature_mapping_dataframe.input(gate_validate_btn,
351
- inputs=[model_id_input, dataset_id_input, dataset_config_input, dataset_split_input, id2label_mapping_dataframe, feature_mapping_dataframe],
352
- outputs=[run_btn, loading_row, preview_row, example_input, example_labels, id2label_mapping_dataframe, feature_mapping_dataframe])
353
- scanners.change(write_scanners, inputs=scanners)
354
- run_inference.change(
355
- write_inference_type,
356
- inputs=[run_inference]
 
357
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
358
 
359
  run_btn.click(
360
  try_submit,
@@ -370,4 +555,4 @@ def get_demo():
370
  outputs=[
371
  run_btn,
372
  ],
373
- )
 
1
+ import json
2
+ import logging
 
3
  import os
 
4
  import subprocess
5
+ import time
 
 
6
 
7
+ import datasets
8
+ import gradio as gr
9
+ import huggingface_hub
10
  from transformers.pipelines import TextClassificationPipeline
11
 
12
+ from io_utils import (
13
+ convert_column_mapping_to_json,
14
+ read_inference_type,
15
+ read_scanners,
16
+ write_inference_type,
17
+ write_scanners,
18
+ )
19
+ from text_classification import (
20
+ check_column_mapping_keys_validity,
21
+ text_classification_fix_column_mapping,
22
+ )
23
+ from wordings import CONFIRM_MAPPING_DETAILS_FAIL_MD, CONFIRM_MAPPING_DETAILS_MD
24
+
25
+ HF_REPO_ID = "HF_REPO_ID"
26
+ HF_SPACE_ID = "SPACE_ID"
27
+ HF_WRITE_TOKEN = "HF_WRITE_TOKEN"
28
 
 
 
 
29
 
30
  def check_model(model_id):
31
  try:
 
35
 
36
  try:
37
  from transformers import pipeline
38
+
39
  ppl = pipeline(task=task, model=model_id)
40
 
41
  return model_id, ppl
 
65
  return dataset_id, None, None
66
  return dataset_id, dataset_config, dataset_split
67
 
68
+
69
+ def try_validate(
70
+ m_id, ppl, dataset_id, dataset_config, dataset_split, column_mapping="{}"
71
+ ):
72
  # Validate model
73
  if m_id is None:
74
+ gr.Warning(
75
+ "Model is not accessible. Please set your HF_TOKEN if it is a private model."
76
+ )
77
  return (
78
+ gr.update(interactive=False), # Submit button
79
+ gr.update(visible=True), # Loading row
80
+ gr.update(visible=False), # Preview row
81
+ gr.update(visible=False), # Model prediction input
82
+ gr.update(visible=False), # Model prediction preview
83
+ gr.update(visible=False), # Label mapping preview
84
+ gr.update(visible=False), # feature mapping preview
85
  )
86
  if isinstance(ppl, Exception):
87
  gr.Warning(f'Failed to load model": {ppl}')
88
  return (
89
+ gr.update(interactive=False), # Submit button
90
+ gr.update(visible=True), # Loading row
91
+ gr.update(visible=False), # Preview row
92
+ gr.update(visible=False), # Model prediction input
93
+ gr.update(visible=False), # Model prediction preview
94
+ gr.update(visible=False), # Label mapping preview
95
+ gr.update(visible=False), # feature mapping preview
96
  )
97
 
98
  # Validate dataset
99
+ d_id, config, split = check_dataset(
100
+ dataset_id=dataset_id,
101
+ dataset_config=dataset_config,
102
+ dataset_split=dataset_split,
103
+ )
104
 
105
  dataset_ok = False
106
  if d_id is None:
107
+ gr.Warning(
108
+ f'Dataset "{dataset_id}" is not accessible. Please set your HF_TOKEN if it is a private dataset.'
109
+ )
110
  elif isinstance(config, list):
111
+ gr.Warning(
112
+ f'Dataset "{dataset_id}" does not have "{dataset_config}" config. Please choose a valid config.'
113
+ )
114
  config = gr.update(choices=config, value=config[0])
115
  elif isinstance(split, list):
116
+ gr.Warning(
117
+ f'Dataset "{dataset_id}" does not have "{dataset_split}" split. Please choose a valid split.'
118
+ )
119
  split = gr.update(choices=split, value=split[0])
120
  else:
121
  dataset_ok = True
122
 
123
  if not dataset_ok:
124
  return (
125
+ gr.update(interactive=False), # Submit button
126
+ gr.update(visible=True), # Loading row
127
+ gr.update(visible=False), # Preview row
128
+ gr.update(visible=False), # Model prediction input
129
+ gr.update(visible=False), # Model prediction preview
130
+ gr.update(visible=False), # Label mapping preview
131
+ gr.update(visible=False), # feature mapping preview
132
  )
133
 
134
  # TODO: Validate column mapping by running once
 
140
  except Exception:
141
  column_mapping = {}
142
 
143
+ (
144
+ column_mapping,
145
+ prediction_input,
146
+ prediction_result,
147
+ id2label_df,
148
+ feature_df,
149
+ ) = text_classification_fix_column_mapping(
150
+ column_mapping, ppl, d_id, config, split
151
+ )
152
 
153
  column_mapping = json.dumps(column_mapping, indent=2)
154
 
155
  if prediction_result is None and id2label_df is not None:
156
+ gr.Warning(
157
+ 'The model failed to predict with the first row in the dataset. Please provide feature mappings in "Advance" settings.'
158
+ )
159
  return (
160
+ gr.update(interactive=False), # Submit button
161
+ gr.update(visible=False), # Loading row
162
+ gr.update(CONFIRM_MAPPING_DETAILS_MD, visible=True), # Preview row
163
+ gr.update(
164
+ value=f"**Sample Input**: {prediction_input}", visible=True
165
+ ), # Model prediction input
166
+ gr.update(visible=False), # Model prediction preview
167
+ gr.update(
168
+ value=id2label_df, visible=True, interactive=True
169
+ ), # Label mapping preview
170
+ gr.update(
171
+ value=feature_df, visible=True, interactive=True
172
+ ), # feature mapping preview
173
  )
174
  elif id2label_df is None:
175
+ gr.Warning(
176
+ 'The prediction result does not conform the labels in the dataset. Please provide label mappings in "Advance" settings.'
177
+ )
178
  return (
179
+ gr.update(interactive=False), # Submit button
180
+ gr.update(visible=False), # Loading row
181
+ gr.update(CONFIRM_MAPPING_DETAILS_MD, visible=True), # Preview row
182
+ gr.update(
183
+ value=f"**Sample Input**: {prediction_input}", visible=True
184
+ ), # Model prediction input
185
+ gr.update(
186
+ value=prediction_result, visible=True
187
+ ), # Model prediction preview
188
+ gr.update(visible=True, interactive=True), # Label mapping preview
189
+ gr.update(visible=True, interactive=True), # feature mapping preview
190
  )
191
 
192
+ gr.Info(
193
+ "Model and dataset validations passed. Your can submit the evaluation task."
194
+ )
195
 
196
  return (
197
+ gr.update(interactive=True), # Submit button
198
+ gr.update(visible=False), # Loading row
199
+ gr.update(CONFIRM_MAPPING_DETAILS_MD, visible=True), # Preview row
200
+ gr.update(
201
+ value=f"**Sample Input**: {prediction_input}", visible=True
202
+ ), # Model prediction input
203
+ gr.update(value=prediction_result, visible=True), # Model prediction preview
204
+ gr.update(
205
+ value=id2label_df, visible=True, interactive=True
206
+ ), # Label mapping preview
207
+ gr.update(
208
+ value=feature_df, visible=True, interactive=True
209
+ ), # feature mapping preview
210
  )
211
 
212
 
213
+ def try_submit(
214
+ m_id,
215
+ d_id,
216
+ config,
217
+ split,
218
+ id2label_mapping_dataframe,
219
+ feature_mapping_dataframe,
220
+ local,
221
+ ):
222
  label_mapping = {}
223
  for i, label in id2label_mapping_dataframe["Model Prediction Labels"].items():
224
  label_mapping.update({str(i): label})
225
+
226
  feature_mapping = {}
227
  for i, feature in feature_mapping_dataframe["Dataset Features"].items():
228
+ feature_mapping.update(
229
+ {feature_mapping_dataframe["Model Input Features"][i]: feature}
230
+ )
231
 
232
  # TODO: Set column mapping for some dataset such as `amazon_polarity`
233
 
 
235
  command = [
236
  "python",
237
  "cli.py",
238
+ "--loader",
239
+ "huggingface",
240
+ "--model",
241
+ m_id,
242
+ "--dataset",
243
+ d_id,
244
+ "--dataset_config",
245
+ config,
246
+ "--dataset_split",
247
+ split,
248
+ "--hf_token",
249
+ os.environ.get(HF_WRITE_TOKEN),
250
+ "--discussion_repo",
251
+ os.environ.get(HF_REPO_ID) or os.environ.get(HF_SPACE_ID),
252
+ "--output_format",
253
+ "markdown",
254
+ "--output_portal",
255
+ "huggingface",
256
+ "--feature_mapping",
257
+ json.dumps(feature_mapping),
258
+ "--label_mapping",
259
+ json.dumps(label_mapping),
260
+ "--scan_config",
261
+ "../config.yaml",
262
  ]
263
 
264
  eval_str = f"[{m_id}]<{d_id}({config}, {split} set)>"
 
272
  )
273
  result = evaluator.wait()
274
 
275
+ logging.info(
276
+ f"Finished local evaluation exit code {result} on {eval_str}: {time.time() - start:.2f}s"
277
+ )
278
 
279
+ gr.Info(
280
+ f"Finished local evaluation exit code {result} on {eval_str}: {time.time() - start:.2f}s"
281
+ )
282
  else:
283
  gr.Info("TODO: Submit task to an endpoint")
284
+
285
  return gr.update(interactive=True) # Submit button
286
 
287
 
 
304
  return gr.Dropdown(splits, value=splits[0], visible=True)
305
  except Exception as e:
306
  # Dataset may not exist
307
+ gr.Warning(
308
+ f"Failed to load dataset {dataset_id} with config {dataset_config}: {e}"
309
+ )
310
+
311
  def clear_column_mapping_tables():
312
  return [
313
  gr.update(CONFIRM_MAPPING_DETAILS_FAIL_MD, visible=True),
314
  gr.update(value=[], visible=False, interactive=True),
315
  gr.update(value=[], visible=False, interactive=True),
316
  ]
317
+
318
+ def gate_validate_btn(
319
+ model_id,
320
+ dataset_id,
321
+ dataset_config,
322
+ dataset_split,
323
+ id2label_mapping_dataframe=None,
324
+ feature_mapping_dataframe=None,
325
+ ):
326
+ column_mapping = "{}"
327
  _, ppl = check_model(model_id=model_id)
328
 
329
  if id2label_mapping_dataframe is not None:
330
+ labels = convert_column_mapping_to_json(
331
+ id2label_mapping_dataframe.value, label="data"
332
+ )
333
+ features = convert_column_mapping_to_json(
334
+ feature_mapping_dataframe.value, label="text"
335
+ )
336
  column_mapping = json.dumps({**labels, **features}, indent=2)
337
 
338
  if check_column_mapping_keys_validity(column_mapping, ppl) is False:
339
+ gr.Warning("Label mapping table has invalid contents. Please check again.")
340
+ return (
341
+ gr.update(interactive=False),
342
+ gr.update(CONFIRM_MAPPING_DETAILS_FAIL_MD, visible=True),
343
+ gr.update(),
344
+ gr.update(),
345
+ gr.update(),
346
+ gr.update(),
347
+ gr.update(),
348
+ )
349
  else:
350
  if model_id and dataset_id and dataset_config and dataset_split:
351
+ return try_validate(
352
+ model_id,
353
+ ppl,
354
+ dataset_id,
355
+ dataset_config,
356
+ dataset_split,
357
+ column_mapping,
358
+ )
359
  else:
360
+ return (
361
+ gr.update(interactive=False),
362
+ gr.update(visible=True),
363
+ gr.update(visible=False),
364
+ gr.update(visible=False),
365
+ gr.update(visible=False),
366
+ gr.update(visible=False),
367
+ gr.update(visible=False),
368
+ )
369
+
370
  with gr.Row():
371
  gr.Markdown(CONFIRM_MAPPING_DETAILS_MD)
372
  with gr.Row():
373
  run_local = gr.Checkbox(value=True, label="Run in this Space")
374
+ use_inference = read_inference_type("./config.yaml") == "hf_inference_api"
375
  run_inference = gr.Checkbox(value=use_inference, label="Run with Inference API")
376
+
377
  with gr.Row():
378
+ selected = read_scanners("./config.yaml")
379
+ scan_config = selected + ["data_leakage"]
380
+ scanners = gr.CheckboxGroup(
381
+ choices=scan_config, value=selected, label="Scan Settings", visible=True
382
+ )
383
 
384
  with gr.Row():
385
  model_id_input = gr.Textbox(
 
392
  placeholder="tweet_eval",
393
  )
394
  with gr.Row():
395
+ dataset_config_input = gr.Dropdown(label="Dataset Config", visible=False)
396
+ dataset_split_input = gr.Dropdown(label="Dataset Split", visible=False)
397
+
398
  with gr.Row(visible=True) as loading_row:
399
+ gr.Markdown(
400
+ """
401
  <p style="text-align: center;">
402
  🚀🐢Please validate your model and dataset first...
403
  </p>
404
+ """
405
+ )
406
+
407
  with gr.Row(visible=False) as preview_row:
408
+ gr.Markdown(
409
+ """
410
  <h1 style="text-align: center;">
411
  Confirm Pre-processing Details
412
  </h1>
413
  Base on your model and dataset, we inferred this label mapping and feature mapping. <b>If the mapping is incorrect, please modify it in the table below.</b>
414
+ """
415
+ )
416
+
417
  with gr.Row():
418
+ id2label_mapping_dataframe = gr.DataFrame(
419
+ label="Preview of label mapping", interactive=True, visible=False
420
+ )
421
+ feature_mapping_dataframe = gr.DataFrame(
422
+ label="Preview of feature mapping", interactive=True, visible=False
423
+ )
424
  with gr.Row():
425
+ example_input = gr.Markdown("Sample Input: ", visible=False)
426
+
427
  with gr.Row():
428
+ example_labels = gr.Label(label="Model Prediction Sample", visible=False)
429
+
430
  run_btn = gr.Button(
431
  "Get Evaluation Result",
432
  variant="primary",
433
  interactive=False,
434
  size="lg",
435
  )
 
 
436
 
437
+ model_id_input.blur(
438
+ clear_column_mapping_tables,
439
+ outputs=[id2label_mapping_dataframe, feature_mapping_dataframe],
440
+ )
441
 
442
+ dataset_id_input.blur(
443
+ check_dataset_and_get_config, dataset_id_input, dataset_config_input
444
+ )
445
+ dataset_id_input.submit(
446
+ check_dataset_and_get_config, dataset_id_input, dataset_config_input
447
+ )
448
 
449
  dataset_config_input.change(
450
+ check_dataset_and_get_split,
451
+ inputs=[dataset_config_input, dataset_id_input],
452
+ outputs=[dataset_split_input],
453
+ )
454
+
455
+ dataset_id_input.blur(
456
+ clear_column_mapping_tables,
457
+ outputs=[id2label_mapping_dataframe, feature_mapping_dataframe],
458
+ )
459
+ # model_id_input.blur(gate_validate_btn,
460
+ # inputs=[model_id_input, dataset_id_input, dataset_config_input, dataset_split_input],
461
  # outputs=[run_btn, loading_row, preview_row, example_input, example_labels, id2label_mapping_dataframe, feature_mapping_dataframe])
462
+ # dataset_id_input.blur(gate_validate_btn,
463
+ # inputs=[model_id_input, dataset_id_input, dataset_config_input, dataset_split_input],
464
+ # outputs=[run_btn, loading_row, preview_row, example_input, example_labels, id2label_mapping_dataframe, feature_mapping_dataframe])
465
+ dataset_config_input.change(
466
+ gate_validate_btn,
467
+ inputs=[
468
+ model_id_input,
469
+ dataset_id_input,
470
+ dataset_config_input,
471
+ dataset_split_input,
472
+ ],
473
+ outputs=[
474
+ run_btn,
475
+ loading_row,
476
+ preview_row,
477
+ example_input,
478
+ example_labels,
479
+ id2label_mapping_dataframe,
480
+ feature_mapping_dataframe,
481
+ ],
482
  )
483
+ dataset_split_input.change(
484
+ gate_validate_btn,
485
+ inputs=[
486
+ model_id_input,
487
+ dataset_id_input,
488
+ dataset_config_input,
489
+ dataset_split_input,
490
+ ],
491
+ outputs=[
492
+ run_btn,
493
+ loading_row,
494
+ preview_row,
495
+ example_input,
496
+ example_labels,
497
+ id2label_mapping_dataframe,
498
+ feature_mapping_dataframe,
499
+ ],
500
+ )
501
+ id2label_mapping_dataframe.input(
502
+ gate_validate_btn,
503
+ inputs=[
504
+ model_id_input,
505
+ dataset_id_input,
506
+ dataset_config_input,
507
+ dataset_split_input,
508
+ id2label_mapping_dataframe,
509
+ feature_mapping_dataframe,
510
+ ],
511
+ outputs=[
512
+ run_btn,
513
+ loading_row,
514
+ preview_row,
515
+ example_input,
516
+ example_labels,
517
+ id2label_mapping_dataframe,
518
+ feature_mapping_dataframe,
519
+ ],
520
+ )
521
+ feature_mapping_dataframe.input(
522
+ gate_validate_btn,
523
+ inputs=[
524
+ model_id_input,
525
+ dataset_id_input,
526
+ dataset_config_input,
527
+ dataset_split_input,
528
+ id2label_mapping_dataframe,
529
+ feature_mapping_dataframe,
530
+ ],
531
+ outputs=[
532
+ run_btn,
533
+ loading_row,
534
+ preview_row,
535
+ example_input,
536
+ example_labels,
537
+ id2label_mapping_dataframe,
538
+ feature_mapping_dataframe,
539
+ ],
540
+ )
541
+ scanners.change(write_scanners, inputs=scanners)
542
+ run_inference.change(write_inference_type, inputs=[run_inference])
543
 
544
  run_btn.click(
545
  try_submit,
 
555
  outputs=[
556
  run_btn,
557
  ],
558
+ )
app_text_classification.py CHANGED
@@ -1,15 +1,28 @@
1
  import gradio as gr
2
  import uuid
3
- from io_utils import read_scanners, write_scanners, read_inference_type, write_inference_type, get_logs_file
 
 
 
 
 
 
4
  from wordings import INTRODUCTION_MD, CONFIRM_MAPPING_DETAILS_MD
5
- from text_classification_ui_helpers import try_submit, check_dataset_and_get_config, check_dataset_and_get_split, check_model_and_show_prediction, write_column_mapping_to_config
 
 
 
 
 
 
6
 
7
  MAX_LABELS = 20
8
  MAX_FEATURES = 20
9
 
10
- EXAMPLE_MODEL_ID = 'cardiffnlp/twitter-roberta-base-sentiment-latest'
11
- EXAMPLE_DATA_ID = 'tweet_eval'
12
- CONFIG_PATH='./config.yaml'
 
13
 
14
  def get_demo(demo):
15
  with gr.Row():
@@ -24,18 +37,20 @@ def get_demo(demo):
24
  label="Hugging Face Dataset id",
25
  placeholder=EXAMPLE_DATA_ID + " (press enter to confirm)",
26
  )
27
-
28
  with gr.Row():
29
- dataset_config_input = gr.Dropdown(label='Dataset Config', visible=False)
30
- dataset_split_input = gr.Dropdown(label='Dataset Split', visible=False)
31
-
32
  with gr.Row():
33
- example_input = gr.Markdown('Example Input', visible=False)
34
  with gr.Row():
35
- example_prediction = gr.Label(label='Model Prediction Sample', visible=False)
36
-
37
  with gr.Row():
38
- with gr.Accordion(label='Label and Feature Mapping', visible=False, open=False) as column_mapping_accordion:
 
 
39
  with gr.Row():
40
  gr.Markdown(CONFIRM_MAPPING_DETAILS_MD)
41
  column_mappings = []
@@ -43,22 +58,24 @@ def get_demo(demo):
43
  with gr.Column():
44
  for _ in range(MAX_LABELS):
45
  column_mappings.append(gr.Dropdown(visible=False))
46
- with gr.Column():
47
  for _ in range(MAX_LABELS, MAX_LABELS + MAX_FEATURES):
48
  column_mappings.append(gr.Dropdown(visible=False))
49
-
50
- with gr.Accordion(label='Model Wrap Advance Config (optional)', open=False):
51
  run_local = gr.Checkbox(value=True, label="Run in this Space")
52
- use_inference = read_inference_type('./config.yaml') == 'hf_inference_api'
53
  run_inference = gr.Checkbox(value=use_inference, label="Run with Inference API")
54
-
55
- with gr.Accordion(label='Scanner Advance Config (optional)', open=False):
56
- selected = read_scanners('./config.yaml')
57
  # currently we remove data_leakage from the default scanners
58
  # Reason: data_leakage barely raises any issues and takes too many requests
59
  # when using inference API, causing rate limit error
60
- scan_config = selected + ['data_leakage']
61
- scanners = gr.CheckboxGroup(choices=scan_config, value=selected, label='Scan Settings', visible=True)
 
 
62
 
63
  with gr.Row():
64
  run_btn = gr.Button(
@@ -67,69 +84,97 @@ def get_demo(demo):
67
  interactive=True,
68
  size="lg",
69
  )
70
-
71
  with gr.Row():
72
  uid = uuid.uuid4()
73
- uid_label = gr.Textbox(label="Evaluation ID:", value=uid, visible=False, interactive=False)
 
 
74
  logs = gr.Textbox(label="Giskard Bot Evaluation Log:", visible=False)
75
  demo.load(get_logs_file, uid_label, logs, every=0.5)
76
-
77
- gr.on(triggers=[label.change for label in column_mappings],
 
78
  fn=write_column_mapping_to_config,
79
- inputs=[dataset_id_input, dataset_config_input, dataset_split_input, *column_mappings])
 
 
 
 
 
 
80
 
81
- gr.on(triggers=[model_id_input.change, dataset_config_input.change, dataset_split_input.change],
 
 
 
 
 
82
  fn=check_model_and_show_prediction,
83
- inputs=[model_id_input, dataset_id_input, dataset_config_input, dataset_split_input],
84
- outputs=[example_input, example_prediction, column_mapping_accordion, *column_mappings])
 
 
 
 
 
 
 
 
 
 
 
85
 
86
- dataset_id_input.blur(check_dataset_and_get_config, dataset_id_input, dataset_config_input)
 
 
87
 
88
  dataset_config_input.change(
89
- check_dataset_and_get_split,
90
- inputs=[dataset_id_input, dataset_config_input],
91
- outputs=[dataset_split_input])
92
-
93
- scanners.change(
94
- write_scanners,
95
- inputs=scanners
96
  )
97
 
98
- run_inference.change(
99
- write_inference_type,
100
- inputs=[run_inference]
101
- )
102
 
103
  gr.on(
104
  triggers=[
105
  run_btn.click,
106
- ],
107
  fn=try_submit,
108
  inputs=[
109
- model_id_input,
110
- dataset_id_input,
111
- dataset_config_input,
112
- dataset_split_input,
113
  run_local,
114
- uid_label],
115
- outputs=[run_btn, logs])
116
-
 
 
117
  def enable_run_btn():
118
- return (gr.update(interactive=True))
 
119
  gr.on(
120
  triggers=[
121
- model_id_input.change,
122
- dataset_config_input.change,
123
- dataset_split_input.change,
124
- run_inference.change,
125
- run_local.change,
126
- scanners.change],
 
127
  fn=enable_run_btn,
128
  inputs=None,
129
- outputs=[run_btn])
130
-
 
131
  gr.on(
132
  triggers=[label.change for label in column_mappings],
133
  fn=enable_run_btn,
134
  inputs=None,
135
- outputs=[run_btn])
 
 
1
  import gradio as gr
2
  import uuid
3
+ from io_utils import (
4
+ read_scanners,
5
+ write_scanners,
6
+ read_inference_type,
7
+ write_inference_type,
8
+ get_logs_file,
9
+ )
10
  from wordings import INTRODUCTION_MD, CONFIRM_MAPPING_DETAILS_MD
11
+ from text_classification_ui_helpers import (
12
+ try_submit,
13
+ check_dataset_and_get_config,
14
+ check_dataset_and_get_split,
15
+ check_model_and_show_prediction,
16
+ write_column_mapping_to_config,
17
+ )
18
 
19
  MAX_LABELS = 20
20
  MAX_FEATURES = 20
21
 
22
+ EXAMPLE_MODEL_ID = "cardiffnlp/twitter-roberta-base-sentiment-latest"
23
+ EXAMPLE_DATA_ID = "tweet_eval"
24
+ CONFIG_PATH = "./config.yaml"
25
+
26
 
27
  def get_demo(demo):
28
  with gr.Row():
 
37
  label="Hugging Face Dataset id",
38
  placeholder=EXAMPLE_DATA_ID + " (press enter to confirm)",
39
  )
40
+
41
  with gr.Row():
42
+ dataset_config_input = gr.Dropdown(label="Dataset Config", visible=False)
43
+ dataset_split_input = gr.Dropdown(label="Dataset Split", visible=False)
44
+
45
  with gr.Row():
46
+ example_input = gr.Markdown("Example Input", visible=False)
47
  with gr.Row():
48
+ example_prediction = gr.Label(label="Model Prediction Sample", visible=False)
49
+
50
  with gr.Row():
51
+ with gr.Accordion(
52
+ label="Label and Feature Mapping", visible=False, open=False
53
+ ) as column_mapping_accordion:
54
  with gr.Row():
55
  gr.Markdown(CONFIRM_MAPPING_DETAILS_MD)
56
  column_mappings = []
 
58
  with gr.Column():
59
  for _ in range(MAX_LABELS):
60
  column_mappings.append(gr.Dropdown(visible=False))
61
+ with gr.Column():
62
  for _ in range(MAX_LABELS, MAX_LABELS + MAX_FEATURES):
63
  column_mappings.append(gr.Dropdown(visible=False))
64
+
65
+ with gr.Accordion(label="Model Wrap Advance Config (optional)", open=False):
66
  run_local = gr.Checkbox(value=True, label="Run in this Space")
67
+ use_inference = read_inference_type(CONFIG_PATH) == "hf_inference_api"
68
  run_inference = gr.Checkbox(value=use_inference, label="Run with Inference API")
69
+
70
+ with gr.Accordion(label="Scanner Advance Config (optional)", open=False):
71
+ selected = read_scanners(CONFIG_PATH)
72
  # currently we remove data_leakage from the default scanners
73
  # Reason: data_leakage barely raises any issues and takes too many requests
74
  # when using inference API, causing rate limit error
75
+ scan_config = selected + ["data_leakage"]
76
+ scanners = gr.CheckboxGroup(
77
+ choices=scan_config, value=selected, label="Scan Settings", visible=True
78
+ )
79
 
80
  with gr.Row():
81
  run_btn = gr.Button(
 
84
  interactive=True,
85
  size="lg",
86
  )
87
+
88
  with gr.Row():
89
  uid = uuid.uuid4()
90
+ uid_label = gr.Textbox(
91
+ label="Evaluation ID:", value=uid, visible=False, interactive=False
92
+ )
93
  logs = gr.Textbox(label="Giskard Bot Evaluation Log:", visible=False)
94
  demo.load(get_logs_file, uid_label, logs, every=0.5)
95
+
96
+ gr.on(
97
+ triggers=[label.change for label in column_mappings],
98
  fn=write_column_mapping_to_config,
99
+ inputs=[
100
+ dataset_id_input,
101
+ dataset_config_input,
102
+ dataset_split_input,
103
+ *column_mappings,
104
+ ],
105
+ )
106
 
107
+ gr.on(
108
+ triggers=[
109
+ model_id_input.change,
110
+ dataset_config_input.change,
111
+ dataset_split_input.change,
112
+ ],
113
  fn=check_model_and_show_prediction,
114
+ inputs=[
115
+ model_id_input,
116
+ dataset_id_input,
117
+ dataset_config_input,
118
+ dataset_split_input,
119
+ ],
120
+ outputs=[
121
+ example_input,
122
+ example_prediction,
123
+ column_mapping_accordion,
124
+ *column_mappings,
125
+ ],
126
+ )
127
 
128
+ dataset_id_input.blur(
129
+ check_dataset_and_get_config, dataset_id_input, dataset_config_input
130
+ )
131
 
132
  dataset_config_input.change(
133
+ check_dataset_and_get_split,
134
+ inputs=[dataset_id_input, dataset_config_input],
135
+ outputs=[dataset_split_input],
 
 
 
 
136
  )
137
 
138
+ scanners.change(write_scanners, inputs=scanners)
139
+
140
+ run_inference.change(write_inference_type, inputs=[run_inference])
 
141
 
142
  gr.on(
143
  triggers=[
144
  run_btn.click,
145
+ ],
146
  fn=try_submit,
147
  inputs=[
148
+ model_id_input,
149
+ dataset_id_input,
150
+ dataset_config_input,
151
+ dataset_split_input,
152
  run_local,
153
+ uid_label,
154
+ ],
155
+ outputs=[run_btn, logs],
156
+ )
157
+
158
  def enable_run_btn():
159
+ return gr.update(interactive=True)
160
+
161
  gr.on(
162
  triggers=[
163
+ model_id_input.change,
164
+ dataset_config_input.change,
165
+ dataset_split_input.change,
166
+ run_inference.change,
167
+ run_local.change,
168
+ scanners.change,
169
+ ],
170
  fn=enable_run_btn,
171
  inputs=None,
172
+ outputs=[run_btn],
173
+ )
174
+
175
  gr.on(
176
  triggers=[label.change for label in column_mappings],
177
  fn=enable_run_btn,
178
  inputs=None,
179
+ outputs=[run_btn],
180
+ )
fetch_utils.py CHANGED
@@ -1,6 +1,8 @@
1
- import datasets
2
  import logging
3
 
 
 
 
4
  def check_dataset_and_get_config(dataset_id):
5
  try:
6
  configs = datasets.get_dataset_config_names(dataset_id)
@@ -9,17 +11,22 @@ def check_dataset_and_get_config(dataset_id):
9
  # Dataset may not exist
10
  return None
11
 
 
12
  def check_dataset_and_get_split(dataset_id, dataset_config):
13
  try:
14
  ds = datasets.load_dataset(dataset_id, dataset_config)
15
  except Exception as e:
16
  # Dataset may not exist
17
- logging.warning(f"Failed to load dataset {dataset_id} with config {dataset_config}: {e}")
 
 
18
  return None
19
  try:
20
  splits = list(ds.keys())
21
  return splits
22
  except Exception as e:
23
  # Dataset has no splits
24
- logging.warning(f"Dataset {dataset_id} with config {dataset_config} has no splits: {e}")
25
- return None
 
 
 
 
1
  import logging
2
 
3
+ import datasets
4
+
5
+
6
  def check_dataset_and_get_config(dataset_id):
7
  try:
8
  configs = datasets.get_dataset_config_names(dataset_id)
 
11
  # Dataset may not exist
12
  return None
13
 
14
+
15
  def check_dataset_and_get_split(dataset_id, dataset_config):
16
  try:
17
  ds = datasets.load_dataset(dataset_id, dataset_config)
18
  except Exception as e:
19
  # Dataset may not exist
20
+ logging.warning(
21
+ f"Failed to load dataset {dataset_id} with config {dataset_config}: {e}"
22
+ )
23
  return None
24
  try:
25
  splits = list(ds.keys())
26
  return splits
27
  except Exception as e:
28
  # Dataset has no splits
29
+ logging.warning(
30
+ f"Dataset {dataset_id} with config {dataset_config} has no splits: {e}"
31
+ )
32
+ return None
io_utils.py CHANGED
@@ -1,14 +1,17 @@
1
- import yaml
2
- import subprocess
3
  import os
 
 
 
4
 
5
  YAML_PATH = "./config.yaml"
6
  PIPE_PATH = "./tmp/pipe"
7
 
 
8
  class Dumper(yaml.Dumper):
9
  def increase_indent(self, flow=False, *args, **kwargs):
10
  return super().increase_indent(flow=flow, indentless=False)
11
-
 
12
  # read scanners from yaml file
13
  # return a list of scanners
14
  def read_scanners(path):
@@ -18,6 +21,7 @@ def read_scanners(path):
18
  scanners = config.get("detectors", [])
19
  return scanners
20
 
 
21
  # convert a list of scanners to yaml file
22
  def write_scanners(scanners):
23
  print(scanners)
@@ -28,6 +32,7 @@ def write_scanners(scanners):
28
  # save scanners to detectors in yaml
29
  yaml.dump(config, f, Dumper=Dumper)
30
 
 
31
  # read model_type from yaml file
32
  def read_inference_type(path):
33
  inference_type = ""
@@ -36,17 +41,19 @@ def read_inference_type(path):
36
  inference_type = config.get("inference_type", "")
37
  return inference_type
38
 
 
39
  # write model_type to yaml file
40
  def write_inference_type(use_inference):
41
  with open(YAML_PATH, "r+") as f:
42
  config = yaml.load(f, Loader=yaml.FullLoader)
43
  if use_inference:
44
- config["inference_type"] = 'hf_inference_api'
45
  else:
46
- config["inference_type"] = 'hf_pipeline'
47
  # save inference_type to inference_type in yaml
48
  yaml.dump(config, f, Dumper=Dumper)
49
 
 
50
  # read column mapping from yaml file
51
  def read_column_mapping(path):
52
  column_mapping = {}
@@ -56,6 +63,7 @@ def read_column_mapping(path):
56
  column_mapping = config.get("column_mapping", dict())
57
  return column_mapping
58
 
 
59
  # write column mapping to yaml file
60
  def write_column_mapping(mapping):
61
  with open(YAML_PATH, "r") as f:
@@ -70,6 +78,7 @@ def write_column_mapping(mapping):
70
  # save column_mapping to column_mapping in yaml
71
  yaml.dump(config, f, Dumper=Dumper)
72
 
 
73
  # convert column mapping dataframe to json
74
  def convert_column_mapping_to_json(df, label=""):
75
  column_mapping = {}
@@ -78,6 +87,7 @@ def convert_column_mapping_to_json(df, label=""):
78
  column_mapping[label].append(row.tolist())
79
  return column_mapping
80
 
 
81
  def get_logs_file(uid):
82
  try:
83
  file = open(f"./tmp/{uid}_log", "r")
@@ -85,20 +95,23 @@ def get_logs_file(uid):
85
  except Exception:
86
  return "Log file does not exist"
87
 
 
88
  def write_log_to_user_file(id, log):
89
  with open(f"./tmp/{id}_log", "a") as f:
90
  f.write(log)
91
 
 
92
  def save_job_to_pipe(id, job, lock):
93
- if not os.path.exists('./tmp'):
94
- os.makedirs('./tmp')
95
  job = [str(i) for i in job]
96
  job = ",".join(job)
97
  print(job)
98
  with lock:
99
  with open(PIPE_PATH, "a") as f:
100
  # write each element in job
101
- f.write(f'{id}@{job}\n')
 
102
 
103
  def pop_job_from_pipe():
104
  if not os.path.exists(PIPE_PATH):
@@ -113,7 +126,7 @@ def pop_job_from_pipe():
113
  f.close()
114
  if len(job) == 0:
115
  return
116
- job_info = job.split('\n')[0].split("@")
117
  if len(job_info) != 2:
118
  raise ValueError("Invalid job info: ", job_info)
119
 
 
 
 
1
  import os
2
+ import subprocess
3
+
4
+ import yaml
5
 
6
  YAML_PATH = "./config.yaml"
7
  PIPE_PATH = "./tmp/pipe"
8
 
9
+
10
  class Dumper(yaml.Dumper):
11
  def increase_indent(self, flow=False, *args, **kwargs):
12
  return super().increase_indent(flow=flow, indentless=False)
13
+
14
+
15
  # read scanners from yaml file
16
  # return a list of scanners
17
  def read_scanners(path):
 
21
  scanners = config.get("detectors", [])
22
  return scanners
23
 
24
+
25
  # convert a list of scanners to yaml file
26
  def write_scanners(scanners):
27
  print(scanners)
 
32
  # save scanners to detectors in yaml
33
  yaml.dump(config, f, Dumper=Dumper)
34
 
35
+
36
  # read model_type from yaml file
37
  def read_inference_type(path):
38
  inference_type = ""
 
41
  inference_type = config.get("inference_type", "")
42
  return inference_type
43
 
44
+
45
  # write model_type to yaml file
46
  def write_inference_type(use_inference):
47
  with open(YAML_PATH, "r+") as f:
48
  config = yaml.load(f, Loader=yaml.FullLoader)
49
  if use_inference:
50
+ config["inference_type"] = "hf_inference_api"
51
  else:
52
+ config["inference_type"] = "hf_pipeline"
53
  # save inference_type to inference_type in yaml
54
  yaml.dump(config, f, Dumper=Dumper)
55
 
56
+
57
  # read column mapping from yaml file
58
  def read_column_mapping(path):
59
  column_mapping = {}
 
63
  column_mapping = config.get("column_mapping", dict())
64
  return column_mapping
65
 
66
+
67
  # write column mapping to yaml file
68
  def write_column_mapping(mapping):
69
  with open(YAML_PATH, "r") as f:
 
78
  # save column_mapping to column_mapping in yaml
79
  yaml.dump(config, f, Dumper=Dumper)
80
 
81
+
82
  # convert column mapping dataframe to json
83
  def convert_column_mapping_to_json(df, label=""):
84
  column_mapping = {}
 
87
  column_mapping[label].append(row.tolist())
88
  return column_mapping
89
 
90
+
91
  def get_logs_file(uid):
92
  try:
93
  file = open(f"./tmp/{uid}_log", "r")
 
95
  except Exception:
96
  return "Log file does not exist"
97
 
98
+
99
  def write_log_to_user_file(id, log):
100
  with open(f"./tmp/{id}_log", "a") as f:
101
  f.write(log)
102
 
103
+
104
  def save_job_to_pipe(id, job, lock):
105
+ if not os.path.exists("./tmp"):
106
+ os.makedirs("./tmp")
107
  job = [str(i) for i in job]
108
  job = ",".join(job)
109
  print(job)
110
  with lock:
111
  with open(PIPE_PATH, "a") as f:
112
  # write each element in job
113
+ f.write(f"{id}@{job}\n")
114
+
115
 
116
  def pop_job_from_pipe():
117
  if not os.path.exists(PIPE_PATH):
 
126
  f.close()
127
  if len(job) == 0:
128
  return
129
+ job_info = job.split("\n")[0].split("@")
130
  if len(job_info) != 2:
131
  raise ValueError("Invalid job info: ", job_info)
132
 
mlflow_test.py ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pathlib import Path
2
+ from mlflow.utils.environment import _PythonEnv
3
+ from mlflow.utils.virtualenv import (
4
+ _PYENV_ROOT_DIR,
5
+ _VIRTUALENV_ENVS_DIR,
6
+ _create_virtualenv,
7
+ _get_mlflow_virtualenv_root,
8
+ _get_virtualenv_extra_env_vars,
9
+ _get_virtualenv_name,
10
+ _install_python,
11
+ )
12
+
13
+
14
+ _create_virtualenv(
15
+ "/Users/inoki/giskard-home/projects/credit/models/2a2b6a9c-4050-4bb6-9024-00bf15651262",
16
+ Path("/opt/homebrew/bin/python3.10"),
17
+ Path("/Users/inoki/giskard-home/mlflow-venv1"),
18
+ _PythonEnv()
19
+ )
20
+
run_jobs.py CHANGED
@@ -1,11 +1,13 @@
1
- from io_utils import pop_job_from_pipe
2
- import time
3
  import threading
 
 
 
 
4
 
5
  def start_process_run_job():
6
  try:
7
  print("Running jobs in thread")
8
- global thread
9
  thread = threading.Thread(target=run_job)
10
  thread.daemon = True
11
  thread.do_run = True
@@ -13,11 +15,14 @@ def start_process_run_job():
13
 
14
  except Exception as e:
15
  print("Failed to start thread: ", e)
 
 
16
  def stop_thread():
17
  print("Stop thread")
18
  thread.do_run = False
19
 
20
- def run_job():
 
21
  while True:
22
  print(thread.do_run)
23
  try:
@@ -26,4 +31,4 @@ def run_job():
26
  except KeyboardInterrupt:
27
  print("KeyboardInterrupt stop background thread")
28
  stop_thread()
29
- break
 
 
 
1
  import threading
2
+ import time
3
+
4
+ from io_utils import pop_job_from_pipe
5
+
6
 
7
  def start_process_run_job():
8
  try:
9
  print("Running jobs in thread")
10
+ global thread
11
  thread = threading.Thread(target=run_job)
12
  thread.daemon = True
13
  thread.do_run = True
 
15
 
16
  except Exception as e:
17
  print("Failed to start thread: ", e)
18
+
19
+
20
  def stop_thread():
21
  print("Stop thread")
22
  thread.do_run = False
23
 
24
+
25
+ def run_job():
26
  while True:
27
  print(thread.do_run)
28
  try:
 
31
  except KeyboardInterrupt:
32
  print("KeyboardInterrupt stop background thread")
33
  stop_thread()
34
+ break
text_classification.py CHANGED
@@ -1,10 +1,12 @@
1
- import datasets
2
- import logging
3
  import json
4
- import pandas as pd
 
 
5
  import huggingface_hub
 
6
  from transformers import pipeline
7
 
 
8
  def get_labels_and_features_from_dataset(dataset_id, dataset_config, split):
9
  try:
10
  ds = datasets.load_dataset(dataset_id, dataset_config)[split]
@@ -13,9 +15,12 @@ def get_labels_and_features_from_dataset(dataset_id, dataset_config, split):
13
  features = [f for f in dataset_features.keys() if f != "label"]
14
  return labels, features
15
  except Exception as e:
16
- logging.warning(f"Failed to load dataset {dataset_id} with config {dataset_config}: {e}")
 
 
17
  return None, None
18
 
 
19
  def check_model(model_id):
20
  try:
21
  task = huggingface_hub.model_info(model_id).pipeline_tag
@@ -28,7 +33,7 @@ def check_model(model_id):
28
  return ppl
29
  except Exception:
30
  return None
31
-
32
 
33
  def text_classificaiton_match_label_case_unsensative(id2label_mapping, label):
34
  for model_label in id2label_mapping.keys():
@@ -45,7 +50,7 @@ def text_classification_map_model_and_dataset_labels(id2label, dataset_features)
45
  continue
46
  if len(feature.names) != len(id2label_mapping.keys()):
47
  continue
48
-
49
  dataset_labels = feature.names
50
  # Try to match labels
51
  for label in feature.names:
@@ -53,7 +58,9 @@ def text_classification_map_model_and_dataset_labels(id2label, dataset_features)
53
  model_label = label
54
  else:
55
  # Try to find case unsensative
56
- model_label, label = text_classificaiton_match_label_case_unsensative(id2label_mapping, label)
 
 
57
  if model_label is not None:
58
  id2label_mapping[model_label] = label
59
  else:
@@ -61,7 +68,8 @@ def text_classification_map_model_and_dataset_labels(id2label, dataset_features)
61
 
62
  return id2label_mapping, dataset_labels
63
 
64
- '''
 
65
  params:
66
  column_mapping: dict
67
  example: {
@@ -72,7 +80,9 @@ params:
72
  }
73
  }
74
  ppl: pipeline
75
- '''
 
 
76
  def check_column_mapping_keys_validity(column_mapping, ppl):
77
  # get the element in all the list elements
78
  column_mapping = json.loads(column_mapping)
@@ -83,10 +93,11 @@ def check_column_mapping_keys_validity(column_mapping, ppl):
83
 
84
  id2label = ppl.model.config.id2label
85
  original_labels = set(id2label.values())
86
-
87
  return user_labels == model_labels == original_labels
88
 
89
- '''
 
90
  params:
91
  column_mapping: dict
92
  dataset_features: dict
@@ -94,7 +105,9 @@ params:
94
  'text': Value(dtype='string', id=None),
95
  'label': ClassLabel(names=['negative', 'neutral', 'positive'], id=None)
96
  }
97
- '''
 
 
98
  def infer_text_input_column(column_mapping, dataset_features):
99
  # Check whether we need to infer the text input column
100
  infer_text_input_column = True
@@ -109,18 +122,20 @@ def infer_text_input_column(column_mapping, dataset_features):
109
 
110
  if infer_text_input_column:
111
  # Try to retrieve one
112
- candidates = [f for f in dataset_features if dataset_features[f].dtype == "string"]
113
- feature_map_df = pd.DataFrame({
114
- "Dataset Features": [candidates[0]],
115
- "Model Input Features": ["text"]
116
- })
 
117
  if len(candidates) > 0:
118
  logging.debug(f"Candidates are {candidates}")
119
  column_mapping["text"] = candidates[0]
120
-
121
  return column_mapping, feature_map_df
122
 
123
- '''
 
124
  params:
125
  column_mapping: dict
126
  id2label_mapping: dict
@@ -130,8 +145,12 @@ params:
130
  'neutral': 'neutral',
131
  'positive': 'positive'
132
  }
133
- '''
134
- def infer_output_label_column(column_mapping, id2label_mapping, id2label, dataset_labels):
 
 
 
 
135
  # Check whether we need to infer the output label column
136
  if "data" in column_mapping.keys():
137
  if isinstance(column_mapping["data"], list):
@@ -139,25 +158,29 @@ def infer_output_label_column(column_mapping, id2label_mapping, id2label, datase
139
  for user_label, model_label in column_mapping["data"]:
140
  id2label_mapping[model_label] = user_label
141
  elif None in id2label_mapping.values():
142
- column_mapping["label"] = {
143
- i: None for i in id2label.keys()
144
- }
145
  return column_mapping, None
146
-
147
  if "data" not in column_mapping.keys():
148
  # Column mapping should contain original model labels
149
  column_mapping["label"] = {
150
- str(i): id2label_mapping[label] for i, label in zip(id2label.keys(), dataset_labels)
 
151
  }
152
  # print('>>>>> column_mapping >>>>>', column_mapping)
153
 
154
- id2label_df = pd.DataFrame({
155
- "Dataset Labels": dataset_labels,
156
- "Model Prediction Labels": [id2label_mapping[label] for label in dataset_labels],
157
- })
 
 
 
 
158
 
159
  return column_mapping, id2label_df
160
 
 
161
  def check_dataset_features_validity(d_id, config, split):
162
  # We assume dataset is ok here
163
  ds = datasets.load_dataset(d_id, config)[split]
@@ -171,6 +194,7 @@ def check_dataset_features_validity(d_id, config, split):
171
 
172
  return df, dataset_features
173
 
 
174
  def get_example_prediction(ppl, dataset_id, dataset_config, dataset_split):
175
  # get a sample prediction from the model on the dataset
176
  prediction_input = None
@@ -184,7 +208,7 @@ def get_example_prediction(ppl, dataset_id, dataset_config, dataset_split):
184
  else:
185
  prediction_input = ds[0]["text"]
186
 
187
- print('prediction_input', prediction_input)
188
  results = ppl(prediction_input, top_k=None)
189
  # Display results in original label and mapped label
190
  prediction_result = {
@@ -193,7 +217,6 @@ def get_example_prediction(ppl, dataset_id, dataset_config, dataset_split):
193
  except Exception:
194
  # Pipeline prediction failed, need to provide labels
195
  return prediction_input, None
196
-
197
 
198
  return prediction_input, prediction_result
199
 
@@ -212,37 +235,55 @@ def get_sample_prediction(ppl, df, column_mapping, id2label_mapping):
212
  except Exception:
213
  # Pipeline prediction failed, need to provide labels
214
  return prediction_input, None
215
-
216
  # Display results in original label and mapped label
217
  prediction_result = {
218
- f'{result["label"]}(original) - {id2label_mapping[result["label"]]}(mapped)': result["score"] for result in results
 
 
 
219
  }
220
  return prediction_input, prediction_result
221
 
 
222
  def text_classification_fix_column_mapping(column_mapping, ppl, d_id, config, split):
223
  # load dataset as pd DataFrame
224
  # get features column from dataset
225
  df, dataset_features = check_dataset_features_validity(d_id, config, split)
226
 
227
- column_mapping, feature_map_df = infer_text_input_column(column_mapping, dataset_features)
 
 
228
  if feature_map_df is None:
229
  # dataset does not have any features
230
- return None, None, None, None, None
231
 
232
  # Retrieve all labels
233
  id2label = ppl.model.config.id2label
234
 
235
  # Infer labels
236
- id2label_mapping, dataset_labels = text_classification_map_model_and_dataset_labels(id2label, dataset_features)
237
- column_mapping, id2label_df = infer_output_label_column(column_mapping, id2label_mapping, id2label, dataset_labels)
 
 
 
 
238
  if id2label_df is None:
239
  # does not able to infer output label column
240
  return column_mapping, None, None, None, feature_map_df
241
-
242
  # Get a sample prediction
243
- prediction_input, prediction_result = get_sample_prediction(ppl, df, column_mapping, id2label_mapping)
 
 
244
  if prediction_result is None:
245
  # does not able to get a sample prediction
246
  return column_mapping, prediction_input, None, id2label_df, feature_map_df
247
-
248
- return column_mapping, prediction_input, prediction_result, id2label_df, feature_map_df
 
 
 
 
 
 
 
 
 
1
  import json
2
+ import logging
3
+
4
+ import datasets
5
  import huggingface_hub
6
+ import pandas as pd
7
  from transformers import pipeline
8
 
9
+
10
  def get_labels_and_features_from_dataset(dataset_id, dataset_config, split):
11
  try:
12
  ds = datasets.load_dataset(dataset_id, dataset_config)[split]
 
15
  features = [f for f in dataset_features.keys() if f != "label"]
16
  return labels, features
17
  except Exception as e:
18
+ logging.warning(
19
+ f"Failed to load dataset {dataset_id} with config {dataset_config}: {e}"
20
+ )
21
  return None, None
22
 
23
+
24
  def check_model(model_id):
25
  try:
26
  task = huggingface_hub.model_info(model_id).pipeline_tag
 
33
  return ppl
34
  except Exception:
35
  return None
36
+
37
 
38
  def text_classificaiton_match_label_case_unsensative(id2label_mapping, label):
39
  for model_label in id2label_mapping.keys():
 
50
  continue
51
  if len(feature.names) != len(id2label_mapping.keys()):
52
  continue
53
+
54
  dataset_labels = feature.names
55
  # Try to match labels
56
  for label in feature.names:
 
58
  model_label = label
59
  else:
60
  # Try to find case unsensative
61
+ model_label, label = text_classificaiton_match_label_case_unsensative(
62
+ id2label_mapping, label
63
+ )
64
  if model_label is not None:
65
  id2label_mapping[model_label] = label
66
  else:
 
68
 
69
  return id2label_mapping, dataset_labels
70
 
71
+
72
+ """
73
  params:
74
  column_mapping: dict
75
  example: {
 
80
  }
81
  }
82
  ppl: pipeline
83
+ """
84
+
85
+
86
  def check_column_mapping_keys_validity(column_mapping, ppl):
87
  # get the element in all the list elements
88
  column_mapping = json.loads(column_mapping)
 
93
 
94
  id2label = ppl.model.config.id2label
95
  original_labels = set(id2label.values())
96
+
97
  return user_labels == model_labels == original_labels
98
 
99
+
100
+ """
101
  params:
102
  column_mapping: dict
103
  dataset_features: dict
 
105
  'text': Value(dtype='string', id=None),
106
  'label': ClassLabel(names=['negative', 'neutral', 'positive'], id=None)
107
  }
108
+ """
109
+
110
+
111
  def infer_text_input_column(column_mapping, dataset_features):
112
  # Check whether we need to infer the text input column
113
  infer_text_input_column = True
 
122
 
123
  if infer_text_input_column:
124
  # Try to retrieve one
125
+ candidates = [
126
+ f for f in dataset_features if dataset_features[f].dtype == "string"
127
+ ]
128
+ feature_map_df = pd.DataFrame(
129
+ {"Dataset Features": [candidates[0]], "Model Input Features": ["text"]}
130
+ )
131
  if len(candidates) > 0:
132
  logging.debug(f"Candidates are {candidates}")
133
  column_mapping["text"] = candidates[0]
134
+
135
  return column_mapping, feature_map_df
136
 
137
+
138
+ """
139
  params:
140
  column_mapping: dict
141
  id2label_mapping: dict
 
145
  'neutral': 'neutral',
146
  'positive': 'positive'
147
  }
148
+ """
149
+
150
+
151
+ def infer_output_label_column(
152
+ column_mapping, id2label_mapping, id2label, dataset_labels
153
+ ):
154
  # Check whether we need to infer the output label column
155
  if "data" in column_mapping.keys():
156
  if isinstance(column_mapping["data"], list):
 
158
  for user_label, model_label in column_mapping["data"]:
159
  id2label_mapping[model_label] = user_label
160
  elif None in id2label_mapping.values():
161
+ column_mapping["label"] = {i: None for i in id2label.keys()}
 
 
162
  return column_mapping, None
163
+
164
  if "data" not in column_mapping.keys():
165
  # Column mapping should contain original model labels
166
  column_mapping["label"] = {
167
+ str(i): id2label_mapping[label]
168
+ for i, label in zip(id2label.keys(), dataset_labels)
169
  }
170
  # print('>>>>> column_mapping >>>>>', column_mapping)
171
 
172
+ id2label_df = pd.DataFrame(
173
+ {
174
+ "Dataset Labels": dataset_labels,
175
+ "Model Prediction Labels": [
176
+ id2label_mapping[label] for label in dataset_labels
177
+ ],
178
+ }
179
+ )
180
 
181
  return column_mapping, id2label_df
182
 
183
+
184
  def check_dataset_features_validity(d_id, config, split):
185
  # We assume dataset is ok here
186
  ds = datasets.load_dataset(d_id, config)[split]
 
194
 
195
  return df, dataset_features
196
 
197
+
198
  def get_example_prediction(ppl, dataset_id, dataset_config, dataset_split):
199
  # get a sample prediction from the model on the dataset
200
  prediction_input = None
 
208
  else:
209
  prediction_input = ds[0]["text"]
210
 
211
+ print("prediction_input", prediction_input)
212
  results = ppl(prediction_input, top_k=None)
213
  # Display results in original label and mapped label
214
  prediction_result = {
 
217
  except Exception:
218
  # Pipeline prediction failed, need to provide labels
219
  return prediction_input, None
 
220
 
221
  return prediction_input, prediction_result
222
 
 
235
  except Exception:
236
  # Pipeline prediction failed, need to provide labels
237
  return prediction_input, None
238
+
239
  # Display results in original label and mapped label
240
  prediction_result = {
241
+ f'{result["label"]}(original) - {id2label_mapping[result["label"]]}(mapped)': result[
242
+ "score"
243
+ ]
244
+ for result in results
245
  }
246
  return prediction_input, prediction_result
247
 
248
+
249
  def text_classification_fix_column_mapping(column_mapping, ppl, d_id, config, split):
250
  # load dataset as pd DataFrame
251
  # get features column from dataset
252
  df, dataset_features = check_dataset_features_validity(d_id, config, split)
253
 
254
+ column_mapping, feature_map_df = infer_text_input_column(
255
+ column_mapping, dataset_features
256
+ )
257
  if feature_map_df is None:
258
  # dataset does not have any features
259
+ return None, None, None, None, None
260
 
261
  # Retrieve all labels
262
  id2label = ppl.model.config.id2label
263
 
264
  # Infer labels
265
+ id2label_mapping, dataset_labels = text_classification_map_model_and_dataset_labels(
266
+ id2label, dataset_features
267
+ )
268
+ column_mapping, id2label_df = infer_output_label_column(
269
+ column_mapping, id2label_mapping, id2label, dataset_labels
270
+ )
271
  if id2label_df is None:
272
  # does not able to infer output label column
273
  return column_mapping, None, None, None, feature_map_df
274
+
275
  # Get a sample prediction
276
+ prediction_input, prediction_result = get_sample_prediction(
277
+ ppl, df, column_mapping, id2label_mapping
278
+ )
279
  if prediction_result is None:
280
  # does not able to get a sample prediction
281
  return column_mapping, prediction_input, None, id2label_df, feature_map_df
282
+
283
+ return (
284
+ column_mapping,
285
+ prediction_input,
286
+ prediction_result,
287
+ id2label_df,
288
+ feature_map_df,
289
+ )
text_classification_ui_helpers.py CHANGED
@@ -1,23 +1,35 @@
1
- import gradio as gr
2
- from wordings import CONFIRM_MAPPING_DETAILS_FAIL_RAW
3
  import json
4
- import os
5
  import logging
 
6
  import threading
7
- from io_utils import read_column_mapping, write_column_mapping, save_job_to_pipe, write_log_to_user_file
8
  import datasets
9
- import collections
10
- from text_classification import get_labels_and_features_from_dataset, check_model, get_example_prediction
11
  from transformers.pipelines import TextClassificationPipeline
12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  MAX_LABELS = 20
14
  MAX_FEATURES = 20
15
 
16
- HF_REPO_ID = 'HF_REPO_ID'
17
- HF_SPACE_ID = 'SPACE_ID'
18
- HF_WRITE_TOKEN = 'HF_WRITE_TOKEN'
19
  CONFIG_PATH = "./config.yaml"
20
 
 
21
  def check_dataset_and_get_config(dataset_id):
22
  try:
23
  write_column_mapping(None)
@@ -27,6 +39,7 @@ def check_dataset_and_get_config(dataset_id):
27
  # Dataset may not exist
28
  pass
29
 
 
30
  def check_dataset_and_get_split(dataset_id, dataset_config):
31
  try:
32
  splits = list(datasets.load_dataset(dataset_id, dataset_config).keys())
@@ -36,8 +49,11 @@ def check_dataset_and_get_split(dataset_id, dataset_config):
36
  # gr.Warning(f"Failed to load dataset {dataset_id} with config {dataset_config}: {e}")
37
  pass
38
 
 
39
  def write_column_mapping_to_config(dataset_id, dataset_config, dataset_split, *labels):
40
- ds_labels, ds_features = get_labels_and_features_from_dataset(dataset_id, dataset_config, dataset_split)
 
 
41
  if labels is None:
42
  return
43
  labels = [*labels]
@@ -54,45 +70,73 @@ def write_column_mapping_to_config(dataset_id, dataset_config, dataset_split, *l
54
 
55
  if "features" not in all_mappings.keys():
56
  all_mappings["features"] = dict()
57
- for i, feat in enumerate(labels[MAX_LABELS:(MAX_LABELS + MAX_FEATURES)]):
58
  if feat:
59
  all_mappings["features"][feat] = ds_features[i]
60
  write_column_mapping(all_mappings)
61
 
 
62
  def list_labels_and_features_from_dataset(ds_labels, ds_features, model_id2label):
63
  model_labels = list(model_id2label.values())
64
  len_model_labels = len(model_labels)
65
- print(model_labels, model_id2label, 3%len_model_labels)
66
- lables = [gr.Dropdown(label=f"{label}", choices=model_labels, value=model_id2label[i%len_model_labels], interactive=True, visible=True) for i, label in enumerate(ds_labels[:MAX_LABELS])]
 
 
 
 
 
 
 
 
 
67
  lables += [gr.Dropdown(visible=False) for _ in range(MAX_LABELS - len(lables))]
68
  # TODO: Substitute 'text' with more features for zero-shot
69
- features = [gr.Dropdown(label=f"{feature}", choices=ds_features, value=ds_features[0], interactive=True, visible=True) for feature in ['text']]
70
- features += [gr.Dropdown(visible=False) for _ in range(MAX_FEATURES - len(features))]
 
 
 
 
 
 
 
 
 
 
 
71
  return lables + features
72
 
73
- def check_model_and_show_prediction(model_id, dataset_id, dataset_config, dataset_split):
 
 
 
74
  ppl = check_model(model_id)
75
  if ppl is None or not isinstance(ppl, TextClassificationPipeline):
76
  gr.Warning("Please check your model.")
77
  return (
78
  gr.update(visible=False),
79
  gr.update(visible=False),
80
- *[gr.update(visible=False) for _ in range(MAX_LABELS + MAX_FEATURES)]
81
  )
82
-
83
- dropdown_placement = [gr.Dropdown(visible=False) for _ in range(MAX_LABELS + MAX_FEATURES)]
84
-
85
- if ppl is None: # pipeline not found
 
 
86
  gr.Warning("Model not found")
87
  return (
88
  gr.update(visible=False),
89
  gr.update(visible=False),
90
  gr.update(visible=False, open=False),
91
- *dropdown_placement
92
  )
93
  model_id2label = ppl.model.config.id2label
94
- ds_labels, ds_features = get_labels_and_features_from_dataset(dataset_id, dataset_config, dataset_split)
95
-
 
 
96
  # when dataset does not have labels or features
97
  if not isinstance(ds_labels, list) or not isinstance(ds_features, list):
98
  # gr.Warning(CONFIRM_MAPPING_DETAILS_FAIL_RAW)
@@ -100,9 +144,9 @@ def check_model_and_show_prediction(model_id, dataset_id, dataset_config, datase
100
  gr.update(visible=False),
101
  gr.update(visible=False),
102
  gr.update(visible=False, open=False),
103
- *dropdown_placement
104
  )
105
-
106
  column_mappings = list_labels_and_features_from_dataset(
107
  ds_labels,
108
  ds_features,
@@ -111,23 +155,29 @@ def check_model_and_show_prediction(model_id, dataset_id, dataset_config, datase
111
 
112
  # when labels or features are not aligned
113
  # show manually column mapping
114
- if collections.Counter(model_id2label.values()) != collections.Counter(ds_labels) or ds_features[0] != 'text':
 
 
 
115
  gr.Warning(CONFIRM_MAPPING_DETAILS_FAIL_RAW)
116
  return (
117
  gr.update(visible=False),
118
  gr.update(visible=False),
119
  gr.update(visible=True, open=True),
120
- *column_mappings
121
  )
122
 
123
- prediction_input, prediction_output = get_example_prediction(ppl, dataset_id, dataset_config, dataset_split)
 
 
124
  return (
125
  gr.update(value=prediction_input, visible=True),
126
  gr.update(value=prediction_output, visible=True),
127
  gr.update(visible=True, open=False),
128
- *column_mappings
129
  )
130
 
 
131
  def try_submit(m_id, d_id, config, split, local, uid):
132
  all_mappings = read_column_mapping(CONFIG_PATH)
133
 
@@ -139,7 +189,7 @@ def try_submit(m_id, d_id, config, split, local, uid):
139
  gr.Warning(CONFIRM_MAPPING_DETAILS_FAIL_RAW)
140
  return (gr.update(interactive=True), gr.update(visible=False))
141
  label_mapping = all_mappings["labels"]
142
-
143
  if "features" not in all_mappings.keys():
144
  gr.Warning(CONFIRM_MAPPING_DETAILS_FAIL_RAW)
145
  return (gr.update(interactive=True), gr.update(visible=False))
@@ -150,32 +200,47 @@ def try_submit(m_id, d_id, config, split, local, uid):
150
  command = [
151
  "python",
152
  "cli.py",
153
- "--loader", "huggingface",
154
- "--model", m_id,
155
- "--dataset", d_id,
156
- "--dataset_config", config,
157
- "--dataset_split", split,
158
- "--hf_token", os.environ.get(HF_WRITE_TOKEN),
159
- "--discussion_repo", os.environ.get(HF_REPO_ID) or os.environ.get(HF_SPACE_ID),
160
- "--output_format", "markdown",
161
- "--output_portal", "huggingface",
162
- "--feature_mapping", json.dumps(feature_mapping),
163
- "--label_mapping", json.dumps(label_mapping),
164
- "--scan_config", "../config.yaml",
 
 
 
 
 
 
 
 
 
 
 
 
165
  ]
166
 
167
  eval_str = f"[{m_id}]<{d_id}({config}, {split} set)>"
168
  logging.info(f"Start local evaluation on {eval_str}")
169
  save_job_to_pipe(uid, command, threading.Lock())
170
- write_log_to_user_file(uid, f"Start local evaluation on {eval_str}. Please wait for your job to start...\n")
 
 
 
171
  gr.Info(f"Start local evaluation on {eval_str}")
172
 
173
  return (
174
  gr.update(interactive=False),
175
- gr.update(lines=5, visible=True, interactive=False))
 
176
 
177
  else:
178
  gr.Info("TODO: Submit task to an endpoint")
179
-
180
- return (gr.update(interactive=True), # Submit button
181
- gr.update(visible=False))
 
1
+ import collections
 
2
  import json
 
3
  import logging
4
+ import os
5
  import threading
6
+
7
  import datasets
8
+ import gradio as gr
 
9
  from transformers.pipelines import TextClassificationPipeline
10
 
11
+ from io_utils import (
12
+ read_column_mapping,
13
+ save_job_to_pipe,
14
+ write_column_mapping,
15
+ write_log_to_user_file,
16
+ )
17
+ from text_classification import (
18
+ check_model,
19
+ get_example_prediction,
20
+ get_labels_and_features_from_dataset,
21
+ )
22
+ from wordings import CONFIRM_MAPPING_DETAILS_FAIL_RAW
23
+
24
  MAX_LABELS = 20
25
  MAX_FEATURES = 20
26
 
27
+ HF_REPO_ID = "HF_REPO_ID"
28
+ HF_SPACE_ID = "SPACE_ID"
29
+ HF_WRITE_TOKEN = "HF_WRITE_TOKEN"
30
  CONFIG_PATH = "./config.yaml"
31
 
32
+
33
  def check_dataset_and_get_config(dataset_id):
34
  try:
35
  write_column_mapping(None)
 
39
  # Dataset may not exist
40
  pass
41
 
42
+
43
  def check_dataset_and_get_split(dataset_id, dataset_config):
44
  try:
45
  splits = list(datasets.load_dataset(dataset_id, dataset_config).keys())
 
49
  # gr.Warning(f"Failed to load dataset {dataset_id} with config {dataset_config}: {e}")
50
  pass
51
 
52
+
53
  def write_column_mapping_to_config(dataset_id, dataset_config, dataset_split, *labels):
54
+ ds_labels, ds_features = get_labels_and_features_from_dataset(
55
+ dataset_id, dataset_config, dataset_split
56
+ )
57
  if labels is None:
58
  return
59
  labels = [*labels]
 
70
 
71
  if "features" not in all_mappings.keys():
72
  all_mappings["features"] = dict()
73
+ for i, feat in enumerate(labels[MAX_LABELS : (MAX_LABELS + MAX_FEATURES)]):
74
  if feat:
75
  all_mappings["features"][feat] = ds_features[i]
76
  write_column_mapping(all_mappings)
77
 
78
+
79
  def list_labels_and_features_from_dataset(ds_labels, ds_features, model_id2label):
80
  model_labels = list(model_id2label.values())
81
  len_model_labels = len(model_labels)
82
+ print(model_labels, model_id2label, 3 % len_model_labels)
83
+ lables = [
84
+ gr.Dropdown(
85
+ label=f"{label}",
86
+ choices=model_labels,
87
+ value=model_id2label[i % len_model_labels],
88
+ interactive=True,
89
+ visible=True,
90
+ )
91
+ for i, label in enumerate(ds_labels[:MAX_LABELS])
92
+ ]
93
  lables += [gr.Dropdown(visible=False) for _ in range(MAX_LABELS - len(lables))]
94
  # TODO: Substitute 'text' with more features for zero-shot
95
+ features = [
96
+ gr.Dropdown(
97
+ label=f"{feature}",
98
+ choices=ds_features,
99
+ value=ds_features[0],
100
+ interactive=True,
101
+ visible=True,
102
+ )
103
+ for feature in ["text"]
104
+ ]
105
+ features += [
106
+ gr.Dropdown(visible=False) for _ in range(MAX_FEATURES - len(features))
107
+ ]
108
  return lables + features
109
 
110
+
111
+ def check_model_and_show_prediction(
112
+ model_id, dataset_id, dataset_config, dataset_split
113
+ ):
114
  ppl = check_model(model_id)
115
  if ppl is None or not isinstance(ppl, TextClassificationPipeline):
116
  gr.Warning("Please check your model.")
117
  return (
118
  gr.update(visible=False),
119
  gr.update(visible=False),
120
+ *[gr.update(visible=False) for _ in range(MAX_LABELS + MAX_FEATURES)],
121
  )
122
+
123
+ dropdown_placement = [
124
+ gr.Dropdown(visible=False) for _ in range(MAX_LABELS + MAX_FEATURES)
125
+ ]
126
+
127
+ if ppl is None: # pipeline not found
128
  gr.Warning("Model not found")
129
  return (
130
  gr.update(visible=False),
131
  gr.update(visible=False),
132
  gr.update(visible=False, open=False),
133
+ *dropdown_placement,
134
  )
135
  model_id2label = ppl.model.config.id2label
136
+ ds_labels, ds_features = get_labels_and_features_from_dataset(
137
+ dataset_id, dataset_config, dataset_split
138
+ )
139
+
140
  # when dataset does not have labels or features
141
  if not isinstance(ds_labels, list) or not isinstance(ds_features, list):
142
  # gr.Warning(CONFIRM_MAPPING_DETAILS_FAIL_RAW)
 
144
  gr.update(visible=False),
145
  gr.update(visible=False),
146
  gr.update(visible=False, open=False),
147
+ *dropdown_placement,
148
  )
149
+
150
  column_mappings = list_labels_and_features_from_dataset(
151
  ds_labels,
152
  ds_features,
 
155
 
156
  # when labels or features are not aligned
157
  # show manually column mapping
158
+ if (
159
+ collections.Counter(model_id2label.values()) != collections.Counter(ds_labels)
160
+ or ds_features[0] != "text"
161
+ ):
162
  gr.Warning(CONFIRM_MAPPING_DETAILS_FAIL_RAW)
163
  return (
164
  gr.update(visible=False),
165
  gr.update(visible=False),
166
  gr.update(visible=True, open=True),
167
+ *column_mappings,
168
  )
169
 
170
+ prediction_input, prediction_output = get_example_prediction(
171
+ ppl, dataset_id, dataset_config, dataset_split
172
+ )
173
  return (
174
  gr.update(value=prediction_input, visible=True),
175
  gr.update(value=prediction_output, visible=True),
176
  gr.update(visible=True, open=False),
177
+ *column_mappings,
178
  )
179
 
180
+
181
  def try_submit(m_id, d_id, config, split, local, uid):
182
  all_mappings = read_column_mapping(CONFIG_PATH)
183
 
 
189
  gr.Warning(CONFIRM_MAPPING_DETAILS_FAIL_RAW)
190
  return (gr.update(interactive=True), gr.update(visible=False))
191
  label_mapping = all_mappings["labels"]
192
+
193
  if "features" not in all_mappings.keys():
194
  gr.Warning(CONFIRM_MAPPING_DETAILS_FAIL_RAW)
195
  return (gr.update(interactive=True), gr.update(visible=False))
 
200
  command = [
201
  "python",
202
  "cli.py",
203
+ "--loader",
204
+ "huggingface",
205
+ "--model",
206
+ m_id,
207
+ "--dataset",
208
+ d_id,
209
+ "--dataset_config",
210
+ config,
211
+ "--dataset_split",
212
+ split,
213
+ "--hf_token",
214
+ os.environ.get(HF_WRITE_TOKEN),
215
+ "--discussion_repo",
216
+ os.environ.get(HF_REPO_ID) or os.environ.get(HF_SPACE_ID),
217
+ "--output_format",
218
+ "markdown",
219
+ "--output_portal",
220
+ "huggingface",
221
+ "--feature_mapping",
222
+ json.dumps(feature_mapping),
223
+ "--label_mapping",
224
+ json.dumps(label_mapping),
225
+ "--scan_config",
226
+ "../config.yaml",
227
  ]
228
 
229
  eval_str = f"[{m_id}]<{d_id}({config}, {split} set)>"
230
  logging.info(f"Start local evaluation on {eval_str}")
231
  save_job_to_pipe(uid, command, threading.Lock())
232
+ write_log_to_user_file(
233
+ uid,
234
+ f"Start local evaluation on {eval_str}. Please wait for your job to start...\n",
235
+ )
236
  gr.Info(f"Start local evaluation on {eval_str}")
237
 
238
  return (
239
  gr.update(interactive=False),
240
+ gr.update(lines=5, visible=True, interactive=False),
241
+ )
242
 
243
  else:
244
  gr.Info("TODO: Submit task to an endpoint")
245
+
246
+ return (gr.update(interactive=True), gr.update(visible=False)) # Submit button
 
validate_queue.py ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import random
2
+ import time
3
+
4
+ import gradio as gr
5
+
6
+
7
+ def sleep_a_while():
8
+ seconds = random.randint(5, 10)
9
+ print(f"Working for {seconds} seconds")
10
+ start = time.time()
11
+ while start + seconds > time.time():
12
+ continue
13
+ return str(seconds)
14
+
15
+
16
+
17
+ with gr.Blocks() as iface:
18
+ text = gr.Textbox(label="Slept second")
19
+
20
+ run_btn = gr.Button("Run")
21
+ run_btn.click(sleep_a_while, queue=False, outputs=text, concurrency_limit=1)
22
+
23
+ if __name__ == "__main__":
24
+ iface.queue(max_size=2, default_concurrency_limit=2).launch()
wordings.py CHANGED
@@ -1,22 +1,22 @@
1
- INTRODUCTION_MD = '''
2
  <h1 style="text-align: center;">
3
  🐢Giskard Evaluator
4
  </h1>
5
  Welcome to Giskard Evaluator Space! Get your report immediately by simply input your model id and dataset id below. Follow our leads and improve your model in no time.
6
- '''
7
- CONFIRM_MAPPING_DETAILS_MD = '''
8
  <h1 style="text-align: center;">
9
  Confirm Pre-processing Details
10
  </h1>
11
  Please confirm the pre-processing details below. Align the column names of your model in the <b>dropdown</b> menu to your dataset's. If you are not sure, please double check your model and dataset.
12
- '''
13
- CONFIRM_MAPPING_DETAILS_FAIL_MD = '''
14
  <h1 style="text-align: center;">
15
  Confirm Pre-processing Details
16
  </h1>
17
  Sorry, we cannot align the input/output of your dataset with the model. <b>Pleaser double check your model and dataset.</b>
18
- '''
19
 
20
- CONFIRM_MAPPING_DETAILS_FAIL_RAW= '''
21
  Sorry, we cannot align the input/output of your dataset with the model. Pleaser double check your model and dataset.
22
- '''
 
1
+ INTRODUCTION_MD = """
2
  <h1 style="text-align: center;">
3
  🐢Giskard Evaluator
4
  </h1>
5
  Welcome to Giskard Evaluator Space! Get your report immediately by simply input your model id and dataset id below. Follow our leads and improve your model in no time.
6
+ """
7
+ CONFIRM_MAPPING_DETAILS_MD = """
8
  <h1 style="text-align: center;">
9
  Confirm Pre-processing Details
10
  </h1>
11
  Please confirm the pre-processing details below. Align the column names of your model in the <b>dropdown</b> menu to your dataset's. If you are not sure, please double check your model and dataset.
12
+ """
13
+ CONFIRM_MAPPING_DETAILS_FAIL_MD = """
14
  <h1 style="text-align: center;">
15
  Confirm Pre-processing Details
16
  </h1>
17
  Sorry, we cannot align the input/output of your dataset with the model. <b>Pleaser double check your model and dataset.</b>
18
+ """
19
 
20
+ CONFIRM_MAPPING_DETAILS_FAIL_RAW = """
21
  Sorry, we cannot align the input/output of your dataset with the model. Pleaser double check your model and dataset.
22
+ """