achapman commited on
Commit
c492fa7
·
1 Parent(s): 82e4f6a

initial commit

Browse files
Files changed (3) hide show
  1. Dockerfile +11 -0
  2. app.py +128 -0
  3. requirements.txt +8 -0
Dockerfile ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.9
2
+ RUN useradd -m -u 1000 user
3
+ USER user
4
+ ENV HOME=/home/user \
5
+ PATH=/home/user/.local/bin:$PATH
6
+ WORKDIR $HOME/app
7
+ COPY --chown=user . $HOME/app
8
+ COPY ./requirements.txt ~/app/requirements.txt
9
+ RUN pip install -r requirements.txt
10
+ COPY . .
11
+ CMD ["chainlit", "run", "app.py", "--port", "7860"]
app.py ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import chainlit as cl
3
+ from dotenv import load_dotenv
4
+ from operator import itemgetter
5
+ from langchain_huggingface import HuggingFaceEndpoint
6
+ from langchain_community.document_loaders import TextLoader
7
+ from langchain_text_splitters import RecursiveCharacterTextSplitter
8
+ from langchain_community.vectorstores import FAISS
9
+ from langchain_huggingface import HuggingFaceEndpointEmbeddings
10
+ from langchain_core.prompts import PromptTemplate
11
+ from langchain.schema.output_parser import StrOutputParser
12
+ from langchain.schema.runnable import RunnablePassthrough
13
+ from langchain.schema.runnable.config import RunnableConfig
14
+
15
+ # GLOBAL SCOPE - ENTIRE APPLICATION HAS ACCESS TO VALUES SET IN THIS SCOPE #
16
+ # ---- ENV VARIABLES ---- #
17
+ """
18
+ This function will load our environment file (.env) if it is present.
19
+
20
+ NOTE: Make sure that .env is in your .gitignore file - it is by default, but please ensure it remains there.
21
+ """
22
+ load_dotenv()
23
+ HF_LLM_ENDPOINT = os.environ["HF_LLM_ENDPOINT"]
24
+ HF_EMBED_ENDPOINT = os.environ["HF_EMBED_ENDPOINT"]
25
+ HF_TOKEN = os.environ["HF_TOKEN"]
26
+
27
+ # ---- GLOBAL DECLARATIONS ---- #
28
+ # -- RETRIEVAL -- #
29
+ hf_embeddings = HuggingFaceEndpointEmbeddings(
30
+ model=HF_EMBED_ENDPOINT,
31
+ task="feature-extraction",
32
+ huggingfacehub_api_token=os.environ["HF_TOKEN"],
33
+ )
34
+
35
+ # Load vectorstore (prepopulated with a notebook, because it takes forever)
36
+ if os.path.exists("./data/vectorstore"):
37
+ vectorstore = FAISS.load_local(
38
+ "./data/vectorstore",
39
+ hf_embeddings,
40
+ allow_dangerous_deserialization=True # this is necessary to load the vectorstore from disk as it's stored as a `.pkl` file.
41
+ )
42
+ hf_retriever = vectorstore.as_retriever()
43
+ print("Loaded Vectorstore")
44
+
45
+ # -- AUGMENTED -- #
46
+ ### 1. DEFINE STRING TEMPLATE
47
+ RAG_PROMPT_TEMPLATE = """\
48
+ <|start_header_id|>system<|end_header_id|>
49
+ You are a helpful assistant who is an expert in tech, entrepreneurship, and personal development. You answer user questions based on provided context.
50
+ If you can't answer the question with the provided context, say you don't know.
51
+ You only talk about tech, entrepreneurship, and personal development. Politely decline to discuss other topics.
52
+ <|eot_id|>
53
+
54
+ <|start_header_id|>user<|end_header_id|>
55
+ User Query:
56
+ {query}
57
+
58
+ Context:
59
+ {context}<|eot_id|>
60
+
61
+ <|start_header_id|>assistant<|end_header_id|>
62
+ """
63
+ ### 2. CREATE PROMPT TEMPLATE
64
+ rag_prompt = PromptTemplate.from_template(RAG_PROMPT_TEMPLATE)
65
+
66
+ # -- GENERATION -- #
67
+ ### 1. CREATE HUGGINGFACE ENDPOINT FOR LLM
68
+ hf_llm = HuggingFaceEndpoint(
69
+ endpoint_url=f"{HF_LLM_ENDPOINT}",
70
+ max_new_tokens=512,
71
+ top_k=10,
72
+ top_p=0.95,
73
+ typical_p=0.95,
74
+ temperature=0.01,
75
+ repetition_penalty=1.03,
76
+ huggingfacehub_api_token=os.environ["HF_TOKEN"]
77
+ )
78
+
79
+ @cl.author_rename
80
+ def rename(original_author: str):
81
+ """
82
+ This function can be used to rename the 'author' of a message.
83
+ In this case, we're overriding the 'Assistant' author to be 'Paul Graham Essay Bot'.
84
+ """
85
+ rename_dict = {
86
+ "Assistant" : "Paul Graham Essay Bot"
87
+ }
88
+ return rename_dict.get(original_author, original_author)
89
+
90
+ @cl.on_chat_start
91
+ async def start_chat():
92
+ """
93
+ This function will be called at the start of every user session.
94
+ We will build our LCEL RAG chain here, and store it in the user session.
95
+ The user session is a dictionary that is unique to each user session, and is stored in the memory of the server.
96
+ """
97
+ if not hf_retriever:
98
+ raise ValueError("Retriever not initialized")
99
+
100
+ ### BUILD LCEL RAG CHAIN THAT ONLY RETURNS TEXT
101
+ lcel_rag_chain = {"context": itemgetter("query") | hf_retriever, "query": itemgetter("query")}| rag_prompt | hf_llm
102
+
103
+ cl.user_session.set("lcel_rag_chain", lcel_rag_chain)
104
+ await cl.Message(content="I'm ready! My fav topics are tech and entrepreneurship. What would you like to chat about today?").send()
105
+
106
+ @cl.on_message
107
+ async def main(message: cl.Message):
108
+ """
109
+ This function will be called every time a message is recieved from a session.
110
+ We will use the LCEL RAG chain to generate a response to the user query.
111
+ The LCEL RAG chain is stored in the user session, and is unique to each user session - this is why we can access it here.
112
+ """
113
+ lcel_rag_chain = cl.user_session.get("lcel_rag_chain")
114
+
115
+ msg = cl.Message(content="")
116
+ try:
117
+ async for chunk in lcel_rag_chain.astream(
118
+ {"query": message.content},
119
+ config=RunnableConfig(callbacks=[cl.LangchainCallbackHandler()]),
120
+ ):
121
+ if not "<|eot_id|>" in chunk:
122
+ await msg.stream_token(chunk)
123
+ except Exception as e:
124
+ print(f"error in chain execution: {e}")
125
+ msg.content = "An error occurred processing your request! Better luck next time!"
126
+ raise
127
+
128
+ await msg.send()
requirements.txt ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ chainlit==1.1.302
2
+ langchain==0.2.5
3
+ langchain_community==0.2.5
4
+ langchain_core==0.2.9
5
+ langchain_huggingface==0.0.3
6
+ langchain_text_splitters==0.2.1
7
+ python-dotenv==1.0.1
8
+ faiss-cpu