Spaces:
Build error
Build error
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,13 +1,7 @@
|
|
| 1 |
"""
|
| 2 |
Phi-2 Chatbot Playground β Hugging Face Space
|
| 3 |
==============================================
|
| 4 |
-
|
| 5 |
-
Features:
|
| 6 |
-
- System instruction editor
|
| 7 |
-
- Training data / few-shot examples editor
|
| 8 |
-
- Temperature & max token controls
|
| 9 |
-
- Chat interface with history
|
| 10 |
-
- Clear conversation button
|
| 11 |
"""
|
| 12 |
|
| 13 |
import gradio as gr
|
|
@@ -34,8 +28,8 @@ print("Model loaded on CPU!")
|
|
| 34 |
|
| 35 |
def build_prompt(system_instruction: str, training_data: str, history: list, user_input: str) -> str:
|
| 36 |
"""
|
| 37 |
-
Assembles a Phi-2 compatible prompt.
|
| 38 |
-
|
| 39 |
"""
|
| 40 |
prompt = ""
|
| 41 |
|
|
@@ -45,8 +39,14 @@ def build_prompt(system_instruction: str, training_data: str, history: list, use
|
|
| 45 |
if training_data.strip():
|
| 46 |
prompt += f"{training_data.strip()}\n\n"
|
| 47 |
|
| 48 |
-
|
| 49 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
|
| 51 |
prompt += f"Instruct: {user_input}\nOutput:"
|
| 52 |
return prompt
|
|
@@ -64,11 +64,11 @@ def generate_response(
|
|
| 64 |
repetition_penalty: float,
|
| 65 |
):
|
| 66 |
if not user_input.strip():
|
| 67 |
-
return history,
|
| 68 |
|
| 69 |
prompt = build_prompt(system_instruction, training_data, history, user_input)
|
| 70 |
|
| 71 |
-
inputs = tokenizer(prompt, return_tensors="pt")
|
| 72 |
input_len = inputs["input_ids"].shape[1]
|
| 73 |
|
| 74 |
with torch.no_grad():
|
|
@@ -78,7 +78,7 @@ def generate_response(
|
|
| 78 |
temperature=float(temperature),
|
| 79 |
top_p=float(top_p),
|
| 80 |
repetition_penalty=float(repetition_penalty),
|
| 81 |
-
do_sample=temperature > 0,
|
| 82 |
pad_token_id=tokenizer.eos_token_id,
|
| 83 |
eos_token_id=tokenizer.eos_token_id,
|
| 84 |
)
|
|
@@ -86,18 +86,22 @@ def generate_response(
|
|
| 86 |
generated_ids = output[0][input_len:]
|
| 87 |
reply = tokenizer.decode(generated_ids, skip_special_tokens=True)
|
| 88 |
|
| 89 |
-
#
|
| 90 |
reply = reply.split("Instruct:")[0].strip()
|
| 91 |
|
| 92 |
-
|
| 93 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 94 |
|
| 95 |
|
| 96 |
def clear_chat():
|
| 97 |
-
return [],
|
| 98 |
|
| 99 |
|
| 100 |
-
# ββ
|
| 101 |
|
| 102 |
DEFAULT_SYSTEM = (
|
| 103 |
"You are a helpful, respectful, and honest assistant. "
|
|
@@ -111,6 +115,8 @@ Output: 2 + 2 equals 4.
|
|
| 111 |
Instruct: What is the capital of Japan?
|
| 112 |
Output: The capital of Japan is Tokyo."""
|
| 113 |
|
|
|
|
|
|
|
| 114 |
with gr.Blocks(
|
| 115 |
title="Phi-2 Playground",
|
| 116 |
theme=gr.themes.Soft(
|
|
@@ -119,8 +125,7 @@ with gr.Blocks(
|
|
| 119 |
font=gr.themes.GoogleFont("IBM Plex Mono"),
|
| 120 |
),
|
| 121 |
css="""
|
| 122 |
-
#chatbot { height:
|
| 123 |
-
.gr-button-primary { background: #7c3aed !important; }
|
| 124 |
footer { display: none !important; }
|
| 125 |
.title-block { text-align: center; padding: 12px 0 4px 0; }
|
| 126 |
.title-block h1 { font-size: 2rem; font-weight: 800; letter-spacing: -1px; }
|
|
@@ -128,11 +133,10 @@ with gr.Blocks(
|
|
| 128 |
""",
|
| 129 |
) as demo:
|
| 130 |
|
| 131 |
-
# ββ Title ββ
|
| 132 |
gr.HTML("""
|
| 133 |
<div class="title-block">
|
| 134 |
<h1>Ξ¦ Phi-2 Playground</h1>
|
| 135 |
-
<p>microsoft/phi-2 Β· 2.7B Parameters Β·
|
| 136 |
</div>
|
| 137 |
""")
|
| 138 |
|
|
@@ -140,9 +144,16 @@ with gr.Blocks(
|
|
| 140 |
|
| 141 |
with gr.Tabs():
|
| 142 |
|
| 143 |
-
# ββ Tab 1: Chat ββ
|
| 144 |
with gr.TabItem("π¬ Chat"):
|
| 145 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 146 |
|
| 147 |
with gr.Row():
|
| 148 |
user_input = gr.Textbox(
|
|
@@ -150,22 +161,19 @@ with gr.Blocks(
|
|
| 150 |
label="Your message",
|
| 151 |
lines=2,
|
| 152 |
scale=8,
|
|
|
|
| 153 |
)
|
| 154 |
send_btn = gr.Button("Send β€", variant="primary", scale=1, min_width=80)
|
| 155 |
|
| 156 |
clear_btn = gr.Button("ποΈ Clear Conversation", variant="secondary")
|
| 157 |
|
| 158 |
-
gr.Markdown(
|
| 159 |
-
"_Press **Enter** to send. Use **Shift+Enter** for a new line._",
|
| 160 |
-
elem_id="hint",
|
| 161 |
-
)
|
| 162 |
|
| 163 |
-
# ββ Tab 2:
|
| 164 |
with gr.TabItem("βοΈ Instructions & Data"):
|
|
|
|
| 165 |
gr.Markdown("### π§ System Instruction")
|
| 166 |
-
gr.Markdown(
|
| 167 |
-
"This text is prepended to every prompt to define the model's role and behavior."
|
| 168 |
-
)
|
| 169 |
system_instruction = gr.Textbox(
|
| 170 |
value=DEFAULT_SYSTEM,
|
| 171 |
lines=4,
|
|
@@ -176,54 +184,73 @@ with gr.Blocks(
|
|
| 176 |
gr.Markdown("---")
|
| 177 |
gr.Markdown("### π Few-Shot / Training Data")
|
| 178 |
gr.Markdown(
|
| 179 |
-
"
|
| 180 |
-
"
|
| 181 |
)
|
| 182 |
training_data = gr.Textbox(
|
| 183 |
value=DEFAULT_TRAINING_DATA,
|
| 184 |
lines=10,
|
| 185 |
-
label="
|
| 186 |
placeholder="Instruct: What is X?\nOutput: X is β¦",
|
| 187 |
)
|
| 188 |
|
| 189 |
with gr.Accordion("π Quick Templates", open=False):
|
| 190 |
-
gr.Markdown("Click a template to load it into the
|
| 191 |
with gr.Row():
|
| 192 |
-
tpl_qa
|
| 193 |
-
tpl_code
|
| 194 |
tpl_summary = gr.Button("Summarizer")
|
| 195 |
|
| 196 |
tpl_qa.click(
|
| 197 |
-
fn=lambda:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 198 |
outputs=training_data,
|
| 199 |
)
|
| 200 |
tpl_code.click(
|
| 201 |
-
fn=lambda:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 202 |
outputs=training_data,
|
| 203 |
)
|
| 204 |
tpl_summary.click(
|
| 205 |
-
fn=lambda:
|
|
|
|
|
|
|
|
|
|
|
|
|
| 206 |
outputs=training_data,
|
| 207 |
)
|
| 208 |
|
| 209 |
-
# ββ Tab 3: Parameters ββ
|
| 210 |
with gr.TabItem("ποΈ Parameters"):
|
|
|
|
| 211 |
gr.Markdown("### Generation Parameters")
|
| 212 |
|
| 213 |
temperature = gr.Slider(
|
| 214 |
0.01, 2.0, value=0.7, step=0.01,
|
| 215 |
label="Temperature",
|
| 216 |
-
info="Higher = more creative
|
| 217 |
)
|
| 218 |
max_new_tokens = gr.Slider(
|
| 219 |
-
32,
|
| 220 |
label="Max New Tokens",
|
| 221 |
-
info="
|
| 222 |
)
|
| 223 |
top_p = gr.Slider(
|
| 224 |
0.1, 1.0, value=0.95, step=0.01,
|
| 225 |
label="Top-p (Nucleus Sampling)",
|
| 226 |
-
info="
|
| 227 |
)
|
| 228 |
repetition_penalty = gr.Slider(
|
| 229 |
1.0, 2.0, value=1.1, step=0.05,
|
|
@@ -234,6 +261,7 @@ with gr.Blocks(
|
|
| 234 |
gr.Markdown("---")
|
| 235 |
gr.Markdown("""
|
| 236 |
**Model Details**
|
|
|
|
| 237 |
| Property | Value |
|
| 238 |
|---|---|
|
| 239 |
| Model | `microsoft/phi-2` |
|
|
@@ -241,6 +269,7 @@ with gr.Blocks(
|
|
| 241 |
| Architecture | Transformer Decoder |
|
| 242 |
| Context Length | 2048 tokens |
|
| 243 |
| License | MIT |
|
|
|
|
| 244 |
|
| 245 |
[π Model Card on Hugging Face](https://huggingface.co/microsoft/phi-2)
|
| 246 |
""")
|
|
@@ -252,15 +281,20 @@ with gr.Blocks(
|
|
| 252 |
system_instruction, training_data,
|
| 253 |
temperature, max_new_tokens, top_p, repetition_penalty,
|
| 254 |
]
|
| 255 |
-
gen_outputs = [
|
|
|
|
|
|
|
|
|
|
| 256 |
|
| 257 |
send_btn.click(generate_response, inputs=gen_inputs, outputs=gen_outputs).then(
|
| 258 |
-
lambda:
|
| 259 |
)
|
| 260 |
user_input.submit(generate_response, inputs=gen_inputs, outputs=gen_outputs).then(
|
| 261 |
-
lambda:
|
|
|
|
|
|
|
|
|
|
| 262 |
)
|
| 263 |
-
clear_btn.click(clear_chat, outputs=[chatbot, state])
|
| 264 |
|
| 265 |
|
| 266 |
# ββ Launch ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
|
|
| 1 |
"""
|
| 2 |
Phi-2 Chatbot Playground β Hugging Face Space
|
| 3 |
==============================================
|
| 4 |
+
Compatible with Gradio 6.x (messages format) + CPU deployment.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5 |
"""
|
| 6 |
|
| 7 |
import gradio as gr
|
|
|
|
| 28 |
|
| 29 |
def build_prompt(system_instruction: str, training_data: str, history: list, user_input: str) -> str:
|
| 30 |
"""
|
| 31 |
+
Assembles a Phi-2 compatible prompt from Gradio 6 messages format.
|
| 32 |
+
history = [{"role": "user"|"assistant", "content": "..."}]
|
| 33 |
"""
|
| 34 |
prompt = ""
|
| 35 |
|
|
|
|
| 39 |
if training_data.strip():
|
| 40 |
prompt += f"{training_data.strip()}\n\n"
|
| 41 |
|
| 42 |
+
# Pair up messages from history
|
| 43 |
+
i = 0
|
| 44 |
+
while i < len(history) - 1:
|
| 45 |
+
if history[i]["role"] == "user" and history[i+1]["role"] == "assistant":
|
| 46 |
+
prompt += f"Instruct: {history[i]['content']}\nOutput: {history[i+1]['content']}\n"
|
| 47 |
+
i += 2
|
| 48 |
+
else:
|
| 49 |
+
i += 1
|
| 50 |
|
| 51 |
prompt += f"Instruct: {user_input}\nOutput:"
|
| 52 |
return prompt
|
|
|
|
| 64 |
repetition_penalty: float,
|
| 65 |
):
|
| 66 |
if not user_input.strip():
|
| 67 |
+
return history, ""
|
| 68 |
|
| 69 |
prompt = build_prompt(system_instruction, training_data, history, user_input)
|
| 70 |
|
| 71 |
+
inputs = tokenizer(prompt, return_tensors="pt")
|
| 72 |
input_len = inputs["input_ids"].shape[1]
|
| 73 |
|
| 74 |
with torch.no_grad():
|
|
|
|
| 78 |
temperature=float(temperature),
|
| 79 |
top_p=float(top_p),
|
| 80 |
repetition_penalty=float(repetition_penalty),
|
| 81 |
+
do_sample=temperature > 0.01,
|
| 82 |
pad_token_id=tokenizer.eos_token_id,
|
| 83 |
eos_token_id=tokenizer.eos_token_id,
|
| 84 |
)
|
|
|
|
| 86 |
generated_ids = output[0][input_len:]
|
| 87 |
reply = tokenizer.decode(generated_ids, skip_special_tokens=True)
|
| 88 |
|
| 89 |
+
# Stop at next "Instruct:" if model keeps generating
|
| 90 |
reply = reply.split("Instruct:")[0].strip()
|
| 91 |
|
| 92 |
+
# Gradio 6 messages format
|
| 93 |
+
history = history + [
|
| 94 |
+
{"role": "user", "content": user_input},
|
| 95 |
+
{"role": "assistant", "content": reply},
|
| 96 |
+
]
|
| 97 |
+
return history, ""
|
| 98 |
|
| 99 |
|
| 100 |
def clear_chat():
|
| 101 |
+
return [], ""
|
| 102 |
|
| 103 |
|
| 104 |
+
# ββ Defaults ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 105 |
|
| 106 |
DEFAULT_SYSTEM = (
|
| 107 |
"You are a helpful, respectful, and honest assistant. "
|
|
|
|
| 115 |
Instruct: What is the capital of Japan?
|
| 116 |
Output: The capital of Japan is Tokyo."""
|
| 117 |
|
| 118 |
+
# ββ UI ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 119 |
+
|
| 120 |
with gr.Blocks(
|
| 121 |
title="Phi-2 Playground",
|
| 122 |
theme=gr.themes.Soft(
|
|
|
|
| 125 |
font=gr.themes.GoogleFont("IBM Plex Mono"),
|
| 126 |
),
|
| 127 |
css="""
|
| 128 |
+
#chatbot { height: 460px; overflow-y: auto; }
|
|
|
|
| 129 |
footer { display: none !important; }
|
| 130 |
.title-block { text-align: center; padding: 12px 0 4px 0; }
|
| 131 |
.title-block h1 { font-size: 2rem; font-weight: 800; letter-spacing: -1px; }
|
|
|
|
| 133 |
""",
|
| 134 |
) as demo:
|
| 135 |
|
|
|
|
| 136 |
gr.HTML("""
|
| 137 |
<div class="title-block">
|
| 138 |
<h1>Ξ¦ Phi-2 Playground</h1>
|
| 139 |
+
<p>microsoft/phi-2 Β· 2.7B Parameters Β· CPU Β· Gradio 6</p>
|
| 140 |
</div>
|
| 141 |
""")
|
| 142 |
|
|
|
|
| 144 |
|
| 145 |
with gr.Tabs():
|
| 146 |
|
| 147 |
+
# ββ Tab 1: Chat βββββββββββββββββββββββββββββββββββββββββββββββββββοΏ½οΏ½οΏ½βββ
|
| 148 |
with gr.TabItem("π¬ Chat"):
|
| 149 |
+
|
| 150 |
+
chatbot = gr.Chatbot(
|
| 151 |
+
elem_id="chatbot",
|
| 152 |
+
label="Conversation",
|
| 153 |
+
type="messages", # Gradio 6 messages format
|
| 154 |
+
bubble_full_width=False,
|
| 155 |
+
show_label=False,
|
| 156 |
+
)
|
| 157 |
|
| 158 |
with gr.Row():
|
| 159 |
user_input = gr.Textbox(
|
|
|
|
| 161 |
label="Your message",
|
| 162 |
lines=2,
|
| 163 |
scale=8,
|
| 164 |
+
show_label=False,
|
| 165 |
)
|
| 166 |
send_btn = gr.Button("Send β€", variant="primary", scale=1, min_width=80)
|
| 167 |
|
| 168 |
clear_btn = gr.Button("ποΈ Clear Conversation", variant="secondary")
|
| 169 |
|
| 170 |
+
gr.Markdown("_β οΈ CPU mode: responses may take 1β3 minutes. Please be patient!_")
|
|
|
|
|
|
|
|
|
|
| 171 |
|
| 172 |
+
# ββ Tab 2: Instructions & Data ββββββββββββββββββββββββββββββββββββββββ
|
| 173 |
with gr.TabItem("βοΈ Instructions & Data"):
|
| 174 |
+
|
| 175 |
gr.Markdown("### π§ System Instruction")
|
| 176 |
+
gr.Markdown("Prepended to every prompt β defines the assistant's persona and behavior.")
|
|
|
|
|
|
|
| 177 |
system_instruction = gr.Textbox(
|
| 178 |
value=DEFAULT_SYSTEM,
|
| 179 |
lines=4,
|
|
|
|
| 184 |
gr.Markdown("---")
|
| 185 |
gr.Markdown("### π Few-Shot / Training Data")
|
| 186 |
gr.Markdown(
|
| 187 |
+
"Add `Instruct: β¦ / Output: β¦` example pairs here to guide the model's style. "
|
| 188 |
+
"These act as in-context few-shot examples injected before your message."
|
| 189 |
)
|
| 190 |
training_data = gr.Textbox(
|
| 191 |
value=DEFAULT_TRAINING_DATA,
|
| 192 |
lines=10,
|
| 193 |
+
label="Few-Shot Examples",
|
| 194 |
placeholder="Instruct: What is X?\nOutput: X is β¦",
|
| 195 |
)
|
| 196 |
|
| 197 |
with gr.Accordion("π Quick Templates", open=False):
|
| 198 |
+
gr.Markdown("Click a template below to load it into the few-shot box.")
|
| 199 |
with gr.Row():
|
| 200 |
+
tpl_qa = gr.Button("Q&A")
|
| 201 |
+
tpl_code = gr.Button("Code Assistant")
|
| 202 |
tpl_summary = gr.Button("Summarizer")
|
| 203 |
|
| 204 |
tpl_qa.click(
|
| 205 |
+
fn=lambda: (
|
| 206 |
+
"Instruct: What is the boiling point of water?\n"
|
| 207 |
+
"Output: Water boils at 100Β°C (212Β°F) at sea level.\n\n"
|
| 208 |
+
"Instruct: Who wrote Romeo and Juliet?\n"
|
| 209 |
+
"Output: Romeo and Juliet was written by William Shakespeare."
|
| 210 |
+
),
|
| 211 |
outputs=training_data,
|
| 212 |
)
|
| 213 |
tpl_code.click(
|
| 214 |
+
fn=lambda: (
|
| 215 |
+
"Instruct: Write a Python function to check if a number is prime.\n"
|
| 216 |
+
"Output: def is_prime(n):\n"
|
| 217 |
+
" if n < 2: return False\n"
|
| 218 |
+
" for i in range(2, int(n**0.5)+1):\n"
|
| 219 |
+
" if n % i == 0: return False\n"
|
| 220 |
+
" return True\n\n"
|
| 221 |
+
"Instruct: How do I reverse a list in Python?\n"
|
| 222 |
+
"Output: Use list[::-1] to get a reversed copy, or list.reverse() to reverse in place."
|
| 223 |
+
),
|
| 224 |
outputs=training_data,
|
| 225 |
)
|
| 226 |
tpl_summary.click(
|
| 227 |
+
fn=lambda: (
|
| 228 |
+
"Instruct: Summarize the following in one sentence.\n"
|
| 229 |
+
"Text: The Amazon rainforest covers much of northwestern Brazil and is the world's largest tropical rainforest.\n"
|
| 230 |
+
"Output: The Amazon rainforest is the world's largest tropical rainforest, located mainly in Brazil."
|
| 231 |
+
),
|
| 232 |
outputs=training_data,
|
| 233 |
)
|
| 234 |
|
| 235 |
+
# ββ Tab 3: Parameters βββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 236 |
with gr.TabItem("ποΈ Parameters"):
|
| 237 |
+
|
| 238 |
gr.Markdown("### Generation Parameters")
|
| 239 |
|
| 240 |
temperature = gr.Slider(
|
| 241 |
0.01, 2.0, value=0.7, step=0.01,
|
| 242 |
label="Temperature",
|
| 243 |
+
info="Higher = more creative. Lower = more focused.",
|
| 244 |
)
|
| 245 |
max_new_tokens = gr.Slider(
|
| 246 |
+
32, 512, value=200, step=16,
|
| 247 |
label="Max New Tokens",
|
| 248 |
+
info="Max tokens to generate. Keep low on CPU for faster responses.",
|
| 249 |
)
|
| 250 |
top_p = gr.Slider(
|
| 251 |
0.1, 1.0, value=0.95, step=0.01,
|
| 252 |
label="Top-p (Nucleus Sampling)",
|
| 253 |
+
info="Restricts sampling to top probability mass.",
|
| 254 |
)
|
| 255 |
repetition_penalty = gr.Slider(
|
| 256 |
1.0, 2.0, value=1.1, step=0.05,
|
|
|
|
| 261 |
gr.Markdown("---")
|
| 262 |
gr.Markdown("""
|
| 263 |
**Model Details**
|
| 264 |
+
|
| 265 |
| Property | Value |
|
| 266 |
|---|---|
|
| 267 |
| Model | `microsoft/phi-2` |
|
|
|
|
| 269 |
| Architecture | Transformer Decoder |
|
| 270 |
| Context Length | 2048 tokens |
|
| 271 |
| License | MIT |
|
| 272 |
+
| Runtime | CPU (float32) |
|
| 273 |
|
| 274 |
[π Model Card on Hugging Face](https://huggingface.co/microsoft/phi-2)
|
| 275 |
""")
|
|
|
|
| 281 |
system_instruction, training_data,
|
| 282 |
temperature, max_new_tokens, top_p, repetition_penalty,
|
| 283 |
]
|
| 284 |
+
gen_outputs = [state, user_input]
|
| 285 |
+
|
| 286 |
+
def sync_chatbot(history, _user_input):
|
| 287 |
+
return history
|
| 288 |
|
| 289 |
send_btn.click(generate_response, inputs=gen_inputs, outputs=gen_outputs).then(
|
| 290 |
+
fn=lambda h: h, inputs=state, outputs=chatbot
|
| 291 |
)
|
| 292 |
user_input.submit(generate_response, inputs=gen_inputs, outputs=gen_outputs).then(
|
| 293 |
+
fn=lambda h: h, inputs=state, outputs=chatbot
|
| 294 |
+
)
|
| 295 |
+
clear_btn.click(clear_chat, outputs=[state, user_input]).then(
|
| 296 |
+
fn=lambda h: h, inputs=state, outputs=chatbot
|
| 297 |
)
|
|
|
|
| 298 |
|
| 299 |
|
| 300 |
# ββ Launch ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|