Asaad Almutareb commited on
Commit
45f1f60
1 Parent(s): 2675407

new repo Initial

Browse files
.devcontainer/Dockerfile ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ARG VARIANT="3.10-bookworm"
2
+ #FROM mcr.microsoft.com/devcontainers/python:1-${VARIANT}
3
+ FROM langchain/langchain
4
+
5
+ # [Optional] Uncomment if you want to install an additional version of node using nvm
6
+ # ARG EXTRA_NODE_VERSION=10
7
+ # RUN su node -c "source /usr/local/share/nvm/nvm.sh && nvm install ${EXTRA_NODE_VERSION}"
8
+
9
+ # [Optional] Uncomment if you want to install more global node modules
10
+ # RUN su node -c "npm install -g <your-package-list-here>"
11
+
12
+ #COPY library-scripts/github-debian.sh /tmp/library-scripts/
13
+ RUN apt-get update && apt-get update
14
+ RUN pip install --upgrade pip
15
+ #RUN pip install -r requirements.txt
.devcontainer/devcontainer.json ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // For format details, see https://aka.ms/devcontainer.json. For config options, see the
2
+ // README at: https://github.com/devcontainers/templates/tree/main/src/python
3
+ {
4
+ "name": "Langchain latest",
5
+ // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
6
+ //"image": "mcr.microsoft.com/devcontainers/python:1-3.10-bookworm",
7
+
8
+ // build config for the docker image instead:
9
+ "build": { "dockerfile": "Dockerfile" },
10
+
11
+ // Features to add to the dev container. More info: https://containers.dev/features.
12
+ // "features": {},
13
+
14
+ // Use 'forwardPorts' to make a list of ports inside the container available locally.
15
+ // "forwardPorts": [],
16
+
17
+ // Use 'postCreateCommand' to run commands after the container is created.
18
+ // "postCreateCommand": "pip3 install --user -r requirements.txt",
19
+
20
+ // Configure tool-specific properties.
21
+ "customizations": {
22
+ // Configure properties specific to VS Code.
23
+ "vscode": {
24
+ //Add the IDs of extensions you want installed when the container is created.
25
+ "extensions": ["ms-azuretools.vscode-docker"]
26
+ }
27
+ } //,
28
+
29
+ // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
30
+ // "remoteUser": "root"
31
+
32
+ // mount the SSH directory on win
33
+ /*"mounts": [
34
+ "type=bind,source=${localWorkspaceFolder},target=/work",
35
+ "type=bind,source=/home/${localEnv:USER}/.ssh,target=/home/vscode/.ssh,readonly"
36
+ ]*/
37
+ }
.gitattributes ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ *.sqlite3 filter=lfs diff=lfs merge=lfs -text
2
+ *.bin filter=lfs diff=lfs merge=lfs -text
.github/workflows/check_file_size.yaml ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Check file size
2
+ on: # or directly `on: [push]` to run the action on every push on any branch
3
+ pull_request:
4
+ branches: [main]
5
+
6
+ # to run this workflow manually from the Actions tab
7
+ workflow_dispatch:
8
+
9
+ jobs:
10
+ sync-to-hub:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - name: Check large files
14
+ uses: ActionsDesk/lfs-warning@v2.0
15
+ with:
16
+ filesizelimit: 10485760 # this is 10MB so we can sync to HF Spaces
.github/workflows/sync_2_hf.yml ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Sync to Hugging Face hub
2
+ on:
3
+ push:
4
+ branches: [main]
5
+
6
+ # to run this workflow manually from the Actions tab
7
+ workflow_dispatch:
8
+
9
+ jobs:
10
+ sync-to-hub:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v3
14
+ with:
15
+ fetch-depth: 0
16
+ lfs: true
17
+ - name: Push to hub
18
+ env:
19
+ HF_TOKEN: ${{ secrets.HF_TOKEN }}
20
+ run: git push https://sabazo:$HF_TOKEN@huggingface.co/spaces/sabazo/docs-qachat-demo main
.gitignore CHANGED
@@ -158,3 +158,11 @@ cython_debug/
158
  # and can be added to the global gitignore or merged into this file. For a more nuclear
