gkbalu commited on
Commit
f19a88e
·
1 Parent(s): 8d064e5

RAG Optimization

Browse files
Files changed (6) hide show
  1. Dockerfile +12 -0
  2. README.md +185 -5
  3. app.py +152 -0
  4. chainlit.md +1 -0
  5. data/paul_graham_essays.txt +0 -0
  6. requirements.txt +8 -0
Dockerfile ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.9
2
+ RUN mkdir -p $HOME/app/data/vectorstore && chown -R user:user $HOME/app/data and in app.py via constant path to make a directory path: DATA_DIR = "./data" VECTORSTORE_DIR = os.path.join(DATA_DIR, "vectorstore") VECTORSTORE_PATH = os.path.join(VECTORSTORE_DIR, "index.faiss")
3
+ RUN useradd -m -u 1000 user
4
+ USER user
5
+ ENV HOME=/home/user \
6
+ PATH=/home/user/.local/bin:$PATH
7
+ WORKDIR $HOME/app
8
+ COPY --chown=user . $HOME/app
9
+ COPY ./requirements.txt ~/app/requirements.txt
10
+ RUN pip install -r requirements.txt
11
+ COPY . .
12
+ CMD ["chainlit", "run", "app.py", "--port", "7860"]
README.md CHANGED
@@ -1,10 +1,190 @@
1
  ---
2
- title: RAG Optimization
3
- emoji: 📈
4
- colorFrom: red
5
- colorTo: red
6
  sdk: docker
7
  pinned: false
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: BeyondChatGPT Demo
3
+ emoji: 📉
4
+ colorFrom: pink
5
+ colorTo: yellow
6
  sdk: docker
7
  pinned: false
8
+ app_port: 7860
9
  ---
10
 
