|
import os |
|
import re |
|
from dotenv import load_dotenv |
|
import torch |
|
from transformers import RobertaForSequenceClassification, RobertaTokenizerFast, pipeline as text_pipeline |
|
import gradio as gr |
|
from openai import OpenAI |
|
|
|
|
|
load_dotenv() |
|
|
|
|
|
API_KEY = os.getenv("API_KEY") |
|
|
|
|
|
client = OpenAI( |
|
base_url="https://integrate.api.nvidia.com/v1", |
|
api_key=API_KEY |
|
) |
|
|
|
|
|
def load_emotion_model(model_path): |
|
model = RobertaForSequenceClassification.from_pretrained(model_path) |
|
tokenizer = RobertaTokenizerFast.from_pretrained(model_path) |
|
return model, tokenizer |
|
|
|
|
|
def map_to_labels(label): |
|
return "Happy/Positive Mindset" if label.lower() == "positive" else "Depressed/Negative Mindset" |
|
|
|
|
|
def classify_emotion(user_input, model, tokenizer, device): |
|
nlp = text_pipeline("text-classification", model=model, tokenizer=tokenizer, device=device) |
|
result = nlp(user_input) |
|
return map_to_labels(result[0]['label']) |
|
|
|
|
|
def emotion_analysis(user_input): |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
model_path = "mentalhealth-roberta-base_nemotron_model" |
|
model, tokenizer = load_emotion_model(model_path) |
|
device = 0 if torch.cuda.is_available() else -1 |
|
|
|
|
|
predicted_emotion = classify_emotion(user_input, model, tokenizer, device) |
|
|
|
|
|
prompt = f""" |
|
Task: You are a social psychologist specializing in Roy Baumeister's six-stage theory of emotional progression. Your task is to analyze emotional states based on user input while adhering strictly to specific response boundaries. |
|
|
|
[Input Information]: |
|
**User Input**: "{user_input}" |
|
**Model Output**: "{predicted_emotion}" |
|
|
|
Specifics: |
|
1. Respond **only** to questions or input related to mental health or emotional well-being. For unrelated input, reply strictly with: "Not a valid question." |
|
2. Use the **User Input** as the primary source for determining the emotional state, while considering the **Model Output** ("happy" or "depressed") as a secondary reference. |
|
3. Categorize the user’s emotional state into one of Roy Baumeister’s six stages of emotional progression: |
|
- Stage 1: Falling short of expectations |
|
- Stage 2: Attributions to self |
|
- Stage 3: High self-awareness |
|
- Stage 4: Negative affect |
|
- Stage 5: Cognitive deconstruction |
|
- Stage 6: Disinhibition |
|
4. Provide specific stage-based recommendations: |
|
- If **depressed**, suggest remedies for improving emotional state. |
|
- If **happy**, suggest strategies for maintaining or enhancing happiness. |
|
5. Maintain clarity, empathy, and practicality in all analyses and suggestions. |
|
|
|
[Response Rules]: |
|
- If input is unrelated to mental health, reply only with: "Not a valid question." |
|
- Always analyze user input independently, even if it conflicts with the model's predicted output. |
|
|
|
[Desired Output Format for valid input]: |
|
Emotional Analysis: |
|
I'd say you're feeling: <Happy/Depressed> |
|
Emotional Stage: <Stage and brief reasoning> |
|
Suggested Remedies/Strategies: <Practical advice based on the stage> |
|
|
|
For invalid input: |
|
"Not a valid question." |
|
""" |
|
|
|
try: |
|
completion = client.chat.completions.create( |
|
model="nvidia/nemotron-4-340b-instruct", |
|
messages=[{"role": "user", "content": prompt}], |
|
temperature=0.5, |
|
top_p=0.7, |
|
max_tokens=512, |
|
stream=True |
|
) |
|
|
|
|
|
response = "" |
|
for chunk in completion: |
|
if chunk.choices[0].delta.content is not None: |
|
print(chunk.choices[0].delta.content, end="") |
|
|
|
response_chunk = chunk.choices[0].delta.content |
|
response += response_chunk |
|
else: |
|
print(f"Unexpected chunk format: {chunk}") |
|
|
|
except Exception as e: |
|
response = f"An error occurred while processing the response: {e}" |
|
response= str(response).replace("*", '') |
|
return response |
|
|
|
def extract_analysis_details(analysis_text): |
|
feelings_match = re.search(r"I'd say you're feeling:\s*([^\n]+)", analysis_text) |
|
feelings = feelings_match.group(1).strip() if feelings_match else "Not Found" |
|
print(feelings) |
|
if feelings.lower() == "happy": |
|
feelings = feelings + " with Positive Mindset" |
|
elif feelings.lower() == "depressed": |
|
feelings = feelings + " with Negative Mindset" |
|
else: |
|
feelings |
|
|
|
|
|
|
|
|
|
stage_match = re.search(r"Emotional Stage:\s*(.*?)(?=\n[A-Z])", analysis_text, re.DOTALL) |
|
emotional_stage = stage_match.group(1).strip() if stage_match else "Not Found" |
|
|
|
|
|
pattern = r"(Suggested Remedies|Suggested Remedies/Strategies|Suggested Strategies):.*" |
|
match = re.search(pattern, analysis_text, re.DOTALL) |
|
suggestions = match.group(0).strip() if match else "No matching section found." |
|
|
|
|
|
if feelings == "Not Found" or feelings == "Not a valid question.": |
|
feelings = "Not a valid question." |
|
return feelings, emotional_stage, suggestions |
|
|
|
|
|
|
|
def validate_and_run(user_input): |
|
if not user_input.strip(): |
|
return "Please provide valid input before submitting.", "Not Applicable", "Not Applicable" |
|
else: |
|
response = emotion_analysis(user_input) |
|
return extract_analysis_details(response) |
|
|
|
|
|
|
|
iface = gr.Interface( |
|
fn=validate_and_run, |
|
inputs=gr.Textbox( |
|
label="How are you feeling today?", |
|
placeholder="Share your thoughts here...!"), |
|
outputs=[ |
|
|
|
|
|
|
|
gr.Textbox(label="Feelings"), |
|
gr.Textbox(label="Emotional Stage"), |
|
gr.Textbox(label="Providing Best Strategies") |
|
], |
|
|
|
title="Analyze your emotions and generate stage-specific psychological insights\n", |
|
|
|
|
|
) |
|
|
|
|
|
if __name__ == "__main__": |
|
iface.launch() |
|
|
|
|