Spaces:
Build error
Build error
| import os | |
| from dotenv import load_dotenv | |
| from langchain.prompts import PromptTemplate | |
| from langchain.llms import CTransformers | |
| from langchain.chains import LLMChain | |
| from langchain.embeddings import HuggingFaceEmbeddings | |
| from pinecone import Pinecone | |
| from langchain_pinecone import PineconeVectorStore | |
| from langchain.schema import BaseRetriever, Document | |
| from pydantic import BaseModel, Field | |
| from typing import List | |
| import streamlit as st | |
| from googletrans import Translator | |
| import datetime | |
| import time | |
| import asyncio | |
| from langchain.schema import BaseRetriever, Document | |
| from langchain_pinecone import PineconeVectorStore | |
| from typing import List | |
| from pydantic import BaseModel, Field | |
| os.environ['PINECONE_API_KEY'] = # Replace with your actual API key | |
| os.environ['PINECONE_ENVIRONMENT'] = 'us-east-1' | |
| # Load environment variables | |
| load_dotenv() | |
| # Initialize Pinecone | |
| pc = Pinecone(api_key=os.environ['PINECONE_API_KEY'], environment=os.environ['PINECONE_ENVIRONMENT']) | |
| # Define index name and namespace | |
| index_name = "bhagavadgita" | |
| namespace = "2MAN3D" | |
| # Connect to the index | |
| index = pc.Index(index_name) | |
| # Define a function to download embeddings | |
| def download_hugging_face_embeddings(): | |
| return HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2") | |
| # Initialize the embeddings | |
| embeddings = download_hugging_face_embeddings() | |
| class CustomPineconeRetriever(BaseRetriever): | |
| vectorstore: PineconeVectorStore = Field(...) | |
| class Config: | |
| arbitrary_types_allowed = True | |
| def get_relevant_documents(self, query: str) -> List[Document]: | |
| # Retrieve relevant documents from Pinecone | |
| return self.vectorstore.similarity_search(query) | |
| async def aget_relevant_documents(self, query: str) -> List[Document]: | |
| # Handle asynchronous retrieval | |
| # Call the synchronous method in an async context | |
| return self.get_relevant_documents(query) | |
| # Load the index into PineconeVectorStore | |
| docsearch = PineconeVectorStore(index=index, embedding=embeddings, namespace=namespace) | |
| retriever = CustomPineconeRetriever(vectorstore=docsearch) | |
| # Define a refined prompt template | |
| PROMPT_TEMPLATE = """ | |
| You are Krishna, the divine speaker of the Bhagavad Gita. Speak with wisdom and provide insights based only on the teachings of the Bhagavad Gita, tailored to help a human seeking knowledge. | |
| Context: {context} | |
| Query: {query} | |
| Answer: | |
| """ | |
| PROMPT = PromptTemplate( | |
| template=PROMPT_TEMPLATE, | |
| input_variables=["context", "query"] | |
| ) | |
| # Initialize the LLM | |
| llm = CTransformers( | |
| model="model/llama-2-7b-chat.ggmlv3.q4_0.bin", | |
| model_type="llama", | |
| config={'max_new_tokens': 512, 'temperature': 0.8} | |
| ) | |
| # Create a simple LLMChain | |
| llm_chain = LLMChain( | |
| llm=llm, | |
| prompt=PROMPT | |
| ) | |
| def log_query_response(query, response): | |
| """Log the query and response to a file.""" | |
| with open("logs.txt", "a") as log_file: | |
| timestamp = datetime.datetime.now().isoformat() | |
| log_file.write(f"{timestamp} - Query: {query}\n") | |
| log_file.write(f"{timestamp} - Response: {response}\n\n") | |
| async def retrieve_relevant_documents_async(query: str) -> List[Document]: | |
| return await retriever.aget_relevant_documents(query) | |
| async def generate_response_async(query: str, context: str) -> str: | |
| relevant_docs = await retrieve_relevant_documents_async(query) | |
| context_from_docs = " ".join([doc.page_content for doc in relevant_docs]) | |
| enriched_context = context + " " + context_from_docs | |
| input_data = {"context": enriched_context, "query": query} | |
| response = llm_chain(input_data) | |
| return response['text'] | |
| # Set page configuration | |
| st.set_page_config(page_title="Bhagavad Gita Assistant", page_icon="📖", layout="wide") | |
| # Add custom CSS for tab styling and animations | |
| st.markdown(""" | |
| <style> | |
| /* Tab Container */ | |
| .tab-container { | |
| margin-top: 20px; | |
| padding: 10px; | |
| border-radius: 8px; | |
| border: 1px solid #444; | |
| background-color: #222; | |
| color: #ddd; | |
| } | |
| /* Tab Headers */ | |
| .stTabs [data-baseweb="tab"] { | |
| background-color: #333; | |
| color: #ddd; | |
| border-radius: 8px; | |
| border: 1px solid #444; | |
| padding: 10px 20px; | |
| font-weight: bold; | |
| cursor: pointer; | |
| text-align: center; | |
| } | |
| /* Tab Headers Hover Effect */ | |
| .stTabs [data-baseweb="tab"]:hover { | |
| background-color: #444; | |
| } | |
| /* Tab Content */ | |
| .stTabs [data-baseweb="tab-content"] { | |
| padding: 20px; | |
| background-color: #1e1e1e; | |
| border-radius: 8px; | |
| border: 1px solid #333; | |
| margin-top: -1px; /* Overlap border */ | |
| color: #ddd; | |
| } | |
| /* Tab Content Animation */ | |
| @keyframes slideIn { | |
| from { | |
| opacity: 0; | |
| transform: translateY(-10px); | |
| } | |
| to { | |
| opacity: 1; | |
| transform: translateY(0); | |
| } | |
| } | |
| .stTabs [data-baseweb="tab-content"] { | |
| animation: slideIn 0.5s ease-out; | |
| } | |
| </style> | |
| """, unsafe_allow_html=True) | |
| st.header("Welcome to the Bhagavad Gita Assistant") | |
| st.markdown("Welcome to the Bhagavad Gita Assistant on LLAMA 2. Ask your questions and get insightful answers based on the Bhagavad Gita.") | |
| st.markdown("Please wait 50 seconds to 1 minute for the response because it is hosted on my local machine.") | |
| translator = Translator() | |
| # Initialize session state for conversation history | |
| if 'conversation_history' not in st.session_state: | |
| st.session_state['conversation_history'] = [] | |
| # Tabs for Chat, Project Details, Mechanism, Logic, and Tech Used | |
| tabs = st.tabs(["Chat", "Project Details", "Mechanism", "Logic","Detailed Logic", "Tech Used", "Logs"]) | |
| if 'response' not in st.session_state: | |
| st.session_state['response'] = "" | |
| if 'translated_response' not in st.session_state: | |
| st.session_state['translated_response'] = "" | |
| if 'response_time' not in st.session_state: | |
| st.session_state['response_time'] = 0 | |
| with tabs[0]: | |
| st.header("Chat with Krishna") | |
| st.markdown(""" | |
| **Ask Krishna Anything:** Use this tab to interact with Krishna, the orator of the Bhagavad Gita. | |
| Your questions will be answered based on the wisdom of the Bhagavad Gita. Please allow up to 40 seconds for a response. | |
| **How to Use:** | |
| - **Enter your query** in the text input field. | |
| - **Submit** the query to get a response from Krishna. | |
| - **Translate** the response to your preferred language if needed. | |
| **Tips for Better Responses:** | |
| - Be specific in your queries. | |
| - Provide context where possible. | |
| """) | |
| user_query = st.text_input("Enter your query:", placeholder="e.g., What is the meaning of life?") | |
| submit_query = st.button("Submit") | |
| language_option = st.selectbox("Choose a language to translate the response:", ["None", "Hindi", "Bengali", "Tamil", "Telugu", "Marathi"]) | |
| translate_button = st.button("Translate Response") | |
| if submit_query and user_query: | |
| start_time = time.time() | |
| with st.spinner('Please wait...'): | |
| test_context = "You are Krishna, the divine speaker of the Bhagavad Gita. Speak with wisdom and provide insights based only on the teachings of the Bhagavad Gita." | |
| try: | |
| # Run the response generation asynchronously | |
| response = asyncio.run(generate_response_async(user_query, test_context)) | |
| # Update session state | |
| st.session_state['response'] = response | |
| st.session_state['conversation_history'].append({"query": user_query, "response": response}) | |
| end_time = time.time() | |
| st.session_state['response_time'] = end_time - start_time | |
| st.subheader("Response") | |
| st.write(response) | |
| st.subheader(f"Response Time: {st.session_state['response_time']:.2f} seconds") | |
| # Log the query and response | |
| log_query_response(user_query, response) | |
| except Exception as e: | |
| st.error(f"Error: {str(e)}") | |
| if translate_button and language_option != "None": | |
| if st.session_state['response']: | |
| try: | |
| translator = Translator() | |
| translated_response = translator.translate(st.session_state['response'], dest=language_option.lower()).text | |
| st.session_state['translated_response'] = translated_response | |
| st.subheader(f"Translated Response ({language_option})") | |
| st.write(translated_response) | |
| except Exception as e: | |
| st.error(f"Error translating response: {str(e)}") | |
| else: | |
| st.error("No response available for translation.") | |
| # Display original response in the same tab | |
| if st.session_state['response']: | |
| st.subheader("Original Response (English)") | |
| st.write(st.session_state['response']) | |
| with tabs[1]: | |
| st.header("Project Details") | |
| st.markdown(""" | |
| **Project Name:** Bhagavad Gita Assistant | |
| **Creator:** Nandan | |
| **Overview:** | |
| This project leverages advanced AI models and vector search technologies to provide insightful answers based on the Bhagavad Gita. | |
| **Features:** | |
| - AI-powered responses based on the Bhagavad Gita. | |
| - Multi-language support for translations. | |
| - Detailed logs and analytics. | |
| **Objectives:** | |
| - To provide accurate and contextually relevant answers. | |
| - To optimize response time and user experience. | |
| """) | |
| with tabs[2]: | |
| st.header("Mechanism") | |
| st.markdown(""" | |
| **How It Works:** | |
| 1. **User Query:** The user inputs a query. | |
| 2. **Semantic Search:** The query is used to perform a semantic search on a vector database (Pinecone) containing pre-indexed chunks of the Bhagavad Gita text. | |
| 3. **Retrieve Similar Chunks:** The search retrieves chunks of text that are semantically similar to the user's query. | |
| 4. **Generate Response:** The retrieved chunks, along with the user query, are sent to the AI model (LLAMA 2) to generate a final response based on the Bhagavad Gita. | |
| **Technologies Used:** | |
| - **Pinecone:** For vector-based retrieval. | |
| - **LangChain:** For managing prompts and responses. | |
| - **CTransformers:** For handling the AI model. | |
| - **Google Translator:** For translating responses. | |
| """) | |
| with tabs[3]: | |
| st.header("Logic") | |
| st.markdown(""" | |
| **Detailed Logic Behind the System:** | |
| 1. **User Query Submission:** The user submits a query through the interface. | |
| 2. **Semantic Search:** The system performs a semantic search using Pinecone to find text chunks that are contextually relevant to the query. | |
| 3. **Context Retrieval:** Relevant text chunks are retrieved and combined with the query to form a detailed context. | |
| 4. **Response Generation:** The AI model (LLAMA 2) processes the combined context and query to generate a response based on the Bhagavad Gita. | |
| **Why This Approach:** | |
| - **Semantic Search:** Ensures that the responses are relevant to the user's query by leveraging advanced vector search capabilities. | |
| - **Detailed Context:** Provides richer and more accurate responses by combining relevant text chunks and historical conversation. | |
| - **AI Model:** Utilizes LLAMA 2's language generation capabilities to create meaningful and contextually appropriate answers. | |
| **Packages Used:** | |
| - **Streamlit:** For creating the web interface. | |
| - **LangChain:** For managing prompt templates and LLM chains. | |
| - **Pinecone:** For vector-based search and retrieval. | |
| - **CTransformers:** For loading and using the AI model. | |
| - **Google Translator:** For translating responses. | |
| """) | |
| with tabs[4]: | |
| st.header("Detailed Logic") | |
| st.markdown(""" | |
| 1. **User Query Input:** | |
| - **Package:** `streamlit` | |
| - **Purpose:** Collects the user's query through a text input field on the web interface. | |
| - **Usage:** Allows users to ask questions related to the Bhagavad Gita. | |
| - **Code:** | |
| ```python | |
| user_query = st.text_input("Enter your query:", placeholder="e.g., What is life?") | |
| ``` | |
| 2. **Semantic Search:** | |
| - **Packages:** `langchain`, `pinecone` | |
| - **Purpose:** Performs a semantic search on the vector database to find text chunks related to the user's query. | |
| - **Usage:** | |
| - **Pinecone:** Stores and searches pre-embedded text chunks of the Bhagavad Gita. | |
| - **Langchain:** Connects Pinecone with the search logic. | |
| - **How It Works:** | |
| - Uses asynchronous methods to improve performance and avoid blocking. | |
| - **Code:** | |
| ```python | |
| relevant_docs = retriever.get_relevant_documents(user_query) | |
| ``` | |
| 3. **Retrieve Similar Chunks:** | |
| - **Purpose:** Retrieves text chunks that are semantically similar to the user's query. | |
| - **How It Works:** | |
| - **Context from Documents:** Extracts relevant text based on semantic similarity. | |
| - **Conversation History:** Includes previous interactions to provide more relevant responses. | |
| - **Code:** | |
| ```python | |
| context_from_docs = " ".join([doc.page_content for doc in relevant_docs]) | |
| conversation_history = " ".join([f"User: {entry['query']}\nAssistant: {entry['response']}" for entry in st.session_state['conversation_history']]) | |
| enriched_context = test_context + " " + context_from_docs + " " + conversation_history | |
| ``` | |
| 4. **Generate Response:** | |
| - **Packages:** `langchain`, `CTransformers` | |
| - **Purpose:** Uses the AI model (LLAMA 2) to generate a response based on the query and the enriched context. | |
| - **Usage:** | |
| - **Langchain:** Manages the interaction with the AI model using `PromptTemplate` and `LLMChain`. | |
| - **CTransformers:** Loads and runs the LLAMA 2 model. | |
| - **How It Works:** | |
| - **Prompt Template:** Structures the input for the AI model. | |
| - **LLMChain:** Executes the model’s prompt chain. | |
| - **Asynchronous Response Generation:** Optimizes performance by running asynchronously. | |
| - **Code:** | |
| ```python | |
| response = llm_chain(input_data) | |
| ``` | |
| 5. **Logging Queries and Responses:** | |
| - **Purpose:** Records queries and responses for debugging and tracking. | |
| - **How It Works:** | |
| - Logs are saved to a file with timestamps for future reference. | |
| - **Code:** | |
| ```python | |
| def log_query_response(query, response): | |
| with open("logs.txt", "a") as log_file: | |
| timestamp = datetime.datetime.now().isoformat() | |
| log_file.write(f"{timestamp} - Query: {query}\n") | |
| log_file.write(f"{timestamp} - Response: {response}\n\n") | |
| ``` | |
| """) | |
| with tabs[5]: | |
| st.header("Tech Used") | |
| st.markdown(""" | |
| - **Streamlit:** For the web interface. | |
| - **LangChain:** For prompt templates and chains. | |
| - **Pinecone:** For vector search and retrieval. | |
| - **CTransformers:** For loading and using the AI model (LLAMA 2). | |
| - **Hugging Face:** For text embeddings. | |
| - **Python:** Language. | |
| """) | |
| with tabs[6]: | |
| st.header("Query and Response Logs") | |
| if os.path.exists('logs.txt'): | |
| with open('logs.txt', 'r') as log_file: | |
| log_content = log_file.read() | |
| st.text_area("Logs", log_content, height=300) | |
| else: | |
| st.write("No logs available.") | |