abersbail commited on
Commit
c34bacc
·
verified ·
1 Parent(s): 71553b8

Add sentiment analyzer CPU Space

Browse files
README.md CHANGED
@@ -1,12 +1,13 @@
1
  ---
2
- title: Sentiment Analyzer Cpu
3
- emoji: 😻
4
- colorFrom: indigo
5
  colorTo: gray
6
  sdk: gradio
7
- sdk_version: 6.10.0
8
  app_file: app.py
9
  pinned: false
 
10
  ---
11
 
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
1
  ---
2
+ title: Sentiment Analyzer CPU
3
+ colorFrom: yellow
 
4
  colorTo: gray
5
  sdk: gradio
 
6
  app_file: app.py
7
  pinned: false
8
+ license: mit
9
  ---
10
 
11
+ # Sentiment Analyzer CPU
12
+
13
+ Free CPU sentiment analyzer using `cardiffnlp/twitter-roberta-base-sentiment-latest`.
app.py ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+
3
+ from sentiment_tool.service import SentimentService
4
+
5
+
6
+ service = SentimentService()
7
+
8
+
9
+ def analyze_sentiment(text):
10
+ return service.analyze(text)
11
+
12
+
13
+ with gr.Blocks(
14
+ title="Sentiment Analyzer CPU",
15
+ theme=gr.themes.Soft(primary_hue="yellow", secondary_hue="gray"),
16
+ ) as demo:
17
+ gr.Markdown(
18
+ """
19
+ # Sentiment Analyzer CPU
20
+ Paste text and get positive, neutral, and negative sentiment scores.
21
+ """
22
+ )
23
+
24
+ text_input = gr.Textbox(label="Input Text", lines=8, placeholder="Write review, opinion, or message here")
25
+ run_button = gr.Button("Analyze", variant="primary")
26
+
27
+ label_output = gr.Textbox(label="Top Label", lines=1)
28
+ score_output = gr.Textbox(label="Score Breakdown", lines=4)
29
+ status_output = gr.Textbox(label="Status", lines=2)
30
+
31
+ run_button.click(
32
+ fn=analyze_sentiment,
33
+ inputs=[text_input],
34
+ outputs=[label_output, score_output, status_output],
35
+ )
36
+
37
+
38
+ if __name__ == "__main__":
39
+ demo.launch()
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ gradio>=5.23.0
2
+ huggingface_hub>=0.34.0,<1.0
3
+ safetensors>=0.5.3
4
+ torch>=2.3.0
5
+ transformers>=4.49.0
sentiment_tool/__init__.py ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ from .service import SentimentService
2
+
3
+ __all__ = ["SentimentService"]
sentiment_tool/service.py ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+
3
+ import torch
4
+
5
+
6
+ MODEL_ID = "cardiffnlp/twitter-roberta-base-sentiment-latest"
7
+
8
+
9
+ class SentimentService:
10
+ def __init__(self):
11
+ self.pipe = None
12
+ cpu_count = os.cpu_count() or 1
13
+ torch.set_num_threads(max(1, min(4, cpu_count)))
14
+
15
+ def analyze(self, text):
16
+ clean_text = " ".join((text or "").split())
17
+ if not clean_text:
18
+ return "", "", "Write text first."
19
+
20
+ try:
21
+ results = self._run_model(clean_text)
22
+ top = max(results, key=lambda item: item["score"])
23
+ top_label = top["label"].title()
24
+ breakdown = self._format_results(results)
25
+ return top_label, breakdown, f"Analyzed sentiment with {MODEL_ID}."
26
+ except Exception as exc:
27
+ return "", "", f"Sentiment analysis failed: {type(exc).__name__}: {exc}"
28
+
29
+ def _load_pipeline(self):
30
+ if self.pipe is not None:
31
+ return
32
+
33
+ from transformers import pipeline
34
+
35
+ self.pipe = pipeline(
36
+ "text-classification",
37
+ model=MODEL_ID,
38
+ top_k=None,
39
+ device=-1,
40
+ )
41
+
42
+ def _run_model(self, text):
43
+ self._load_pipeline()
44
+ return self.pipe(text)[0]
45
+
46
+ def _format_results(self, results):
47
+ lines = []
48
+ for item in sorted(results, key=lambda x: x["score"], reverse=True):
49
+ label = item["label"].title()
50
+ score = f"{item['score'] * 100:.1f}%"
51
+ lines.append(f"{label}: {score}")
52
+ return "\n".join(lines)