Sam commited on
Commit
ce74f64
·
0 Parent(s):

Initial commit

Browse files
Files changed (8) hide show
  1. .env.sample +5 -0
  2. .gitignore +5 -0
  3. Dockerfile +27 -0
  4. README.md +152 -0
  5. chainlit.md +23 -0
  6. midterm-app +1 -0
  7. midterm_app.py +124 -0
  8. requirements.txt +21 -0
.env.sample ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ # !!! DO NOT UPDATE THIS FILE DIRECTLY. MAKE A COPY AND RENAME IT `.env` TO PROCEED !!! #
2
+ HF_LLM_ENDPOINT="YOUR_LLM_ENDPOINT_URL_HERE"
3
+ HF_EMBED_ENDPOINT="YOUR_EMBED_MODEL_ENDPOINT_URL_HERE"
4
+ HF_TOKEN="YOUR_HF_TOKEN_HERE"
5
+ # !!! DO NOT UPDATE THIS FILE DIRECTLY. MAKE A COPY AND RENAME IT `.env` TO PROCEED !!! #
.gitignore ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ .env
2
+ __pycache__/
3
+ .chainlit
4
+ *.pkl
5
+ .files
Dockerfile ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.9
2
+
3
+ RUN pip install --upgrade pip
4
+
5
+ # Create a user and set up the environment
6
+ RUN useradd -m -u 1000 user
7
+ USER user
8
+
9
+ ENV HOME=/home/user \
10
+ PATH=/home/user/.local/bin:$PATH
11
+
12
+ WORKDIR $HOME/app
13
+
14
+ # Add this line to copy the data directory
15
+ COPY ./data /home/user/app/data
16
+
17
+ # Copy only requirements.txt first to leverage Docker cache
18
+ COPY --chown=user requirements.txt $HOME/app/requirements.txt
19
+
20
+ # Install dependencies
21
+ RUN pip install --no-cache-dir -r requirements.txt
22
+
23
+ # Copy the rest of the application code
24
+ COPY --chown=user . $HOME/app
25
+
26
+ # Run the application
27
+ CMD ["chainlit", "run", "midterm_app.py", "--port", "7860"]
README.md ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #Note to self: Revise this later
2
+
3
+ # Week 4: Tuesday
4
+
5
+ In today's assignment, we'll be creating an Open Source LLM-powered LangChain RAG Application in Chainlit.
6
+
7
+ There are 2 main sections to this assignment:
8
+
9
+ ## Build 🏗️
10
+
11
+ ### Build Task 1: Deploy LLM and Embedding Model to SageMaker Endpoint Through Hugging Face Inference Endpoints
12
+
13
+ #### LLM Endpoint
14
+
15
+ Select "Inference Endpoint" from the "Solutions" button in Hugging Face:
16
+
17
+ ![image](https://i.imgur.com/6KC9TCD.png)
18
+
19
+ Create a "+ New Endpoint" from the Inference Endpoints dashboard.
20
+
21
+ ![image](https://i.imgur.com/G6Bq9KC.png)
22
+
23
+ Select the `NousResearch/Meta-Llama-3-8B-Instruct` model repository and name your endpoint. Select N. Virginia as your region (`us-east-1`). Give your endpoint an appropriate name. Make sure to select *at least* a L4 GPU.
24
+
25
+ ![image](https://i.imgur.com/X3YlUbh.png)
26
+
27
+ Select the following settings for your `Advanced Configuration`.
28
+
29
+ ![image](https://i.imgur.com/c0HQ7g1.png)
30
+
31
+ Create a `Protected` endpoint.
32
+
33
+ ![image](https://i.imgur.com/Ak8kchZ.png)
34
+
35
+ If you were successful, you should see the following screen:
36
+
37
+ ![image](https://i.imgur.com/IBYG3wm.png)
38
+
39
+ #### Embedding Model Endpoint
40
+ We'll be using `Snowflake/snowflake-arctic-embed-m` for our embedding model today.
41
+
42
+ The process is the same as the LLM - but we'll make a few specific tweaks:
43
+
44
+ Let's make sure our set-up reflects the following screenshots:
45
+
46
+ ![image](https://i.imgur.com/IHh8FnC.png)
47
+
48
+ After which, make sure the advanced configuration is set like so:
49
+
50
+ ![image](https://i.imgur.com/bbcrhUj.png)
51
+
52
+ > #### NOTE: PLEASE SHUTDOWN YOUR INSTANCES WHEN YOU HAVE COMPLETED THE ASSIGNMENT TO PREVENT UNESSECARY CHARGES.
53
+
54
+ ### Build Task 2: Create RAG Pipeline with LangChain
55
+
56
+ Follow the [notebook](https://colab.research.google.com/drive/1v1FYmvKH4gsqcdZwIT9wvbQe0GUjrc9d?usp=sharing) to create a LangChain pipeline powered by Hugging Face endpoints!
57
+
58
+ Once you're done - please move on to Build Task 3!
59
+
60
+ ### Build Task 3: Create a Chainlit Application
61
+
62
+ 1. Create a new empty Docker space through Hugging Face - with the following settings:
63
+
64
+ ![image](https://i.imgur.com/0YzyQX7.png)
65
+
66
+ > NOTE: You may notice the application builds slowly (~15min.) with the default free-tier hardware. The process will be faster using the `CPU upgrade` Space Hardware - though it is not required.
67
+
68
+ 2. Clone the newly created space into a directory that is *NOT IN YOUR AI MAKERSPACE REPOSITORY* using the SSH option.
69
+
70
+ > NOTE: You may need to ensure you've added your SSH key to Hugging Face, as well as GitHub. This should already be done.
71
+
72
+ ![image](https://i.imgur.com/5RyBdP5.png)
73
+
74
+ 3. Copy and Paste (`cp ...` or through UI) the contents of `Week 4/Day 1` into the newly cloned repository.
75
+
76
+ > NOTE: Please keep the `README.md` that was cloned from your space and delete the class `README.md`.
77
+
78
+ 4. Using the `ls` command or the `tree` command verify that you have copied over:
79
+ - `app.py`
80
+ - `Dockerfile`
81
+ - `data/paul_graham_essays.txt`
82
+ - `chainlit.md`
83
+ - `.gitignore`
84
+ - `.env.sample`
85
+ - `solution_app.py`
86
+ - `requirements.txt`
87
+
88
+ Here is an example as the `ls -al` CLI command:
89
+
90
+ ![image](https://i.imgur.com/vazGYeb.png)
91
+
92
+ 5. Work through the `app.py` file to migrate your LCEL LangChain RAG Chain from the Notebook to Chainlit!
93
+
94
+ 6. Be sure to modify your `README.md` and `chainlit.md` as you see fit!
95
+
96
+ > NOTE: If you get stuck, there is a working reference version in `solution_app.py`.
97
+
98
+ 7. When you are done with local testing - push your changes to your space.
99
+
100
+ 8. Make sure you add your `HF_LLM_ENDPOINT`, `HF_EMBED_ENDPOINT`, `HF_TOKEN` as "Secrets" in your Hugging Face Space.
101
+
102
+ ### Terminating Your Resources
103
+
104
+ Please head to the settings of each endpoint and select `Delete Endpoint`. You will need to type the name of the endpoint to delete the resources.
105
+
106
+ ### Deliverables
107
+
108
+ - Completed Notebook
109
+ - Chainlit Application in a Hugging Face Space Powered by Hugging Face Endpoints
110
+ - Screenshot of endpoint usage
111
+
112
+ Example Screen Shot:
113
+
114
+ ![image](https://i.imgur.com/qfbcVpS.png)
115
+
116
+ ## Ship 🚢
117
+
118
+ Create a Hugging Face Space powered by Hugging Face Endpoints!
119
+
120
+ ### Deliverables
121
+
122
+ - A short Loom of the space, and a 1min. walkthrough of the application in full
123
+
124
+ ## Share 🚀
125
+
126
+ Make a social media post about your final application!
127
+
128
+ ### Deliverables
129
+
130
+ - Make a post on any social media platform about what you built!
131
+
132
+ Here's a template to get you started:
133
+
134
+ ```
135
+ 🚀 Exciting News! 🚀
136
+
137
+ I am thrilled to announce that I have just built and shipped a open-source LLM-powered Retrieval Augmented Generation Application with LangChain! 🎉🤖
138
+
139
+ 🔍 Three Key Takeaways:
140
+ 1️⃣
141
+ 2️⃣
142
+ 3️⃣
143
+
144
+ Let's continue pushing the boundaries of what's possible in the world of AI and question-answering. Here's to many more innovations! 🚀
145
+ Shout out to @AIMakerspace !
146
+
147
+ #LangChain #QuestionAnswering #RetrievalAugmented #Innovation #AI #TechMilestone
148
+
149
+ Feel free to reach out if you're curious or would like to collaborate on similar projects! 🤝🔥
150
+ ```
151
+
152
+ > #### NOTE: PLEASE SHUTDOWN YOUR INSTANCES WHEN YOU HAVE COMPLETED THE ASSIGNMENT TO PREVENT UNESSECARY CHARGES.
chainlit.md ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Welcome to the AirBnB 10k filing QnA Bot!
2
+
3
+ This bot answers questions from Airbnb's Q1 2024 10-K filings to demonstrate the power of AI to process complex financial documents and provide precise insights. It's the midterm assignment for the AI Makerspace AI Engineering Bootcamp.
4
+
5
+ My mind is buzzing with the potential to harness this kind of application to drive social impact, and I can't wait to use what I'm learning co-create solutions with nonprofits, social enterprises, and government agencies across the US.
6
+
7
+ Here's a bit more on the assignment for those who are interested:
8
+
9
+ Build 🏗️
10
+
11
+ Data: Airbnb 10-k Filings from Q1, 2024
12
+ LLM: You decide! (I picked OpenAI.)
13
+ Embedding Model: You decide! (I picked OpenAI.)
14
+ Infrastructure: LangChain
15
+ Vector Store: QDrant
16
+ Deployment: Chainlit, Hugging Face
17
+
18
+ Ship 🚢
19
+
20
+ Evaluate your answers to the following questions
21
+ Q1 "What is Airbnb's 'Description of Business'?"
22
+ Q2 "What was the total value of 'Cash and cash equivalents' as of December 31, 2023?"
23
+ Q3 "What is the 'maximum number of shares to be sold under the 10b5-1 Trading plan' by Brian Chesky?"
midterm-app ADDED
@@ -0,0 +1 @@
 
 
1
+ Subproject commit a6492b2481dbd143f30a0d5ebf707b3b070e7f54
midterm_app.py ADDED
@@ -0,0 +1,124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Import Required Libraries
2
+ import os
3
+ from dotenv import load_dotenv
4
+
5
+ import openai
6
+ import fitz # PyMuPDF
7
+ import pandas as pd
8
+ from transformers import pipeline
9
+ from qdrant_client import QdrantClient
10
+ from qdrant_client.http import models as qdrant_models
11
+ import chainlit as cl
12
+ import tiktoken
13
+
14
+ # Specific imports from the libraries
15
+ from langchain.document_loaders import PyMuPDFLoader
16
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
17
+ from langchain.embeddings import OpenAIEmbeddings
18
+ #old import from langchain_openai import OpenAIEmbeddings
19
+ from langchain_community.vectorstores import Qdrant
20
+ from langchain.prompts import ChatPromptTemplate
21
+ from langchain.chat_models import ChatOpenAI
22
+ #old import from langchain_openai import ChatOpenAI
23
+ from operator import itemgetter
24
+ from langchain.schema.output_parser import StrOutputParser
25
+ from langchain.schema.runnable import RunnablePassthrough
26
+
27
+ # Set Environment Variables
28
+ load_dotenv()
29
+
30
+ # Load environment variables
31
+ OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
32
+
33
+ # Initialize OpenAI client after loading the environment variables
34
+ openai.api_key = OPENAI_API_KEY
35
+
36
+ # Load and split documents
37
+ loader = PyMuPDFLoader("/home/user/app/data/airbnb_q1_2024.pdf")
38
+ #old file path is loader = PyMuPDFLoader("/Users/sampazar/AIE3-Midterm/data/airbnb_q1_2024.pdf")
39
+ documents = loader.load()
40
+
41
+ def tiktoken_len(text):
42
+ tokens = tiktoken.encoding_for_model("gpt-4o").encode(text)
43
+ return len(tokens)
44
+
45
+ text_splitter = RecursiveCharacterTextSplitter(
46
+ chunk_size=150,
47
+ chunk_overlap=100,
48
+ length_function = tiktoken_len
49
+ )
50
+
51
+ split_chunks = text_splitter.split_documents(documents)
52
+
53
+
54
+ # Load OpenAI Embeddings Model
55
+ embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
56
+
57
+ # Creating a Qdrant Vector Store
58
+ qdrant_vector_store = Qdrant.from_documents(
59
+ split_chunks,
60
+ embeddings,
61
+ location=":memory:",
62
+ collection_name="Airbnb_Q1_2024",
63
+ )
64
+
65
+ # Create a Retriever
66
+ retriever = qdrant_vector_store.as_retriever()
67
+
68
+ # Create a prompt template
69
+ template = """Answer the question based only on the following context. If you cannot answer the question with the context, please respond with 'I don't know':
70
+
71
+ Context:
72
+ {context}
73
+
74
+ Question:
75
+ {question}
76
+ """
77
+
78
+ prompt = ChatPromptTemplate.from_template(template)
79
+
80
+ # Define the primary LLM
81
+ primary_llm = ChatOpenAI(model_name="gpt-4o", temperature=0)
82
+
83
+ # Creating a Retrieval Augmented Generation (RAG) Chain
84
+ retrieval_augmented_qa_chain = (
85
+ # INVOKE CHAIN WITH: {"question" : "<>"}
86
+ # "question" : populated by getting the value of the "question" key
87
+ # "context" : populated by getting the value of the "question" key and chaining it into the base_retriever
88
+ {"context": itemgetter("question") | retriever, "question": itemgetter("question")}
89
+ # "context" : is assigned to a RunnablePassthrough object (will not be called or considered in the next step)
90
+ # by getting the value of the "context" key from the previous step
91
+ | RunnablePassthrough.assign(context=itemgetter("context"))
92
+ # "response" : the "context" and "question" values are used to format our prompt object and then piped
93
+ # into the LLM and stored in a key called "response"
94
+ # "context" : populated by getting the value of the "context" key from the previous step
95
+ | {"response": prompt | primary_llm, "context": itemgetter("context")}
96
+ )
97
+
98
+ # Chainlit integration for deployment
99
+ @cl.on_chat_start # marks a function that will be executed at the start of a user session
100
+ async def start_chat():
101
+ settings = {
102
+ "model": "gpt-4o",
103
+ "temperature": 0,
104
+ "max_tokens": 500,
105
+ "top_p": 1,
106
+ "frequency_penalty": 0,
107
+ "presence_penalty": 0,
108
+ }
109
+ cl.user_session.set("settings", settings)
110
+
111
+ @cl.on_message # marks a function that should be run each time the chatbot receives a message from a user
112
+ async def handle_message(message: cl.Message):
113
+ settings = cl.user_session.get("settings")
114
+
115
+ response = retrieval_augmented_qa_chain.invoke({"question": message.content})
116
+
117
+ #msg = cl.Message(content=response["response"])
118
+ #await msg.send()
119
+
120
+ # Extracting and sending just the content
121
+ content = response["response"].content
122
+ pretty_content = content.strip() # Remove any leading/trailing whitespace
123
+
124
+ await cl.Message(content=pretty_content).send()
requirements.txt ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ chainlit==0.7.700
2
+ langchain==0.2.5
3
+ langchain_community==0.2.5
4
+ langchain_core==0.2.9
5
+ langchain_text_splitters==0.2.1
6
+ python-dotenv==1.0.1
7
+
8
+ #Adding OpenAI API client and Qdrant client
9
+ openai==1.35.3 #Be sure to use the latest version 'pip show openai'
10
+ qdrant-client==1.9.2 #Be sure to use the latest version 'pip show qdrant-client'
11
+
12
+ # Adding PyMuPDF for PDF processing
13
+ PyMuPDF==1.24.5 #Be sure to use the latest version 'pip show pymupdf'
14
+
15
+ tiktoken==0.7.0
16
+ #cohere==4.37
17
+ transformers==4.37.0
18
+ pandas==2.0.3
19
+ #Removed Hugging Face and FAISS dependencies
20
+ #langchain_huggingface==0.0.3
21
+ #faiss-cpu