Gansaw98's picture
Upload 4 files
b60a4b7 verified
Raw
History Blame Contribute Delete
4.02 kB
# app.py β€” Hugging Face Space (ZeroGPU) Gradio demo
# Fine-tuned Qwen2.5-Coder-7B (LoRA) for Text-to-SQL on the Spider benchmark.
import os
import gradio as gr
import spaces # ZeroGPU β€” provides a free GPU during decorated calls
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import PeftModel
BASE_MODEL = "Qwen/Qwen2.5-Coder-7B-Instruct"
ADAPTER = "Gansaw98/qwen2.5-coder-7b-text2sql-spider"
HF_TOKEN = os.environ.get("HF_TOKEN") # only needed if the adapter repo is private
# Exact system prompt the model was fine-tuned on β€” do not change.
SYSTEM_PROMPT = (
"You are an expert SQL generator. "
"Given a database schema and a natural language question, "
"write the correct SQL query. "
"Output only the SQL query with no explanation or markdown."
)
# --- Load once at startup (ZeroGPU provides a GPU for initialization) -----------
tokenizer = AutoTokenizer.from_pretrained(BASE_MODEL, trust_remote_code=True, token=HF_TOKEN)
base = AutoModelForCausalLM.from_pretrained(
BASE_MODEL, torch_dtype=torch.bfloat16, trust_remote_code=True, token=HF_TOKEN
).to("cuda")
model = PeftModel.from_pretrained(base, ADAPTER, token=HF_TOKEN)
model.eval()
PAD_ID = tokenizer.pad_token_id or tokenizer.eos_token_id
@spaces.GPU(duration=60)
def generate_sql(schema: str, question: str) -> str:
schema = (schema or "").strip()
question = (question or "").strip()
if not schema or not question:
return "-- Please provide both a database schema and a question."
user = f"### Database Schema:\n{schema}\n\n### Question:\n{question}"
messages = [
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": user},
]
inputs = tokenizer.apply_chat_template(
messages, add_generation_prompt=True, return_tensors="pt", return_dict=True
).to(model.device)
with torch.no_grad():
out = model.generate(
**inputs,
max_new_tokens=256,
do_sample=False, # greedy, deterministic
num_beams=1,
pad_token_id=PAD_ID,
)
gen = out[0][inputs["input_ids"].shape[1]:]
return tokenizer.decode(gen, skip_special_tokens=True).strip()
# --- UI -------------------------------------------------------------------------
EXAMPLE_SCHEMA = """CREATE TABLE singer (
Singer_ID REAL PRIMARY KEY,
Name TEXT,
Country TEXT,
Song_Name TEXT,
Song_release_year TEXT,
Age REAL,
Is_male TEXT
)
CREATE TABLE concert (
concert_ID REAL PRIMARY KEY,
concert_Name TEXT,
Theme TEXT,
Stadium_ID TEXT,
Year TEXT
)"""
with gr.Blocks(title="Text-to-SQL β€” Fine-tuned Qwen2.5-Coder-7B") as demo:
gr.Markdown(
"# πŸ—ƒοΈ Text-to-SQL Demo\n"
"Fine-tuned **Qwen2.5-Coder-7B** (LoRA / QLoRA) on the **Spider** benchmark β€” "
"**77.7% execution accuracy**, beating a zero-shot 70B model by 24.5%.\n\n"
"Paste a database schema and ask a question in plain English; the model returns SQL."
)
with gr.Row():
with gr.Column():
schema_in = gr.Textbox(label="Database Schema (CREATE TABLE ...)", lines=14, value=EXAMPLE_SCHEMA)
question_in = gr.Textbox(label="Question (English)", lines=2,
value="How many singers are there from each country?")
btn = gr.Button("Generate SQL", variant="primary")
with gr.Column():
sql_out = gr.Code(label="Generated SQL", language="sql")
btn.click(generate_sql, inputs=[schema_in, question_in], outputs=sql_out)
gr.Examples(
examples=[
[EXAMPLE_SCHEMA, "How many singers are there from each country?"],
[EXAMPLE_SCHEMA, "What are the names of singers older than 40, ordered by age descending?"],
[EXAMPLE_SCHEMA, "Show the theme and year of every concert."],
],
inputs=[schema_in, question_in],
)
if __name__ == "__main__":
demo.launch()