udituen commited on
Commit
bb8424a
·
1 Parent(s): 03b759a

prompt engineering

Browse files
.github/workflows/ci.yml ADDED
@@ -0,0 +1 @@
 
 
1
+ # GitHub Actions CI workflow
.gitignore CHANGED
@@ -3,4 +3,4 @@ todo.txt
3
  /airflow
4
  .env
5
  /src/.streamlit/secrets.toml
6
- /vectorstore/
 
3
  /airflow
4
  .env
5
  /src/.streamlit/secrets.toml
6
+ /vectorstore
app/Dockerfile.api ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ FROM python:3.10
2
+ WORKDIR /app
3
+ COPY . /app
4
+ RUN pip install --no-cache-dir -r requirements.txt
5
+ CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]
app/main.py ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI
2
+ from langchain_community.vectorstores import FAISS
3
+ from langchain_community.embeddings import HuggingFaceEmbeddings
4
+ from langchain.chains import RetrievalQA
5
+ from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
6
+ from langchain_community.llms import HuggingFacePipeline
7
+
8
+ app = FastAPI()
9
+
10
+ vectorstore = FAISS.load_local(
11
+ "./vectorstore/",
12
+ embeddings=HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
13
+ )
14
+
15
+ tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-2-7b-chat-hf") # Or llama-3
16
+ model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-2-7b-chat-hf")
17
+ pipe = pipeline("text-generation", model=model, tokenizer=tokenizer, max_new_tokens=512)
18
+ llm = HuggingFacePipeline(pipeline=pipe)
19
+
20
+ retriever = vectorstore.as_retriever(search_kwargs={"k": 3})
21
+ rag_chain = RetrievalQA.from_chain_type(llm=llm, retriever=retriever, chain_type="stuff")
22
+
23
+ @app.get("/query/")
24
+ def query_rag(question: str):
25
+ return {"response": rag_chain.run(question)}
app/rag.py ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # source:https://python.langchain.com/api_reference/langchain/chains/langchain.chains.retrieval_qa.base.RetrievalQA.html
2
+
3
+ from langchain_community.embeddings import HuggingFaceEmbeddings
4
+ from langchain_community.vectorstores import FAISS
5
+ from langchain.prompts import ChatPromptTemplate
6
+ from langchain.chains import create_retrieval_chain
7
+ from langchain.chains.combine_documents import create_stuff_documents_chain
8
+ from langchain_community.llms import Ollama
9
+ from fastapi import FastAPI
10
+ import requests
11
+ from pydantic import BaseModel
12
+ from langchain.chains import create_retrieval_chain
13
+ from dotenv import load_dotenv
14
+ import os
15
+
16
+
17
+ load_dotenv()
18
+ token= os.getenv("TOKEN")
19
+ app = FastAPI()
20
+
21
+ class QueryInput(BaseModel):
22
+ query: str
23
+
24
+
25
+ # build the retrieval and augmented generator chain here
26
+
27
+ embeddings = HuggingFaceEmbeddings(model_name="all-MiniLM-L6-v2")
28
+ db = FAISS.load_local("./vectorstore/agriquery_faiss_index", embeddings, allow_dangerous_deserialization=True)
29
+ llm = Ollama(model="llama3", base_url="http://localhost:11434")
30
+
31
+ retriever = db.as_retriever()
32
+
33
+ system_prompt = (
34
+ "You are an agriultural research assistant."
35
+ "Use the given context to answer the question."
36
+ "If you don't know the answer, say you don't know."
37
+ "Context: {context}"
38
+ )
39
+
40
+ prompt = ChatPromptTemplate.from_messages(
41
+ [
42
+ ("system", system_prompt),
43
+ ("human", "{input}"),
44
+ ]
45
+ )
46
+
47
+ question_answer_chain = create_stuff_documents_chain(llm,prompt)
48
+ chain = create_retrieval_chain(retriever, question_answer_chain)
49
+
50
+
51
+ @app.post("/query")
52
+ async def query_handler(input: QueryInput):
53
+ result = chain.invoke({"input": input.query})
54
+ answer = result['answer'].replace("\\n", "\n").strip()
55
+
56
+ return {"answer": answer}
app/requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ fastapi
2
+ uvicorn
3
+ transformers
4
+ sentence-transformers
5
+ faiss-cpu
6
+ langchain
7
+ langchain_community
app/streamlit_app.py ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from langchain.chains import RetrievalQA
3
+ from langchain_community.llms import HuggingFacePipeline
4
+ from transformers import pipeline
5
+ from langchain_community.embeddings import HuggingFaceEmbeddings
6
+ from langchain_community.vectorstores import FAISS
7
+ from langchain.prompts import ChatPromptTemplate
8
+ from langchain.chains import create_retrieval_chain
9
+ from langchain.chains.combine_documents import create_stuff_documents_chain
10
+ from langchain_community.llms import Ollama
11
+ import os
12
+ import torch
13
+ from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
14
+
15
+
16
+ # ----------------------
17
+ system_prompt = (
18
+ "You are an agriultural research assistant."
19
+ "Use the given context to answer the question."
20
+ "If you don't know the answer, say you don't know."
21
+ "Context: {context}"
22
+ )
23
+
24
+ prompt = ChatPromptTemplate.from_messages(
25
+ [
26
+ ("system", system_prompt),
27
+ ("human", "{input}"),
28
+ ]
29
+ )
30
+
31
+ # Initialize embeddings & documents
32
+ @st.cache_resource
33
+ def load_retriever():
34
+ embeddings = HuggingFaceEmbeddings(model_name="all-MiniLM-L6-v2")
35
+ db = FAISS.load_local("./vectorstore/agriquery_faiss_index", embeddings, allow_dangerous_deserialization=True)
36
+ retriever = db.as_retriever()
37
+ return retriever
38
+
39
+ # Load a lightweight model via HuggingFace pipeline
40
+ @st.cache_resource
41
+ def load_llm():
42
+ # pipe = pipeline("text-generation", model="google/flan-t5-small", max_new_tokens=256)
43
+
44
+ # load the tokenizer and model on cpu/gpu
45
+ model_name = "meta-llama/Llama-2-7b-chat-hf"
46
+ tokenizer = AutoTokenizer.from_pretrained(model_name)
47
+ model = AutoModelForCausalLM.from_pretrained(model_name, torch_dtype=torch.float16, device_map="auto")
48
+ pipe = pipeline("text-generation", model=model, tokenizer=tokenizer, max_new_tokens=256)
49
+ return HuggingFacePipeline(pipeline=pipe)
50
+
51
+ # Setup RAG Chain
52
+ @st.cache_resource
53
+ def setup_qa():
54
+
55
+ retriever = load_retriever()
56
+ llm = load_llm()
57
+ question_answer_chain = create_stuff_documents_chain(llm,prompt)
58
+ chain = create_retrieval_chain(retriever, question_answer_chain)
59
+
60
+ # qa_chain = RetrievalQA.from_chain_type(llm=llm, retriever=retriever)
61
+ return chain
62
+
63
+
64
+ # Streamlit App UI
65
+ st.title("🌾 AgriQuery: RAG-Based Q&A Assistant")
66
+
67
+ query = st.text_input("Ask a question related to agriculture:")
68
+
69
+ if query:
70
+ qa = setup_qa()
71
+ with st.spinner("Thinking..."):
72
+ result = qa.invoke({"input": query})
73
+ st.success(result['answer'])
app/templates/index.html ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ <!DOCTYPE html>
3
+ <html lang="en">
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <title>AgriQuery</title>
7
+ </head>
8
+ <body>
9
+ <h1>AgriQuery</h1>
10
+ <form action="/query" method="get">
11
+ <label for="q">Enter your question:</label><br>
12
+ <input type="text" id="q" name="q" required><br><br>
13
+ <input type="submit" value="Ask">
14
+ </form>
15
+ </body>
16
+ </html>
archive/RAG.ipynb ADDED
The diff for this file is too large to render. See raw diff
 