159
  # option (not recommended) you can uncomment the following to ignore the entire idea folder.
160
  #.idea/
 
 
 
 
 
 
 
 
 
158
  # and can be added to the global gitignore or merged into this file. For a more nuclear
159
  # option (not recommended) you can uncomment the following to ignore the entire idea folder.
160
  #.idea/
161
+
162
+ # embeddings db
163
+ *.sqlite3*
164
+ *.bin
165
+ *.pickle
166
+ chroma_db/*
167
+ bin
168
+ obj
README.md CHANGED
@@ -1 +1 @@
1
- # docs-qachat
 
1
+ # docu-qachat-demo
app.py ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # gradio
2
+ import gradio as gr
3
+ import random
4
+ import time
5
+ #boto3 for S3 access
6
+ import boto3
7
+ from botocore import UNSIGNED
8
+ from botocore.client import Config
9
+ # access .env file
10
+ from dotenv import load_dotenv
11
+ #from bs4 import BeautifulSoup
12
+ # HF libraries
13
+ from langchain.llms import HuggingFaceHub
14
+ from langchain.embeddings import HuggingFaceHubEmbeddings
15
+ # vectorestore
16
+ from langchain.vectorstores import Chroma
17
+ from langchain.vectorstores import FAISS
18
+ # retrieval chain
19
+ from langchain.chains import RetrievalQA
20
+ # prompt template
21
+ from langchain.prompts import PromptTemplate
22
+ from langchain.memory import ConversationBufferMemory
23
+ # logging
24
+ #import logging
25
+ import zipfile
26
+
27
+ # load HF Token
28
+ config = load_dotenv(".env")
29
+
30
+
31
+ model_id = HuggingFaceHub(repo_id="HuggingFaceH4/zephyr-7b-beta", model_kwargs={
32
+ "temperature":0.1,
33
+ "max_new_tokens":1024,
34
+ "repetition_penalty":1.2,
35
+ "streaming": True,
36
+ "return_full_text":True
37
+ })
38
+
39
+ model_name = "sentence-transformers/multi-qa-mpnet-base-dot-v1"
40
+ embeddings = HuggingFaceHubEmbeddings(repo_id=model_name)
41
+
42
+
43
+ s3 = boto3.client('s3', config=Config(signature_version=UNSIGNED))
44
+
45
+ ## Chroma DB
46
+ s3.download_file('rad-rag-demos', 'vectorstores/chroma.sqlite3', './chroma_db/chroma.sqlite3')
47
+ db = Chroma(persist_directory="./chroma_db", embedding_function=embeddings)
48
+ db.get()
49
+
50
+ ## FAISS DB
51
+ # s3.download_file('rad-rag-demos', 'vectorstores/faiss_db_ray.zip', './chroma_db/faiss_db_ray.zip')
52
+ # with zipfile.ZipFile('./chroma_db/faiss_db_ray.zip', 'r') as zip_ref:
53
+ # zip_ref.extractall('./chroma_db/')
54
+
55
+ # FAISS_INDEX_PATH='./chroma_db/faiss_db_ray'
56
+ # db = FAISS.load_local(FAISS_INDEX_PATH, embeddings)
57
+
58
+ retriever = db.as_retriever(search_type = "mmr")#, search_kwargs={'k': 5, 'fetch_k': 25})
59
+ global qa
60
+ template = """
61
+ You are the friendly documentation buddy Arti, who helps the Human in using RAY, the open-source unified framework for scaling AI and Python applications.\
62
+ Use the following context (delimited by <ctx></ctx>) and the chat history (delimited by <hs></hs>) to answer the question :
63
+ ------
64
+ <ctx>
65
+ {context}
66
+ </ctx>
67
+ ------
68
+ <hs>
69
+ {history}
70
+ </hs>
71
+ ------
72
+ {question}
73
+ Answer:
74
+ """
75
+ prompt = PromptTemplate(
76
+ input_variables=["history", "context", "question"],
77
+ template=template,
78
+ )
79
+ memory = ConversationBufferMemory(memory_key="history", input_key="question")
80
+ qa = RetrievalQA.from_chain_type(llm=model_id, chain_type="stuff", retriever=retriever, verbose=True, return_source_documents=True, chain_type_kwargs={
81
+ "verbose": True,
82
+ "memory": memory,
83
+ "prompt": prompt
84
+ }
85
+ )
86
+
87
+
88
+ def add_text(history, text):
89
+ history = history + [(text, None)]
90
+ return history, ""
91
+
92
+ def bot(history):
93
+ response = infer(history[-1][0], history)
94
+ print(*memory)
95
+ sources = [doc.metadata.get("source") for doc in response['source_documents']]
96
+ src_list = '\n'.join(sources)
97
+ print_this = response['result']+"\n\n\n Sources: \n\n\n"+src_list
98
+
99
+ #history[-1][1] = ""
100
+ #for character in response['result']: #print_this:
101
+ # history[-1][1] += character
102
+ # time.sleep(0.05)
103
+ # yield history
104
+ history[-1][1] = print_this #response['result']
105
+ return history
106
+
107
+ def infer(question, history):
108
+ query = question
109
+ result = qa({"query": query, "history": history, "question": question})
110
+ return result
111
+
112
+ css="""
113
+ #col-container {max-width: 700px; margin-left: auto; margin-right: auto;}
114
+ """
115
+
116
+ title = """
117
+ <div style="text-align: center;max-width: 700px;">
118
+ <h1>Chat with your Documentation</h1>
119
+ <p style="text-align: center;">Chat with Documentation, <br />
120
+ when everything is ready, you can start asking questions about the docu ;)</p>
121
+ </div>
122
+ """
123
+
124
+ with gr.Blocks(css=css) as demo:
125
+ with gr.Column(elem_id="col-container"):
126
+ gr.HTML(title)
127
+ chatbot = gr.Chatbot([], elem_id="chatbot")
128
+ clear = gr.Button("Clear")
129
+ with gr.Row():
130
+ question = gr.Textbox(label="Question", placeholder="Type your question and hit Enter ")
131
+ question.submit(add_text, [chatbot, question], [chatbot, question], queue=False).then(
132
+ bot, chatbot, chatbot
133
+ )
134
+ clear.click(lambda: None, None, chatbot, queue=False)
135
+
136
+ demo.queue()
137
+ demo.launch()
example.env ADDED
@@ -0,0 +1 @@
 
 
1
+ OPENAI_API_KEY=
localembedding.py ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import chromadb
2
+ from chromadb.config import Settings
3
+ from langchain.vectorstores import Chroma
4
+ from langchain.vectorstores.utils import filter_complex_metadata
5
+ import time
6
+ from langchain.embeddings import HuggingFaceEmbeddings
7
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
8
+
9
+ text_splitter = RecursiveCharacterTextSplitter(
10
+ # Set a really small chunk size, just to show.
11
+ chunk_size = 1000,
12
+ chunk_overlap = 100,
13
+ length_function = len,
14
+ )
15
+
16
+ # Stage one: read all the docs, split them into chunks.
17
+ st = time.time()
18
+ print('Loading documents ...')
19
+ docs = loader.load()
20
+ chunks = text_splitter.create_documents([doc.page_content for doc in docs], metadatas=[doc.metadata for doc in docs])
21
+ et = time.time() - st
22
+ print(f'Time taken: {et} seconds.')
23
+
24
+ #Stage two: embed the docs.
25
+ # use all-mpnet-base-v2 sentence transformer to convert pieces of text in vectors to store them in the vector store
26
+ model_name = "sentence-transformers/all-mpnet-base-v2"
27
+ model_kwargs = {"device": "cuda"}
28
+
29
+ embeddings = HuggingFaceEmbeddings(
30
+ model_name=model_name,
31
+ model_kwargs=model_kwargs
32
+ )
33
+ print(f'Loading chunks into vector store ...')
34
+ st = time.time()
35
+ db = Chroma.from_documents(filter_complex_metadata(chunks), embeddings, persist_directory="/content/chroma_db")
36
+ et = time.time() - st
37
+ print(f'Time taken: {et} seconds.')
requirements.txt ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ huggingface_hub
2
+ chromadb
3
+ faiss-cpu
4
+ langchain
5
+ python-dotenv
6
+ bs4
7
+ gradio
8
+ boto3