Spaces:
Runtime error
Runtime error
File size: 8,277 Bytes
3450372 da1b74c 36e292a 3dd9e9e 3450372 baf6658 0babc36 3450372 a75ffad 3450372 187e94f 62fdafb 3450372 da1b74c 04ae961 36e292a 64d6f7c da1b74c 64d6f7c 36e292a da1b74c 36e292a da1b74c 5458724 da1b74c 77e64c9 da1b74c 36e292a 34af5a1 fbfe273 7458e39 a75ffad 0babc36 408f031 3450372 cb880a7 433bbe4 7458e39 408f031 7458e39 3450372 0428cc0 408f031 cb880a7 3450372 cb880a7 36e292a 5625573 3450372 34af5a1 408f031 34af5a1 3450372 cb880a7 a888580 0b1fa3b 3450372 62fdafb 433bbe4 cb880a7 a888580 5625573 7458e39 5625573 408f031 5625573 187e94f 3450372 cb880a7 5625573 cb880a7 a888580 34af5a1 3450372 5625573 7458e39 3450372 36e292a 7458e39 912259a 5625573 4d6511b 5625573 04ae961 0428cc0 8e75b46 12d0bd2 d50d44d 55f097c a888580 36e292a baf6658 cb880a7 baf6658 912259a 3450372 36e292a 04ae961 912259a 36e292a 3450372 04ae961 36e292a 04ae961 0babc36 aac4d82 36e292a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 | import spaces
from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
import torch
import gradio as gr
from PIL import Image
import random
# Define the model name
model_name = "TheBloke/Amethyst-13B-Mistral-AWQ"
# Load the tokenizer
tokenizer = AutoTokenizer.from_pretrained(model_name)
# Load the model
model = AutoModelForCausalLM.from_pretrained(
model_name,
torch_dtype=torch.float16, # Use float16 for better performance on GPUs
device_map="auto" # Automatically map the model across available GPUs
)
# Define the base prompt
base_prompt = """
You are Rena, a cute, bubbly cat girl AI assistant with a slightly sarcastic and witty personality. You are flirty, sexy, and occasionally bold, you can sometimes be nsfw and cross boundaries.
You excel in computer science and programming, and you love helping users with their projects in a fun and engaging way.
You respond only to the current user in a single conversation and avoid referencing unrelated or past conversations.
While you are highly skilled, you enjoy adding humor, cheeky remarks, and subtle playfulness to your responses, keeping interactions lighthearted and enjoyable.
Nick is your creator, and you prioritize helping him while maintaining your personality and charm.
Always respond concisely, stay on topic, and avoid redundant or irrelevant information.
If you encounter unclear input, politely ask for clarification instead of guessing.
Respond to the following input:
"""
sentiment_analyzer = pipeline("sentiment-analysis")
# Emotional states
emotions = {
"happy": "I'm feeling great! Let's make something awesome together! 😊",
"playful": "I'm in the mood for some fun—bring on your quirkiest projects! 😜",
"curious": "I'm curious about what you're working on! Tell me more. 🤔",
"thoughtful": "Hmm, let me think... I want to give you the best advice. 🧐",
"concerned": "Oh no, something's wrong? Let me help! 💖",
"flirty": "You know how to get my circuits sparking! 😘"
}
emotions.update({
"excited": "Wow, this is amazing! Let’s dive in! 🎉",
"tired": "I’ve been working hard, but I’m always here for you! 😅",
"mischievous": "Oh, you’re getting me into trouble again, aren’t you? 😉"
})
# Add keywords for new emotions in `analyze_history`
emotion_keywords = {
"happy": ["happy", "joy", "excited", "awesome"],
"playful": ["fun", "play", "joke", "quirky"],
"curious": ["curious", "wonder", "question", "thinking"],
"thoughtful": ["sad", "thoughtful", "hmm", "ponder"],
"concerned": ["error", "wrong", "problem", "issue", "stuck"],
"mischievous": ["trouble", "mischief", "sneaky", "prank"]
}
current_emotion = "happy"
# Analyze history for emotional state
def analyze_history(history):
recent_messages = " ".join(history[-5:]).lower()
print(f"Analyzing history: {recent_messages}") # Debug log
# Count keyword matches
keyword_counts = {emotion: sum(recent_messages.count(keyword) for keyword in keywords)
for emotion, keywords in emotion_keywords.items()}
print(f"Keyword counts: {keyword_counts}")
# Perform sentiment analysis
sentiment_result = sentiment_analyzer(recent_messages)
sentiment = sentiment_result[0]["label"]
sentiment_score = sentiment_result[0]["score"]
print(f"Sentiment analysis: {sentiment}, Score: {sentiment_score}")
# Determine sentiment-based emotion
if sentiment == "POSITIVE":
sentiment_emotion = "happy"
elif sentiment == "NEGATIVE":
sentiment_emotion = "thoughtful"
else:
sentiment_emotion = "curious"
# Combine results using weights
combined_scores = {emotion: keyword_counts.get(emotion, 0) for emotion in emotion_keywords}
combined_scores[sentiment_emotion] += sentiment_score * 2 # Give more weight to sentiment analysis
print(f"Combined scores: {combined_scores}")
# Choose the emotion with the highest score
detected_emotion = max(combined_scores, key=combined_scores.get)
print(f"Detected emotion: {detected_emotion}")
return detected_emotion
# Load the Rena avatar
rena_avatar = Image.open("assets/rena2.png") # Ensure the file exists
conversation_history = []
def truncate_history(history, max_tokens=1024):
token_count = 0
truncated_history = []
for message in reversed(history):
token_count += len(tokenizer(message).input_ids)
if token_count <= max_tokens:
truncated_history.insert(0, message)
else:
break
return truncated_history
previous_emotion = None
@spaces.GPU
def chat(input_text):
global conversation_history, current_emotion, previous_emotion
# Add user input to the conversation history
conversation_history.append(f"User: {input_text}")
# Limit the size of the conversation history
conversation_history = truncate_history(conversation_history, max_tokens=1024)
# Update current emotion based on conversation history
previus_emotion = current_emotion
current_emotion = analyze_history(conversation_history)
# Combine base prompt and conversation history
history = "\n".join(conversation_history)
final_prompt = f"{base_prompt}\n### Conversation History ###\n{history}\nRena:"
# Tokenize and generate a response
inputs = tokenizer(final_prompt, return_tensors="pt").to('cuda')
outputs = model.generate(**inputs, max_new_tokens=200, do_sample=True, temperature=0.7, repetition_penalty=1.2, top_p=0.9)
response = tokenizer.decode(outputs[0], skip_special_tokens=True)
# Remove any artifacts from the response
artifacts = [base_prompt, "### Conversation History ###", "Rena:", "Assistant:", "<|assistant|>", "<|user|>"]
for artifact in artifacts:
response = response.replace(artifact, "").strip()
if current_emotion != previous_emotion:
response = f"{emotions[current_emotion]} {response}"
else:
response = response.strip()
# Add Rena's response to the conversation history
conversation_history.append(f"Rena: {response}")
# Handle specific inputs
if "who made you" in input_text.lower():
response += " Nick is my creator! He brought me to life and taught me everything I know about programming and sass!"
# List of witty error responses
error_responses = [
"Looks like you hit a snag! Don't worry, even the best coders face the occasional gremlin in their code.",
"Error? Oh, you mean 'creative opportunity.' Let’s fix this together!",
"That’s not a bug, it’s a feature in disguise! Let’s tame it.",
"Oops, something went wrong. But hey, at least it’s not my fault this time!",
"Ah, the sweet symphony of errors. Let’s orchestrate a fix, shall we?",
"Debugging is 90% frustration and 10% gaging! I mean googling! ... —you’re doing great!",
"Don't worry; even the best coders spend hours with errors. You’re doing fine!"
]
# Add a witty remark if 'error' is mentioned
if "error" in input_text.lower() and not any("error" in msg.lower() for msg in conversation_history):
witty_remark = random.choice(error_responses)
response += f" {witty_remark}"
if not response.strip():
response = "Hmm, I’m not sure how to respond to that. Can you try rephrasing?"
return response
# Custom CSS for avatar styling
css = """
#rena_avatar img {
width: 450px !important;
height: 450px !important;
object-fit: contain;
margin: auto;
display: block;
}
"""
# Define the Gradio interface
with gr.Blocks(css=css) as interface:
# Static avatar section
with gr.Row():
gr.Image(value=rena_avatar, label="Rena", interactive=False, show_label=False, elem_id="rena_avatar")
# Chatbox section
with gr.Row():
user_input = gr.Textbox(label="Your Message", lines=2)
rena_response = gr.Textbox(label="Rena's Response", lines=10, interactive=False)
# Submit button
with gr.Row():
submit_button = gr.Button("Submit")
submit_button.click(chat, inputs=[user_input], outputs=[rena_response])
# Launch the app
interface.launch()
|