Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,125 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import json
|
2 |
+
import numpy as np
|
3 |
+
from tokenizers import Tokenizer
|
4 |
+
import onnxruntime as ort
|
5 |
+
from huggingface_hub import hf_hub_download
|
6 |
+
import gradio as gr
|
7 |
+
|
8 |
+
|
9 |
+
class ONNXInferencePipeline:
|
10 |
+
def __init__(self, repo_id):
|
11 |
+
# Download files from Hugging Face Hub using the provided repo_id.
|
12 |
+
# Note: The ONNX model file is now "moodmeter.onnx"
|
13 |
+
self.onnx_path = hf_hub_download(repo_id=repo_id, filename="minddmeter.onnx")
|
14 |
+
self.tokenizer_path = hf_hub_download(repo_id=repo_id, filename="train_bpe_tokenizer.json")
|
15 |
+
self.config_path = hf_hub_download(repo_id=repo_id, filename="hyperparameters.json")
|
16 |
+
|
17 |
+
# Load configuration from the hyperparameters file.
|
18 |
+
# Ensure that the JSON contains a "tokenizer" key with "max_len" defined.
|
19 |
+
with open(self.config_path, "r") as f:
|
20 |
+
self.config = json.load(f)
|
21 |
+
|
22 |
+
# Initialize the tokenizer using the downloaded file.
|
23 |
+
self.tokenizer = Tokenizer.from_file(self.tokenizer_path)
|
24 |
+
self.max_len = self.config["tokenizer"]["max_len"]
|
25 |
+
|
26 |
+
# Initialize the ONNX runtime session with the downloaded model.
|
27 |
+
self.session = ort.InferenceSession(self.onnx_path)
|
28 |
+
# Use CUDA if available; otherwise, default to CPU.
|
29 |
+
self.providers = ['CPUExecutionProvider']
|
30 |
+
if 'CUDAExecutionProvider' in ort.get_available_providers():
|
31 |
+
self.providers = ['CUDAExecutionProvider']
|
32 |
+
self.session.set_providers(self.providers)
|
33 |
+
|
34 |
+
def preprocess(self, text):
|
35 |
+
"""
|
36 |
+
Tokenize the input text, truncate or pad it to the maximum length, and return a numpy array.
|
37 |
+
"""
|
38 |
+
encoding = self.tokenizer.encode(text)
|
39 |
+
# Truncate token ids to self.max_len tokens.
|
40 |
+
ids = encoding.ids[:self.max_len]
|
41 |
+
# Pad with zeros if the sequence is shorter than self.max_len.
|
42 |
+
padding = [0] * (self.max_len - len(ids))
|
43 |
+
return np.array(ids + padding, dtype=np.int64).reshape(1, -1)
|
44 |
+
|
45 |
+
def predict(self, text):
|
46 |
+
"""
|
47 |
+
Given an input text string, run inference and return:
|
48 |
+
- The predicted label (mapped from the model output),
|
49 |
+
- The confidence of that prediction,
|
50 |
+
- The full list of probabilities.
|
51 |
+
"""
|
52 |
+
# Preprocess the text
|
53 |
+
input_array = self.preprocess(text)
|
54 |
+
|
55 |
+
# Run inference using the ONNX runtime session.
|
56 |
+
results = self.session.run(None, {"input": input_array})
|
57 |
+
|
58 |
+
# Compute softmax probabilities from the logits.
|
59 |
+
logits = results[0]
|
60 |
+
exp_logits = np.exp(logits)
|
61 |
+
probabilities = exp_logits / np.sum(exp_logits, axis=1, keepdims=True)
|
62 |
+
predicted_class = int(np.argmax(probabilities))
|
63 |
+
|
64 |
+
# Map the predicted index to the actual class label.
|
65 |
+
# Here we assume the model outputs: 0 -> "neg" and 1 -> "pos"
|
66 |
+
label_mapping = {'neg': 'Negative', 'pos': 'Positive'}
|
67 |
+
class_labels = ['neg', 'pos']
|
68 |
+
predicted_label = label_mapping[class_labels[predicted_class]]
|
69 |
+
confidence = float(probabilities[0][predicted_class])
|
70 |
+
|
71 |
+
return {
|
72 |
+
'label': predicted_label,
|
73 |
+
'confidence': confidence,
|
74 |
+
'probabilities': probabilities[0].tolist()
|
75 |
+
}
|
76 |
+
|
77 |
+
|
78 |
+
# Example usage and Gradio Interface
|
79 |
+
if __name__ == "__main__":
|
80 |
+
# Initialize the pipeline with the correct Hugging Face repository ID.
|
81 |
+
pipeline = ONNXInferencePipeline(repo_id="iimran/MindMeter")
|
82 |
+
|
83 |
+
# Example texts for testing (stress/sentiment related)
|
84 |
+
example_texts = [
|
85 |
+
"I feel the constant strain of financial hardship, and the stress of it all leaves me emotionally drained.",
|
86 |
+
"I am stressed by the thought of unexpected expenses derailing my already fragile budget. Can I request council to make an installment plan for me?",
|
87 |
+
"The burden of my debt is immense, and the stress from my financial hardships is unbearable. Can I request council to waive my rates fee?"
|
88 |
+
]
|
89 |
+
|
90 |
+
for text in example_texts:
|
91 |
+
result = pipeline.predict(text)
|
92 |
+
print(f"Input: {text}")
|
93 |
+
print(f"Prediction: {result['label']} ({result['confidence']:.2%})")
|
94 |
+
print(f"Confidence Scores: Negative={result['probabilities'][0]:.2%}, Positive={result['probabilities'][1]:.2%}")
|
95 |
+
print("-" * 80)
|
96 |
+
|
97 |
+
# Define a function for Gradio to call.
|
98 |
+
def gradio_predict(text):
|
99 |
+
result = pipeline.predict(text)
|
100 |
+
return (
|
101 |
+
f"Prediction: {result['label']} ({result['confidence']:.2%})\n"
|
102 |
+
f"Confidence Scores: Negative={result['probabilities'][0]:.2%}, Positive={result['probabilities'][1]:.2%}"
|
103 |
+
)
|
104 |
+
|
105 |
+
# Create the Gradio interface.
|
106 |
+
iface = gr.Interface(
|
107 |
+
fn=gradio_predict,
|
108 |
+
inputs=gr.Textbox(lines=7, placeholder="Enter text here..."),
|
109 |
+
outputs="text",
|
110 |
+
title="MindMeter – Service-Focused Stress Identification Agent",
|
111 |
+
description=(
|
112 |
+
"MindMeter evaluates the mental and emotional tone of your text input. "
|
113 |
+
"It analyzes the content to provide an indication of the overall stress element in the input, "
|
114 |
+
"displaying a Low Stressed, Medium Stressed, High Stressed or not stressed scores. "
|
115 |
+
"Enter your text below to see the analysis."
|
116 |
+
),
|
117 |
+
examples=[
|
118 |
+
"I feel the constant strain of financial hardship, and the stress of it all leaves me emotionally drained.",
|
119 |
+
"I am stressed by the thought of unexpected expenses derailing my already fragile budget. Can I request council to make an installment plan for me?",
|
120 |
+
"The burden of my debt is immense, and the stress from my financial hardships is unbearable. Can I request council to waive my rates fee?"
|
121 |
+
]
|
122 |
+
)
|
123 |
+
|
124 |
+
# Launch the Gradio app.
|
125 |
+
iface.launch()
|