Spaces:
Sleeping
Sleeping
Recommender basics
Browse files- app.py +57 -4
- requirements.txt +5 -1
app.py
CHANGED
@@ -1,7 +1,60 @@
|
|
1 |
import gradio as gr
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
-
|
4 |
-
|
|
|
|
|
5 |
|
6 |
-
|
7 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import gradio as gr
|
2 |
+
from pinecone import Pinecone
|
3 |
+
import torch
|
4 |
+
from transformers import AutoTokenizer, AutoModel
|
5 |
+
import pandas as pd
|
6 |
+
import os
|
7 |
+
import openai
|
8 |
+
import textwrap
|
9 |
|
10 |
+
MODEL_NAME = 'sentence-transformers/all-MiniLM-L6-v2'
|
11 |
+
INDEX_NAME = 'charity-assistant'
|
12 |
+
tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
|
13 |
+
model = AutoModel.from_pretrained(MODEL_NAME)
|
14 |
|
15 |
+
def text_to_embedding(text):
|
16 |
+
inputs = tokenizer(text, padding=True, truncation=True, return_tensors="pt")
|
17 |
+
with torch.no_grad():
|
18 |
+
outputs = model(**inputs)
|
19 |
+
embeddings = outputs.last_hidden_state.mean(dim=1).numpy()
|
20 |
+
return embeddings.flatten().tolist()
|
21 |
+
|
22 |
+
def find_similar_media(query_text, top_k=1):
|
23 |
+
query_embedding = text_to_embedding(query_text)
|
24 |
+
results = index.query(vector=query_embedding, top_k=top_k, include_metadata=True)
|
25 |
+
matches=results['matches']
|
26 |
+
resultsdf=pd.DataFrame({'album':[m['id'] for m in matches],\
|
27 |
+
'artist':[m['metadata']['artist'] for m in matches],\
|
28 |
+
'score':[m['score'] for m in matches],\
|
29 |
+
'description':[m['metadata']['description'] for m in matches]})
|
30 |
+
return resultsdf
|
31 |
+
|
32 |
+
def motivate_recommendation(album, artist, description, query_text):
|
33 |
+
prompt = (f"Based on the description: '{description}', explain why \"{album}\" by \"{artist}\" "
|
34 |
+
f"matches the query: '{query_text}'.")
|
35 |
+
|
36 |
+
response = openai.ChatCompletion.create(
|
37 |
+
model="gpt-4", #
|
38 |
+
messages=[
|
39 |
+
{"role": "system", "content": "You are helping to recommend music albums based on their description."},
|
40 |
+
{"role": "user", "content": prompt}
|
41 |
+
]
|
42 |
+
)
|
43 |
+
|
44 |
+
explanation = response.choices[0].message['content'].strip()
|
45 |
+
clean_explanation = explanation.replace('\'', '"').replace('\"', '"')
|
46 |
+
wrapped_explanation = textwrap.fill(clean_explanation, width=70)
|
47 |
+
recommendation = (f"May I suggest \"{album}\" by \"{artist}\"? It matches what you were "
|
48 |
+
f"looking for because {wrapped_explanation}")
|
49 |
+
return textwrap.fill(recommendation, width=70)
|
50 |
+
|
51 |
+
def recommend(user_query: str) -> str:
|
52 |
+
most_similar = find_similar_media(user_query).loc[0]
|
53 |
+
motivation=motivate_recommendation(most_similar.album, most_similar.artist, most_similar.description, user_query).replace("\n"," ")
|
54 |
+
return motivation
|
55 |
+
|
56 |
+
pc=Pinecone()
|
57 |
+
index = pc.Index(INDEX_NAME)
|
58 |
+
openai.api_key = os.environ['OPENAI_API_KEY']
|
59 |
+
recommender = gr.Interface(fn=recommend, inputs="text", outputs="text")
|
60 |
+
recommender.launch()
|
requirements.txt
CHANGED
@@ -1 +1,5 @@
|
|
1 |
-
gradio
|
|
|
|
|
|
|
|
|
|
1 |
+
gradio
|
2 |
+
pinecone-client
|
3 |
+
torch
|
4 |
+
transformers
|
5 |
+
openai==0.28
|