nishu08 commited on
Commit
8464aea
·
verified ·
1 Parent(s): 9b2cded

Deploy CodeBERT training Space

Browse files
.gitignore CHANGED
@@ -4,9 +4,7 @@ __pycache__/
4
  venv/
5
  .env
6
  data/*.parquet
7
- data/*.csv
8
- models/*.joblib
9
- models/evaluation/
10
  .DS_Store
11
  *.egg-info/
12
  dist/
 
4
  venv/
5
  .env
6
  data/*.parquet
7
+ models/
 
 
8
  .DS_Store
9
  *.egg-info/
10
  dist/
Dockerfile ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Python 3.12 — avoids Gradio/pydub audioop breakage on Python 3.13
2
+ FROM python:3.12-slim
3
+
4
+ RUN apt-get update && apt-get install -y --no-install-recommends \
5
+ build-essential \
6
+ git \
7
+ && rm -rf /var/lib/apt/lists/*
8
+
9
+ WORKDIR /app
10
+
11
+ COPY requirements.txt .
12
+ RUN pip install --no-cache-dir -r requirements.txt
13
+
14
+ COPY . .
15
+
16
+ EXPOSE 7860
17
+ CMD ["python", "train_space_app.py"]
README.md CHANGED
@@ -3,9 +3,8 @@ title: SQL Error Classifier Training
3
  emoji: 🧠
4
  colorFrom: blue
5
  colorTo: green
6
- sdk: gradio
7
- sdk_version: 4.44.0
8
- app_file: train_space_app.py
9
  pinned: false
10
  license: mit
11
  hardware: t4-small
 
3
  emoji: 🧠
4
  colorFrom: blue
5
  colorTo: green
6
+ sdk: docker
7
+ app_port: 7860
 
8
  pinned: false
9
  license: mit
10
  hardware: t4-small
README_TRAIN_SPACE.md CHANGED
@@ -3,9 +3,8 @@ title: SQL Error Classifier Training
3
  emoji: 🧠
4
  colorFrom: blue
5
  colorTo: green
6
- sdk: gradio
7
- sdk_version: 4.44.0
8
- app_file: train_space_app.py
9
  pinned: false
10
  license: mit
11
  hardware: t4-small
 
3
  emoji: 🧠
4
  colorFrom: blue
5
  colorTo: green
6
+ sdk: docker
7
+ app_port: 7860
 
8
  pinned: false
9
  license: mit
10
  hardware: t4-small
app.py CHANGED
@@ -1,155 +1,66 @@
1
- """
2
- Gradio app for Hugging Face Spaces.
3
-
4
- Deploy: create a Space with sdk=gradio and point app_file to this file.
5
- Set SPACE_MODEL_ID env var to your HF model repo (e.g. username/sql-error-classifier).
6
- """
7
 
8
  from __future__ import annotations
9
 
10
- import json
11
- import os
12
- from pathlib import Path
13
-
14
  import gradio as gr
15
 
16
- from src.huggingface import SQLLErrorClassifierHF
17
 
18
- MODEL_ID = os.getenv("SPACE_MODEL_ID", "models/hf_package")
19
- LOCAL_PACKAGE = Path(__file__).parent / "models" / "hf_package"
 
 
 
 
 
 
20
 
21
  EXAMPLE = {
22
  "question": "What is the average score of students in each department?",
23
  "schema": "students(id, name, score, department_id) | departments(id, name)",
24
- "correct_query": (
25
- "SELECT department_id, AVG(score) FROM students GROUP BY department_id"
26
- ),
27
- "student_query": (
28
- "SELECT department_id, SUM(score) FROM students GROUP BY department_id"
29
- ),
30
- "error_message": "query executes but produces incorrect result set",
31
  }
32
 
33
 
34
- def _load_classifier() -> SQLLErrorClassifierHF:
35
- if LOCAL_PACKAGE.exists() and (LOCAL_PACKAGE / "config.json").exists():
36
- return SQLLErrorClassifierHF.from_pretrained(LOCAL_PACKAGE)
37
- return SQLLErrorClassifierHF.from_pretrained(MODEL_ID)
38
-
39
-
40
- clf = _load_classifier()
41
-
42
-
43
- def classify(
44
- question: str,
45
- schema: str,
46
- correct_query: str,
47
- student_query: str,
48
- error_message: str,
49
- ) -> tuple[str, str, str]:
50
  result = clf.predict(
51
  question=question.strip(),
52
  schema=schema.strip(),
53
- correct_query=correct_query.strip(),
54
- student_query=student_query.strip(),
55
- error_message=error_message.strip() or None,
56
  )
57
-
58
  summary = (
59
- f"**{result['label_name']}** \n"
60
- f"Confidence: **{result['confidence']:.1%}**"
61
  )
62
- top_k = "\n".join(
63
- f"- {item['label_name']}: {item['confidence']:.1%}"
64
- for item in result["top_k"]
65
  )
66
- sims = result.get("similarities") or result.get("pair_scores") or {}
67
- diagnostics = "\n".join(
68
- f"- **{k.replace('_', ' ').title()}**: {v:.3f}"
69
- for k, v in sims.items()
70
- )
71
- if not diagnostics:
72
- diagnostics = "_No diagnostic scores for this model type._"
73
- return summary, top_k, diagnostics
74
 
75
 
76
  with gr.Blocks(title="SQL Error Classifier") as demo:
77
- gr.Markdown(
78
- """
79
- # SQL Error Classifier
80
- Classify **which mistake area** a student is struggling with, using:
81
- **question**, **schema**, **correct query**, and the **student's query**.
82
-
83
- Powered by a multi-tower MiniLM architecture on Hugging Face.
84
- """
85
- )
86
-
87
  with gr.Row():
88
  with gr.Column():
89
- question = gr.Textbox(
90
- label="Question",
91
- lines=2,
92
- value=EXAMPLE["question"],
93
- )
94
- schema = gr.Textbox(
95
- label="Schema",
96
- lines=2,
97
- value=EXAMPLE["schema"],
98
- )
99
- correct_query = gr.Textbox(
100
- label="Correct Query",
101
- lines=3,
102
- value=EXAMPLE["correct_query"],
103
- )
104
- student_query = gr.Textbox(
105
- label="Student Query",
106
- lines=3,
107
- value=EXAMPLE["student_query"],
108
- )
109
- error_message = gr.Textbox(
110
- label="DB Error Message (optional)",
111
- lines=2,
112
- value=EXAMPLE["error_message"],
113
- )
114
- run_btn = gr.Button("Classify", variant="primary")
115
-
116
  with gr.Column():
117
- prediction = gr.Markdown(label="Prediction")
118
- top_k = gr.Markdown(label="Top 3")
119
- diagnostics = gr.Markdown(label="Semantic Diagnostics")
120
 
121
- run_btn.click(
122
  classify,
123
- inputs=[question, schema, correct_query, student_query, error_message],
124
- outputs=[prediction, top_k, diagnostics],
125
- )
126
-
127
- gr.Examples(
128
- examples=[
129
- [
130
- EXAMPLE["question"],
131
- EXAMPLE["schema"],
132
- EXAMPLE["correct_query"],
133
- EXAMPLE["student_query"],
134
- EXAMPLE["error_message"],
135
- ],
136
- [
137
- "Find students who have not provided an email address.",
138
- "students(id, name, email, phone)",
139
- "SELECT name FROM students WHERE email IS NULL",
140
- "SELECT name FROM students WHERE email = NULL",
141
- "use IS NULL or IS NOT NULL to test for null values",
142
- ],
143
- [
144
- "List each student's name along with their department name.",
145
- "students(id, name, department_id) | departments(id, name)",
146
- "SELECT students.name, departments.name FROM students "
147
- "INNER JOIN departments ON students.department_id = departments.id",
148
- "SELECT students.name, departments.name FROM students JOIN departments",
149
- "missing ON clause or invalid join condition",
150
- ],
151
- ],
152
- inputs=[question, schema, correct_query, student_query, error_message],
153
  )
154
 
155
  if __name__ == "__main__":
 
1
+ """CodeBERT inference Gradio app (optional HF Space for predictions)."""
 
 
 
 
 
2
 
3
  from __future__ import annotations
4
 
 
 
 
 
5
  import gradio as gr
6
 
7
+ from src.hf_predict_codebert import CodeBERTSQLErrorClassifier
8
 
9
+ MODEL_DIR = "models/codebert-cross-encoder"
10
+
11
+ try:
12
+ clf = CodeBERTSQLErrorClassifier(MODEL_DIR)
13
+ model_status = f"Loaded model from `{MODEL_DIR}`"
14
+ except Exception as exc:
15
+ clf = None
16
+ model_status = f"Model not loaded: {exc}. Train first or set SPACE_MODEL_DIR."
17
 
18
  EXAMPLE = {
19
  "question": "What is the average score of students in each department?",
20
  "schema": "students(id, name, score, department_id) | departments(id, name)",
21
+ "student_sql": "SELECT department_id, SUM(score) FROM students GROUP BY department_id",
22
+ "correct_sql": "SELECT department_id, AVG(score) FROM students GROUP BY department_id",
 
 
 
 
 
23
  }
24
 
25
 
26
+ def classify(question, schema, student_sql, correct_sql, threshold):
27
+ if clf is None:
28
+ return "Train a model first.", ""
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  result = clf.predict(
30
  question=question.strip(),
31
  schema=schema.strip(),
32
+ student_sql=student_sql.strip(),
33
+ correct_sql=correct_sql.strip(),
34
+ threshold=threshold,
35
  )
 
36
  summary = (
37
+ f"**{result['primary_label']}** ({result['primary_confidence']:.1%})\n\n"
38
+ f"All labels above threshold: {', '.join(result['error_labels']) or 'none'}"
39
  )
40
+ probs = "\n".join(
41
+ f"- {k}: {v:.1%}" for k, v in result["probabilities"].items()
 
42
  )
43
+ return summary, probs
 
 
 
 
 
 
 
44
 
45
 
46
  with gr.Blocks(title="SQL Error Classifier") as demo:
47
+ gr.Markdown(f"# SQL Error Classifier (CodeBERT)\n{model_status}")
 
 
 
 
 
 
 
 
 
48
  with gr.Row():
49
  with gr.Column():
50
+ question = gr.Textbox(label="Question", lines=2, value=EXAMPLE["question"])
51
+ schema = gr.Textbox(label="Schema", lines=2, value=EXAMPLE["schema"])
52
+ student_sql = gr.Textbox(label="Student SQL", lines=3, value=EXAMPLE["student_sql"])
53
+ correct_sql = gr.Textbox(label="Correct SQL", lines=3, value=EXAMPLE["correct_sql"])
54
+ threshold = gr.Slider(0.1, 0.9, value=0.5, step=0.05, label="Threshold")
55
+ btn = gr.Button("Classify", variant="primary")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
  with gr.Column():
57
+ prediction = gr.Markdown()
58
+ probabilities = gr.Markdown()
 
59
 
60
+ btn.click(
61
  classify,
62
+ [question, schema, student_sql, correct_sql, threshold],
63
+ [prediction, probabilities],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  )
65
 
66
  if __name__ == "__main__":
requirements.txt CHANGED
@@ -1,15 +1,13 @@
1
  numpy>=1.24.0
2
  pandas>=2.0.0
3
  scikit-learn>=1.3.0
4
- joblib>=1.3.0
5
  pyarrow>=14.0.0
6
  tqdm>=4.66.0
7
  pyyaml>=6.0
8
- matplotlib>=3.7.0
9
- sentence-transformers>=2.2.0
10
  torch>=2.0.0
11
  transformers>=4.36.0
12
  accelerate>=0.25.0
13
  datasets>=2.16.0
14
  huggingface_hub>=0.20.0
15
  gradio>=4.44.0
 
 
1
  numpy>=1.24.0
2
  pandas>=2.0.0
3
  scikit-learn>=1.3.0
 
4
  pyarrow>=14.0.0
5
  tqdm>=4.66.0
6
  pyyaml>=6.0
 
 
7
  torch>=2.0.0
8
  transformers>=4.36.0
9
  accelerate>=0.25.0
10
  datasets>=2.16.0
11
  huggingface_hub>=0.20.0
12
  gradio>=4.44.0
13
+ pyaudioop>=0.3.0
scripts/deploy_train_space.sh CHANGED
@@ -1,15 +1,9 @@
1
  #!/usr/bin/env bash
2
- # Deploy training Space to Hugging Face.
3
- # Usage: ./scripts/deploy_train_space.sh YOUR_HF_USERNAME/sql-error-classifier-train
4
  set -euo pipefail
5
 
6
- SPACE_ID="${1:-}"
7
- if [[ -z "${SPACE_ID}" ]]; then
8
- echo "Usage: $0 YOUR_USERNAME/sql-error-classifier-train"
9
- exit 1
10
- fi
11
-
12
- ROOT="$(cd "$(dirname "$0")/.." && pwd)"
13
  TOKEN="${HF_TOKEN:-${HUGGING_FACE_HUB_TOKEN:-}}"
14
 
15
  if [[ -z "${TOKEN}" ]]; then
@@ -17,27 +11,42 @@ if [[ -z "${TOKEN}" ]]; then
17
  exit 1
18
  fi
19
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  WORKDIR=$(mktemp -d)
21
  trap 'rm -rf "${WORKDIR}"' EXIT
22
 
23
- echo "==> Preparing Space files in ${WORKDIR}..."
24
  rsync -a \
25
  --exclude '.venv' \
26
  --exclude 'models' \
27
  --exclude '__pycache__' \
28
  --exclude '.git' \
 
29
  "${ROOT}/" "${WORKDIR}/"
30
 
31
  cp "${ROOT}/README_TRAIN_SPACE.md" "${WORKDIR}/README.md"
32
 
33
- echo "==> Creating / updating Space ${SPACE_ID}..."
34
  python - <<PY
35
  from huggingface_hub import HfApi
36
  api = HfApi(token="${TOKEN}")
37
- api.create_repo("${SPACE_ID}", repo_type="space", space_sdk="gradio", exist_ok=True)
38
  PY
39
 
40
- echo "==> Uploading to Hugging Face Space..."
41
  python - <<PY
42
  from huggingface_hub import HfApi
43
  api = HfApi(token="${TOKEN}")
@@ -49,6 +58,5 @@ api.upload_folder(
49
  )
50
  PY
51
 
52
- echo "==> Done: https://huggingface.co/spaces/${SPACE_ID}"
53
- echo "Next: Space Settings → Hardware → GPU t4-small"
54
- echo " Space Settings → Secrets → HF_TOKEN"
 
1
  #!/usr/bin/env bash
2
+ # Deploy CodeBERT training Space to Hugging Face.
3
+ # Usage: ./scripts/deploy_train_space.sh [YOUR_USERNAME/space-name]
4
  set -euo pipefail
5
 
6
+ SPACE_SUFFIX="${1:-sql-error-classifier-train}"
 
 
 
 
 
 
7
  TOKEN="${HF_TOKEN:-${HUGGING_FACE_HUB_TOKEN:-}}"
8
 
9
  if [[ -z "${TOKEN}" ]]; then
 
11
  exit 1
12
  fi
13
 
14
+ # Resolve full space id — must use an account you own
15
+ if [[ "${SPACE_SUFFIX}" == */* ]]; then
16
+ SPACE_ID="${SPACE_SUFFIX}"
17
+ else
18
+ USERNAME=$(python - <<PY
19
+ from huggingface_hub import HfApi
20
+ api = HfApi(token="${TOKEN}")
21
+ print(api.whoami()["name"])
22
+ PY
23
+ )
24
+ SPACE_ID="${USERNAME}/${SPACE_SUFFIX}"
25
+ fi
26
+
27
+ ROOT="$(cd "$(dirname "$0")/.." && pwd)"
28
  WORKDIR=$(mktemp -d)
