Spaces:
Sleeping
Sleeping
File size: 7,065 Bytes
5f5f8de 6404fd8 5f5f8de 6404fd8 c2dd28c 5f5f8de 121ef90 6404fd8 5f5f8de 6404fd8 121ef90 6404fd8 121ef90 6404fd8 121ef90 6404fd8 121ef90 38dd749 6404fd8 121ef90 6404fd8 121ef90 6404fd8 c2dd28c 6404fd8 cb15139 6404fd8 cb15139 6404fd8 cb15139 6404fd8 cb15139 6404fd8 cb15139 6404fd8 121ef90 6404fd8 121ef90 6404fd8 a53e1b6 6404fd8 a53e1b6 5f5f8de 6404fd8 5f5f8de 6404fd8 105179a 6404fd8 a53e1b6 6404fd8 a53e1b6 6404fd8 cb7bbf3 6404fd8 cb7bbf3 6404fd8 121ef90 6404fd8 5f5f8de 6404fd8 121ef90 6404fd8 5f5f8de 6404fd8 5f5f8de 6404fd8 121ef90 6404fd8 5f5f8de 6404fd8 5f5f8de 6404fd8 5f5f8de 6404fd8 105179a 6404fd8 5f5f8de 6404fd8 38dd749 6404fd8 |
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 |
import gradio as gr
from typing import List, Dict
from langchain_core.prompts import ChatPromptTemplate
from langchain_community.llms.huggingface_pipeline import HuggingFacePipeline
from transformers import pipeline
import chromadb
from chromadb.utils import embedding_functions
from sentence_transformers import SentenceTransformer
import os
class ChromaDBChatbot:
def __init__(self):
# Initialize in-memory ChromaDB
self.chroma_client = chromadb.Client()
# Initialize embedding function
self.embedding_function = embedding_functions.SentenceTransformerEmbeddingFunction(
model_name="all-MiniLM-L6-v2"
)
# Create or get collection
self.collection = self.chroma_client.create_collection(
name="text_collection",
embedding_function=self.embedding_function
)
# Initialize the model - using a smaller model suitable for CPU
pipe = pipeline(
"text-generation",
model="TinyLlama/TinyLlama-1.1B-Chat-v1.0",
max_new_tokens=512,
temperature=0.7,
top_p=0.95,
repetition_penalty=1.15
)
self.llm = HuggingFacePipeline(pipeline=pipe)
# Enhanced prompt templates
self.templates = {
"default": """
IMPORTANT: You are a helpful assistant that provides information based on the retrieved context.
STRICT RULES:
1. Base your response ONLY on the provided context
2. If you cannot find relevant information, respond with: "I apologize, but I cannot find information about that in the database."
3. Do not make assumptions or use external knowledge
4. Be concise and accurate in your responses
5. If quoting from the context, clearly indicate it
Context: {context}
Chat History: {chat_history}
Question: {question}
Answer:""",
"summary": """
Create a concise summary of the following context.
Context: {context}
Key Requirements:
1. Highlight the main points
2. Keep it brief and clear
3. Use bullet points if appropriate
4. Include only information from the context
Summary:""",
"technical": """
Provide a technical explanation based on the context.
Context: {context}
Question: {question}
Guidelines:
1. Focus on technical details
2. Explain complex concepts clearly
3. Use appropriate technical terminology
4. Provide examples if present in the context
Technical Explanation:"""
}
self.chat_history = ""
self.loaded = False
def load_data(self, file_path: str):
"""Load data into ChromaDB"""
if self.loaded:
return
try:
# Read the text file
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
# Split into chunks (512 tokens each with 50 token overlap)
chunk_size = 512
overlap = 50
chunks = []
for i in range(0, len(content), chunk_size - overlap):
chunk = content[i:i + chunk_size]
chunks.append(chunk)
# Add documents to collection
self.collection.add(
documents=chunks,
ids=[f"doc_{i}" for i in range(len(chunks))]
)
self.loaded = True
print(f"Loaded {len(chunks)} chunks into ChromaDB")
except Exception as e:
print(f"Error loading data: {str(e)}")
return False
def _search_chroma(self, query: str) -> List[Dict]:
"""Search ChromaDB for relevant documents"""
try:
results = self.collection.query(
query_texts=[query],
n_results=5
)
return [{"content": doc} for doc in results['documents'][0]]
except Exception as e:
print(f"Error searching ChromaDB: {str(e)}")
return []
def chat(self, query: str, history) -> str:
"""Process a query and return a response"""
try:
if not self.loaded:
self.load_data('a2023-45.txt')
# Determine template type based on query
template_type = "default"
if any(word in query.lower() for word in ["summarize", "summary"]):
template_type = "summary"
elif any(word in query.lower() for word in ["technical", "explain", "how does"]):
template_type = "technical"
# Search ChromaDB for relevant content
search_results = self._search_chroma(query)
if not search_results:
return "I apologize, but I cannot find information about that in the database."
# Extract and combine relevant content
context = "\n\n".join([result['content'] for result in search_results])
# Create prompt with selected template
prompt = ChatPromptTemplate.from_template(self.templates[template_type])
# Generate response using LLM
chain = prompt | self.llm
result = chain.invoke({
"context": context,
"chat_history": self.chat_history,
"question": query
})
# Update chat history
self.chat_history += f"\nUser: {query}\nAI: {result}\n"
return result
except Exception as e:
return f"Error processing query: {str(e)}"
# Initialize the chatbot
chatbot = ChromaDBChatbot()
# Create the Gradio interface
demo = gr.Interface(
fn=chatbot.chat,
inputs=[
gr.Textbox(
label="Your Question",
placeholder="Ask anything about the document...",
lines=2
),
gr.State([]) # For chat history
],
outputs=gr.Textbox(label="Answer", lines=10),
title="ChromaDB-powered Document Q&A",
description="""
Ask questions about your document:
- For summaries, include words like 'summarize' or 'summary'
- For technical details, use words like 'technical', 'explain', 'how does'
- For general questions, just ask normally
""",
examples=[
["Can you summarize the main points?"],
["What are the technical details about this topic?"],
["Give me a general overview of the content."],
],
theme=gr.themes.Soft()
)
# Launch the interface
if __name__ == "__main__":
demo.launch() |