pihull commited on
Commit
bc3f5f2
·
1 Parent(s): 9713609

Add dataset files using LFS

Browse files
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ llmsql_2.0/*.jsonl filter=lfs diff=lfs merge=lfs -text
app.py CHANGED
@@ -14,7 +14,16 @@ from build_prompt import (
14
  build_prompt_1shot,
15
  build_prompt_5shot,
16
  )
17
- from dataset_generator import questions, split_info, tables
 
 
 
 
 
 
 
 
 
18
  from evaluate import evaluate_sample
19
 
20
  # Global variables for caching
@@ -22,28 +31,56 @@ model = None
22
  tokenizer = None
23
  current_model_id = None
24
  conn = None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
 
26
 
27
  # =====================
28
  # Initialization Logic
29
  # =====================
30
- def initialize_data():
31
- """Loads datasets once and calculates actual key ranges."""
32
- global conn
33
 
 
34
  APP_DIR = os.getcwd()
35
- DB_FILE = os.path.join(APP_DIR, "sqlite_tables.db")
36
-
37
- if not os.path.exists(DB_FILE):
38
- print("Downloading database...")
39
- hf_hub_download(
40
- repo_id="llmsql-bench/llmsql-benchmark",
41
- repo_type="dataset",
42
- filename="sqlite_tables.db",
43
- local_dir=APP_DIR,
44
- )
 
 
 
 
 
45
 
46
- conn = sqlite3.connect(DB_FILE, check_same_thread=False)
 
 
 
47
 
48
 
49
  def load_model_if_needed(model_id):
@@ -65,9 +102,6 @@ def load_model_if_needed(model_id):
65
  print(f"Model {model_id} loaded successfully.")
66
 
67
 
68
- # Pre-load data once at startup (CPU tasks)
69
- initialize_data()
70
-
71
  few_shot_selection = {
72
  "0": build_prompt_0shot,
73
  "1": build_prompt_1shot,
@@ -79,53 +113,47 @@ few_shot_selection = {
79
  # Main Logic
80
  # =====================
81
  @spaces.GPU
82
- def run_inference(model_id, question_idx, few_shots):
83
- # Ensure data is ready and model is correct one
84
- initialize_data()
85
  load_model_if_needed(model_id)
86
 
 
 
 
 
87
  try:
88
- question_idx = int(question_idx)
 
89
  except:
90
- return "Question id should be integer.", "", "", None, None, None
91
 
92
- # Extraction
93
- question = questions[question_idx]["question"]
94
- ground_truth_sql = questions[question_idx]["sql"]
95
- table_id = questions[question_idx]["table_id"]
96
- table = tables.get(table_id)
97
 
98
  if not table:
99
- return "Table data missing", "", "", None, None, None
100
 
101
  example_row = table["rows"][0] if table["rows"] else []
102
-
103
- # Prompt Engineering
104
  raw_prompt = few_shot_selection[few_shots](
105
  question, table["header"], table["types"], example_row
106
  )
107
 
108
- messages = [
109
- {"role": "user", "content": raw_prompt},
110
- ]
111
-
112
  text_input = tokenizer.apply_chat_template(
113
  messages, tokenize=False, add_generation_prompt=True
114
  )
115
  model_inputs = tokenizer([text_input], return_tensors="pt").to("cuda")
116
 
117
- # Generation
118
  generated_ids = model.generate(
119
  **model_inputs, max_new_tokens=512, temperature=0.0, do_sample=False
120
  )
121
-
122
- # Slice off the prompt tokens
123
  new_tokens = generated_ids[0][len(model_inputs.input_ids[0]) :]
124
  completion = tokenizer.decode(new_tokens, skip_special_tokens=True)
125
 
126
- is_match, mismatch_info, error_info = evaluate_sample(
127
- item={"question_id": question_idx, "completion": completion},
128
- questions=questions,
129
  conn=conn,
130
  )
131
 
@@ -143,32 +171,31 @@ def run_inference(model_id, question_idx, few_shots):
143
  # =====================
144
  # UI Helpers
145
  # =====================
146
- def get_range_text(split_name):
147
- info = split_info.get(split_name, {})
148
- return (
149
- f"IDs: {info.get('first')} to {info.get('last')} (Total: {info.get('count')})"
150
- )
 
 
 
151
 
152
 
153
- # Helper to build your static range text
154
- range_display = "\n".join(
155
- [f"**{s.capitalize()}**: {get_range_text(s)}" for s in split_info.keys()]
156
- )
157
-
158
  with gr.Blocks(title="Text-to-SQL Debugger", theme=gr.themes.Soft()) as app:
159
  gr.Markdown("## 🔍 Text-to-SQL Interactive Debugger")
160
 
161
  with gr.Row():
 
 
 
 
 
 
162
  model_dropdown = gr.Dropdown(
163
- choices=[
164
- "Qwen/Qwen2.5-1.5B-Instruct",
165
- # "microsoft/Phi-3.5-mini-instruct",
166
- "openai/gpt-oss-20b",
167
- # "Qwen/Qwen3-Coder-30B-A3B-Instruct",
168
- ],
169
  value="Qwen/Qwen2.5-1.5B-Instruct",
170
  label="1. Select Model",
171
- scale=2,
172
  )
173
  few_shot_dropdown = gr.Dropdown(
174
  choices=["0", "1", "5"],
@@ -182,20 +209,12 @@ with gr.Blocks(title="Text-to-SQL Debugger", theme=gr.themes.Soft()) as app:
182
  label="3. Enter Question ID",
183
  value="1",
184
  lines=2,
185
- placeholder="e.g. 15001",
186
  scale=2,
187
- min_width=200,
188
  )
189
- with gr.Column(scale=1):
190
- gr.Markdown(
191
- f"**Available ID Ranges:**\n{range_display}",
192
- line_breaks=True,
193
- padding=True,
194
- )
195
-
196
- with gr.Row():
197
- run_button = gr.Button("Run Inference", variant="primary")
198
 
 
199
  question_box = gr.Textbox(
200
  label="Natural Language Question", lines=2, interactive=False
201
  )
@@ -206,69 +225,76 @@ with gr.Blocks(title="Text-to-SQL Debugger", theme=gr.themes.Soft()) as app:
206
 
207
  gr.Markdown("### Data Comparison")
208
  with gr.Row():
209
- generated_table = gr.Dataframe(
210
- label="Generated Result", type="pandas", wrap=True
211
- )
212
- gt_table = gr.Dataframe(label="Ground Truth Result", type="pandas", wrap=True)
213
 
214
  with gr.Accordion("See Full Source Table", open=False):
215
  full_table = gr.Dataframe(label="Full Table Content", type="pandas")
216
 
217
- def update_question_info(q_id):
 
 
 
 
218
  try:
219
  idx = int(q_id) if (q_id and str(q_id).isdigit()) else 1
220
- question = questions[idx]["question"]
221
- gt_sql = questions[idx]["sql"]
222
- table_id = questions[idx]["table_id"]
223
-
224
- raw_table_data = tables.get(table_id)
225
 
226
- if raw_table_data and "rows" in raw_table_data:
227
- df = pd.DataFrame(
228
- raw_table_data["rows"], columns=raw_table_data["header"]
229
- )
230
- else:
231
- df = pd.DataFrame()
232
-
233
- return (question, gt_sql, df, gr.update(label="Generated SQL", value=""))
234
- except Exception as e:
235
- print(f"Error: {e}") # Helpful for debugging
236
- return "ID not found", "", None, gr.update(label="Generated SQL")
 
 
 
 
 
 
 
237
 
238
- def handle_inference(model, few_shot, q_id):
239
  q_text, gen_sql, gt_sql, gen_df, gt_df, full_df, is_match = run_inference(
240
- model, q_id, few_shot
241
  )
242
-
243
- status_label = (
244
  "✅ Generated SQL (MATCH SUCCESS)"
245
  if is_match
246
  else "❌ Generated SQL (MATCH FAILED)"
247
  )
 
248
 
249
- return (gr.update(label=status_label, value=gen_sql), gen_df, gt_df)
 
 
 
 
 
250
 
251
  question_input.change(
252
- fn=update_question_info,
253
- inputs=[question_input],
254
- outputs=[question_box, gt_sql_box, full_table, generated_sql_box],
255
  )
256
 
257
- app.load(
258
- fn=update_question_info,
259
- inputs=[question_input],
260
- outputs=[question_box, gt_sql_box, full_table, generated_sql_box],
261
  )
262
 
263
- # 3. Inference Button
264
- run_button.click(
265
- fn=handle_inference,
266
- inputs=[model_dropdown, few_shot_dropdown, question_input],
267
- outputs=[
268
- generated_sql_box,
269
- generated_table,
270
- gt_table,
271
- ],
272
  )
273
 
274
  app.launch()
 
14
  build_prompt_1shot,
15
  build_prompt_5shot,
16
  )
17
+
18
+ # Import both versions of the dataset
19
+ from dataset_generator import (
20
+ questions_llmsql_1,
21
+ questions_llmsql_2,
22
+ tables_llmsql_1,
23
+ tables_llmsql_2,
24
+ )
25
+ from dataset_generator import split_info as split_info_v1
26
+ from dataset_generator import split_info as split_info_v2
27
  from evaluate import evaluate_sample
28
 
29
  # Global variables for caching
 
31
  tokenizer = None
32
  current_model_id = None
33
  conn = None
34
+ current_db_path = None
35
+
36
+ # Mapping for dynamic access
37
+ DATASETS = {
38
+ "LLMSQL 1.0": {
39
+ "questions": questions_llmsql_1,
40
+ "tables": tables_llmsql_1,
41
+ "split_info": split_info_v1,
42
+ "repo": "llmsql-bench/llmsql-benchmark",
43
+ "folder": "llmsql_1.0",
44
+ },
45
+ "LLMSQL 2.0": {
46
+ "questions": questions_llmsql_2,
47
+ "tables": tables_llmsql_2,
48
+ "split_info": split_info_v2,
49
+ "repo": "llmsql-bench/llmsql-2.0",
50
+ "folder": "llmsql_2.0",
51
+ },
52
+ }
53
 
54
 
55
  # =====================
56
  # Initialization Logic
57
  # =====================
58
+ def initialize_data(version):
59
+ """Downloads and connects to the version-specific database."""
60
+ global conn, current_db_path
61
 
62
+ config = DATASETS[version]
63
  APP_DIR = os.getcwd()
64
+ VER_DIR = os.path.join(APP_DIR, config["folder"])
65
+ os.makedirs(VER_DIR, exist_ok=True)
66
+
67
+ DB_FILE = os.path.join(VER_DIR, "sqlite_tables.db")
68
+
69
+ # Only reconnect if the version changed or conn is None
70
+ if current_db_path != DB_FILE:
71
+ if not os.path.exists(DB_FILE):
72
+ print(f"Downloading database for {version}...")
73
+ hf_hub_download(
74
+ repo_id=config["repo"],
75
+ repo_type="dataset",
76
+ filename="sqlite_tables.db",
77
+ local_dir=VER_DIR,
78
+ )
79
 
80
+ if conn:
81
+ conn.close()
82
+ conn = sqlite3.connect(DB_FILE, check_same_thread=False)
83
+ current_db_path = DB_FILE
84
 
85
 
86
  def load_model_if_needed(model_id):
 
102
  print(f"Model {model_id} loaded successfully.")
103
 
104
 
 
 
 
105
  few_shot_selection = {
106
  "0": build_prompt_0shot,
107
  "1": build_prompt_1shot,
 
113
  # Main Logic
114
  # =====================
115
  @spaces.GPU
116
+ def run_inference(version, model_id, question_idx, few_shots):
117
+ initialize_data(version)
 
118
  load_model_if_needed(model_id)
119
 
120
+ dataset = DATASETS[version]
121
+ qs = dataset["questions"]
122
+ ts = dataset["tables"]
123
+
124
  try:
125
+ idx = int(question_idx)
126
+ q_data = qs[idx]
127
  except:
128
+ return "Invalid ID", "", "", None, None, None, False
129
 
130
+ question = q_data["question"]
131
+ ground_truth_sql = q_data["sql"]
132
+ table = ts.get(q_data["table_id"])
 
 
133
 
134
  if not table:
135
+ return "Table data missing", "", "", None, None, None, False
136
 
137
  example_row = table["rows"][0] if table["rows"] else []
 
 
138
  raw_prompt = few_shot_selection[few_shots](
139
  question, table["header"], table["types"], example_row
140
  )
141
 
142
+ messages = [{"role": "user", "content": raw_prompt}]
 
 
 
143
  text_input = tokenizer.apply_chat_template(
144
  messages, tokenize=False, add_generation_prompt=True
145
  )
146
  model_inputs = tokenizer([text_input], return_tensors="pt").to("cuda")
147
 
 
148
  generated_ids = model.generate(
149
  **model_inputs, max_new_tokens=512, temperature=0.0, do_sample=False
150
  )
 
 
151
  new_tokens = generated_ids[0][len(model_inputs.input_ids[0]) :]
152
  completion = tokenizer.decode(new_tokens, skip_special_tokens=True)
153
 
154
+ is_match, mismatch_info, _ = evaluate_sample(
155
+ item={"question_id": idx, "completion": completion},
156
+ questions=qs,
157
  conn=conn,
158
  )
159
 
 
171
  # =====================
172
  # UI Helpers
173
  # =====================
174
+ def get_range_display(version):
175
+ info_dict = DATASETS[version]["split_info"]
176
+ lines = []
177
+ for s, info in info_dict.items():
178
+ lines.append(
179
+ f"**{s.capitalize()}**: IDs {info.get('first')} to {info.get('last')} (Total: {info.get('count')})"
180
+ )
181
+ return "\n".join(lines)
182
 
183
 
 
 
 
 
 
184
  with gr.Blocks(title="Text-to-SQL Debugger", theme=gr.themes.Soft()) as app:
185
  gr.Markdown("## 🔍 Text-to-SQL Interactive Debugger")
186
 
187
  with gr.Row():
188
+ version_dropdown = gr.Dropdown(
189
+ choices=["LLMSQL 1.0", "LLMSQL 2.0"],
190
+ value="LLMSQL 2.0",
191
+ label="Dataset Version",
192
+ scale=1,
193
+ )
194
  model_dropdown = gr.Dropdown(
195
+ choices=["Qwen/Qwen2.5-1.5B-Instruct", "openai/gpt-oss-20b"],
 
 
 
 
 
196
  value="Qwen/Qwen2.5-1.5B-Instruct",
197
  label="1. Select Model",
198
+ scale=1,
199
  )
200
  few_shot_dropdown = gr.Dropdown(
201
  choices=["0", "1", "5"],
 
209
  label="3. Enter Question ID",
210
  value="1",
211
  lines=2,
212
+ placeholder="e.g. 1",
213
  scale=2,
 
214
  )
215
+ range_md = gr.Markdown(get_range_display("LLMSQL 2.0"), scale=1)
 
 
 
 
 
 
 
 
216
 
217
+ run_button = gr.Button("Run Inference", variant="primary")
218
  question_box = gr.Textbox(
219
  label="Natural Language Question", lines=2, interactive=False
220
  )
 
225
 
226
  gr.Markdown("### Data Comparison")
227
  with gr.Row():
228
+ generated_table = gr.Dataframe(label="Generated Result", type="pandas")
229
+ gt_table = gr.Dataframe(label="Ground Truth Result", type="pandas")
 
 
230
 
231
  with gr.Accordion("See Full Source Table", open=False):
232
  full_table = gr.Dataframe(label="Full Table Content", type="pandas")
233
 
234
+ def update_ui_on_version_or_id(version, q_id):
235
+ """Updates range text and pre-loads question data when version or ID changes."""
236
+ dataset = DATASETS[version]
237
+ range_text = get_range_display(version)
238
+
239
  try:
240
  idx = int(q_id) if (q_id and str(q_id).isdigit()) else 1
241
+ q_data = dataset["questions"][idx]
242
+ table_id = q_data["table_id"]
243
+ raw_table = dataset["tables"].get(table_id, {})
 
 
244
 
245
+ df = pd.DataFrame(
246
+ raw_table.get("rows", []), columns=raw_table.get("header", [])
247
+ )
248
+ return (
249
+ q_data["question"],
250
+ q_data["sql"],
251
+ df,
252
+ gr.update(label="Generated SQL", value=""),
253
+ range_text,
254
+ )
255
+ except Exception:
256
+ return (
257
+ "ID not found in this version",
258
+ "",
259
+ pd.DataFrame(),
260
+ gr.update(label="Generated SQL"),
261
+ range_text,
262
+ )
263
 
264
+ def handle_inference(version, model, few_shot, q_id):
265
  q_text, gen_sql, gt_sql, gen_df, gt_df, full_df, is_match = run_inference(
266
+ version, model, q_id, few_shot
267
  )
268
+ status = (
 
269
  "✅ Generated SQL (MATCH SUCCESS)"
270
  if is_match
271
  else "❌ Generated SQL (MATCH FAILED)"
272
  )
273
+ return gr.update(label=status, value=gen_sql), gen_df, gt_df
274
 
275
+ # Event Listeners
276
+ version_dropdown.change(
277
+ update_ui_on_version_or_id,
278
+ inputs=[version_dropdown, question_input],
279
+ outputs=[question_box, gt_sql_box, full_table, generated_sql_box, range_md],
280
+ )
281
 
282
  question_input.change(
283
+ update_ui_on_version_or_id,
284
+ inputs=[version_dropdown, question_input],
285
+ outputs=[question_box, gt_sql_box, full_table, generated_sql_box, range_md],
286
  )
287
 
288
+ run_button.click(
289
+ handle_inference,
290
+ inputs=[version_dropdown, model_dropdown, few_shot_dropdown, question_input],
291
+ outputs=[generated_sql_box, generated_table, gt_table],
292
  )
293
 
294
+ app.load(
295
+ update_ui_on_version_or_id,
296
+ inputs=[version_dropdown, question_input],
297
+ outputs=[question_box, gt_sql_box, full_table, generated_sql_box, range_md],
 
 
 
 
 
298
  )
299
 
300
  app.launch()
dataset_generator.py CHANGED
@@ -1,19 +1,61 @@
 
 
1
  import pandas as pd
2
 
3
- tables = pd.read_pickle("llmsql_tables.pkl")
4
- questions_splits = pd.read_pickle("llmsql_formatted.pkl")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
 
7
  split_info = dict()
8
- questions = dict()
9
- for split_name in list(questions_splits.keys()):
10
  sorted_keys = sorted(
11
- list(questions_splits[split_name].keys()), key=lambda x: int(x)
12
  )
13
  split_info[split_name] = {
14
  "first": sorted_keys[0],
15
  "last": sorted_keys[-1],
16
  "count": len(sorted_keys),
17
  }
18
- for question_id, items in questions_splits[split_name].items():
19
- questions[int(question_id)] = items
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+
3
  import pandas as pd
4
 
5
+
6
+ def load_jsonl(path: str) -> list[dict]:
7
+ """Load a JSONL file into a list of dicts."""
8
+ with open(path, encoding="utf-8") as f:
9
+ return [json.loads(line) for line in f if line.strip()]
10
+
11
+
12
+ ## LLMSQL 1.0
13
+ tables_llmsql_1 = pd.read_pickle("llmsql_1.0/llmsql_tables.pkl")
14
+ questions_splits_llmsql_1 = pd.read_pickle("llmsql_1.0/llmsql_formatted.pkl")
15
+
16
+
17
+ split_info_llmsql_1 = dict()
18
+ questions_llmsql_1 = dict()
19
+ for split_name in list(questions_splits_llmsql_1.keys()):
20
+ sorted_keys = sorted(
21
+ list(questions_splits_llmsql_1[split_name].keys()), key=lambda x: int(x)
22
+ )
23
+ split_info_llmsql_1[split_name] = {
24
+ "first": sorted_keys[0],
25
+ "last": sorted_keys[-1],
26
+ "count": len(sorted_keys),
27
+ }
28
+ for question_id, items in questions_splits_llmsql_1[split_name].items():
29
+ questions_llmsql_1[int(question_id)] = items
30
+
31
+ tables_llmsql_1 = pd.read_pickle("llmsql_1.0/llmsql_tables.pkl")
32
+ questions_splits_llmsql_1 = pd.read_pickle("llmsql_1.0/llmsql_formatted.pkl")
33
 
34
 
35
  split_info = dict()
36
+ questions_llmsql_1 = dict()
37
+ for split_name in list(questions_splits_llmsql_1.keys()):
38
  sorted_keys = sorted(
39
+ list(questions_splits_llmsql_1[split_name].keys()), key=lambda x: int(x)
40
  )
41
  split_info[split_name] = {
42
  "first": sorted_keys[0],
43
  "last": sorted_keys[-1],
44
  "count": len(sorted_keys),
45
  }
46
+ for question_id, items in questions_splits_llmsql_1[split_name].items():
47
+ questions_llmsql_1[int(question_id)] = items
48
+
49
+
50
+ ## LLMSQL 2.0
51
+ tables_list_llmsql_2 = load_jsonl("llmsql_2.0/tables.jsonl")
52
+ questions_list_llmsql_2 = load_jsonl("llmsql_2.0/questions.jsonl")
53
+
54
+
55
+ questions_llmsql_2 = dict()
56
+ for question in questions_list_llmsql_2:
57
+ questions_llmsql_2[question["question_id"]] = question
58
+
59
+ tables_llmsql_2 = dict()
60
+ for table in tables_list_llmsql_2:
61
+ tables_llmsql_2[table["table_id"]] = table
llmsql_formatted.pkl → llmsql_1.0/llmsql_formatted.pkl RENAMED
File without changes
llmsql_tables.pkl → llmsql_1.0/llmsql_tables.pkl RENAMED
File without changes
llmsql_2.0/questions.jsonl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:dbdaf154133f693142501a807613c3555105d72dd9c9c9cff509063f43efec14
3
+ size 18317052
llmsql_2.0/tables.jsonl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1b7487109222fba276f843523536d0efd5dd3ab24d6343fd84d19fe94aba3eeb
3
+ size 45341094