Spaces:
Paused
Paused
File size: 6,918 Bytes
72f831c 7814b36 bef6630 7814b36 bef6630 7814b36 72f831c bef6630 7814b36 bef6630 7814b36 bef6630 7814b36 0c4a8eb ab83281 0c4a8eb 7814b36 25c6eb9 7814b36 bef6630 7814b36 bef6630 ab83281 25c6eb9 ab83281 7814b36 25c6eb9 7814b36 25c6eb9 7814b36 25c6eb9 7814b36 25c6eb9 7814b36 25c6eb9 7814b36 25c6eb9 7814b36 25c6eb9 7814b36 25c6eb9 7814b36 25c6eb9 7814b36 bef6630 0c4a8eb 7814b36 0c4a8eb 7814b36 ab83281 7814b36 25c6eb9 7814b36 25c6eb9 7814b36 25c6eb9 7814b36 ab83281 7814b36 ab83281 7814b36 0c4a8eb 7814b36 25c6eb9 7814b36 25c6eb9 ab83281 7814b36 25c6eb9 7814b36 25c6eb9 7814b36 ab83281 7814b36 0c4a8eb 7814b36 0c4a8eb 7814b36 |
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 |
# codingo/chatbot/chatbot.py
"""Interactive chatbot using Flan-T5 for dynamic responses"""
import os
import shutil
from typing import List
import torch
os.environ.setdefault("HF_HOME", "/tmp/huggingface")
os.environ.setdefault("TRANSFORMERS_CACHE", "/tmp/huggingface/transformers")
os.environ.setdefault("HUGGINGFACE_HUB_CACHE", "/tmp/huggingface/hub")
_model = None
_tokenizer = None
_chatbot_embedder = None
_chatbot_collection = None
_current_dir = os.path.dirname(os.path.abspath(__file__))
_knowledge_base_path = os.path.join(_current_dir, "chatbot.txt")
_chroma_db_dir = "/tmp/chroma_db"
# Using Flan-T5 - it's small, fast, and great for Q&A
MODEL_NAME = "google/flan-t5-small"
def _init_model():
global _model, _tokenizer
if _model is not None and _tokenizer is not None:
return
print("Loading Flan-T5 model...")
from transformers import T5ForConditionalGeneration, T5Tokenizer
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(f"Using device: {device}")
tokenizer = T5Tokenizer.from_pretrained(MODEL_NAME)
model = T5ForConditionalGeneration.from_pretrained(
MODEL_NAME,
torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32,
low_cpu_mem_usage=True
)
model = model.to(device)
model.eval()
_model = model
_tokenizer = tokenizer
print("Model loaded successfully!")
def _init_vector_store():
global _chatbot_embedder, _chatbot_collection
if _chatbot_embedder is not None and _chatbot_collection is not None:
return
print("Initializing vector store...")
from langchain.text_splitter import RecursiveCharacterTextSplitter
from sentence_transformers import SentenceTransformer
import chromadb
from chromadb.config import Settings
# Clean and create directory
shutil.rmtree(_chroma_db_dir, ignore_errors=True)
os.makedirs(_chroma_db_dir, exist_ok=True)
# Load knowledge base
try:
with open(_knowledge_base_path, encoding="utf-8") as f:
raw_text = f.read()
print(f"Loaded knowledge base: {len(raw_text)} characters")
except FileNotFoundError:
print("Knowledge base not found!")
raw_text = "Codingo is an AI recruitment platform."
# Split into chunks
splitter = RecursiveCharacterTextSplitter(chunk_size=400, chunk_overlap=50)
docs = [doc.strip() for doc in splitter.split_text(raw_text) if doc.strip()]
print(f"Created {len(docs)} document chunks")
# Create embeddings
embedder = SentenceTransformer("all-MiniLM-L6-v2")
embeddings = embedder.encode(docs, show_progress_bar=False)
# Create ChromaDB collection
client = chromadb.Client(Settings(anonymized_telemetry=False, is_persistent=False))
try:
client.delete_collection("chatbot")
except:
pass
collection = client.create_collection("chatbot")
ids = [f"doc_{i}" for i in range(len(docs))]
collection.add(documents=docs, embeddings=embeddings.tolist(), ids=ids)
_chatbot_embedder = embedder
_chatbot_collection = collection
print("Vector store ready!")
def get_chatbot_response(query: str) -> str:
try:
if not query or not query.strip():
return "Hi! I'm LUNA AI. Ask me anything about Codingo!"
print(f"\nProcessing: '{query}'")
# Clear GPU cache
if torch.cuda.is_available():
torch.cuda.empty_cache()
# Initialize
_init_vector_store()
_init_model()
# Search for relevant context
query_embedding = _chatbot_embedder.encode([query])[0]
results = _chatbot_collection.query(
query_embeddings=[query_embedding.tolist()],
n_results=3
)
retrieved_docs = results.get("documents", [[]])[0] if results else []
print(f"Found {len(retrieved_docs)} relevant chunks")
# Combine the most relevant information
context = " ".join(retrieved_docs[:2]) if retrieved_docs else "Codingo is an AI recruitment platform."
# Create a prompt for Flan-T5
prompt = f"""Answer the question based on the context about Codingo.
Context: {context}
Question: {query}
Answer:"""
# Tokenize
inputs = _tokenizer(
prompt,
max_length=512,
truncation=True,
return_tensors="pt"
).to(_model.device)
# Generate response
with torch.no_grad():
outputs = _model.generate(
**inputs,
max_new_tokens=150,
num_beams=4,
temperature=0.7,
do_sample=True,
top_p=0.9,
repetition_penalty=1.2
)
# Decode response
response = _tokenizer.decode(outputs[0], skip_special_tokens=True)
print(f"Generated: '{response}'")
# Make sure we have a good response
if not response or len(response) < 5:
# Fallback: try a simpler prompt
simple_prompt = f"Question about Codingo: {query}\nAnswer:"
inputs = _tokenizer(simple_prompt, max_length=256, truncation=True, return_tensors="pt").to(_model.device)
with torch.no_grad():
outputs = _model.generate(**inputs, max_new_tokens=100, temperature=0.8)
response = _tokenizer.decode(outputs[0], skip_special_tokens=True)
# Clean up the response
response = response.strip()
# If still too short, provide a helpful response
if len(response) < 10:
if "hello" in query.lower() or "hi" in query.lower():
return "Hello! I'm LUNA AI, your Codingo assistant. I can help you with questions about our AI recruitment platform, job matching, CV tips, and more!"
else:
return f"I can help you with that! Based on what I know about Codingo: {retrieved_docs[0][:200] if retrieved_docs else 'Codingo is an AI-powered recruitment platform that helps match candidates with jobs.'}"
return response
except Exception as e:
print(f"Error: {e}")
import traceback
traceback.print_exc()
return "I'm having a technical issue. Please try asking your question again!"
# Test function
if __name__ == "__main__":
# Test the chatbot
test_queries = [
"What is Codingo?",
"How does it work?",
"What makes Codingo special?",
"How can I improve my profile?",
"Is it free?"
]
print("Testing chatbot...")
for q in test_queries:
response = get_chatbot_response(q)
print(f"\nQ: {q}")
print(f"A: {response}")
print("-" * 50) |