ENTUM-AI commited on
Commit
4b7df86
Β·
verified Β·
1 Parent(s): 9a7f830

Upload FinBERT-Multi Financial Sentiment Gradio Space

Browse files
Files changed (2) hide show
  1. app.py +502 -0
  2. requirements.txt +3 -0
app.py ADDED
@@ -0,0 +1,502 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from transformers import pipeline
3
+ import time
4
+
5
+ # ==========================================
6
+ # MODEL CONFIGURATION
7
+ # ==========================================
8
+ MODEL_NAME = "ENTUM-AI/FinBERT-Multi"
9
+
10
+ print(f"Loading model: {MODEL_NAME}...")
11
+ try:
12
+ classifier = pipeline("text-classification", model=MODEL_NAME, top_k=3)
13
+ print("Model loaded successfully!")
14
+ except Exception as e:
15
+ print(f"Error loading model: {e}")
16
+ classifier = None
17
+
18
+
19
+ # ==========================================
20
+ # PREDICTION LOGIC
21
+ # ==========================================
22
+ SENTIMENT_CONFIG = {
23
+ "Positive": {"color": "#16a34a", "bg": "#f0fdf4", "icon": "πŸ“ˆ", "bar": "#22c55e"},
24
+ "Negative": {"color": "#dc2626", "bg": "#fef2f2", "icon": "πŸ“‰", "bar": "#ef4444"},
25
+ "Neutral": {"color": "#2563eb", "bg": "#eff6ff", "icon": "βž–", "bar": "#3b82f6"},
26
+ }
27
+
28
+
29
+ def predict_single(text):
30
+ """Classify a single financial text."""
31
+ if not text or not text.strip():
32
+ return create_empty_result()
33
+
34
+ if classifier is None:
35
+ return create_error_result()
36
+
37
+ start = time.time()
38
+ results = classifier(text.strip())[0]
39
+ elapsed = (time.time() - start) * 1000
40
+
41
+ top = results[0]
42
+ return create_result_html(text.strip(), top["label"], results, elapsed)
43
+
44
+
45
+ def predict_batch(texts):
46
+ """Classify multiple financial texts (one per line)."""
47
+ if not texts or not texts.strip():
48
+ return "<p style='color:#94a3b8; text-align:center;'>Enter financial texts, one per line.</p>"
49
+
50
+ if classifier is None:
51
+ return create_error_result()
52
+
53
+ lines = [line.strip() for line in texts.strip().split("\n") if line.strip()]
54
+ if not lines:
55
+ return "<p style='color:#94a3b8; text-align:center;'>No valid texts found.</p>"
56
+
57
+ start = time.time()
58
+ all_results = classifier(lines)
59
+ elapsed = (time.time() - start) * 1000
60
+
61
+ counts = {"Positive": 0, "Negative": 0, "Neutral": 0}
62
+ html_parts = []
63
+
64
+ for text, results in zip(lines, all_results):
65
+ top = results[0]
66
+ label = top["label"]
67
+ score = top["score"]
68
+ counts[label] = counts.get(label, 0) + 1
69
+
70
+ cfg = SENTIMENT_CONFIG.get(label, SENTIMENT_CONFIG["Neutral"])
71
+ bar_width = int(score * 100)
72
+
73
+ html_parts.append(f"""
74
+ <div style="
75
+ background: {cfg['bg']};
76
+ border: 1px solid {cfg['color']}22;
77
+ border-left: 4px solid {cfg['color']};
78
+ border-radius: 12px;
79
+ padding: 16px 20px;
80
+ margin-bottom: 10px;
81
+ ">
82
+ <div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:8px;">
83
+ <span style="color:#1e293b; font-size:14px; flex:1; margin-right:12px;">{cfg['icon']} {text}</span>
84
+ <span style="
85
+ background: {cfg['color']}15;
86
+ color: {cfg['color']};
87
+ padding: 4px 12px;
88
+ border-radius: 20px;
89
+ font-size: 12px;
90
+ font-weight: 700;
91
+ letter-spacing: 0.5px;
92
+ white-space: nowrap;
93
+ ">{label.upper()} {score:.0%}</span>
94
+ </div>
95
+ <div style="background:#e2e8f0; border-radius:6px; height:6px; overflow:hidden;">
96
+ <div style="width:{bar_width}%; height:100%; background:linear-gradient(90deg, {cfg['bar']}aa, {cfg['bar']}); border-radius:6px;"></div>
97
+ </div>
98
+ </div>
99
+ """)
100
+
101
+ total = len(lines)
102
+ summary = f"""
103
+ <div style="
104
+ background: #ffffff;
105
+ border: 1px solid #e2e8f0;
106
+ border-radius: 14px;
107
+ padding: 20px 24px;
108
+ margin-bottom: 16px;
109
+ text-align: center;
110
+ box-shadow: 0 1px 3px rgba(0,0,0,0.06);
111
+ ">
112
+ <span style="color:#64748b; font-size:12px; text-transform:uppercase; letter-spacing:1px;">Batch Sentiment Analysis</span>
113
+ <div style="display:flex; justify-content:center; gap:24px; margin-top:12px;">
114
+ <div>
115
+ <div style="color:#16a34a; font-size:24px; font-weight:800;">πŸ“ˆ {counts.get('Positive', 0)}</div>
116
+ <div style="color:#64748b; font-size:12px;">Positive</div>
117
+ </div>
118
+ <div>
119
+ <div style="color:#2563eb; font-size:24px; font-weight:800;">βž– {counts.get('Neutral', 0)}</div>
120
+ <div style="color:#64748b; font-size:12px;">Neutral</div>
121
+ </div>
122
+ <div>
123
+ <div style="color:#dc2626; font-size:24px; font-weight:800;">πŸ“‰ {counts.get('Negative', 0)}</div>
124
+ <div style="color:#64748b; font-size:12px;">Negative</div>
125
+ </div>
126
+ </div>
127
+ <div style="color:#94a3b8; font-size:12px; margin-top:10px;">{total} texts analyzed in {elapsed:.0f}ms</div>
128
+ </div>
129
+ """
130
+
131
+ return summary + "\n".join(html_parts)
132
+
133
+
134
+ # ==========================================
135
+ # HTML RESULT BUILDERS
136
+ # ==========================================
137
+ def create_result_html(text, top_label, all_scores, elapsed_ms):
138
+ cfg = SENTIMENT_CONFIG.get(top_label, SENTIMENT_CONFIG["Neutral"])
139
+
140
+ bars_html = ""
141
+ for item in all_scores:
142
+ lbl = item["label"]
143
+ sc = item["score"]
144
+ c = SENTIMENT_CONFIG.get(lbl, SENTIMENT_CONFIG["Neutral"])
145
+ pct = int(sc * 100)
146
+ bars_html += f"""
147
+ <div style="margin-bottom:10px;">
148
+ <div style="display:flex; justify-content:space-between; margin-bottom:4px;">
149
+ <span style="color:#475569; font-size:13px; font-weight:600;">{c['icon']} {lbl}</span>
150
+ <span style="color:{c['color']}; font-weight:700; font-size:14px;">{sc:.1%}</span>
151
+ </div>
152
+ <div style="background:#f1f5f9; border-radius:6px; height:8px; overflow:hidden;">
153
+ <div style="width:{pct}%; height:100%; background:linear-gradient(90deg, {c['bar']}aa, {c['bar']}); border-radius:6px;"></div>
154
+ </div>
155
+ </div>
156
+ """
157
+
158
+ if top_label == "Positive":
159
+ gradient = "linear-gradient(135deg, #dcfce7, #bbf7d0, #86efac)"
160
+ text_color = "#166534"
161
+ elif top_label == "Negative":
162
+ gradient = "linear-gradient(135deg, #fee2e2, #fecaca, #fca5a5)"
163
+ text_color = "#991b1b"
164
+ else:
165
+ gradient = "linear-gradient(135deg, #dbeafe, #bfdbfe, #93c5fd)"
166
+ text_color = "#1e40af"
167
+
168
+ top_score = all_scores[0]["score"]
169
+
170
+ return f"""
171
+ <div style="font-family: 'Inter', 'Segoe UI', sans-serif;">
172
+ <div style="
173
+ background: {gradient};
174
+ border-radius: 20px;
175
+ padding: 32px;
176
+ text-align: center;
177
+ margin-bottom: 20px;
178
+ border: 1px solid {cfg['color']}22;
179
+ box-shadow: 0 4px 24px {cfg['color']}15;
180
+ ">
181
+ <div style="font-size: 48px; margin-bottom: 8px;">{cfg['icon']}</div>
182
+ <div style="
183
+ color: {text_color};
184
+ font-size: 22px;
185
+ font-weight: 800;
186
+ letter-spacing: 2px;
187
+ margin-bottom: 6px;
188
+ ">{top_label.upper()} SENTIMENT</div>
189
+ <div style="color: {text_color}99; font-size: 14px;">Confidence: {top_score:.1%}</div>
190
+ </div>
191
+
192
+ <div style="
193
+ background: #ffffff;
194
+ border: 1px solid #e2e8f0;
195
+ border-radius: 16px;
196
+ padding: 24px;
197
+ box-shadow: 0 1px 3px rgba(0,0,0,0.06);
198
+ ">
199
+ <div style="margin-bottom: 20px;">
200
+ <span style="color: #64748b; font-size: 11px; text-transform: uppercase; letter-spacing: 1px;">Analyzed Text</span>
201
+ <div style="color: #1e293b; font-size: 15px; margin-top: 6px; font-style: italic;">"{text}"</div>
202
+ </div>
203
+
204
+ <div style="margin-bottom: 16px;">
205
+ <span style="color: #64748b; font-size: 11px; text-transform: uppercase; letter-spacing: 1px; margin-bottom: 10px; display:block;">Score Breakdown</span>
206
+ {bars_html}
207
+ </div>
208
+
209
+ <div style="
210
+ display: flex;
211
+ justify-content: center;
212
+ gap: 24px;
213
+ padding-top: 12px;
214
+ border-top: 1px solid #f1f5f9;
215
+ ">
216
+ <div style="text-align: center;">
217
+ <span style="color: #94a3b8; font-size: 11px; text-transform: uppercase; letter-spacing: 0.5px;">Model</span>
218
+ <div style="color: #6366f1; font-size: 13px; font-weight: 600; margin-top: 2px;">FinBERT-Multi</div>
219
+ </div>
220
+ <div style="text-align: center;">
221
+ <span style="color: #94a3b8; font-size: 11px; text-transform: uppercase; letter-spacing: 0.5px;">Latency</span>
222
+ <div style="color: #0891b2; font-size: 13px; font-weight: 600; margin-top: 2px;">{elapsed_ms:.0f}ms</div>
223
+ </div>
224
+ <div style="text-align: center;">
225
+ <span style="color: #94a3b8; font-size: 11px; text-transform: uppercase; letter-spacing: 0.5px;">Training Data</span>
226
+ <div style="color: #d97706; font-size: 13px; font-weight: 600; margin-top: 2px;">143K+</div>
227
+ </div>
228
+ </div>
229
+ </div>
230
+ </div>
231
+ """
232
+
233
+
234
+ def create_empty_result():
235
+ return """
236
+ <div style="
237
+ text-align: center;
238
+ padding: 60px 24px;
239
+ color: #94a3b8;
240
+ ">
241
+ <div style="font-size: 48px; margin-bottom: 12px;">πŸ’Ή</div>
242
+ <div style="font-size: 16px; font-weight: 600; color: #475569;">Awaiting Input</div>
243
+ <div style="font-size: 13px; margin-top: 4px;">Enter a financial text above and click <b>Analyze</b></div>
244
+ </div>
245
+ """
246
+
247
+
248
+ def create_error_result():
249
+ return """
250
+ <div style="
251
+ text-align: center;
252
+ padding: 40px 24px;
253
+ background: #fef2f2;
254
+ border-radius: 16px;
255
+ border: 1px solid #fecaca;
256
+ ">
257
+ <div style="font-size: 36px; margin-bottom: 8px;">⚠️</div>
258
+ <div style="color: #dc2626; font-size: 15px; font-weight: 600;">Model Not Available</div>
259
+ <div style="color: #64748b; font-size: 13px; margin-top: 4px;">Please wait while the model loads or try refreshing.</div>
260
+ </div>
261
+ """
262
+
263
+
264
+ # ==========================================
265
+ # CUSTOM CSS
266
+ # ==========================================
267
+ CUSTOM_CSS = """
268
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap');
269
+
270
+ * { font-family: 'Inter', 'Segoe UI', sans-serif !important; }
271
+
272
+ .gradio-container {
273
+ max-width: 960px !important;
274
+ margin: 0 auto !important;
275
+ background: linear-gradient(180deg, #f8fafc 0%, #f1f5f9 50%, #e2e8f0 100%) !important;
276
+ }
277
+
278
+ .main-header {
279
+ text-align: center;
280
+ padding: 40px 20px 20px;
281
+ }
282
+
283
+ .main-header h1 {
284
+ background: linear-gradient(135deg, #059669, #0891b2, #2563eb);
285
+ -webkit-background-clip: text;
286
+ -webkit-text-fill-color: transparent;
287
+ font-size: 2.5rem !important;
288
+ font-weight: 800 !important;
289
+ margin-bottom: 8px !important;
290
+ letter-spacing: -0.5px;
291
+ }
292
+
293
+ .main-header p {
294
+ color: #64748b !important;
295
+ font-size: 15px !important;
296
+ }
297
+
298
+ .model-badge {
299
+ display: inline-block;
300
+ background: linear-gradient(135deg, #ecfdf5, #e0f2fe);
301
+ border: 1px solid #a7f3d0;
302
+ color: #047857 !important;
303
+ padding: 6px 16px;
304
+ border-radius: 24px;
305
+ font-size: 13px !important;
306
+ font-weight: 600;
307
+ letter-spacing: 0.5px;
308
+ margin-top: 12px;
309
+ }
310
+
311
+ .data-badge {
312
+ display: inline-block;
313
+ background: linear-gradient(135deg, #fef3c7, #fde68a);
314
+ border: 1px solid #fbbf24;
315
+ color: #92400e !important;
316
+ padding: 4px 12px;
317
+ border-radius: 16px;
318
+ font-size: 12px !important;
319
+ font-weight: 600;
320
+ margin-left: 8px;
321
+ }
322
+
323
+ footer { display: none !important; }
324
+
325
+ .tab-nav button {
326
+ color: #64748b !important;
327
+ font-weight: 600 !important;
328
+ font-size: 14px !important;
329
+ }
330
+
331
+ .tab-nav button.selected {
332
+ color: #059669 !important;
333
+ border-color: #059669 !important;
334
+ }
335
+ """
336
+
337
+
338
+ # ==========================================
339
+ # GRADIO UI
340
+ # ==========================================
341
+ with gr.Blocks(
342
+ css=CUSTOM_CSS,
343
+ title="FinBERT-Multi β€” Financial Sentiment Analyzer",
344
+ theme=gr.themes.Soft(
345
+ primary_hue="emerald",
346
+ secondary_hue="cyan",
347
+ neutral_hue="slate",
348
+ ),
349
+ ) as demo:
350
+
351
+ # Header
352
+ gr.HTML("""
353
+ <div class="main-header">
354
+ <h1>πŸ’Ή FinBERT-Multi</h1>
355
+ <p>Financial sentiment analysis powered by <b>FinBERT</b>, fine-tuned on <b>143K+ samples</b> from 5 expert datasets</p>
356
+ <span class="model-badge">🧠 ENTUM-AI / FinBERT-Multi</span>
357
+ <span class="data-badge">πŸ“Š 143K+ training samples</span>
358
+ </div>
359
+ """)
360
+
361
+ with gr.Tabs():
362
+ # --- Tab 1: Single Analysis ---
363
+ with gr.Tab("πŸ” Single Analysis"):
364
+ with gr.Row():
365
+ with gr.Column(scale=3):
366
+ single_input = gr.Textbox(
367
+ label="Financial Text",
368
+ placeholder="e.g. Stock price soars on record-breaking earnings report",
369
+ lines=2,
370
+ max_lines=4,
371
+ )
372
+ single_btn = gr.Button("⚑ Analyze Sentiment", variant="primary", size="lg")
373
+ with gr.Column(scale=4):
374
+ single_output = gr.HTML(value=create_empty_result())
375
+
376
+ gr.Examples(
377
+ examples=[
378
+ ["Stock price soars on record-breaking earnings report"],
379
+ ["Revenue decline signals weakening market position"],
380
+ ["Company announces quarterly earnings results"],
381
+ ["Shares surge 15% after strong Q3 revenue growth"],
382
+ ["Major layoffs expected as company restructures operations"],
383
+ ["The board of directors met to discuss routine operations"],
384
+ ["Bankruptcy filing raises concerns about long-term viability"],
385
+ ["Profit margins improved significantly driven by cost optimization"],
386
+ ],
387
+ inputs=single_input,
388
+ label="πŸ“‹ Try these examples",
389
+ )
390
+
391
+ single_btn.click(fn=predict_single, inputs=single_input, outputs=single_output)
392
+ single_input.submit(fn=predict_single, inputs=single_input, outputs=single_output)
393
+
394
+ # --- Tab 2: Batch Analysis ---
395
+ with gr.Tab("πŸ“Š Batch Analysis"):
396
+ gr.Markdown("Paste multiple financial texts β€” **one per line** β€” for batch sentiment classification.")
397
+ with gr.Row():
398
+ with gr.Column(scale=2):
399
+ batch_input = gr.Textbox(
400
+ label="Financial Texts (one per line)",
401
+ placeholder="Headline 1\nHeadline 2\nHeadline 3",
402
+ lines=8,
403
+ max_lines=20,
404
+ )
405
+ batch_btn = gr.Button("⚑ Analyze All", variant="primary", size="lg")
406
+ with gr.Column(scale=3):
407
+ batch_output = gr.HTML(
408
+ value="<p style='color:#94a3b8; text-align:center; padding:40px;'>Results will appear here.</p>"
409
+ )
410
+
411
+ batch_btn.click(fn=predict_batch, inputs=batch_input, outputs=batch_output)
412
+
413
+ # --- Tab 3: About ---
414
+ with gr.Tab("ℹ️ About"):
415
+ gr.HTML("""
416
+ <div style="
417
+ background: #ffffff;
418
+ border: 1px solid #e2e8f0;
419
+ border-radius: 20px;
420
+ padding: 36px;
421
+ color: #1e293b;
422
+ box-shadow: 0 1px 3px rgba(0,0,0,0.06);
423
+ ">
424
+ <h2 style="
425
+ background: linear-gradient(135deg, #059669, #0891b2);
426
+ -webkit-background-clip: text;
427
+ -webkit-text-fill-color: transparent;
428
+ font-size: 24px;
429
+ margin-bottom: 24px;
430
+ ">About FinBERT-Multi</h2>
431
+
432
+ <p style="color:#475569; font-size:14px; line-height:1.7; margin-bottom:20px;">
433
+ A financial sentiment model built on
434
+ <a href="https://huggingface.co/ProsusAI/finbert" style="color:#059669; text-decoration:none; font-weight:600;">ProsusAI/FinBERT</a>.
435
+ Fine-tuned on <b>143K+ samples</b> from 5 combined financial datasets for maximum coverage and robustness.
436
+ </p>
437
+
438
+ <table style="width:100%; border-collapse:separate; border-spacing:0 8px;">
439
+ <tr>
440
+ <td style="color:#64748b; padding:8px 16px; font-size:13px; width:35%;">Base Model</td>
441
+ <td style="color:#1e293b; padding:8px 16px; font-size:14px; font-weight:600;">ProsusAI/FinBERT (BERT-based)</td>
442
+ </tr>
443
+ <tr>
444
+ <td style="color:#64748b; padding:8px 16px; font-size:13px;">Task</td>
445
+ <td style="color:#1e293b; padding:8px 16px; font-size:14px; font-weight:600;">3-Class Sentiment (Positive / Negative / Neutral)</td>
446
+ </tr>
447
+ <tr>
448
+ <td style="color:#64748b; padding:8px 16px; font-size:13px;">Training Data</td>
449
+ <td style="color:#1e293b; padding:8px 16px; font-size:14px; font-weight:600;">143K+ samples from 5 datasets</td>
450
+ </tr>
451
+ <tr>
452
+ <td style="color:#64748b; padding:8px 16px; font-size:13px;">Language</td>
453
+ <td style="color:#1e293b; padding:8px 16px; font-size:14px; font-weight:600;">English</td>
454
+ </tr>
455
+ <tr>
456
+ <td style="color:#64748b; padding:8px 16px; font-size:13px;">License</td>
457
+ <td style="color:#1e293b; padding:8px 16px; font-size:14px; font-weight:600;">Apache 2.0</td>
458
+ </tr>
459
+ </table>
460
+
461
+ <h3 style="color:#059669; margin-top:28px; margin-bottom:12px; font-size:16px;">πŸ“Š Training Datasets</h3>
462
+ <div style="overflow-x:auto;">
463
+ <table style="width:100%; border-collapse:separate; border-spacing:0; border:1px solid #e2e8f0; border-radius:12px; overflow:hidden;">
464
+ <thead>
465
+ <tr style="background:#f8fafc;">
466
+ <th style="padding:12px 16px; text-align:left; color:#475569; font-size:13px; font-weight:600; border-bottom:1px solid #e2e8f0;">Dataset</th>
467
+ <th style="padding:12px 16px; text-align:right; color:#475569; font-size:13px; font-weight:600; border-bottom:1px solid #e2e8f0;">Samples</th>
468
+ </tr>
469
+ </thead>
470
+ <tbody>
471
+ <tr><td style="padding:10px 16px; font-size:13px; color:#1e293b; border-bottom:1px solid #f1f5f9;">FinanceInc/auditor_sentiment</td><td style="padding:10px 16px; font-size:13px; color:#475569; text-align:right; border-bottom:1px solid #f1f5f9;">~4.8K</td></tr>
472
+ <tr><td style="padding:10px 16px; font-size:13px; color:#1e293b; border-bottom:1px solid #f1f5f9;">nickmuchi/financial-classification</td><td style="padding:10px 16px; font-size:13px; color:#475569; text-align:right; border-bottom:1px solid #f1f5f9;">~5K</td></tr>
473
+ <tr><td style="padding:10px 16px; font-size:13px; color:#1e293b; border-bottom:1px solid #f1f5f9;">warwickai/financial_phrasebank_mirror</td><td style="padding:10px 16px; font-size:13px; color:#475569; text-align:right; border-bottom:1px solid #f1f5f9;">~4.8K</td></tr>
474
+ <tr><td style="padding:10px 16px; font-size:13px; color:#1e293b; border-bottom:1px solid #f1f5f9;">NOSIBLE/financial-sentiment</td><td style="padding:10px 16px; font-size:13px; color:#475569; text-align:right; border-bottom:1px solid #f1f5f9;">~100K</td></tr>
475
+ <tr><td style="padding:10px 16px; font-size:13px; color:#1e293b;">TimKoornstra/financial-tweets-sentiment</td><td style="padding:10px 16px; font-size:13px; color:#475569; text-align:right;">~38K</td></tr>
476
+ </tbody>
477
+ </table>
478
+ </div>
479
+
480
+ <h3 style="color:#059669; margin-top:28px; margin-bottom:12px; font-size:16px;">🐍 Python API</h3>
481
+ <pre style="
482
+ background:#f8fafc;
483
+ border:1px solid #e2e8f0;
484
+ border-radius:12px;
485
+ padding:20px;
486
+ color:#1e293b;
487
+ font-size:13px;
488
+ overflow-x:auto;
489
+ font-family: 'Fira Code', 'Cascadia Code', monospace !important;
490
+ "><span style="color:#059669">from</span> transformers <span style="color:#059669">import</span> pipeline
491
+
492
+ classifier = pipeline(<span style="color:#d97706">"text-classification"</span>,
493
+ model=<span style="color:#d97706">"ENTUM-AI/FinBERT-Multi"</span>)
494
+
495
+ result = classifier(<span style="color:#d97706">"Stock price soars on earnings"</span>)
496
+ <span style="color:#94a3b8"># [{'label': 'Positive', 'score': 0.99}]</span></pre>
497
+ </div>
498
+ """)
499
+
500
+
501
+ # Launch
502
+ demo.launch()
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ gradio>=4.0.0
2
+ transformers
3
+ torch