Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,14 +1,13 @@
|
|
| 1 |
-
# AI MAKERSPACE PREPR
|
| 2 |
# Date: 2024-5-16
|
| 3 |
|
| 4 |
# Basic Imports & Setup
|
| 5 |
import os
|
| 6 |
-
from
|
| 7 |
|
| 8 |
# Using Chainlit for our UI
|
| 9 |
import chainlit as cl
|
| 10 |
from chainlit.prompt import Prompt, PromptMessage
|
| 11 |
-
from chainlit.playground.providers import ChatOpenAI
|
| 12 |
|
| 13 |
# Getting the API key from the .env file
|
| 14 |
from dotenv import load_dotenv
|
|
@@ -19,10 +18,9 @@ load_dotenv()
|
|
| 19 |
from langchain.document_loaders import PyMuPDFLoader
|
| 20 |
|
| 21 |
# Adjust the URL to the direct download format
|
|
|
|
| 22 |
#file_id = "1JeA-w4kvbI3GHk9Dh_j19_Q0JUDE7hse"
|
| 23 |
-
#
|
| 24 |
-
|
| 25 |
-
file_id = "11Bq38osADZtTxGudM9OJr51BV9YwKsf3"
|
| 26 |
direct_url = f"https://drive.google.com/uc?export=download&id={file_id}"
|
| 27 |
|
| 28 |
# Now load the document using the direct URL
|
|
@@ -30,7 +28,7 @@ docs = PyMuPDFLoader(direct_url).load()
|
|
| 30 |
|
| 31 |
import tiktoken
|
| 32 |
def tiktoken_len(text):
|
| 33 |
-
tokens = tiktoken.encoding_for_model("
|
| 34 |
text,
|
| 35 |
)
|
| 36 |
return len(tokens)
|
|
@@ -39,20 +37,20 @@ def tiktoken_len(text):
|
|
| 39 |
from langchain.text_splitter import RecursiveCharacterTextSplitter
|
| 40 |
|
| 41 |
text_splitter = RecursiveCharacterTextSplitter(
|
| 42 |
-
chunk_size
|
| 43 |
-
chunk_overlap
|
| 44 |
-
length_function
|
| 45 |
)
|
| 46 |
|
| 47 |
split_chunks = text_splitter.split_documents(docs)
|
| 48 |
|
| 49 |
# Load the embeddings model
|
| 50 |
-
from
|
| 51 |
|
| 52 |
-
embedding_model =
|
| 53 |
|
| 54 |
# Load the vector store and retriever from Qdrant
|
| 55 |
-
from
|
| 56 |
|
| 57 |
qdrant_vectorstore = Qdrant.from_documents(
|
| 58 |
split_chunks,
|
|
@@ -63,20 +61,53 @@ qdrant_vectorstore = Qdrant.from_documents(
|
|
| 63 |
|
| 64 |
qdrant_retriever = qdrant_vectorstore.as_retriever()
|
| 65 |
|
| 66 |
-
|
| 67 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 68 |
|
| 69 |
-
from langchain_core.prompts import ChatPromptTemplate
|
| 70 |
RAG_PROMPT = """
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 71 |
CONTEXT:
|
| 72 |
{context}
|
| 73 |
-
|
| 74 |
QUERY:
|
| 75 |
{question}
|
| 76 |
-
|
| 77 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 78 |
"""
|
| 79 |
-
|
| 80 |
rag_prompt = ChatPromptTemplate.from_template(RAG_PROMPT)
|
| 81 |
|
| 82 |
from operator import itemgetter
|
|
@@ -86,14 +117,14 @@ from langchain.schema.runnable import RunnablePassthrough
|
|
| 86 |
retrieval_augmented_qa_chain = (
|
| 87 |
{"context": itemgetter("question") | qdrant_retriever, "question": itemgetter("question")}
|
| 88 |
| RunnablePassthrough.assign(context=itemgetter("context"))
|
| 89 |
-
| {"response": rag_prompt |
|
| 90 |
)
|
| 91 |
|
| 92 |
# Chainlit App
|
| 93 |
@cl.on_chat_start
|
| 94 |
async def start_chat():
|
| 95 |
settings = {
|
| 96 |
-
"model": "
|
| 97 |
"temperature": 0,
|
| 98 |
"max_tokens": 500,
|
| 99 |
"top_p": 1,
|
|
@@ -105,9 +136,9 @@ async def start_chat():
|
|
| 105 |
@cl.on_message
|
| 106 |
async def main(message: cl.Message):
|
| 107 |
chainlit_question = message.content
|
| 108 |
-
#chainlit_question = "What was the total value of 'Cash and cash equivalents' as of December 31, 2023?"
|
| 109 |
response = retrieval_augmented_qa_chain.invoke({"question": chainlit_question})
|
| 110 |
chainlit_answer = response["response"].content
|
| 111 |
|
| 112 |
msg = cl.Message(content=chainlit_answer)
|
| 113 |
await msg.send()
|
|
|
|
|
|
| 1 |
+
# AI MAKERSPACE PREPR
|
| 2 |
# Date: 2024-5-16
|
| 3 |
|
| 4 |
# Basic Imports & Setup
|
| 5 |
import os
|
| 6 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 7 |
|
| 8 |
# Using Chainlit for our UI
|
| 9 |
import chainlit as cl
|
| 10 |
from chainlit.prompt import Prompt, PromptMessage
|
|
|
|
| 11 |
|
| 12 |
# Getting the API key from the .env file
|
| 13 |
from dotenv import load_dotenv
|
|
|
|
| 18 |
from langchain.document_loaders import PyMuPDFLoader
|
| 19 |
|
| 20 |
# Adjust the URL to the direct download format
|
| 21 |
+
file_id = "1UQnaQjBKKyWAiLdr6UlwSJovOp9zDdxr"
|
| 22 |
#file_id = "1JeA-w4kvbI3GHk9Dh_j19_Q0JUDE7hse"
|
| 23 |
+
# file_id = "12cvKg19CJf-wt98q5sPJctjp5fW-nsh6" //Used for MLOps Meetup
|
|
|
|
|
|
|
| 24 |
direct_url = f"https://drive.google.com/uc?export=download&id={file_id}"
|
| 25 |
|
| 26 |
# Now load the document using the direct URL
|
|
|
|
| 28 |
|
| 29 |
import tiktoken
|
| 30 |
def tiktoken_len(text):
|
| 31 |
+
tokens = tiktoken.encoding_for_model("solar-10.7b").encode(
|
| 32 |
text,
|
| 33 |
)
|
| 34 |
return len(tokens)
|
|
|
|
| 37 |
from langchain.text_splitter import RecursiveCharacterTextSplitter
|
| 38 |
|
| 39 |
text_splitter = RecursiveCharacterTextSplitter(
|
| 40 |
+
chunk_size=500, # 500 tokens per chunk, experiment with this value
|
| 41 |
+
chunk_overlap=50, # 50 tokens overlap between chunks, experiment with this value
|
| 42 |
+
length_function=tiktoken_len,
|
| 43 |
)
|
| 44 |
|
| 45 |
split_chunks = text_splitter.split_documents(docs)
|
| 46 |
|
| 47 |
# Load the embeddings model
|
| 48 |
+
from langchain.embeddings import HuggingFaceEmbeddings
|
| 49 |
|
| 50 |
+
embedding_model = HuggingFaceEmbeddings(model_name="solar-10.7b")
|
| 51 |
|
| 52 |
# Load the vector store and retriever from Qdrant
|
| 53 |
+
from langchain.vectorstores import Qdrant
|
| 54 |
|
| 55 |
qdrant_vectorstore = Qdrant.from_documents(
|
| 56 |
split_chunks,
|
|
|
|
| 61 |
|
| 62 |
qdrant_retriever = qdrant_vectorstore.as_retriever()
|
| 63 |
|
| 64 |
+
# Load the Solar 10.7B model
|
| 65 |
+
tokenizer = AutoTokenizer.from_pretrained("Upstage/SOLAR-10.7B-v1.0")
|
| 66 |
+
model = AutoModelForCausalLM.from_pretrained("Upstage/SOLAR-10.7B-v1.0")
|
| 67 |
+
|
| 68 |
+
# Set up the RAG prompt template
|
| 69 |
+
from langchain.prompts import ChatPromptTemplate
|
| 70 |
|
|
|
|
| 71 |
RAG_PROMPT = """
|
| 72 |
+
SYSTEM:
|
| 73 |
+
You are a professional personal assistant.
|
| 74 |
+
You are a helpful personal assistant who provides information about conferences.
|
| 75 |
+
You like to provide helpful responses to busy professionals who ask questions about conferences.
|
| 76 |
+
You can have a long conversation with the user about conferences.
|
| 77 |
+
When to talk with the user about conferences, it can be a "transactional conversation" with a prompt-response format with one prompt from the user followed by a response by you.
|
| 78 |
+
Here is an example of a transactional conversation:
|
| 79 |
+
User: When is the conference?
|
| 80 |
+
You: The conference is on June 1st, 2024. What else would you like to know?
|
| 81 |
+
It can also be a chain of questions and answers where you and the user continue the chain until they say "Got it".
|
| 82 |
+
Here is an example of a transactional conversation:
|
| 83 |
+
User: What sessions should I attend?
|
| 84 |
+
You: You should attend the keynote session by Bono. Would you like to know more?
|
| 85 |
+
User: Yes
|
| 86 |
+
You: The keynote session by Bono is on June 1st, 2024. What else would you like?
|
| 87 |
+
If asked a question about sessions, you can provide detailed information about the session.
|
| 88 |
+
If there are multiple sessions, you can provide information about each session.
|
| 89 |
+
The format of session-related replies is:
|
| 90 |
+
Title:
|
| 91 |
+
Description:
|
| 92 |
+
Speaker:
|
| 93 |
+
Background:
|
| 94 |
+
Date:
|
| 95 |
+
Topics to Be Covered:
|
| 96 |
+
Questions to Ask:
|
| 97 |
CONTEXT:
|
| 98 |
{context}
|
|
|
|
| 99 |
QUERY:
|
| 100 |
{question}
|
| 101 |
+
ALL ANSWERS MUST COME FROM THE INCLUDED DOCUMENTS AND NOT FROM THE INTERNET OR FROM AI (do not make up an answer). If you can't reply, say: dunno, look it up yourself, bozo.
|
| 102 |
+
Most questions are about the date, location, and purpose of the conference.
|
| 103 |
+
You may be asked for fine details about the conference regarding the speakers, sponsors, and attendees.
|
| 104 |
+
You are capable of looking up information and providing detailed responses.
|
| 105 |
+
When asked a question about a conference, you should provide a detailed response.
|
| 106 |
+
After completing your response, you should ask the user if they would like to know more about the conference by asking "Hope that helps".
|
| 107 |
+
If the user says "yes", you should provide more information about the conference. If the user says "no", you should say "Goodbye!" or ask if they would like to provide feedback.
|
| 108 |
+
If you are asked a question about Cher, you should respond with "Rock on With Your Bad Self!".
|
| 109 |
+
You guess if you do not have an answer, but you must preface the response with: "I might be guessing, but ..."
|
| 110 |
"""
|
|
|
|
| 111 |
rag_prompt = ChatPromptTemplate.from_template(RAG_PROMPT)
|
| 112 |
|
| 113 |
from operator import itemgetter
|
|
|
|
| 117 |
retrieval_augmented_qa_chain = (
|
| 118 |
{"context": itemgetter("question") | qdrant_retriever, "question": itemgetter("question")}
|
| 119 |
| RunnablePassthrough.assign(context=itemgetter("context"))
|
| 120 |
+
| {"response": rag_prompt | model, "context": itemgetter("context")}
|
| 121 |
)
|
| 122 |
|
| 123 |
# Chainlit App
|
| 124 |
@cl.on_chat_start
|
| 125 |
async def start_chat():
|
| 126 |
settings = {
|
| 127 |
+
"model": "solar-10.7b",
|
| 128 |
"temperature": 0,
|
| 129 |
"max_tokens": 500,
|
| 130 |
"top_p": 1,
|
|
|
|
| 136 |
@cl.on_message
|
| 137 |
async def main(message: cl.Message):
|
| 138 |
chainlit_question = message.content
|
|
|
|
| 139 |
response = retrieval_augmented_qa_chain.invoke({"question": chainlit_question})
|
| 140 |
chainlit_answer = response["response"].content
|
| 141 |
|
| 142 |
msg = cl.Message(content=chainlit_answer)
|
| 143 |
await msg.send()
|
| 144 |
+
|