muhyousf commited on
Commit
2d3f26f
·
1 Parent(s): aa226bb

Add application file

Browse files
Files changed (3) hide show
  1. app.py +46 -0
  2. build_embeddings.py +31 -0
  3. requirements.txt +5 -0
app.py ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # app.py
2
+ import pickle, faiss, numpy as np
3
+ from sentence_transformers import SentenceTransformer
4
+ from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
5
+ import gradio as gr
6
+
7
+ # Load embeddings + index
8
+ with open("faiss_index.pkl","rb") as f:
9
+ obj = pickle.load(f)
10
+ index = obj["index"]
11
+ texts = obj["texts"]
12
+ metas = obj["metas"]
13
+
14
+ embedder = SentenceTransformer("sentence-transformers/all-MiniLM-L6-v2")
15
+
16
+ # Generator model (small/flan)
17
+ TOKENIZER_MODEL = "google/flan-t5-small"
18
+ tokenizer = AutoTokenizer.from_pretrained(TOKENIZER_MODEL)
19
+ model = AutoModelForSeq2SeqLM.from_pretrained(TOKENIZER_MODEL)
20
+
21
+ def retrieve(query, k=4):
22
+ q = embedder.encode([query], convert_to_numpy=True)
23
+ faiss.normalize_L2(q)
24
+ D, I = index.search(q, k)
25
+ results = []
26
+ for idx in I[0]:
27
+ results.append(texts[idx])
28
+ return results
29
+
30
+ def generate_answer(query):
31
+ contexts = retrieve(query, k=4)
32
+ prompt = "Use the following context to answer the question.\n\nContext:\n" + "\n\n".join(contexts) + "\n\nQuestion: " + query + "\nAnswer:"
33
+ inputs = tokenizer(prompt, return_tensors="pt", truncation=True, max_length=1024)
34
+ out = model.generate(**inputs, max_length=256)
35
+ ans = tokenizer.decode(out[0], skip_special_tokens=True)
36
+ return ans
37
+
38
+ with gr.Blocks() as demo:
39
+ gr.Markdown("# RAG FAQ Bot")
40
+ txt = gr.Textbox(lines=2, placeholder="Type question...")
41
+ btn = gr.Button("Ask")
42
+ out = gr.Textbox(lines=8)
43
+ btn.click(fn=lambda q: generate_answer(q), inputs=txt, outputs=out)
44
+
45
+ if __name__ == "__main__":
46
+ demo.launch()
build_embeddings.py ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # build_embeddings.py
2
+ from sentence_transformers import SentenceTransformer
3
+ import os
4
+ import faiss
5
+ import pickle
6
+
7
+ EMB_MODEL = "sentence-transformers/all-MiniLM-L6-v2"
8
+ embedder = SentenceTransformer(EMB_MODEL)
9
+
10
+ docs_dir = "docs"
11
+ texts = []
12
+ metas = []
13
+ for fn in os.listdir(docs_dir):
14
+ if fn.endswith(".txt"):
15
+ txt = open(os.path.join(docs_dir, fn), encoding="utf-8").read()
16
+ # simple split by paragraph
17
+ chunks = [p.strip() for p in txt.split("\n\n") if p.strip()]
18
+ for i,c in enumerate(chunks):
19
+ texts.append(c)
20
+ metas.append({"source": fn, "chunk": i})
21
+
22
+ embs = embedder.encode(texts, show_progress_bar=True, convert_to_numpy=True)
23
+ d = embs.shape[1]
24
+ index = faiss.IndexFlatIP(d)
25
+ # normalize for cosine
26
+ import numpy as np
27
+ faiss.normalize_L2(embs)
28
+ index.add(embs)
29
+ with open("faiss_index.pkl", "wb") as f:
30
+ pickle.dump({"index": index, "texts": texts, "metas": metas}, f)
31
+ print("built faiss_index.pkl")
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ gradio
2
+ transformers
3
+ sentence-transformers
4
+ faiss-cpu
5
+ torch