Gradio Python coder using the fine-tuned Qwen2.5-0.5B LoRA

#1
Files changed (5) hide show
  1. README.md +21 -4
  2. app.py +68 -0
  3. index.html +0 -19
  4. requirements.txt +4 -0
  5. style.css +0 -28
README.md CHANGED
@@ -1,12 +1,29 @@
1
  ---
2
  title: PyCoder
3
- emoji: 🦀
4
  colorFrom: pink
5
  colorTo: green
6
- sdk: static
 
 
7
  pinned: false
8
  license: mit
9
- short_description: Lightweight coding chatbot powered by Qwen2.5-0.5B-Instruc
 
 
 
10
  ---
11
 
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
  title: PyCoder
3
+ emoji: 🐍
4
  colorFrom: pink
5
  colorTo: green
6
+ sdk: gradio
7
+ sdk_version: 5.49.1
8
+ app_file: app.py
9
  pinned: false
10
  license: mit
11
+ short_description: Lightweight Python coding chatbot (Qwen2.5-0.5B + LoRA)
12
+ models:
13
+ - Qwen/Qwen2.5-0.5B-Instruct
14
+ - ali4566544/qwen2.5-0.5b-instruct-python-lora
15
  ---
16
 
17
+ # PyCoder
18
+
19
+ A simple Python coding chatbot built with Gradio. It runs
20
+ [Qwen/Qwen2.5-0.5B-Instruct](https://huggingface.co/Qwen/Qwen2.5-0.5B-Instruct) with the
21
+ [ali4566544/qwen2.5-0.5b-instruct-python-lora](https://huggingface.co/ali4566544/qwen2.5-0.5b-instruct-python-lora)
22
+ adapter merged in, on CPU, and streams responses.
23
+
24
+ Run locally:
25
+
26
+ ```bash
27
+ pip install gradio -r requirements.txt
28
+ python app.py
29
+ ```
app.py ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import threading
2
+
3
+ import gradio as gr
4
+ import torch
5
+ from peft import PeftModel
6
+ from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer
7
+
8
+ BASE_MODEL = "Qwen/Qwen2.5-0.5B-Instruct"
9
+ ADAPTER = "ali4566544/qwen2.5-0.5b-instruct-python-lora"
10
+ # The adapter was trained with this exact system prompt.
11
+ SYSTEM_PROMPT = (
12
+ "You are a helpful Python coding assistant. Write clear, correct, idiomatic Python, "
13
+ "explain the code concisely, and point out bugs and how to fix them when asked."
14
+ )
15
+
16
+ tokenizer = AutoTokenizer.from_pretrained(ADAPTER)
17
+ base = AutoModelForCausalLM.from_pretrained(BASE_MODEL, torch_dtype=torch.float32)
18
+ # Merge LoRA weights into the base model for faster CPU inference.
19
+ model = PeftModel.from_pretrained(base, ADAPTER).merge_and_unload()
20
+ model.eval()
21
+
22
+
23
+ def respond(message, history, max_new_tokens, temperature):
24
+ messages = [{"role": "system", "content": SYSTEM_PROMPT}]
25
+ messages += [{"role": m["role"], "content": m["content"]} for m in history]
26
+ messages.append({"role": "user", "content": message})
27
+
28
+ inputs = tokenizer.apply_chat_template(
29
+ messages, add_generation_prompt=True, return_tensors="pt", return_dict=True
30
+ )
31
+ streamer = TextIteratorStreamer(tokenizer, skip_prompt=True, skip_special_tokens=True)
32
+ gen_kwargs = dict(**inputs, streamer=streamer, max_new_tokens=int(max_new_tokens))
33
+ if temperature > 0:
34
+ gen_kwargs.update(do_sample=True, temperature=temperature, top_p=0.9)
35
+ else:
36
+ gen_kwargs.update(do_sample=False)
37
+
38
+ threading.Thread(target=model.generate, kwargs=gen_kwargs).start()
39
+ output = ""
40
+ for chunk in streamer:
41
+ output += chunk
42
+ yield output
43
+
44
+
45
+ demo = gr.ChatInterface(
46
+ respond,
47
+ type="messages",
48
+ title="🐍 PyCoder",
49
+ description=(
50
+ "A small Python coding assistant: Qwen2.5-0.5B-Instruct fine-tuned with a "
51
+ f"[LoRA adapter](https://huggingface.co/{ADAPTER}). It's a 0.5B learning project, "
52
+ "so always run and test the code it writes."
53
+ ),
54
+ additional_inputs=[
55
+ gr.Slider(64, 1024, value=512, step=32, label="Max new tokens"),
56
+ gr.Slider(0.0, 1.5, value=0.0, step=0.1, label="Temperature (0 = greedy)"),
57
+ ],
58
+ examples=[
59
+ ["Write a function that removes duplicates from a list while keeping order."],
60
+ ["How do I read a CSV file with pandas and drop rows with missing values?"],
61
+ ["Write a minimal FastAPI app with a /health endpoint."],
62
+ ["Why does this fail? `for i in range(len(xs)): xs.remove(xs[i])`"],
63
+ ],
64
+ cache_examples=False,
65
+ )
66
+
67
+ if __name__ == "__main__":
68
+ demo.launch()
index.html DELETED
@@ -1,19 +0,0 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ --extra-index-url https://download.pytorch.org/whl/cpu
2
+ torch
3
+ transformers==4.57.1
4
+ peft==0.17.1
style.css DELETED
@@ -1,28 +0,0 @@
1
- body {
2
- padding: 2rem;
3
- font-family: -apple-system, BlinkMacSystemFont, "Arial", sans-serif;
4
- }
5
-
6
- h1 {
7
- font-size: 16px;
8
- margin-top: 0;
9
- }
10
-
11
- p {
12
- color: rgb(107, 114, 128);
13
- font-size: 15px;
14
- margin-bottom: 10px;
15
- margin-top: 5px;
16
- }
17
-
18
- .card {
19
- max-width: 620px;
20
- margin: 0 auto;
21
- padding: 16px;
22
- border: 1px solid lightgray;
23
- border-radius: 16px;
24
- }
25
-
26
- .card p:last-child {
27
- margin-bottom: 0;
28
- }