build-small-hackathon/InContext
1
1import gradio as gr2import torch3import json4import html5import traceback6from transformers import AutoModelForCausalLM, AutoTokenizer7 8print("Loading model...")9model_name = "Qwen/Qwen2.5-0.5B-Instruct"10tokenizer = AutoTokenizer.from_pretrained(model_name)11model = AutoModelForCausalLM.from_pretrained(12 model_name,13 torch_dtype=torch.float16,14 device_map="auto"15)16print("Model loaded.")17 18SYSTEM_PROMPT = """You are an English learning assistant. Extract 8-20 useful expressions from the text.19For each expression, output a JSON object with keys: expression, meaning, explanation, original_context, extra_example.20Meaning and explanation should be in Chinese.21Output must be a JSON array. No extra text."""22 23def analyze(text):24 try:25 if not text or len(text.strip()) < 20:26 return "<div style='color:red'>⚠️ Please enter at least 20 characters.</div>"27 28 messages = [29 {"role": "system", "content": SYSTEM_PROMPT},30 {"role": "user", "content": text}31 ]32 inputs = tokenizer.apply_chat_template(33 messages,34 add_generation_prompt=True,35 return_tensors="pt"36 ).to(model.device)37 38 with torch.no_grad():39 outputs = model.generate(40 inputs,41 max_new_tokens=1024,42 do_sample=False,43 temperature=1.044 )45 46 response = tokenizer.decode(outputs[0][inputs.shape[1]:], skip_special_tokens=True)47 48 # 提取 JSON49 if "```json" in response:50 response = response.split("```json")[1].split("```")[0]51 elif "```" in response:52 response = response.split("```")[1].split("```")[0]53 start = response.find("[")54 end = response.rfind("]") + 155 if start == -1 or end == 0:56 return f"<div style='color:red'>No JSON array found. Raw response:<br>{html.escape(response[:300])}</div>"57 58 json_str = response[start:end]59 data = json.loads(json_str)60 61 cards = ""62 for e in data:63 cards += f"""64 <div style="background:white;border-radius:16px;border:1px solid #ddd;padding:1rem;margin-bottom:1rem;">65 <b style="font-size:1.2rem;">{html.escape(str(e.get('expression', '')))}</b><br>66 <b>Meaning</b><br>{html.escape(str(e.get('meaning', '')))}<br>67 <b>Explanation</b><br>{html.escape(str(e.get('explanation', '')))}<br>68 <b>Original Context</b><br>{html.escape(str(e.get('original_context', '')))}<br>69 <b>Extra Example</b><br>{html.escape(str(e.get('extra_example', '')))}70 </div>71 """72 return cards if cards else "<div>No expressions extracted.</div>"73 except Exception as e:74 error_html = f"<div style='color:red; background:#ffe0e0; padding:1rem; border-radius:8px;'>"75 error_html += f"<b>Error:</b> {html.escape(str(e))}<br><br>"76 error_html += f"<details><summary>Full traceback</summary><pre>{html.escape(traceback.format_exc())}</pre></details>"77 error_html += "</div>"78 return error_html79 80# 浅色主题81theme = gr.themes.Soft(82 primary_hue="neutral",83 secondary_hue="neutral",84 font=gr.themes.GoogleFont("Inter"),85).set(86 body_background_fill="#fafaf9",87 button_primary_background_fill="#1a1a1a",88 button_primary_text_color="white",89 block_background_fill="white",90)91 92with gr.Blocks(theme=theme, title="InContext") as demo:93 gr.Markdown("# InContext\n### Learn English Expressions Through Real Content")94 with gr.Row():95 txt = gr.Textbox(lines=10, placeholder="Paste English content here...", label="")96 btn = gr.Button("Analyze", variant="primary")97 out = gr.HTML()98 btn.click(analyze, txt, out)99 100demo.launch()