Spaces:
Sleeping
Sleeping
Updated with Content msg, product recommendation and history information4
Browse files
app.py
CHANGED
@@ -8,6 +8,7 @@ import os
|
|
8 |
import logging
|
9 |
import re
|
10 |
import torch
|
|
|
11 |
|
12 |
# Set up logging
|
13 |
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
@@ -26,7 +27,6 @@ model_repo = "SyedHutter/blenderbot_model"
|
|
26 |
model_subfolder = "blenderbot_model"
|
27 |
model_dir = "/home/user/app/blenderbot_model"
|
28 |
|
29 |
-
# Device setup
|
30 |
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
31 |
logger.info(f"Using device: {device}")
|
32 |
|
@@ -42,9 +42,9 @@ else:
|
|
42 |
logger.info(f"Loading pre-existing model from {model_dir}.")
|
43 |
tokenizer = BlenderbotTokenizer.from_pretrained(model_dir)
|
44 |
model = BlenderbotForConditionalGeneration.from_pretrained(model_dir).to(device)
|
45 |
-
model.eval()
|
46 |
|
47 |
-
# Static Context
|
48 |
context_msg = "I am Hutter, your shopping guide for Hutter Products GmbH, here to help you find sustainable products."
|
49 |
|
50 |
# spaCy Setup
|
@@ -74,11 +74,11 @@ def detect_intent(text: str) -> str:
|
|
74 |
return "recommend_product"
|
75 |
elif any(token.text in ["company", "who", "do"] for token in doc):
|
76 |
return "company_info"
|
77 |
-
elif "name" in text_lower:
|
78 |
return "ask_name"
|
79 |
elif re.search(r"\d+\s*[\+\-\*/]\s*\d+", text_lower):
|
80 |
return "math_query"
|
81 |
-
return "
|
82 |
|
83 |
def search_products_by_keywords(keywords: List[str]) -> List[Dict[str, Any]]:
|
84 |
if not keywords:
|
@@ -101,16 +101,22 @@ def get_product_context(products: List[Dict]) -> str:
|
|
101 |
product_str = "Products: " + ", ".join([f"'{p['name']}' - {p['description']}" for p in products[:2]])
|
102 |
return product_str
|
103 |
|
104 |
-
def format_response(response: str, products: List[Dict], intent: str, input_text: str) -> str:
|
|
|
|
|
|
|
|
|
|
|
|
|
105 |
if intent == "recommend_product":
|
106 |
if not products:
|
107 |
-
return
|
108 |
product = products[0]
|
109 |
return f"Check out our '{product['name']}'—it’s {product['description'].lower()}. Want more options?"
|
110 |
elif intent == "company_info":
|
111 |
return "Hutter Products GmbH offers sustainable products like recycled textiles and ocean plastic goods."
|
112 |
elif intent == "ask_name":
|
113 |
-
return "I’m Hutter, your shopping guide for Hutter Products GmbH.
|
114 |
elif intent == "math_query":
|
115 |
match = re.search(r"(\d+)\s*([\+\-\*/])\s*(\d+)", input_text.lower())
|
116 |
if match:
|
@@ -120,6 +126,11 @@ def format_response(response: str, products: List[Dict], intent: str, input_text
|
|
120 |
elif op == "*": return f"{num1} * {num2} = {num1 * num2}. Explore our products?"
|
121 |
elif op == "/": return f"{num1} / {num2} = {num1 / num2}." if num2 != 0 else "Can’t divide by zero! Try our products?"
|
122 |
return "I can do math—try '2 + 2'. What else can I help with?"
|
|
|
|
|
|
|
|
|
|
|
123 |
if products:
|
124 |
product = products[0]
|
125 |
return f"{response} Also, check out '{product['name']}'—it’s {product['description'].lower()}."
|
@@ -135,7 +146,7 @@ async def process_prompt(request: PromptRequest):
|
|
135 |
try:
|
136 |
logger.info(f"Processing request: {request.input_text}")
|
137 |
input_text = request.input_text
|
138 |
-
history = request.conversation_history[-1:] if request.conversation_history else []
|
139 |
|
140 |
intent = detect_intent(input_text)
|
141 |
keywords = extract_keywords(input_text)
|
@@ -150,17 +161,17 @@ async def process_prompt(request: PromptRequest):
|
|
150 |
logger.info(f"Full input to model: {full_input}")
|
151 |
|
152 |
logger.info("Tokenizing input...")
|
153 |
-
inputs = tokenizer(full_input, return_tensors="pt", truncation=True, max_length=64).to(device)
|
154 |
logger.info("Input tokenized successfully.")
|
155 |
|
156 |
logger.info("Generating model response...")
|
157 |
-
with torch.no_grad():
|
158 |
outputs = model.generate(
|
159 |
**inputs,
|
160 |
-
max_new_tokens=30,
|
161 |
-
do_sample=True,
|
162 |
-
top_p=0.
|
163 |
-
temperature=0.
|
164 |
no_repeat_ngram_size=2
|
165 |
)
|
166 |
logger.info("Model generation complete.")
|
@@ -169,7 +180,7 @@ async def process_prompt(request: PromptRequest):
|
|
169 |
response = tokenizer.decode(outputs[0], skip_special_tokens=True)
|
170 |
logger.info(f"Model response: {response}")
|
171 |
|
172 |
-
enhanced_response = format_response(response, products, intent, input_text)
|
173 |
qa_response = {
|
174 |
"question": input_text,
|
175 |
"answer": enhanced_response,
|
|
|
8 |
import logging
|
9 |
import re
|
10 |
import torch
|
11 |
+
import random # For response variety
|
12 |
|
13 |
# Set up logging
|
14 |
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
|
|
27 |
model_subfolder = "blenderbot_model"
|
28 |
model_dir = "/home/user/app/blenderbot_model"
|
29 |
|
|
|
30 |
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
31 |
logger.info(f"Using device: {device}")
|
32 |
|
|
|
42 |
logger.info(f"Loading pre-existing model from {model_dir}.")
|
43 |
tokenizer = BlenderbotTokenizer.from_pretrained(model_dir)
|
44 |
model = BlenderbotForConditionalGeneration.from_pretrained(model_dir).to(device)
|
45 |
+
model.eval()
|
46 |
|
47 |
+
# Static Context
|
48 |
context_msg = "I am Hutter, your shopping guide for Hutter Products GmbH, here to help you find sustainable products."
|
49 |
|
50 |
# spaCy Setup
|
|
|
74 |
return "recommend_product"
|
75 |
elif any(token.text in ["company", "who", "do"] for token in doc):
|
76 |
return "company_info"
|
77 |
+
elif "name" in text_lower or "yourself" in text_lower or "you" in doc and "about" in doc:
|
78 |
return "ask_name"
|
79 |
elif re.search(r"\d+\s*[\+\-\*/]\s*\d+", text_lower):
|
80 |
return "math_query"
|
81 |
+
return "chat" # New fallback for general conversation
|
82 |
|
83 |
def search_products_by_keywords(keywords: List[str]) -> List[Dict[str, Any]]:
|
84 |
if not keywords:
|
|
|
101 |
product_str = "Products: " + ", ".join([f"'{p['name']}' - {p['description']}" for p in products[:2]])
|
102 |
return product_str
|
103 |
|
104 |
+
def format_response(response: str, products: List[Dict], intent: str, input_text: str, history: List[str]) -> str:
|
105 |
+
no_product_prompts = [
|
106 |
+
"I’d love to recommend something! What are you looking for in our sustainable catalog?",
|
107 |
+
"Our sustainable catalog has lots to offer—what catches your interest?",
|
108 |
+
"Tell me what you’re after, and I’ll find something great from our eco-friendly range!"
|
109 |
+
]
|
110 |
+
|
111 |
if intent == "recommend_product":
|
112 |
if not products:
|
113 |
+
return random.choice(no_product_prompts)
|
114 |
product = products[0]
|
115 |
return f"Check out our '{product['name']}'—it’s {product['description'].lower()}. Want more options?"
|
116 |
elif intent == "company_info":
|
117 |
return "Hutter Products GmbH offers sustainable products like recycled textiles and ocean plastic goods."
|
118 |
elif intent == "ask_name":
|
119 |
+
return "I’m Hutter, your shopping guide for Hutter Products GmbH. I’m here to help you find eco-friendly products—how can I assist?"
|
120 |
elif intent == "math_query":
|
121 |
match = re.search(r"(\d+)\s*([\+\-\*/])\s*(\d+)", input_text.lower())
|
122 |
if match:
|
|
|
126 |
elif op == "*": return f"{num1} * {num2} = {num1 * num2}. Explore our products?"
|
127 |
elif op == "/": return f"{num1} / {num2} = {num1 / num2}." if num2 != 0 else "Can’t divide by zero! Try our products?"
|
128 |
return "I can do math—try '2 + 2'. What else can I help with?"
|
129 |
+
elif intent == "chat":
|
130 |
+
# Use BlenderBot’s response if appropriate, else nudge toward shopping
|
131 |
+
if "yes" in input_text.lower() and history and "hat" in history[-1].lower():
|
132 |
+
return "Great! Besides the Bucket Hat, we have other sustainable items—want to hear more?"
|
133 |
+
return f"{response} How can I assist with our sustainable products today?" if response else "I’m here to help—anything on your mind?"
|
134 |
if products:
|
135 |
product = products[0]
|
136 |
return f"{response} Also, check out '{product['name']}'—it’s {product['description'].lower()}."
|
|
|
146 |
try:
|
147 |
logger.info(f"Processing request: {request.input_text}")
|
148 |
input_text = request.input_text
|
149 |
+
history = request.conversation_history[-1:] if request.conversation_history else []
|
150 |
|
151 |
intent = detect_intent(input_text)
|
152 |
keywords = extract_keywords(input_text)
|
|
|
161 |
logger.info(f"Full input to model: {full_input}")
|
162 |
|
163 |
logger.info("Tokenizing input...")
|
164 |
+
inputs = tokenizer(full_input, return_tensors="pt", truncation=True, max_length=64).to(device)
|
165 |
logger.info("Input tokenized successfully.")
|
166 |
|
167 |
logger.info("Generating model response...")
|
168 |
+
with torch.no_grad():
|
169 |
outputs = model.generate(
|
170 |
**inputs,
|
171 |
+
max_new_tokens=30,
|
172 |
+
do_sample=True,
|
173 |
+
top_p=0.95, # Slightly higher for more variety
|
174 |
+
temperature=0.8, # Slightly higher for creativity
|
175 |
no_repeat_ngram_size=2
|
176 |
)
|
177 |
logger.info("Model generation complete.")
|
|
|
180 |
response = tokenizer.decode(outputs[0], skip_special_tokens=True)
|
181 |
logger.info(f"Model response: {response}")
|
182 |
|
183 |
+
enhanced_response = format_response(response, products, intent, input_text, request.conversation_history)
|
184 |
qa_response = {
|
185 |
"question": input_text,
|
186 |
"answer": enhanced_response,
|