Spaces:
Paused
Paused
File size: 5,195 Bytes
69381c2 86346c3 69381c2 0daa9f6 69381c2 e10ade5 72ccb9c 11e087c fe3da63 69381c2 d54c8f8 69381c2 439e701 0daa9f6 e020321 69381c2 0daa9f6 69381c2 0daa9f6 69381c2 0daa9f6 69381c2 0daa9f6 69381c2 0daa9f6 69381c2 0daa9f6 69381c2 ed4a13f 69381c2 d54c8f8 69381c2 a8813ea 69381c2 86346c3 733b482 e020321 733b482 44cc3dd 65f492b 733b482 a8813ea 733b482 b4f99ee 733b482 69381c2 6a636b6 69381c2 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
import os
import json
import numpy as np
import faiss
from flask import Flask, request, jsonify, send_file
from transformers import LlamaTokenizer, LlamaModel
import torch
from tqdm import tqdm
# Load tokenizer and model (global for both embedding generation and API)
model_name = "openlm-research/open_llama_3b_v2"
tokenizer = LlamaTokenizer.from_pretrained(model_name)
model = LlamaModel.from_pretrained(model_name)
# Set the pad_token to eos_token
tokenizer.pad_token = tokenizer.eos_token
# model.eval()
device = "cuda" if torch.cuda.is_available() else "cpu"
model = model.to(device)
app = Flask(__name__)
file_path = "products.json"
# Function to generate embeddings
def generate_embeddings(batch_size=64, max_length=512):
# Load product data
with open(file_path, "r") as f:
products = json.load(f)
# Initialize storage for embeddings
embeddings = []
product_ids = []
# Process products in batches
num_batches = len(products) // batch_size + (len(products) % batch_size > 0)
for i in tqdm(range(num_batches), desc="Generating embeddings"):
batch = products[i * batch_size : (i + 1) * batch_size]
descriptions = [product["description"] for product in batch]
ids = [product["id"] for product in batch]
# Tokenize and move inputs to the device
inputs = tokenizer(
descriptions, return_tensors="pt", padding=True, truncation=True, max_length=max_length
).to(device)
# Generate embeddings
with torch.no_grad():
outputs = model(**inputs, output_hidden_states=True)
batch_embeddings = outputs.hidden_states[-1].mean(dim=1).cpu().numpy()
# Append results
embeddings.extend(batch_embeddings)
product_ids.extend(ids)
# Convert embeddings to NumPy array
embeddings = np.array(embeddings)
product_ids = np.array(product_ids)
# Save embeddings to FAISS index
dimension = embeddings.shape[1] # Embedding size
index = faiss.IndexFlatL2(dimension)
index.add(embeddings)
faiss.write_index(index, "product_index.faiss")
np.save("product_ids.npy", product_ids)
print(f"Embeddings for {len(product_ids)} products generated successfully!")
return f"Embeddings for {len(product_ids)} products generated successfully!"
@app.route("/", methods=["GET"])
def home():
return "Flask app is running!"
# API Endpoint to Trigger Embedding Generation
@app.route("/generate_embeddings", methods=["POST"])
def trigger_embedding_generation():
print("creating embeddings")
generate_embeddings()
return jsonify({"message": "Embeddings generated successfully!"})
# API Endpoint to Get Similar Products
@app.route("/similar", methods=["POST"])
def get_similar_products():
print("finding right product")
index = faiss.read_index("product_index.faiss")
product_ids = np.load("product_ids.npy")
with open(file_path, "r") as f:
products = {p["id"]: p for p in json.load(f)}
data = request.json
product_id = data.get("product_id")
product_index = np.where(product_ids == product_id)[0]
if len(product_index) == 0:
return jsonify({"error": "Product ID not found"}), 404
query_embedding = index.reconstruct(int(product_index[0]))
distances, indices = index.search(np.expand_dims(query_embedding, axis=0), k=5)
similar_ids = product_ids[indices[0]].tolist()
similar_products = [products[pid] for pid in similar_ids if pid != product_id]
return jsonify({"similar_products": similar_products})
@app.route("/download/<filename>", methods=["GET"])
def download_file(filename):
try:
# Validate allowed files
if filename not in ["product_index.faiss", "product_ids.npy"]:
return {"error": "File not found or not allowed"}, 404
# Serve the file for download
return send_file(filename, as_attachment=True)
except Exception as e:
return {"error": str(e)}, 500
def get_similar_produdcts_direct(product_id):
print("finding right product")
index = faiss.read_index("product_index.faiss")
product_ids = np.load("product_ids.npy")
with open(file_path, "r") as f:
products = {p["id"]: p for p in json.load(f)}
# print(products[:6])
print(len(products))
print(product_id)
product_index = np.where(product_ids == product_id)[0]
if len(product_index) == 0:
return jsonify({"error": "Product ID not found"}), 404
query_embedding = index.reconstruct(int(product_index[0]))
distances, indices = index.search(np.expand_dims(query_embedding, axis=0), k=5)
similar_ids = product_ids[indices[0]].tolist()
similar_products = [products[pid] for pid in similar_ids if pid != product_id]
print("Ran fine")
print(similar_products)
# return jsonify({"similar_products": similar_products})
if __name__ == "__main__":
# Check if embeddings already exist; if not, generate them
if not os.path.exists("product_index.faiss") or not os.path.exists("product_ids.npy"):
generate_embeddings()
# get_similar_produdcts_direct(2)
app.run(host="0.0.0.0", port=7860)
|