docker-compose.yaml ADDED
@@ -0,0 +1,188 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ x-airflow-common:
2
+ &airflow-common
3
+ build:
4
+ context: ./airflow
5
+ dockerfile: Dockerfile.airflow
6
+ environment:
7
+ &airflow-common-env
8
+ AIRFLOW__CORE__EXECUTOR: LocalExecutor
9
+ AIRFLOW__CORE__AUTH_MANAGER: airflow.providers.fab.auth_manager.fab_auth_manager.FabAuthManager
10
+ AIRFLOW__DATABASE__SQL_ALCHEMY_CONN: postgresql+psycopg2://airflow:airflow@postgres/airflow
11
+ AIRFLOW__CORE__FERNET_KEY: ${AIRFLOW__CORE__FERNET_KEY} # needed for multiuser or production
12
+ AIRFLOW__API_AUTH__JWT_SECRET: ${JWT_SECRET}
13
+ AIRFLOW__WEBSERVER__SECRET_KEY: ${AIRFLOW__WEBSERVER__SECRET_KEY}
14
+ AIRFLOW__CORE__DAGS_ARE_PAUSED_AT_CREATION: 'true'
15
+ AIRFLOW__CORE__LOAD_EXAMPLES: 'false'
16
+ AIRFLOW__WEBSERVER__BASE_URL: http://localhost:8080
17
+ AIRFLOW__CORE__EXECUTION_API_SERVER_URL: 'http://airflow-apiserver:8080/execution/'
18
+ AIRFLOW__SCHEDULER__ENABLE_HEALTH_CHECK: 'true'
19
+ # _PIP_ADDITIONAL_REQUIREMENTS: ${_PIP_ADDITIONAL_REQUIREMENTS:-}
20
+ AIRFLOW_CONFIG: '/opt/airflow/config/airflow.cfg'
21
+ # MLFLOW_TRACKING_URI: 'http://mlflow:5000'
22
+
23
+ volumes:
24
+ - ${AIRFLOW_PROJ_DIR:-.}/airflow/dags:/opt/airflow/dags
25
+ - ${AIRFLOW_PROJ_DIR:-.}/airflow/logs:/opt/airflow/logs
26
+ - ${AIRFLOW_PROJ_DIR:-.}/airflow/config:/opt/airflow/config
27
+ - ${AIRFLOW_PROJ_DIR:-.}/airflow/plugins:/opt/airflow/plugins
28
+ - ${AIRFLOW_PROJ_DIR:-.}/data:/opt/airflow/data
29
+ - ${AIRFLOW_PROJ_DIR:-.}/scripts:/opt/airflow/scripts
30
+ - ${AIRFLOW_PROJ_DIR:-.}/model:/opt/airflow/model
31
+ - ${AIRFLOW_PROJ_DIR:-.}/app:/opt/airflow/app
32
+ user: "${AIRFLOW_UID:-50000}:0"
33
+ depends_on:
34
+ &airflow-common-depends-on
35
+ postgres:
36
+ condition: service_healthy
37
+
38
+ services:
39
+ postgres:
40
+ image: postgres:13
41
+ environment:
42
+ POSTGRES_USER: ${POSTGRES_USER} # using nginx would provide an added measure of security wnen in production
43
+ POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
44
+ POSTGRES_DB: airflow
45
+ volumes:
46
+ - postgres-db-volume:/var/lib/postgresql/data
47
+ healthcheck:
48
+ test: ["CMD", "pg_isready", "-U", "airflow"]
49
+ interval: 10s
50
+ retries: 5
51
+ start_period: 5s
52
+ restart: always
53
+
54
+ airflow-apiserver:
55
+ <<: *airflow-common
56
+ command: api-server
57
+ ports:
58
+ - "8080:8080"
59
+ healthcheck:
60
+ test: ["CMD", "curl", "--fail", "http://localhost:8080/api/v2/version"]
61
+ interval: 30s
62
+ timeout: 10s
63
+ retries: 5
64
+ start_period: 30s
65
+ restart: always
66
+ depends_on:
67
+ <<: *airflow-common-depends-on
68
+ airflow-init:
69
+ condition: service_completed_successfully
70
+
71
+ airflow-scheduler:
72
+ <<: *airflow-common
73
+ command: scheduler
74
+ healthcheck:
75
+ test: ["CMD", "curl", "--fail", "http://localhost:8974/health"]
76
+ interval: 30s
77
+ timeout: 60s
78
+ retries: 5
79
+ start_period: 30s
80
+ restart: always
81
+ depends_on:
82
+ airflow-init:
83
+ condition: service_completed_successfully
84
+
85
+ airflow-dag-processor:
86
+ <<: *airflow-common
87
+ command: dag-processor
88
+ healthcheck:
89
+ test: ["CMD-SHELL", 'airflow jobs check --job-type DagProcessorJob --hostname "$${HOSTNAME}"']
90
+ interval: 30s
91
+ timeout: 10s
92
+ retries: 5
93
+ start_period: 30s
94
+ restart: always
95
+ depends_on:
96
+ airflow-init:
97
+ condition: service_completed_successfully
98
+
99
+ airflow-triggerer:
100
+ <<: *airflow-common
101
+ command: triggerer
102
+ healthcheck:
103
+ test: ["CMD-SHELL", 'airflow jobs check --job-type TriggererJob --hostname "$${HOSTNAME}"']
104
+ interval: 40s
105
+ timeout: 10s
106
+ retries: 5
107
+ start_period: 40s
108
+ restart: always
109
+ depends_on:
110
+ airflow-init:
111
+ condition: service_completed_successfully
112
+
113
+ airflow-init:
114
+ <<: *airflow-common
115
+ entrypoint: /bin/bash
116
+ command:
117
+ - -c
118
+ - |
119
+ [[ -z "${AIRFLOW_UID}" ]] && export AIRFLOW_UID=$(id -u)
120
+ mkdir -p /opt/airflow/{logs,dags,plugins,config}
121
+ /entrypoint airflow config list >/dev/null
122
+ chown -R "${AIRFLOW_UID}:0" /opt/airflow
123
+ ls -la /opt/airflow/{logs,dags,plugins,config}
124
+ environment:
125
+ <<: *airflow-common-env
126
+ _AIRFLOW_DB_MIGRATE: 'true'
127
+ _AIRFLOW_WWW_USER_CREATE: 'true'
128
+ _AIRFLOW_WWW_USER_USERNAME: ${AIRFLOW_WWW_USER_USERNAME}
129
+ _AIRFLOW_WWW_USER_PASSWORD: ${AIRFLOW_WWW_USER_PASSWORD}
130
+ # _PIP_ADDITIONAL_REQUIREMENTS: ${_PIP_ADDITIONAL_REQUIREMENTS}
131
+ user: "0:0"
132
+
133
+ airflow-cli:
134
+ <<: *airflow-common
135
+ profiles: [debug]
136
+ command:
137
+ - bash
138
+ - -c
139
+ - airflow
140
+ environment:
141
+ <<: *airflow-common-env
142
+ CONNECTION_CHECK_MAX_COUNT: "0"
143
+ depends_on:
144
+ postgres:
145
+ condition: service_healthy
146
+
147
+ rag-api:
148
+ build: ./app
149
+ ports:
150
+ - "8000:8000"
151
+ volumes:
152
+ - ./vectorstore:/app/vectorstore
153
+
154
+ # streamlit:
155
+ # container_name: streamlit_app
156
+ # build:
157
+ # context: ./app
158
+ # dockerfile: Dockerfile.streamlit
159
+ # volumes:
160
+ # - ./app:/app
161
+ # - ./data:/data
162
+ # - ./script:/script
163
+ # working_dir: /app
164
+ # ports:
165
+ # - "127.0.0.1:8501:8501"
166
+
167
+ # mlflow:
168
+ # build:
169
+ # context: ./mlflow
170
+ # dockerfile: Dockerfile.mlflow
171
+ # ports:
172
+ # - "127.0.0.1:5000:5000"
173
+
174
+ # Optional nginx reverse proxy for shared/internal environments
175
+ # nginx:
176
+ # image: nginx:alpine
177
+ # ports:
178
+ # - "80:80"
179
+ # volumes:
180
+ # - ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
181
+ # - ./nginx/htpasswd:/etc/nginx/.htpasswd:ro
182
+ # depends_on:
183
+ # - airflow-apiserver
184
+ # - mlflow
185
+ # - streamlit
186
+
187
+ volumes:
188
+ postgres-db-volume:
notebooks/exploration.ipynb ADDED
File without changes
src/config.py ADDED
File without changes
src/dependencies.py ADDED
File without changes
src/main.py ADDED
File without changes
vectorstore/agriquery_faiss_index/index.faiss DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:4e423526ab5496cb63337855267b62e4218d9a140d4c8ed99c492f9af0a9aba3
3
- size 6743085
 
 
 
 
vectorstore/agriquery_faiss_index/index.pkl DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:28b483608516c5f1f4f4d101b4bb47194c5de0d19eb9853421dfc6e10374a7f9
3
- size 1527481