Spaces:
Paused
Paused
Update app.py
Browse files
app.py
CHANGED
@@ -1,10 +1,11 @@
|
|
1 |
"""
|
2 |
-
SchoolSpiritΒ AI β
|
3 |
-
|
4 |
-
β’
|
5 |
-
β’
|
6 |
-
β’
|
7 |
-
β’
|
|
|
8 |
"""
|
9 |
|
10 |
import re
|
@@ -20,23 +21,25 @@ from transformers.utils import logging as hf_logging
|
|
20 |
hf_logging.set_verbosity_error()
|
21 |
LOG = hf_logging.get_logger("SchoolSpirit")
|
22 |
|
23 |
-
MODEL_ID = "
|
24 |
MAX_TURNS = 6
|
25 |
-
MAX_TOKENS =
|
26 |
-
MAX_INPUT_CH =
|
27 |
|
28 |
SYSTEM_MSG = (
|
29 |
-
"You are SchoolSpiritΒ AI, the
|
30 |
"offers onβprem AI chat mascots, fineβtuning services, and turnkey GPU "
|
31 |
-
"hardware for schools.
|
32 |
-
"
|
33 |
)
|
34 |
|
35 |
# ββββββββββββββββββββββββββ Model Load ββββββββββββββββββββββββββββββββββββββ
|
36 |
try:
|
37 |
tok = AutoTokenizer.from_pretrained(MODEL_ID)
|
38 |
model = AutoModelForCausalLM.from_pretrained(
|
39 |
-
MODEL_ID,
|
|
|
|
|
40 |
)
|
41 |
generator = pipeline(
|
42 |
"text-generation",
|
@@ -46,81 +49,72 @@ try:
|
|
46 |
do_sample=True,
|
47 |
temperature=0.7,
|
48 |
)
|
49 |
-
|
50 |
except Exception as exc: # noqa: BLE001
|
51 |
-
|
52 |
generator = None
|
53 |
-
LOG.error(
|
54 |
|
55 |
# ββββββββββββββββββββββββββ Helpers ββββββββββββββββββββββββββββββββββββββββ
|
56 |
-
def
|
57 |
-
"""Return
|
58 |
-
return hist[-
|
59 |
|
60 |
|
61 |
-
def
|
62 |
-
"""
|
63 |
-
|
64 |
-
|
65 |
-
return msg or "β¦"
|
66 |
|
67 |
# ββββββββββββββββββββββββββ Chat Callback βββββββββββββββββββββββββββββββββββ
|
68 |
def chat(history, user_msg):
|
69 |
-
|
70 |
-
history = list(history)
|
71 |
|
72 |
-
|
73 |
-
|
74 |
-
history.append((user_msg, MODEL_LOAD_ERR))
|
75 |
return history, ""
|
76 |
|
77 |
-
|
78 |
-
user_msg = (user_msg or "").strip()
|
79 |
if not user_msg:
|
80 |
history.append(("", "Please enter a message."))
|
81 |
return history, ""
|
82 |
if len(user_msg) > MAX_INPUT_CH:
|
83 |
-
history.append(
|
84 |
-
(user_msg, "Sorry, that message is too long. Please shorten it.")
|
85 |
-
)
|
86 |
return history, ""
|
87 |
|
88 |
-
history =
|
89 |
|
90 |
# Build prompt
|
91 |
-
|
92 |
for u, a in history:
|
93 |
-
|
94 |
-
|
95 |
-
prompt = "\n".join(
|
96 |
|
97 |
-
# Generate
|
98 |
try:
|
99 |
-
completion = generator(prompt, truncate=
|
100 |
-
reply =
|
101 |
except Exception as err: # noqa: BLE001
|
102 |
LOG.error(f"Inference error: {err}")
|
103 |
-
reply =
|
104 |
-
"SorryβI'm having trouble right now. Please try again in a moment."
|
105 |
-
)
|
106 |
|
107 |
history.append((user_msg, reply))
|
108 |
return history, ""
|
109 |
|
110 |
-
# ββββββββββββββββββββββββββ Clear Chat
|
111 |
def clear_chat():
|
112 |
return [], ""
|
113 |
|
114 |
# ββββββββββββββββββββββββββ UI Launch βββββββββββββββββββββββββββββββββββββββ
|
115 |
with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue")) as demo:
|
116 |
gr.Markdown("# SchoolSpiritΒ AI Chat")
|
117 |
-
chatbot
|
118 |
-
|
119 |
send_btn = gr.Button("Send")
|
120 |
clear_btn = gr.Button("Clear Chat", variant="secondary")
|
121 |
|
122 |
-
send_btn.click(chat, [chatbot,
|
123 |
-
|
124 |
-
clear_btn.click(clear_chat, outputs=[chatbot,
|
125 |
|
126 |
demo.launch()
|
|
|
1 |
"""
|
2 |
+
SchoolSpiritΒ AI β Graniteβ3.3β2B chatbot Space
|
3 |
+
----------------------------------------------
|
4 |
+
β’ Uses IBM Graniteβ3.3β2BβInstruct (public, no access token).
|
5 |
+
β’ Fits HF CPU Space (2βB params, bfloat16).
|
6 |
+
β’ Keeps last MAX_TURNS exchanges.
|
7 |
+
β’ βClear chatβ button resets context.
|
8 |
+
β’ Robust error handling & logging.
|
9 |
"""
|
10 |
|
11 |
import re
|
|
|
21 |
hf_logging.set_verbosity_error()
|
22 |
LOG = hf_logging.get_logger("SchoolSpirit")
|
23 |
|
24 |
+
MODEL_ID = "ibm-granite/granite-3.3-2b-instruct"
|
25 |
MAX_TURNS = 6
|
26 |
+
MAX_TOKENS = 200
|
27 |
+
MAX_INPUT_CH = 400
|
28 |
|
29 |
SYSTEM_MSG = (
|
30 |
+
"You are SchoolSpiritΒ AI, the upbeat digital mascot for a company that "
|
31 |
"offers onβprem AI chat mascots, fineβtuning services, and turnkey GPU "
|
32 |
+
"hardware for schools. Answer concisely and ageβappropriately. If unsure, "
|
33 |
+
"say so and suggest contacting a human. Do not ask for personal data."
|
34 |
)
|
35 |
|
36 |
# ββββββββββββββββββββββββββ Model Load ββββββββββββββββββββββββββββββββββββββ
|
37 |
try:
|
38 |
tok = AutoTokenizer.from_pretrained(MODEL_ID)
|
39 |
model = AutoModelForCausalLM.from_pretrained(
|
40 |
+
MODEL_ID,
|
41 |
+
device_map="auto",
|
42 |
+
torch_dtype="auto", # bfloat16/float16 under the hood
|
43 |
)
|
44 |
generator = pipeline(
|
45 |
"text-generation",
|
|
|
49 |
do_sample=True,
|
50 |
temperature=0.7,
|
51 |
)
|
52 |
+
MODEL_ERR = None
|
53 |
except Exception as exc: # noqa: BLE001
|
54 |
+
MODEL_ERR = f"Model load error: {exc}"
|
55 |
generator = None
|
56 |
+
LOG.error(MODEL_ERR)
|
57 |
|
58 |
# ββββββββββββββββββββββββββ Helpers ββββββββββββββββββββββββββββββββββββββββ
|
59 |
+
def truncate(hist):
|
60 |
+
"""Return last MAX_TURNS (u,a) pairs."""
|
61 |
+
return hist[-MAX_TURNS:] if len(hist) > MAX_TURNS else hist
|
62 |
|
63 |
|
64 |
+
def clean(text: str) -> str:
|
65 |
+
"""Collapse whitespace; never return empty string."""
|
66 |
+
out = re.sub(r"\s+", " ", text.strip())
|
67 |
+
return out or "β¦"
|
|
|
68 |
|
69 |
# ββββββββββββββββββββββββββ Chat Callback βββββββββββββββββββββββββββββββββββ
|
70 |
def chat(history, user_msg):
|
71 |
+
history = list(history) # Gradio ensures list of tuples
|
|
|
72 |
|
73 |
+
if MODEL_ERR:
|
74 |
+
history.append((user_msg, MODEL_ERR))
|
|
|
75 |
return history, ""
|
76 |
|
77 |
+
user_msg = clean(user_msg or "")
|
|
|
78 |
if not user_msg:
|
79 |
history.append(("", "Please enter a message."))
|
80 |
return history, ""
|
81 |
if len(user_msg) > MAX_INPUT_CH:
|
82 |
+
history.append((user_msg, "That message is too long."))
|
|
|
|
|
83 |
return history, ""
|
84 |
|
85 |
+
history = truncate(history)
|
86 |
|
87 |
# Build prompt
|
88 |
+
prompt_lines = [SYSTEM_MSG]
|
89 |
for u, a in history:
|
90 |
+
prompt_lines += [f"User: {u}", f"AI: {a}"]
|
91 |
+
prompt_lines += [f"User: {user_msg}", "AI:"]
|
92 |
+
prompt = "\n".join(prompt_lines)
|
93 |
|
|
|
94 |
try:
|
95 |
+
completion = generator(prompt, truncate=4096)[0]["generated_text"]
|
96 |
+
reply = clean(completion.split("AI:", 1)[-1])
|
97 |
except Exception as err: # noqa: BLE001
|
98 |
LOG.error(f"Inference error: {err}")
|
99 |
+
reply = "SorryβI'm having trouble right now. Please try again shortly."
|
|
|
|
|
100 |
|
101 |
history.append((user_msg, reply))
|
102 |
return history, ""
|
103 |
|
104 |
+
# ββββββββββββββββββββββββββ Clear Chat ββββββββββββββββββββββββββββββββββββββ
|
105 |
def clear_chat():
|
106 |
return [], ""
|
107 |
|
108 |
# ββββββββββββββββββββββββββ UI Launch βββββββββββββββββββββββββββββββββββββββ
|
109 |
with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue")) as demo:
|
110 |
gr.Markdown("# SchoolSpiritΒ AI Chat")
|
111 |
+
chatbot = gr.Chatbot()
|
112 |
+
msg_box = gr.Textbox(placeholder="Ask me anything about SchoolSpiritΒ AIβ¦")
|
113 |
send_btn = gr.Button("Send")
|
114 |
clear_btn = gr.Button("Clear Chat", variant="secondary")
|
115 |
|
116 |
+
send_btn.click(chat, [chatbot, msg_box], [chatbot, msg_box])
|
117 |
+
msg_box.submit(chat, [chatbot, msg_box], [chatbot, msg_box])
|
118 |
+
clear_btn.click(clear_chat, outputs=[chatbot, msg_box])
|
119 |
|
120 |
demo.launch()
|