11
+ <p align = "center" draggable=”false” ><img src="https://github.com/AI-Maker-Space/LLM-Dev-101/assets/37101144/d1343317-fa2f-41e1-8af1-1dbb18399719"
12
+ width="200px"
13
+ height="auto"/>
14
+ </p>
15
+
16
+
17
+ ## <h1 align="center" id="heading">:wave: Welcome to Beyond ChatGPT!!</h1>
18
+
19
+ For a step-by-step YouTube video walkthrough, watch this! [Deploying Chainlit app on Hugging Face](https://www.youtube.com/live/pRbbZcL0NMI?si=NAYhMZ_suAY84f06&t=2119)
20
+
21
+ ![Beyond ChatGPT: Build Your First LLM Application](https://github.com/AI-Maker-Space/Beyond-ChatGPT/assets/48775140/cb7a74b8-28af-4d12-a008-8f5a51d47b4c)
22
+
23
+ ## 🤖 Your First LLM App
24
+
25
+ > If you need an introduction to `git`, or information on how to set up API keys for the tools we'll be using in this repository - check out our [Interactive Dev Environment for LLM Development](https://github.com/AI-Maker-Space/Interactive-Dev-Environment-for-LLM-Development/tree/main) which has everything you'd need to get started in this repository!
26
+
27
+ In this repository, we'll walk you through the steps to create a Large Language Model (LLM) application using Chainlit, then containerize it using Docker, and finally deploy it on Huggingface Spaces.
28
+
29
+ Are you ready? Let's get started!
30
+
31
+ <details>
32
+ <summary>🖥️ Accessing "gpt-3.5-turbo" (ChatGPT) like a developer</summary>
33
+
34
+ 1. Head to [this notebook](https://colab.research.google.com/drive/1mOzbgf4a2SP5qQj33ZxTz2a01-5eXqk2?usp=sharing) and follow along with the instructions!
35
+
36
+ 2. Complete the notebook and try out your own system/assistant messages!
37
+
38
+ That's it! Head to the next step and start building your application!
39
+
40
+ </details>
41
+
42
+
43
+ <details>
44
+ <summary>🏗️ Building Your First LLM App</summary>
45
+
46
+ 1. Clone [this](https://github.com/AI-Maker-Space/Beyond-ChatGPT/tree/main) repo.
47
+
48
+ ``` bash
49
+ git clone https://github.com/AI-Maker-Space/Beyond-ChatGPT.git
50
+ ```
51
+
52
+ 2. Navigate inside this repo
53
+ ``` bash
54
+ cd Beyond-ChatGPT
55
+ ```
56
+
57
+ 3. Install the packages required for this python envirnoment in `requirements.txt`.
58
+ ``` bash
59
+ pip install -r requirements.txt
60
+ ```
61
+
62
+ 4. Open your `.env` file. Replace the `###` in your `.env` file with your OpenAI Key and save the file.
63
+ ``` bash
64
+ OPENAI_API_KEY=sk-###
65
+ ```
66
+
67
+ 5. Let's try deploying it locally. Make sure you're in the python environment where you installed Chainlit and OpenAI. Run the app using Chainlit. This may take a minute to run.
68
+ ``` bash
69
+ chainlit run app.py -w
70
+ ```
71
+
72
+ <p align = "center" draggable=”false”>
73
+ <img src="https://github.com/AI-Maker-Space/LLMOps-Dev-101/assets/37101144/54bcccf9-12e2-4cef-ab53-585c1e2b0fb5">
74
+ </p>
75
+
76
+ Great work! Let's see if we can interact with our chatbot.
77
+
78
+ <p align = "center" draggable=”false”>
79
+ <img src="https://github.com/AI-Maker-Space/LLMOps-Dev-101/assets/37101144/854e4435-1dee-438a-9146-7174b39f7c61">
80
+ </p>
81
+
82
+ Awesome! Time to throw it into a docker container and prepare it for shipping!
83
+ </details>
84
+
85
+
86
+
87
+ <details>
88
+ <summary>🐳 Containerizing our App</summary>
89
+
90
+ 1. Let's build the Docker image. We'll tag our image as `llm-app` using the `-t` parameter. The `.` at the end means we want all of the files in our current directory to be added to our image.
91
+
92
+ ``` bash
93
+ docker build -t llm-app .
94
+ ```
95
+
96
+ 2. Run and test the Docker image locally using the `run` command. The `-p`parameter connects our **host port #** to the left of the `:` to our **container port #** on the right.
97
+
98
+ ``` bash
99
+ docker run -p 7860:7860 llm-app
100
+ ```
101
+
102
+ 3. Visit http://localhost:7860 in your browser to see if the app runs correctly.
103
+
104
+ <p align = "center" draggable=”false”>
105
+ <img src="https://github.com/AI-Maker-Space/LLMOps-Dev-101/assets/37101144/2c764f25-09a0-431b-8d28-32246e0ca1b7">
106
+ </p>
107
+
108
+ Great! Time to ship!
109
+ </details>
110
+
111
+
112
+ <details>
113
+ <summary>🚀 Deploying Your First LLM App</summary>
114
+
115
+ 1. Let's create a new Huggingface Space. Navigate to [Huggingface](https://huggingface.co) and click on your profile picture on the top right. Then click on `New Space`.
116
+
117
+ <p align = "center" draggable=”false”>
118
+ <img src="https://github.com/AI-Maker-Space/LLMOps-Dev-101/assets/37101144/f0656408-28b8-4876-9887-8f0c4b882bae">
119
+ </p>
120
+
121
+ 2. Setup your space as shown below:
122
+
123
+ - Owner: Your username
124
+ - Space Name: `llm-app`
125
+ - License: `Openrail`
126
+ - Select the Space SDK: `Docker`
127
+ - Docker Template: `Blank`
128
+ - Space Hardware: `CPU basic - 2 vCPU - 16 GB - Free`
129
+ - Repo type: `Public`
130
+
131
+ <p align = "center" draggable=”false”>
132
+ <img src="https://github.com/AI-Maker-Space/LLMOps-Dev-101/assets/37101144/8f16afd1-6b46-4d9f-b642-8fefe355c5c9">
133
+ </p>
134
+
135
+ 3. You should see something like this. We're now ready to send our files to our Huggingface Space. After cloning, move your files to this repo and push it along with your docker file. You DO NOT need to create a Dockerfile. Make sure NOT TO push your `.env` file. This should automatically be ignored.
136
+
137
+ <p align = "center" draggable=”false”>
138
+ <img src="https://github.com/AI-Maker-Space/LLMOps-Dev-101/assets/37101144/cbf366e2-7613-4223-932a-72c67a73f9c6">
139
+ </p>
140
+
141
+ 4. After pushing all files, navigate to the settings in the top right to add your OpenAI API key.
142
+
143
+ <p align = "center" draggable=”false”>
144
+ <img src="https://github.com/AI-Maker-Space/LLMOps-Dev-101/assets/37101144/a1123a6f-abdd-4f76-bea4-39acf9928762">
145
+ </p>
146
+
147
+ 5. Scroll down to `Variables and secrets` and click on `New secret` on the top right.
148
+
149
+ <p align = "center" draggable=”false”>
150
+ <img src="https://github.com/AI-Maker-Space/LLMOps-Dev-101/assets/37101144/a8a4a25d-752b-4036-b572-93381370c2db">
151
+ </p>
152
+
153
+ 6. Set the name to `OPENAI_API_KEY` and add your OpenAI key under `Value`. Click save.
154
+
155
+ <p align = "center" draggable=”false”>
156
+ <img src="https://github.com/AI-Maker-Space/LLMOps-Dev-101/assets/37101144/0a897538-1779-48ff-bcb4-486af30f7a14">
157
+ </p>
158
+
159
+ 7. To ensure your key is being used, we recommend you `Restart this Space`.
160
+
161
+ <p align = "center" draggable=”false”>
162
+ <img src="https://github.com/AI-Maker-Space/LLMOps-Dev-101/assets/37101144/fb1d83af-6ebe-4676-8bf5-b6d88f07c583">
163
+ </p>
164
+
165
+ 8. Congratulations! You just deployed your first LLM! 🚀🚀🚀 Get on linkedin and post your results and experience! Make sure to tag us at #AIMakerspace !
166
+
167
+ Here's a template to get your post started!
168
+
169
+ ```
170
+ 🚀🎉 Exciting News! 🎉🚀
171
+
172
+ 🏗️ Today, I'm thrilled to announce that I've successfully built and shipped my first-ever LLM using the powerful combination of Chainlit, Docker, and the OpenAI API! 🖥️
173
+
174
+ Check it out 👇
175
+ [LINK TO APP]
176
+
177
+ A big shoutout to the @**AI Makerspace** for all making this possible. Couldn't have done it without the incredible community there. 🤗🙏
178
+
179
+ Looking forward to building with the community! 🙌✨ Here's to many more creations ahead! 🥂🎉
180
+
181
+ Who else is diving into the world of AI? Let's connect! 🌐💡
182
+
183
+ #FirstLLM #Chainlit #Docker #OpenAI #AIMakerspace
184
+ ```
185
+
186
+ </details>
187
+
188
+ <p></p>
189
+
190
+ ### That's it for now! And so it begins.... :)
app.py ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+
24
+ """
25
+ We will load our environment variables here.
26
+ """
27
+ HF_LLM_ENDPOINT = os.environ["HF_LLM_ENDPOINT"]
28
+ HF_EMBED_ENDPOINT = os.environ["HF_EMBED_ENDPOINT"]
29
+ HF_TOKEN = os.environ["HF_TOKEN"]
30
+
31
+ # ---- GLOBAL DECLARATIONS ---- #
32
+
33
+ # -- RETRIEVAL -- #
34
+ """
35
+ 1. Load Documents from Text File
36
+ 2. Split Documents into Chunks
37
+ 3. Load HuggingFace Embeddings (remember to use the URL we set above)
38
+ 4. Index Files if they do not exist, otherwise load the vectorstore
39
+ """
40
+ document_loader = TextLoader("./data/paul_graham_essays.txt")
41
+ documents = document_loader.load()
42
+
43
+ text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=30)
44
+ split_documents = text_splitter.split_documents(documents)
45
+
46
+ hf_embeddings = HuggingFaceEndpointEmbeddings(
47
+ model=HF_EMBED_ENDPOINT,
48
+ task="feature-extraction",
49
+ huggingfacehub_api_token=HF_TOKEN,
50
+ )
51
+
52
+ if os.path.exists("./data/vectorstore"):
53
+ vectorstore = FAISS.load_local(
54
+ "./data/vectorstore",
55
+ hf_embeddings,
56
+ allow_dangerous_deserialization=True # this is necessary to load the vectorstore from disk as it's stored as a `.pkl` file.
57
+ )
58
+ hf_retriever = vectorstore.as_retriever()
59
+ print("Loaded Vectorstore")
60
+ else:
61
+ print("Indexing Files")
62
+ os.makedirs("./data/vectorstore", exist_ok=True)
63
+ for i in range(0, len(split_documents), 32):
64
+ if i == 0:
65
+ vectorstore = FAISS.from_documents(split_documents[i:i+32], hf_embeddings)
66
+ continue
67
+ vectorstore.add_documents(split_documents[i:i+32])
68
+ vectorstore.save_local("./data/vectorstore")
69
+
70
+ hf_retriever = vectorstore.as_retriever()
71
+
72
+ # -- AUGMENTED -- #
73
+ """
74
+ 1. Define a String Template
75
+ 2. Create a Prompt Template from the String Template
76
+ """
77
+ RAG_PROMPT_TEMPLATE = """\
78
+ <|start_header_id|>system<|end_header_id|>
79
+ You are a helpful assistant. You answer user questions based on provided context. If you can't answer the question with the provided context, say you don't know.<|eot_id|>
80
+
81
+ <|start_header_id|>user<|end_header_id|>
82
+ User Query:
83
+ {query}
84
+
85
+ Context:
86
+ {context}<|eot_id|>
87
+
88
+ <|start_header_id|>assistant<|end_header_id|>
89
+ """
90
+
91
+ rag_prompt = PromptTemplate.from_template(RAG_PROMPT_TEMPLATE)
92
+
93
+ # -- GENERATION -- #
94
+ """
95
+ 1. Create a HuggingFaceEndpoint for the LLM
96
+ """
97
+ hf_llm = HuggingFaceEndpoint(
98
+ endpoint_url=HF_LLM_ENDPOINT,
99
+ max_new_tokens=512,
100
+ top_k=10,
101
+ top_p=0.95,
102
+ temperature=0.3,
103
+ repetition_penalty=1.15,
104
+ huggingfacehub_api_token=HF_TOKEN,
105
+ )
106
+
107
+ @cl.author_rename
108
+ def rename(original_author: str):
109
+ """
110
+ This function can be used to rename the 'author' of a message.
111
+
112
+ In this case, we're overriding the 'Assistant' author to be 'Paul Graham Essay Bot'.
113
+ """
114
+ rename_dict = {
115
+ "Assistant" : "Paul Graham Essay Bot"
116
+ }
117
+ return rename_dict.get(original_author, original_author)
118
+
119
+ @cl.on_chat_start
120
+ async def start_chat():
121
+ """
122
+ This function will be called at the start of every user session.
123
+
124
+ We will build our LCEL RAG chain here, and store it in the user session.
125
+
126
+ The user session is a dictionary that is unique to each user session, and is stored in the memory of the server.
127
+ """
128
+
129
+ lcel_rag_chain = rag_prompt | hf_llm
130
+
131
+ cl.user_session.set("lcel_rag_chain", lcel_rag_chain)
132
+
133
+ @cl.on_message
134
+ async def main(message: cl.Message):
135
+ """
136
+ This function will be called every time a message is recieved from a session.
137
+
138
+ We will use the LCEL RAG chain to generate a response to the user query.
139
+
140
+ 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.
141
+ """
142
+ lcel_rag_chain = cl.user_session.get("lcel_rag_chain")
143
+
144
+ msg = cl.Message(content="")
145
+
146
+ async for chunk in lcel_rag_chain.astream(
147
+ {"query": message.content},
148
+ config=RunnableConfig(callbacks=[cl.LangchainCallbackHandler()]),
149
+ ):
150
+ await msg.stream_token(chunk)
151
+
152
+ await msg.send()
chainlit.md ADDED
@@ -0,0 +1 @@
 
 
1
+ Ganesh's Optimized RAG
data/paul_graham_essays.txt ADDED
The diff for this file is too large to render. See raw diff
 
requirements.txt ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ chainlit==0.7.700
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