Spaces:
Sleeping
Sleeping
| import os | |
| import pinecone | |
| import logging | |
| import time | |
| import faiss | |
| import nest_asyncio | |
| import streamlit as st | |
| from langchain.llms import OpenAI | |
| from langchain.chat_models.openai import ChatOpenAI | |
| from langchain.llms import HuggingFacePipeline | |
| from langchain import HuggingFaceHub | |
| from langchain import PromptTemplate, LLMChain | |
| from langchain.chains.router import MultiPromptChain | |
| from langchain.llms import OpenAI | |
| from langchain.chains import ConversationChain | |
| from langchain.chains.llm import LLMChain | |
| from langchain.prompts import PromptTemplate | |
| from langchain.chains.router.llm_router import LLMRouterChain, RouterOutputParser | |
| from langchain.chains.router.multi_prompt_prompt import MULTI_PROMPT_ROUTER_TEMPLATE | |
| from langchain.chains.router.embedding_router import EmbeddingRouterChain | |
| from langchain.vectorstores import FAISS | |
| from langchain.embeddings import HuggingFaceEmbeddings | |
| from langchain.embeddings import HuggingFaceEmbeddings, SentenceTransformerEmbeddings | |
| from templates import hebrew_template, greek_template, apologetics_template, theology_template, therapy_template, history_template, commentary_template | |
| from langchain.callbacks.base import BaseCallbackHandler | |
| from langchain.chains import RetrievalQAWithSourcesChain | |
| from langchain.retrievers.web_research import WebResearchRetriever | |
| from langchain.vectorstores import FAISS | |
| from langchain.embeddings.openai import OpenAIEmbeddings | |
| from langchain.docstore import InMemoryDocstore | |
| from langchain.utilities import GoogleSearchAPIWrapper | |
| from langchain.retrievers.multi_query import MultiQueryRetriever | |
| from langchain.chains.question_answering import load_qa_chain | |
| from langchain.vectorstores import Pinecone | |
| st.title("BereaAI Bible Assistant") | |
| st.write("BereaAI has expertise in Biblical Hebrew, Greek, Apologetics, Theology, Counselling and Church History. \ | |
| Though still in the early stages BereaAI shows promise in delivering nuanced and thorough explanations. \ | |
| The first answer takes a while to load but the consequent answers load much faster. \ | |
| ") | |
| #HUGGINGFACEHUB_API_TOKEN = st.secrets["HUGGINGFACEHUB_API_TOKEN"] | |
| GOOGLE_API_KEY = st.secrets["GOOGLE_API_KEY"] | |
| GOOGLE_CSE_ID = st.secrets["GOOGLE_CSE_ID"] | |
| OPENAI_API_BASE = st.secrets["OPENAI_API_BASE"] | |
| OPENAI_API_KEY = st.secrets["OPENAI_API_KEY"] | |
| PINECONE_API_KEY = st.secrets["PINECONE_API_KEY"] | |
| #repo_id = "meta-llama/Llama-2-7b-chat-hf" | |
| #st.header("Parameters") | |
| #temperature = st.slider('Temperature', min_value=0.0, max_value=1.0, value=0.3, step=0.1) | |
| #max_new_tokens = st.slider('Max New Tokens', min_value=100, max_value=2000, value=1024, step=50) | |
| #top_p = st.slider('Top P', min_value=0.0, max_value=1.0, value=0.4, step=0.05) | |
| #llm = HuggingFaceHub(repo_id=repo_id, model_kwargs={"temperature": temperature, "max_new_tokens": max_new_tokens, "top_p": top_p}) | |
| llm = ChatOpenAI(model_name="gpt-3.5-turbo-16k",openai_api_key=OPENAI_API_KEY, temperature=0.3, streaming=True) | |
| # initialize pinecone | |
| pinecone.init( | |
| api_key=PINECONE_API_KEY, # find at app.pinecone.io | |
| environment="us-west1-gcp", # next to api key in console | |
| ) | |
| index_name = "bereaai" | |
| embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/stsb-bert-large") | |
| prompt_infos = [ | |
| { | |
| "name": "hebrew", | |
| "description": "Good for answering questions about Hebrew Old Testament Bible", | |
| "prompt_template": hebrew_template, | |
| }, | |
| { | |
| "name": "greek", | |
| "description": "Good for answering questions about Greek New Testament Bible", | |
| "prompt_template": greek_template, | |
| }, | |
| { | |
| "name": "apologetics", | |
| "description": "Good for answering questions directed against the Bible or Christianity", | |
| "prompt_template": apologetics_template, | |
| }, | |
| { | |
| "name": "theology", | |
| "description": "Good for answering questions about biblical theology", | |
| "prompt_template": theology_template, | |
| }, | |
| { | |
| "name": "therapy", | |
| "description": "Good for answering questions about mental health or personal issues", | |
| "prompt_template": therapy_template, | |
| }, | |
| { | |
| "name": "history", | |
| "description": "Good for answering questions about mental health or personal issues", | |
| "prompt_template": history_template, | |
| }, | |
| { | |
| "name": "commentary", | |
| "description": "Good for answering questions about verses, chapters or books of the Bible", | |
| "prompt_template": commentary_template, | |
| }, | |
| ] | |
| destination_chains = {} | |
| for p_info in prompt_infos: | |
| name = p_info["name"] | |
| prompt_template = p_info["prompt_template"] | |
| prompt = PromptTemplate(template=prompt_template, input_variables=["input"]) | |
| chain = LLMChain(llm=llm, prompt=prompt) | |
| destination_chains[name] = chain | |
| default_chain = ConversationChain(llm=llm, output_key="text") | |
| names_and_descriptions = [ | |
| ("hebrew", ["for questions about hebrew"]), | |
| ("greek", ["for questions about greek"]), | |
| ("apologetics", ["for questions directed against the Bible or Christianity"]), | |
| ("theology", ["for questions about theology"]), | |
| ("therapy", ["for questions about mental health"]), | |
| ("history", ["for questions about history"]), | |
| ("commentary", ["for questions about verses, passages or books of the Bible"]), | |
| ] | |
| router_chain = EmbeddingRouterChain.from_names_and_descriptions( | |
| names_and_descriptions, FAISS, embeddings, routing_keys=["input"] | |
| ) | |
| def generate_response(input_text): | |
| chain = MultiPromptChain( | |
| router_chain=router_chain, | |
| destination_chains=destination_chains, | |
| default_chain=default_chain, | |
| verbose=True,) | |
| return chain.run(input_text) | |
| def settings(): | |
| embedding_size = 1024 | |
| index = faiss.IndexFlatL2(embedding_size) | |
| vectorstore_public = FAISS(embeddings.embed_query, index, InMemoryDocstore({}), {}) | |
| search = GoogleSearchAPIWrapper() | |
| # Initialize | |
| web_retriever = WebResearchRetriever.from_llm( | |
| vectorstore=vectorstore_public, | |
| llm=llm, | |
| search=search, | |
| num_search_results=3 | |
| ) | |
| return web_retriever, llm | |
| # Make retriever and llm | |
| web_retriever, llm = settings() | |
| nest_asyncio.apply() | |
| def web_search(question): | |
| logging.basicConfig() | |
| logging.getLogger("langchain.retrievers.web_research").setLevel(logging.INFO) | |
| qa_chain = RetrievalQAWithSourcesChain.from_chain_type(llm, retriever=web_retriever) | |
| # Get result | |
| result = qa_chain({"question": question}) | |
| return(result) | |
| def vector_search(question): | |
| docsearch = Pinecone.from_existing_index(index_name, embeddings) | |
| logging.basicConfig() | |
| logging.getLogger('langchain.retrievers.multi_query').setLevel(logging.INFO) | |
| qa_chain = RetrievalQAWithSourcesChain.from_chain_type(llm, retriever=docsearch.as_retriever()) | |
| result = qa_chain({"question": question}) | |
| if result: | |
| sources_list = result['sources'].split('/content/drive/MyDrive/Commentaries/') | |
| filenames_with_extension = [os.path.basename(source) for source in sources_list] | |
| filename_without_extension = [os.path.splitext(source)[0] for source in filenames_with_extension] | |
| filtered_sources = [source for source in filename_without_extension if source] | |
| cleaned_sources = "\n- ".join(filtered_sources) | |
| else: | |
| pass | |
| return text, cleaned_sources | |
| def combined_answer(text1, text2, text3, source, question): | |
| text_answer2 = text2['answer'] | |
| books_ref = source | |
| web_ref = text2['sources'] | |
| return text1, books_ref, web_ref | |
| with st.form("my_form"): | |
| text = st.text_area("Enter text:", "Type question here") | |
| submitted = st.form_submit_button("Submit") | |
| if not text: | |
| st.info("You forgot to type something") | |
| elif submitted: | |
| with st.spinner('Researching...'): | |
| text1 = generate_response(text) | |
| text2 = web_search(text) | |
| text3, source = vector_search(text) | |
| answer, source2, source3 = combined_answer(text1, text2, text3, source,text) | |
| st.info(answer) | |
| st.info(f"Web Sources:\n {source3}") | |
| st.info(f"Book Sources: \n\n {source2}") | |
| st.markdown("## Examples") | |
| example1 = "Give me a Hebrew word study of Psalm 23" | |
| example2 = "Give me a Greek word study on John 17:1-5" | |
| example3 = "What is the evidence Jesus actually rose from the dead?" | |
| example4 = "I'm feeling really overwhelmed and overcome by anxiety and I don't know what to do" | |
| example5 = "How and when was the canon of the Bible put together?" | |
| example6 = "Explain the Trinity" | |
| example7 = "Give me a commentary on Matthew 5:3-12" | |
| if st.button(example1): | |
| user_input = example1 | |
| if st.button(example2): | |
| user_input = example2 | |
| if st.button(example3): | |
| user_input = example3 | |
| if st.button(example4): | |
| user_input = example4 | |
| if st.button(example5): | |
| user_input = example5 | |
| if st.button(example6): | |
| user_input = example6 | |
| if st.button(example7): | |
| user_input = example7 | |