| """Gradio chat app for math reasoning with Qwen2.5 + LoRA.""" |
|
|
| import gradio as gr |
| import torch |
| from transformers import AutoModelForCausalLM, AutoTokenizer |
| from peft import PeftModel |
|
|
| MODEL_ID = "Qwen/Qwen2.5-1.5B-Instruct" |
| ADAPTER_ID = "arinbalyan/math-reasoning-lora" |
| DEVICE = "cuda" if torch.cuda.is_available() else "cpu" |
|
|
|
|
| def load_model(): |
| tokenizer = AutoTokenizer.from_pretrained(MODEL_ID, padding_side="left") |
| tokenizer.pad_token = tokenizer.eos_token |
|
|
| base = AutoModelForCausalLM.from_pretrained( |
| MODEL_ID, |
| torch_dtype=torch.float16 if DEVICE == "cuda" else torch.float32, |
| device_map="auto", |
| ) |
| model = PeftModel.from_pretrained(base, ADAPTER_ID) |
| model.eval() |
| return model, tokenizer |
|
|
|
|
| model, tokenizer = load_model() |
|
|
|
|
| def format_prompt(question: str) -> str: |
| return f"<|im_start|>user\n{question}<|im_end|>\n<|im_start|>assistant\n" |
|
|
|
|
| def generate(message: str, history: list) -> str: |
| prompt = format_prompt(message) |
| inputs = tokenizer(prompt, return_tensors="pt").to(DEVICE) |
|
|
| with torch.no_grad(): |
| outputs = model.generate( |
| **inputs, |
| max_new_tokens=512, |
| temperature=0.7, |
| top_p=0.9, |
| do_sample=True, |
| pad_token_id=tokenizer.eos_token_id, |
| ) |
|
|
| response = tokenizer.decode(outputs[0][inputs.input_ids.shape[1]:], skip_special_tokens=True) |
| return response.strip() |
|
|
|
|
| demo = gr.ChatInterface( |
| fn=generate, |
| title="🧮 Math Reasoning Chat", |
| description="Qwen2.5-1.5B fine-tuned on GSM8K for chain-of-thought math reasoning.", |
| theme="soft", |
| ) |
|
|
| if __name__ == "__main__": |
| demo.launch() |
|
|