Commit ·
9c050cb
1
Parent(s): 33e0507
refactor: modernize data ingestion, update LLM pipeline implementation, and improve Qdrant configuration handling
Browse files
app.py
CHANGED
|
@@ -1,52 +1,47 @@
|
|
| 1 |
-
import gradio as gr
|
| 2 |
-
import json
|
| 3 |
import os
|
|
|
|
|
|
|
|
|
|
| 4 |
|
| 5 |
from qdrant_client import QdrantClient
|
| 6 |
-
from qdrant_client import models
|
| 7 |
-
|
| 8 |
from langchain_qdrant import QdrantVectorStore
|
| 9 |
from langchain_huggingface import HuggingFaceEmbeddings
|
| 10 |
|
| 11 |
-
from transformers import pipeline
|
| 12 |
-
|
| 13 |
|
| 14 |
-
# ---------------------------
|
| 15 |
-
# Load data
|
| 16 |
-
# ---------------------------
|
| 17 |
-
def load_files():
|
| 18 |
-
with open("policies.json", "r", encoding="utf-8") as f:
|
| 19 |
-
policies = json.load(f)
|
| 20 |
|
| 21 |
-
|
| 22 |
-
|
|
|
|
|
|
|
| 23 |
|
| 24 |
-
|
|
|
|
| 25 |
|
| 26 |
|
| 27 |
-
#
|
| 28 |
-
#
|
| 29 |
-
#
|
| 30 |
embeddings = HuggingFaceEmbeddings(
|
| 31 |
model_name="sentence-transformers/all-MiniLM-L6-v2"
|
| 32 |
)
|
| 33 |
|
| 34 |
|
| 35 |
-
#
|
| 36 |
-
#
|
| 37 |
-
#
|
| 38 |
client = QdrantClient(
|
| 39 |
-
url=
|
| 40 |
-
api_key=
|
| 41 |
)
|
| 42 |
|
| 43 |
-
collection_name = "playmobil"
|
| 44 |
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
if not client.collection_exists(collection_name):
|
| 48 |
client.create_collection(
|
| 49 |
-
collection_name=
|
| 50 |
vectors_config=models.VectorParams(
|
| 51 |
size=384,
|
| 52 |
distance=models.Distance.COSINE
|
|
@@ -54,22 +49,52 @@ if not client.collection_exists(collection_name):
|
|
| 54 |
)
|
| 55 |
|
| 56 |
|
| 57 |
-
# ---------------------------
|
| 58 |
-
# Vector DB
|
| 59 |
-
# ---------------------------
|
| 60 |
db = QdrantVectorStore(
|
| 61 |
client=client,
|
| 62 |
-
collection_name=
|
| 63 |
embedding=embeddings
|
| 64 |
)
|
| 65 |
|
| 66 |
|
| 67 |
-
#
|
| 68 |
-
#
|
| 69 |
-
#
|
| 70 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 71 |
"text2text-generation",
|
| 72 |
-
model=
|
|
|
|
|
|
|
| 73 |
)
|
| 74 |
|
| 75 |
|
|
@@ -83,55 +108,28 @@ Context:
|
|
| 83 |
Question:
|
| 84 |
{question}
|
| 85 |
|
| 86 |
-
Answer:
|
| 87 |
"""
|
| 88 |
-
result = llm(prompt, max_new_tokens=200)
|
| 89 |
-
return result[0]["generated_text"]
|
| 90 |
|
|
|
|
|
|
|
| 91 |
|
| 92 |
-
# ---------------------------
|
| 93 |
-
# Ingest data
|
| 94 |
-
# ---------------------------
|
| 95 |
-
def ingest_to_qdrant():
|
| 96 |
-
policies, products = load_files()
|
| 97 |
-
all_items = policies + products
|
| 98 |
-
|
| 99 |
-
texts = []
|
| 100 |
-
ids = []
|
| 101 |
-
metadatas = []
|
| 102 |
-
|
| 103 |
-
for item in all_items:
|
| 104 |
-
texts.append(item["text"])
|
| 105 |
-
ids.append(item["id"])
|
| 106 |
-
metadatas.append(
|
| 107 |
-
{"type": "policy" if "policy" in item["id"] else "product"}
|
| 108 |
-
)
|
| 109 |
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
metadatas=metadatas
|
| 114 |
-
)
|
| 115 |
-
|
| 116 |
-
return f"Inserted {len(texts)} items into Qdrant"
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
# ---------------------------
|
| 120 |
-
# Chat function
|
| 121 |
-
# ---------------------------
|
| 122 |
def chat(question):
|
| 123 |
docs = db.similarity_search(question, k=3)
|
| 124 |
-
|
| 125 |
context = "\n".join([d.page_content for d in docs])
|
| 126 |
|
| 127 |
return call_llm(context, question)
|
| 128 |
|
| 129 |
|
| 130 |
-
#
|
| 131 |
-
# UI
|
| 132 |
-
#
|
| 133 |
with gr.Blocks() as demo:
|
| 134 |
-
gr.Markdown("#
|
| 135 |
|
| 136 |
question = gr.Textbox(label="Ask a question")
|
| 137 |
answer = gr.Textbox(label="Answer")
|
|
|
|
|
|
|
|
|
|
| 1 |
import os
|
| 2 |
+
import json
|
| 3 |
+
import gradio as gr
|
| 4 |
+
import requests
|
| 5 |
|
| 6 |
from qdrant_client import QdrantClient
|
| 7 |
+
from qdrant_client.http import models
|
|
|
|
| 8 |
from langchain_qdrant import QdrantVectorStore
|
| 9 |
from langchain_huggingface import HuggingFaceEmbeddings
|
| 10 |
|
| 11 |
+
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM, pipeline
|
| 12 |
+
import torch
|
| 13 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
|
| 15 |
+
# =====================
|
| 16 |
+
# CONFIG
|
| 17 |
+
# =====================
|
| 18 |
+
COLLECTION_NAME = "playmobil"
|
| 19 |
|
| 20 |
+
QDRANT_URL = os.environ["QDRANT_URL"]
|
| 21 |
+
QDRANT_API_KEY = os.environ["QDRANT_API_KEY"]
|
| 22 |
|
| 23 |
|
| 24 |
+
# =====================
|
| 25 |
+
# EMBEDDINGS
|
| 26 |
+
# =====================
|
| 27 |
embeddings = HuggingFaceEmbeddings(
|
| 28 |
model_name="sentence-transformers/all-MiniLM-L6-v2"
|
| 29 |
)
|
| 30 |
|
| 31 |
|
| 32 |
+
# =====================
|
| 33 |
+
# QDRANT CLIENT
|
| 34 |
+
# =====================
|
| 35 |
client = QdrantClient(
|
| 36 |
+
url=QDRANT_URL,
|
| 37 |
+
api_key=QDRANT_API_KEY
|
| 38 |
)
|
| 39 |
|
|
|
|
| 40 |
|
| 41 |
+
# create collection safely (FIX for your 404)
|
| 42 |
+
if not client.collection_exists(COLLECTION_NAME):
|
|
|
|
| 43 |
client.create_collection(
|
| 44 |
+
collection_name=COLLECTION_NAME,
|
| 45 |
vectors_config=models.VectorParams(
|
| 46 |
size=384,
|
| 47 |
distance=models.Distance.COSINE
|
|
|
|
| 49 |
)
|
| 50 |
|
| 51 |
|
|
|
|
|
|
|
|
|
|
| 52 |
db = QdrantVectorStore(
|
| 53 |
client=client,
|
| 54 |
+
collection_name=COLLECTION_NAME,
|
| 55 |
embedding=embeddings
|
| 56 |
)
|
| 57 |
|
| 58 |
|
| 59 |
+
# =====================
|
| 60 |
+
# LOAD DATA
|
| 61 |
+
# =====================
|
| 62 |
+
def load_files():
|
| 63 |
+
with open("policies.json", "r", encoding="utf-8") as f:
|
| 64 |
+
policies = json.load(f)
|
| 65 |
+
|
| 66 |
+
with open("products.json", "r", encoding="utf-8") as f:
|
| 67 |
+
products = json.load(f)
|
| 68 |
+
|
| 69 |
+
return policies, products
|
| 70 |
+
|
| 71 |
+
|
| 72 |
+
def ingest_to_qdrant():
|
| 73 |
+
policies, products = load_files()
|
| 74 |
+
all_items = policies + products
|
| 75 |
+
|
| 76 |
+
texts = [item["text"] for item in all_items]
|
| 77 |
+
ids = [item["id"] for item in all_items]
|
| 78 |
+
|
| 79 |
+
db.add_texts(texts=texts, ids=ids)
|
| 80 |
+
|
| 81 |
+
return f"Ingested {len(texts)} items successfully"
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
# =====================
|
| 85 |
+
# LLM (FIXED - no HF API)
|
| 86 |
+
# =====================
|
| 87 |
+
|
| 88 |
+
model_name = "google/flan-t5-base"
|
| 89 |
+
|
| 90 |
+
tokenizer = AutoTokenizer.from_pretrained(model_name)
|
| 91 |
+
model = AutoModelForSeq2SeqLM.from_pretrained(model_name)
|
| 92 |
+
|
| 93 |
+
llm_pipe = pipeline(
|
| 94 |
"text2text-generation",
|
| 95 |
+
model=model,
|
| 96 |
+
tokenizer=tokenizer,
|
| 97 |
+
device=0 if torch.cuda.is_available() else -1
|
| 98 |
)
|
| 99 |
|
| 100 |
|
|
|
|
| 108 |
Question:
|
| 109 |
{question}
|
| 110 |
|
| 111 |
+
Answer clearly and briefly:
|
| 112 |
"""
|
|
|
|
|
|
|
| 113 |
|
| 114 |
+
result = llm_pipe(prompt, max_new_tokens=200)[0]["generated_text"]
|
| 115 |
+
return result
|
| 116 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 117 |
|
| 118 |
+
# =====================
|
| 119 |
+
# RAG CHAT
|
| 120 |
+
# =====================
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 121 |
def chat(question):
|
| 122 |
docs = db.similarity_search(question, k=3)
|
|
|
|
| 123 |
context = "\n".join([d.page_content for d in docs])
|
| 124 |
|
| 125 |
return call_llm(context, question)
|
| 126 |
|
| 127 |
|
| 128 |
+
# =====================
|
| 129 |
+
# UI
|
| 130 |
+
# =====================
|
| 131 |
with gr.Blocks() as demo:
|
| 132 |
+
gr.Markdown("# Playmobil RAG Assistant")
|
| 133 |
|
| 134 |
question = gr.Textbox(label="Ask a question")
|
| 135 |
answer = gr.Textbox(label="Answer")
|