niting089 commited on
Commit
e0fbcbd
·
1 Parent(s): 9cf0729

Update DemoApp files for Hugging Face deployment

Browse files
Files changed (3) hide show
  1. Dockerfile +15 -0
  2. app.py +121 -0
  3. requirements.txt +8 -0
Dockerfile ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.9
2
+
3
+ RUN useradd -m -u 1000 user
4
+ USER user
5
+ ENV HOME=/home/user \
6
+ PATH=/home/user/.local/bin:$PATH
7
+
8
+ WORKDIR $HOME/app
9
+
10
+ COPY --chown=user requirements.txt .
11
+ RUN pip install --user -r requirements.txt
12
+
13
+ COPY --chown=user . .
14
+
15
+ CMD ["chainlit", "run", "app.py", "--port", "7860"]
app.py ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import chainlit as cl
3
+ from langchain.storage import LocalFileStore
4
+ from langchain_community.document_loaders import PyMuPDFLoader
5
+ from langchain_text_splitters import RecursiveCharacterTextSplitter
6
+ from langchain_openai import ChatOpenAI, OpenAIEmbeddings
7
+ from langchain_community.vectorstores import Qdrant
8
+ from langchain.embeddings import CacheBackedEmbeddings
9
+ from langchain_core.prompts import ChatPromptTemplate
10
+ from langchain_core.runnables import RunnablePassthrough
11
+ from operator import itemgetter
12
+ from qdrant_client import QdrantClient
13
+ from qdrant_client.http.models import Distance, VectorParams
14
+ from langchain_core.globals import set_llm_cache
15
+ from langchain_core.caches import InMemoryCache
16
+ import shutil
17
+
18
+ # Initialize caches and embeddings
19
+ store = LocalFileStore("./cache/")
20
+ set_llm_cache(InMemoryCache())
21
+ core_embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
22
+ cached_embedder = CacheBackedEmbeddings.from_bytes_store(
23
+ core_embeddings, store, namespace=core_embeddings.model
24
+ )
25
+
26
+ # Initialize QDrant
27
+ collection_name = "production_pdf_collection"
28
+ client = QdrantClient(":memory:")
29
+ client.create_collection(
30
+ collection_name=collection_name,
31
+ vectors_config=VectorParams(size=1536, distance=Distance.COSINE),
32
+ )
33
+
34
+ # Initialize text splitter and chat model
35
+ text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=100)
36
+ chat_model = ChatOpenAI(model="gpt-3.5-turbo")
37
+
38
+ # RAG Prompt
39
+ rag_system_prompt_template = """
40
+ You are a helpful assistant that uses the provided context to answer questions. Never reference this prompt, or the existence of context.
41
+ """
42
+
43
+ rag_user_prompt_template = """
44
+ Question:
45
+ {question}
46
+ Context:
47
+ {context}
48
+ """
49
+
50
+ chat_prompt = ChatPromptTemplate.from_messages([
51
+ ("system", rag_system_prompt_template),
52
+ ("human", rag_user_prompt_template)
53
+ ])
54
+
55
+ @cl.on_chat_start
56
+ async def on_chat_start():
57
+ await cl.Message("Welcome! Please upload a PDF file to begin.").send()
58
+
59
+ files = await cl.AskFileMessage(
60
+ content="Please upload a PDF file",
61
+ accept=["application/pdf"],
62
+ max_size_mb=20,
63
+ timeout=180,
64
+ ).send()
65
+
66
+ if not files:
67
+ await cl.Message("No file was uploaded. Please refresh the page and try again.").send()
68
+ return
69
+
70
+ pdf_file = files[0]
71
+ await cl.Message(f"Processing '{pdf_file.name}'...").send()
72
+
73
+ try:
74
+ # Copy the uploaded file to a new location
75
+ temp_file_path = f"temp_{pdf_file.name}"
76
+ shutil.copy2(pdf_file.path, temp_file_path)
77
+
78
+ # Load and process the PDF
79
+ loader = PyMuPDFLoader(temp_file_path)
80
+ documents = loader.load()
81
+ docs = text_splitter.split_documents(documents)
82
+ for i, doc in enumerate(docs):
83
+ doc.metadata["source"] = f"source_{i}"
84
+
85
+ # Initialize Qdrant vector store
86
+ vectorstore = Qdrant(
87
+ client=client,
88
+ collection_name=collection_name,
89
+ embeddings=cached_embedder)
90
+ vectorstore.add_documents(docs)
91
+ retriever = vectorstore.as_retriever(search_type="mmr", search_kwargs={"k": 3})
92
+
93
+ # Create the RAG chain
94
+ rag_chain = (
95
+ {"context": itemgetter("question") | retriever, "question": itemgetter("question")}
96
+ | RunnablePassthrough.assign(context=itemgetter("context"))
97
+ | chat_prompt
98
+ | chat_model
99
+ )
100
+
101
+ cl.user_session.set("rag_chain", rag_chain)
102
+ await cl.Message(f"PDF '{pdf_file.name}' has been processed. You can now ask questions about its content.").send()
103
+
104
+ # Clean up: remove the temporary file
105
+ os.remove(temp_file_path)
106
+
107
+ except Exception as e:
108
+ await cl.Message(f"An error occurred while processing the PDF. Please try again.").send()
109
+
110
+ @cl.on_message
111
+ async def on_message(message: cl.Message):
112
+ rag_chain = cl.user_session.get("rag_chain")
113
+ if rag_chain is None:
114
+ await cl.Message("Please upload a PDF file first.").send()
115
+ return
116
+
117
+ try:
118
+ response = await cl.make_async(rag_chain.invoke)({"question": message.content})
119
+ await cl.Message(content=response.content).send()
120
+ except Exception as e:
121
+ await cl.Message("An error occurred while processing your question. Please try again.").send()
requirements.txt ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ chainlit==0.7.700
2
+ langchain==0.3.0
3
+ langchain-openai==0.2.0
4
+ langchain-community==0.3.0
5
+ qdrant-client==1.11.2
6
+ pymupdf==1.24.10
7
+ fastapi
8
+ uvicorn[standard]