Python_tutor / app.py
krisha06's picture
Update app.py
2149ab2 verified
Raw
History Blame Contribute Delete
3.68 kB
import torch
from peft import PeftModel
from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
import streamlit as st
# Use CPU
device = torch.device("cpu")
# Set page config
st.set_page_config(page_title="Python Tutor", page_icon="🐍")
st.title("Python Tutor for Beginners (LoRA)")
st.markdown("Ask me any *Python programming* question below:")
# Load tokenizer and base model
@st.cache_resource
def load_model():
tokenizer = AutoTokenizer.from_pretrained("TinyLLaMA/TinyLLaMA-1.1B-Chat-v1.0")
tokenizer.pad_token = tokenizer.eos_token if tokenizer.pad_token is None else tokenizer.pad_token
base_model = AutoModelForCausalLM.from_pretrained(
"TinyLlaMA/TinyLlaMA-1.1B-Chat-v1.0",
torch_dtype=torch.float32,
).to(device)
model = PeftModel.from_pretrained(base_model, "lora_adapter").to(device)
model.eval()
classifier = pipeline("zero-shot-classification", model="facebook/bart-large-mnli", device=-1)
return tokenizer, model, classifier
tokenizer, model, classifier = load_model()
# User input
user_question = st.text_input("Your question:", placeholder="e.g. What is a Python dictionary?")
# Helper to check topic relevance
def is_python_related(question):
candidate_labels = [
"Python programming", "Java programming", "General knowledge",
"Geography", "Politics", "Entertainment", "History", "Science"
]
result = classifier(question, candidate_labels)
return result['labels'][0] == "Python programming"
# Code block formatter
def format_code_blocks(text):
if "```" in text:
return text
lines = text.split("\n")
in_code = False
formatted = []
for line in lines:
if line.strip().startswith((">>>", "#")) or line.strip().endswith(":") or ("=" in line and not line.strip().startswith("-")):
if not in_code:
formatted.append("```python")
in_code = True
elif in_code and line.strip() == "":
formatted.append("```")
in_code = False
formatted.append(line)
if in_code:
formatted.append("```")
return "\n".join(formatted)
# Process the question
if user_question:
if len(user_question.strip()) < 10:
st.warning("Please ask a more specific Python question.")
else:
if not is_python_related(user_question):
st.error("Sorry, I am a Python tutor. I cannot answer this.")
else:
with st.spinner("Thinking..."):
prompt = f"""You are a helpful and knowledgeable Python programming tutor.
Always provide short, clear, beginner-friendly explanations with examples.
Question: {user_question}
Answer:"""
inputs = tokenizer(prompt, return_tensors="pt").to(device)
with torch.inference_mode():
output = model.generate(
**inputs,
max_new_tokens=512,
do_sample=False,
repetition_penalty=1.1,
eos_token_id=tokenizer.eos_token_id,
pad_token_id=tokenizer.pad_token_id
)
decoded = tokenizer.decode(output[0], skip_special_tokens=True)
answer = decoded.split("Answer:")[-1].split("Question:")[0].strip() # clean hallucinated extra question
formatted = format_code_blocks(answer)
st.markdown("### πŸ’‘ Answer:")
with st.expander("πŸ” Click to view response"):
st.markdown(formatted)