|
|
from huggingface_hub import InferenceClient |
|
|
|
|
|
|
|
|
from sentence_transformers import SentenceTransformer |
|
|
import torch |
|
|
import gradio as gr |
|
|
import random |
|
|
|
|
|
client=InferenceClient("mistralai/Mistral-7B-Instruct-v0.2") |
|
|
|
|
|
|
|
|
|
|
|
with open("recipes.txt", "r", encoding="utf-8") as file: |
|
|
|
|
|
recipes_text = file.read() |
|
|
|
|
|
|
|
|
print(recipes_text) |
|
|
|
|
|
|
|
|
def preprocess_text(text): |
|
|
|
|
|
cleaned_text = text.strip() |
|
|
|
|
|
|
|
|
chunks = cleaned_text.split("[END]") |
|
|
|
|
|
|
|
|
cleaned_chunks = [] |
|
|
|
|
|
|
|
|
for chunk in chunks: |
|
|
clean = chunk.strip() |
|
|
|
|
|
if len(chunk)>0: |
|
|
cleaned_chunks.append(clean) |
|
|
|
|
|
|
|
|
print(cleaned_chunks) |
|
|
|
|
|
|
|
|
print(len(cleaned_chunks)) |
|
|
|
|
|
|
|
|
return cleaned_chunks |
|
|
|
|
|
|
|
|
cleaned_chunks = preprocess_text(recipes_text) |
|
|
|
|
|
|
|
|
|
|
|
model = SentenceTransformer('all-MiniLM-L6-v2') |
|
|
|
|
|
def create_embeddings(text_chunks): |
|
|
|
|
|
chunk_embeddings = model.encode(text_chunks, convert_to_tensor=True) |
|
|
|
|
|
|
|
|
print(chunk_embeddings) |
|
|
|
|
|
|
|
|
print(chunk_embeddings.shape) |
|
|
|
|
|
|
|
|
return chunk_embeddings |
|
|
|
|
|
|
|
|
chunk_embeddings = create_embeddings(cleaned_chunks) |
|
|
|
|
|
|
|
|
|
|
|
def get_top_chunks(query, chunk_embeddings, text_chunks): |
|
|
|
|
|
query_embedding = model.encode(query,convert_to_tensor=True) |
|
|
|
|
|
|
|
|
query_embedding_normalized = query_embedding / query_embedding.norm() |
|
|
|
|
|
|
|
|
chunk_embeddings_normalized = chunk_embeddings / chunk_embeddings.norm(dim=1, keepdim=True) |
|
|
|
|
|
|
|
|
similarities = torch.matmul(chunk_embeddings_normalized,query_embedding_normalized) |
|
|
|
|
|
|
|
|
print(similarities) |
|
|
|
|
|
|
|
|
top_indices = torch.topk(similarities, k=1).indices |
|
|
|
|
|
|
|
|
print(top_indices) |
|
|
|
|
|
|
|
|
top_chunks = [] |
|
|
|
|
|
|
|
|
for i in top_indices: |
|
|
top_chunks.append(text_chunks[i]) |
|
|
print(top_chunks) |
|
|
|
|
|
|
|
|
return top_chunks |
|
|
|
|
|
def respond(message, selected_options, history,): |
|
|
response = "" |
|
|
best_recipes_chunk = get_top_chunks(message, chunk_embeddings, cleaned_chunks) |
|
|
print(best_recipes_chunk) |
|
|
|
|
|
str_recipes_chunk = "\n".join([str(chunk) for chunk in best_recipes_chunk]) |
|
|
print("RECIPES!!!!!!: " + str_recipes_chunk) |
|
|
|
|
|
|
|
|
messages = [ |
|
|
{ |
|
|
"role": "system", |
|
|
"content": ( |
|
|
"You are a helpful recipe assistant. You are only allowed to use the recipes listed below." |
|
|
f"Available Recipes:\n\n{str_recipes_chunk}\n\n(Use ONLY these to answer)" |
|
|
"You must NOT invent or guess any new recipes or ingredients. " |
|
|
"Don't format the recipe as it is in the available recipes. Format your response like this:" |
|
|
"Here is a recipe that matches your needs: [recipe name]. It is [cuisine] cuisine. You can enjoy it for [time of day]. Its main ingredients are [core ingredients]. It fits a [dietary restriction] diet. This dish is [description]. To prepare it: [steps]" |
|
|
"Switch up the format a bit to make sure the responses are varied. Make sure you use proper grammar and don't have random capitals." |
|
|
"If the user’s question doesn’t match any of the recipes exactly or semantically, politely say: " |
|
|
"‘Sorry, I couldn’t find a match. Can you rephrase or ask about another dish?’" |
|
|
) |
|
|
}, |
|
|
{ |
|
|
"role": "user", |
|
|
"content": message |
|
|
}] |
|
|
|
|
|
|
|
|
if history: |
|
|
messages.extend(history) |
|
|
|
|
|
messages.append({"role":"user","content": message}) |
|
|
|
|
|
|
|
|
|
|
|
response = client.chat_completion(messages, max_tokens = 700, temperature = 0.2, top_p = 0.3) |
|
|
|
|
|
|
|
|
return response['choices'][0]['message']['content'].strip() |
|
|
|
|
|
def vote(data: gr.LikeData): |
|
|
if data.liked: |
|
|
print("You upvoted this response: " + data.value["value"]) |
|
|
else: |
|
|
print("You downvoted this response: " + data.value["value"]) |
|
|
with gr.Blocks() as demo: |
|
|
chatbot = gr.Chatbot(label="NutriAssist") |
|
|
chatbot.like(vote, None, None) |
|
|
with gr.Row(): |
|
|
msg = gr.Textbox(placeholder="Ask about an item (e.g., banana peel)", label="Your Question") |
|
|
checkboxes = gr.CheckboxGroup( |
|
|
choices=["Show fun facts", "Explain why", "Summarize rules"], |
|
|
label="Customize your response", |
|
|
) |
|
|
|
|
|
send_btn = gr.Button("Send") |
|
|
history_state = gr.State([]) |
|
|
send_btn.click( |
|
|
fn=respond, |
|
|
inputs=[msg, checkboxes, history_state], |
|
|
outputs=[chatbot] |
|
|
) |
|
|
demo.launch() |
|
|
|
|
|
|