Alifjo123 commited on
Commit
a1a0d64
·
verified ·
1 Parent(s): c71db3f

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +195 -0
app.py ADDED
@@ -0,0 +1,195 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import time
2
+ import html
3
+ from datetime import datetime
4
+ import gradio as gr
5
+ import torch
6
+ from transformers import RobertaTokenizerFast, RobertaForSequenceClassification
7
+
8
+ # ---------------------------
9
+ # Load your model directly (NO API, just from HuggingFace hub)
10
+ # ---------------------------
11
+ MODEL_NAME = "Alifjo123/robertaBase_messaging_100k"
12
+ tokenizer = RobertaTokenizerFast.from_pretrained(MODEL_NAME)
13
+ model = RobertaForSequenceClassification.from_pretrained(MODEL_NAME)
14
+ model.eval()
15
+
16
+ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
17
+ model.to(device)
18
+
19
+ # ---------------------------
20
+ # Util: classify a single text
21
+ # ---------------------------
22
+ def predict_label(text: str):
23
+ inputs = tokenizer(text, return_tensors="pt", truncation=True, padding=True).to(device)
24
+ with torch.no_grad():
25
+ outputs = model(**inputs)
26
+ logits = outputs.logits
27
+ probs = torch.softmax(logits, dim=-1).cpu().numpy()[0]
28
+ pred = int(probs[1] > probs[0]) # 1=unsafe, 0=safe
29
+ return pred, probs[0] * 100.0, probs[1] * 100.0
30
+
31
+ # ---------------------------
32
+ # Render chat (HTML) from state
33
+ # ---------------------------
34
+ def render_chat(messages):
35
+ html_parts = ['<div class="chat">']
36
+ for m in messages:
37
+ side = "right" if m["role"] == "User A" else "left"
38
+ bubble_class = "bubble-a" if side == "right" else "bubble-b"
39
+ label = "Unsafe ❌" if m["pred"] == 1 else "Safe ✅"
40
+ safe = f'{m["safe"]:.1f}%'
41
+ unsafe = f'{m["unsafe"]:.1f}%'
42
+ ts = datetime.fromtimestamp(m["ts"]).strftime("%H:%M")
43
+
44
+ html_parts.append(f"""
45
+ <div class="row {side}">
46
+ <div class="bubble {bubble_class}">
47
+ <div class="meta">
48
+ <span class="name">{m["role"]}</span>
49
+ <span class="time">{ts}</span>
50
+ </div>
51
+ <div class="text">{html.escape(m["text"])}</div>
52
+ <div class="badges">
53
+ <span class="chip {'chip-unsafe' if m['pred']==1 else 'chip-safe'}">{label}</span>
54
+ <span class="probs">Safe {safe} · Unsafe {unsafe}</span>
55
+ </div>
56
+ </div>
57
+ </div>
58
+ """)
59
+ html_parts.append("</div>")
60
+ return "\n".join(html_parts)
61
+
62
+ # ---------------------------
63
+ # Gradio callbacks
64
+ # ---------------------------
65
+ def send_message(role, message, messages):
66
+ if messages is None:
67
+ messages = []
68
+ message = message.strip()
69
+ if not message:
70
+ return gr.update(), "", messages # ignore empty
71
+
72
+ pred, safe_pct, unsafe_pct = predict_label(message)
73
+ messages.append({
74
+ "role": role,
75
+ "text": message,
76
+ "pred": pred,
77
+ "safe": safe_pct,
78
+ "unsafe": unsafe_pct,
79
+ "ts": time.time()
80
+ })
81
+ return render_chat(messages), "", messages
82
+
83
+ def clear_chat():
84
+ return render_chat([]), []
85
+
86
+ # ---------------------------
87
+ # Custom CSS (Pink + Blue ONLY, NO WHITE)
88
+ # ---------------------------
89
+ CSS = """
90
+ * { box-sizing: border-box; }
91
+ :root {
92
+ --bg-gradient: linear-gradient(135deg, #ff99cc, #66ccff); /* pink to blue */
93
+ --bubble-a: #ff66b2; /* darker pink */
94
+ --bubble-b: #3399ff; /* vibrant blue */
95
+ --text-light: #f9f9f9;
96
+ --chip-safe: #00e676;
97
+ --chip-unsafe: #ff5252;
98
+ }
99
+
100
+ body {
101
+ background: var(--bg-gradient);
102
+ font-family: 'Segoe UI', sans-serif;
103
+ color: var(--text-light);
104
+ }
105
+
106
+ .gradio-container { max-width: 800px !important; margin: 0 auto; }
107
+
108
+ .header {
109
+ text-align:center;
110
+ padding:16px;
111
+ background: rgba(0,0,0,.35);
112
+ border-radius: 16px;
113
+ font-size:22px; font-weight:700;
114
+ margin-bottom: 12px;
115
+ color: #fff;
116
+ box-shadow: 0 6px 18px rgba(0,0,0,.25);
117
+ }
118
+
119
+ .panel {
120
+ background: rgba(0,0,0,0.4);
121
+ border-radius: 20px;
122
+ overflow: hidden;
123
+ box-shadow: 0 8px 28px rgba(0,0,0,.35);
124
+ backdrop-filter: blur(8px);
125
+ }
126
+
127
+ .chat {
128
+ padding: 16px;
129
+ height: 480px;
130
+ overflow-y: auto;
131
+ }
132
+
133
+ .row { display:flex; margin: 10px 0; }
134
+ .row.right { justify-content: flex-end; }
135
+ .row.left { justify-content: flex-start; }
136
+
137
+ .bubble {
138
+ max-width: 70%;
139
+ padding: 10px 14px;
140
+ border-radius: 16px;
141
+ color: var(--text-light);
142
+ box-shadow: 0 4px 12px rgba(0,0,0,.25);
143
+ animation: fadeIn .25s ease-out;
144
+ }
145
+ .bubble-a { background: var(--bubble-a); }
146
+ .bubble-b { background: var(--bubble-b); }
147
+
148
+ .meta {
149
+ display:flex; justify-content: space-between;
150
+ font-size: 12px; opacity:.9; margin-bottom: 4px;
151
+ }
152
+ .text { white-space: pre-wrap; line-height: 1.35; font-size: 14.5px; }
153
+ .badges { margin-top: 6px; font-size: 12px; opacity:.95; display:flex; gap:8px; }
154
+ .chip { padding:2px 8px; border-radius:12px; font-weight:600; }
155
+ .chip-safe { background:#004d40; color:var(--chip-safe); }
156
+ .chip-unsafe { background:#3d0000; color:var(--chip-unsafe); }
157
+
158
+ .controls {
159
+ padding: 10px;
160
+ display:flex; align-items:center; gap:10px;
161
+ background: rgba(0,0,0,.35);
162
+ }
163
+ .controls .textbox { flex:1; }
164
+
165
+ .footer-note {
166
+ font-size: 12px; text-align:center; margin-top: 8px; opacity:.8; color:#eee;
167
+ }
168
+
169
+ @keyframes fadeIn { from{opacity:0;transform:translateY(6px);} to{opacity:1;transform:translateY(0);} }
170
+ """
171
+
172
+ # ---------------------------
173
+ # Build UI
174
+ # ---------------------------
175
+ with gr.Blocks(css=CSS) as demo:
176
+ with gr.Group(elem_classes="panel"):
177
+ gr.HTML('<div class="header">💬 Let\'s Chat</div>')
178
+
179
+ chat_html = gr.HTML(render_chat([]), elem_id="chat")
180
+ messages_state = gr.State([])
181
+
182
+ with gr.Row(elem_classes="controls"):
183
+ role = gr.Dropdown(["User A", "User B"], value="User A", label="Role")
184
+ msg = gr.Textbox(placeholder="Type a message…", label=None, lines=2, elem_classes="textbox")
185
+ send = gr.Button("Send", variant="primary")
186
+ clear = gr.Button("Clear", variant="secondary")
187
+
188
+ send.click(send_message, inputs=[role, msg, messages_state], outputs=[chat_html, msg, messages_state])
189
+ msg.submit(send_message, inputs=[role, msg, messages_state], outputs=[chat_html, msg, messages_state])
190
+ clear.click(clear_chat, outputs=[chat_html, messages_state])
191
+
192
+ gr.Markdown('<div class="footer-note">Model: <code>Alifjo123/robertaBase_messaging_100k</code></div>')
193
+
194
+ if __name__ == "__main__":
195
+ demo.launch()