29
  trap 'rm -rf "${WORKDIR}"' EXIT
30
 
31
+ echo "==> Preparing Space files..."
32
  rsync -a \
33
  --exclude '.venv' \
34
  --exclude 'models' \
35
  --exclude '__pycache__' \
36
  --exclude '.git' \
37
+ --exclude '*.joblib' \
38
  "${ROOT}/" "${WORKDIR}/"
39
 
40
  cp "${ROOT}/README_TRAIN_SPACE.md" "${WORKDIR}/README.md"
41
 
42
+ echo "==> Creating Space: ${SPACE_ID}"
43
  python - <<PY
44
  from huggingface_hub import HfApi
45
  api = HfApi(token="${TOKEN}")
46
+ api.create_repo("${SPACE_ID}", repo_type="space", space_sdk="docker", exist_ok=True)
47
  PY
48
 
49
+ echo "==> Uploading..."
50
  python - <<PY
51
  from huggingface_hub import HfApi
52
  api = HfApi(token="${TOKEN}")
 
58
  )
59
  PY
60
 
61
+ echo "Done: https://huggingface.co/spaces/${SPACE_ID}"
62
+ echo "Set Hardware → GPU t4-small, Secrets → HF_TOKEN"
 
train_space_app.py CHANGED
@@ -227,4 +227,4 @@ with gr.Blocks(title="SQL Error Classifier — Train") as demo:
227
  )
228
 
229
  if __name__ == "__main__":
230
- demo.launch()
 
227
  )
228
 
229
  if __name__ == "__main__":
230
+ demo.launch(server_name="0.0.0.0", server_port=7860)