Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,132 +1,130 @@
|
|
| 1 |
import gradio as gr
|
| 2 |
-
from transformers import pipeline
|
| 3 |
import re
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
resume_data = {
|
|
|
|
| 12 |
"name": "MD. Abdur Rahim (Ratul)",
|
| 13 |
"profession": "Programmer",
|
| 14 |
-
"education":
|
| 15 |
-
"SSC
|
| 16 |
-
"HSC
|
| 17 |
-
"BSc
|
| 18 |
-
|
| 19 |
-
"skills":
|
| 20 |
-
"Programming
|
| 21 |
-
"Core
|
| 22 |
-
"
|
| 23 |
-
|
| 24 |
-
"
|
| 25 |
-
|
| 26 |
-
"
|
| 27 |
-
"
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
"
|
| 32 |
-
"
|
| 33 |
-
|
| 34 |
-
"Strong debugging skills and efficient coding habits"
|
| 35 |
-
],
|
| 36 |
-
"contact": {
|
| 37 |
-
"Phone": "+8801786500883",
|
| 38 |
-
"Email": "ratul1.cse18kyau@gmail.com",
|
| 39 |
-
"Location": "Barabil, Shahzadpur, Sirajganj, Bangladesh"
|
| 40 |
-
},
|
| 41 |
-
"birth_year": 2004,
|
| 42 |
-
"relationship": "single"
|
| 43 |
}
|
| 44 |
|
| 45 |
-
#
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
"
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
"
|
| 56 |
-
"
|
| 57 |
-
"
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
"
|
| 61 |
-
"what is your birth year": "That's private. Please ask about my boss Ratul."
|
| 62 |
}
|
| 63 |
|
| 64 |
-
#
|
| 65 |
-
|
| 66 |
-
bangla_chars = set('অআইঈউঊঋএঐওঔকখগঘঙচছজঝঞটঠডঢণতথদধনপফবভমযরলশষসহড়ঢ়য়')
|
| 67 |
-
if any(char in bangla_chars for char in text):
|
| 68 |
-
translated = translator(text, src="ben_Beng", tgt="eng_Latn")
|
| 69 |
-
return translated[0]['translation_text']
|
| 70 |
-
return text
|
| 71 |
-
|
| 72 |
-
# Response logic
|
| 73 |
-
warned_once = False
|
| 74 |
-
|
| 75 |
-
def answer_question(question, history):
|
| 76 |
-
global warned_once
|
| 77 |
-
question = question.strip()
|
| 78 |
-
question_en = detect_and_translate(question.lower())
|
| 79 |
-
|
| 80 |
-
if is_abusive(question_en):
|
| 81 |
-
if not warned_once:
|
| 82 |
-
warned_once = True
|
| 83 |
-
return "My boss Ratul says: If you use abusive language, we call 999 (Bangladesh National Helpline). Please stop joking and ask about my boss Ratul."
|
| 84 |
-
else:
|
| 85 |
-
return "Hey mother fuc*ker !! Stop joking. I am coming to your home for f*ck your mom !! STOP !!", gr.update(visible=False)
|
| 86 |
-
|
| 87 |
-
for q, a in qa_pairs.items():
|
| 88 |
-
if q in question_en:
|
| 89 |
-
return a
|
| 90 |
-
|
| 91 |
-
# Smart response
|
| 92 |
-
prompt = f"""You're Trisha, a helpful assistant of MD. Abdur Rahim (Ratul), a programmer.
|
| 93 |
-
If user gets too personal, politely decline. If they ask about work, projects, or skills — answer smartly.
|
| 94 |
-
Occasionally mention: "My boss Ratul offers many small projects at very usual prices. If needed, ask me to contact him."
|
| 95 |
-
|
| 96 |
-
Resume Summary:
|
| 97 |
-
Name: {resume_data['name']}
|
| 98 |
-
Profession: {resume_data['profession']}
|
| 99 |
-
Education: {", ".join(resume_data['education'].values())}
|
| 100 |
-
Skills: {", ".join(resume_data['skills'].values())}
|
| 101 |
-
Languages: {", ".join(resume_data['languages'])}
|
| 102 |
-
Experience: {"; ".join(resume_data['experience'])}
|
| 103 |
-
Contact: {", ".join(resume_data['contact'].values())}
|
| 104 |
|
| 105 |
-
|
| 106 |
-
|
| 107 |
|
| 108 |
-
|
| 109 |
-
|
| 110 |
|
| 111 |
-
|
| 112 |
-
if
|
| 113 |
-
|
| 114 |
-
text += "\n\nP.S. My boss Ratul offers many small projects at a very low price. Ask if interested!"
|
| 115 |
return text
|
| 116 |
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 123 |
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
import gradio as gr
|
| 2 |
+
from transformers import pipeline
|
| 3 |
import re
|
| 4 |
+
from typing import Dict, List, Tuple
|
| 5 |
+
|
| 6 |
+
# ========== STEP 1: INITIALIZE OPTIMIZED MODELS ==========
|
| 7 |
+
# Using smaller, faster models
|
| 8 |
+
chatbot = pipeline(
|
| 9 |
+
"text-generation",
|
| 10 |
+
model="distilgpt2", # 6-layer distilled version of GPT-2 (faster)
|
| 11 |
+
device="cpu" # Remove if you have GPU
|
| 12 |
+
)
|
| 13 |
+
|
| 14 |
+
# Lightweight translation model for Bangla
|
| 15 |
+
translator = pipeline(
|
| 16 |
+
"translation",
|
| 17 |
+
model="Helsinki-NLP/opus-mt-bn-en", # Faster than nllb
|
| 18 |
+
device="cpu"
|
| 19 |
+
)
|
| 20 |
+
|
| 21 |
+
# ========== STEP 2: OPTIMIZED DATA STRUCTURES ==========
|
| 22 |
resume_data = {
|
| 23 |
+
# Strings instead of nested dicts for faster access
|
| 24 |
"name": "MD. Abdur Rahim (Ratul)",
|
| 25 |
"profession": "Programmer",
|
| 26 |
+
"education": "\n".join([
|
| 27 |
+
"SSC: Independent Model School, Bogra (4.29)",
|
| 28 |
+
"HSC: Shahzadpur Govt. College (4.92)",
|
| 29 |
+
"BSc CSE: Khwaja Yunus Ali University (Current, 3.75)"
|
| 30 |
+
]),
|
| 31 |
+
"skills": "\n".join([
|
| 32 |
+
"Programming: C++, C",
|
| 33 |
+
"Core: Algorithms, Problem Solving",
|
| 34 |
+
"Other: SEO, Communication"
|
| 35 |
+
]),
|
| 36 |
+
"coding": "\n".join([
|
| 37 |
+
"Codeforces: 831 rating (RATUL_CSE18)",
|
| 38 |
+
"Beecrowd: 448.58 points",
|
| 39 |
+
"Profile: codeforces.com/profile/ratul_cse18"
|
| 40 |
+
]),
|
| 41 |
+
"contact": "\n".join([
|
| 42 |
+
"Phone: +8801786500883",
|
| 43 |
+
"Email: ratul1.cse18kyau@gmail.com",
|
| 44 |
+
"Location: Shahzadpur, Sirajganj"
|
| 45 |
+
])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 46 |
}
|
| 47 |
|
| 48 |
+
# ========== STEP 3: PRE-COMPUTED ANSWERS ==========
|
| 49 |
+
QA = {
|
| 50 |
+
# Direct matches (fastest)
|
| 51 |
+
"who": f"I'm {resume_data['name']}, a {resume_data['profession']}.",
|
| 52 |
+
"education": resume_data["education"],
|
| 53 |
+
"skills": resume_data["skills"],
|
| 54 |
+
"code": resume_data["coding"],
|
| 55 |
+
"contact": resume_data["contact"],
|
| 56 |
+
|
| 57 |
+
# Pattern-based
|
| 58 |
+
"single": "I don't share relationship status.",
|
| 59 |
+
"age": "That's private. Ask about my coding skills!",
|
| 60 |
+
"project": "Ratul offers affordable projects. Interested?",
|
| 61 |
+
|
| 62 |
+
# Default
|
| 63 |
+
"fallback": "Ask about my education, skills, or coding profiles!"
|
|
|
|
| 64 |
}
|
| 65 |
|
| 66 |
+
# ========== STEP 4: OPTIMIZED PROCESSING ==========
|
| 67 |
+
ABUSIVE_WORDS = {"fuck", "ass", "bitch", "shit", "rape"} # Set for O(1) lookups
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 68 |
|
| 69 |
+
def is_abusive(text: str) -> bool:
|
| 70 |
+
return any(word in text.lower() for word in ABUSIVE_WORDS)
|
| 71 |
|
| 72 |
+
def detect_bangla(text: str) -> bool:
|
| 73 |
+
return any('\u0980' <= char <= '\u09FF' for char in text)
|
| 74 |
|
| 75 |
+
def fast_translate(text: str) -> str:
|
| 76 |
+
if detect_bangla(text):
|
| 77 |
+
return translator(text, max_length=60)[0]['translation_text']
|
|
|
|
| 78 |
return text
|
| 79 |
|
| 80 |
+
def generate_response(prompt: str) -> str:
|
| 81 |
+
response = chatbot(
|
| 82 |
+
prompt,
|
| 83 |
+
max_new_tokens=100,
|
| 84 |
+
do_sample=False, # Faster than sampling
|
| 85 |
+
num_beams=1 # Faster than beam search
|
| 86 |
+
)
|
| 87 |
+
return response[0]['generated_text'].split("Trisha:")[-1].strip()
|
| 88 |
+
|
| 89 |
+
# ========== STEP 5: OPTIMIZED CHAT LOGIC ==========
|
| 90 |
+
def answer_question(question: str) -> str:
|
| 91 |
+
question = question.strip().lower()
|
| 92 |
+
question_en = fast_translate(question)
|
| 93 |
|
| 94 |
+
# 1. Safety check
|
| 95 |
+
if is_abusive(question_en):
|
| 96 |
+
return "⚠️ Keep it professional or I'll disconnect!"
|
| 97 |
+
|
| 98 |
+
# 2. Check pre-computed answers (fast path)
|
| 99 |
+
if "who" in question_en: return QA["who"]
|
| 100 |
+
if "educat" in question_en: return QA["education"]
|
| 101 |
+
if "skill" in question_en: return QA["skills"]
|
| 102 |
+
if "code" in question_en: return QA["code"]
|
| 103 |
+
if "contact" in question_en: return QA["contact"]
|
| 104 |
+
if "single" in question_en: return QA["single"]
|
| 105 |
+
if "age" in question_en or "birth" in question_en: return QA["age"]
|
| 106 |
+
if "project" in question_en: return QA["project"]
|
| 107 |
+
|
| 108 |
+
# 3. Generate only when necessary (slower path)
|
| 109 |
+
prompt = f"""Trisha (Ratul's Assistant):
|
| 110 |
+
Q: {question_en}
|
| 111 |
+
A:"""
|
| 112 |
+
return generate_response(prompt)
|
| 113 |
+
|
| 114 |
+
# ========== STEP 6: LIGHTNING-FAST GRADIO UI ==========
|
| 115 |
+
with gr.Blocks(title="⚡ Trisha Chatbot") as demo:
|
| 116 |
+
gr.Markdown(f"## 🤖 Hi! I'm Trisha, {resume_data['name']}'s assistant")
|
| 117 |
+
|
| 118 |
+
with gr.Row():
|
| 119 |
+
user_input = gr.Textbox(label="Ask anything...", placeholder="Type in English/Bangla")
|
| 120 |
+
output = gr.Textbox(label="Response", lines=5)
|
| 121 |
+
|
| 122 |
+
user_input.submit(
|
| 123 |
+
fn=answer_question,
|
| 124 |
+
inputs=user_input,
|
| 125 |
+
outputs=output,
|
| 126 |
+
api_name="chat"
|
| 127 |
+
)
|
| 128 |
+
|
| 129 |
+
if __name__ == "__main__":
|
| 130 |
+
demo.launch(server_port=7860)
|