File size: 4,959 Bytes
22cfb6e
43a8cd8
 
 
 
d592f4d
43a8cd8
8838db8
43a8cd8
40167a9
 
 
 
 
e2d9bbf
ef56eef
 
e2d9bbf
ef56eef
 
 
 
40167a9
 
 
22cfb6e
43a8cd8
9cc7e25
 
43a8cd8
9cc7e25
 
790746b
b1f94d7
 
 
 
2fe908e
790746b
b1f94d7
 
6628b94
 
 
 
b1f94d7
 
790746b
b1f94d7
 
 
790746b
9cc7e25
43a8cd8
 
 
9cc7e25
43a8cd8
d592f4d
9cc7e25
d592f4d
8324d73
2cbda23
790746b
43a8cd8
 
 
 
790746b
 
 
 
 
 
 
bda7944
790746b
40167a9
790746b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43a8cd8
99cdb28
790746b
 
 
 
 
 
f980a2b
40167a9
43a8cd8
 
790746b
 
 
 
 
43a8cd8
9ccd468
43a8cd8
a4674f5
 
 
 
 
 
 
 
 
 
8324d73
43a8cd8
a097b7b
790746b
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
import gradio as gr
import copy
from llama_cpp import Llama
from huggingface_hub import hf_hub_download
import chromadb
from datasets import load_dataset
from sentence_transformers import SentenceTransformer

# Initialize the Llama model
llm = Llama(
    # model_path=hf_hub_download(
    #     repo_id="microsoft/Phi-3-mini-4k-instruct-gguf",
    #     filename="Phi-3-mini-4k-instruct-q4.gguf",
    # ),
    # model_path=hf_hub_download(
    #     repo_id="Ankitajadhav/Phi-3-mini-4k-instruct-q4.gguf",
    #     filename="Phi-3-mini-4k-instruct-q4.gguf",
    # ),
    model_path=hf_hub_download(
        repo_id="TheBloke/CapybaraHermes-2.5-Mistral-7B-GGUF",
        filename="capybarahermes-2.5-mistral-7b.Q2_K.gguf",
    ),
    n_ctx=2048,
    n_gpu_layers=50,  # Adjust based on your VRAM
)

# Initialize ChromaDB Vector Store
class VectorStore:
    def __init__(self, collection_name):
        self.embedding_model = SentenceTransformer('sentence-transformers/multi-qa-MiniLM-L6-cos-v1')
        self.chroma_client = chromadb.Client()
        self.collection = self.chroma_client.create_collection(name=collection_name)
    ## entire dataset
    # def populate_vectors(self, texts):
    #     embeddings = self.embedding_model.encode(texts, batch_size=32).tolist()
    #     for text, embedding in zip(texts, embeddings, ids):
    #         self.collection.add(embeddings=[embedding], documents=[text], ids=[doc_id])

    ## subsetting
    def populate_vectors(self, dataset):
        # Select the text columns to concatenate
        title = dataset['train']['title_cleaned'][:2000]  # Limiting to 2000 examples for the demo
        recipe = dataset['train']['recipe_new'][:2000]
        allergy = dataset['train']['allergy_type'][:2000]
        ingredients = dataset['train']['ingredients_alternatives'][:2000]

        # Concatenate the text from both columns
        texts = [f"{tit} {rep} {ingr} {alle}" for tit, rep, ingr,alle in zip(title, recipe, ingredients,allergy)]
        for i, item in enumerate(texts):
            embeddings = self.embedding_model.encode(item).tolist()
            self.collection.add(embeddings=[embeddings], documents=[item], ids=[str(i)])
    ## Method to populate the vector store with embeddings from a dataset
    def search_context(self, query, n_results=1):
        query_embedding = self.embedding_model.encode([query]).tolist()
        results = self.collection.query(query_embeddings=query_embedding, n_results=n_results)
        return results['documents']

# Example initialization (assuming you've already populated the vector store)
dataset = load_dataset('Thefoodprocessor/recipe_new_with_features_full')
vector_store = VectorStore("embedding_vector")
vector_store.populate_vectors(dataset)


def generate_text(message, max_tokens, temperature, top_p):
    # Retrieve context from vector store
    context_results = vector_store.search_context(message, n_results=1)
    context = context_results[0] if context_results else ""

    # Create the prompt template
    prompt_template = (
        f"SYSTEM: You are a recipe generating bot.\n"
        f"SYSTEM: {context}\n"
        f"USER: {message}\n"
        f"ASSISTANT:\n"
    )

    # Generate text using the language model
    output = llm(
            prompt_template,
            # max_new_tokens=256,
            temperature=0.3,
            top_p=0.95,
            top_k=40,
            repeat_penalty=1.1,
            max_tokens=600,
            # repetition_penalty=1.1
        )

    # Process the output
    input_string = output['choices'][0]['text'].strip()
    cleaned_text = input_string.strip("[]'").replace('\\n', '\n')
    continuous_text = '\n'.join(cleaned_text.split('\n'))
    return continuous_text

# Define the Gradio interface
demo = gr.Interface(
    fn=generate_text,
    inputs=[
        gr.Textbox(lines=2, placeholder="Enter your message here...", label="Message"),
    ],
    outputs=gr.Textbox(label="Generated Text"),
    title="Chatbot - Your Personal Culinary Advisor: Discover What to Cook Next!",
    description="Running LLM with context retrieval from ChromaDB",
    examples=[
        ["I have leftover rice, what can I make out of it?"],
        ["I just have some milk and chocolate, what dessert can I make?"],
        ["I am allergic to coconut milk, what can I use instead in a Thai curry?"],
        ["Can you suggest a vegan breakfast recipe?"],
        ["How do I make a perfect scrambled egg?"],
        ["Can you guide me through making a soufflé?"],
    ],
    cache_examples=False,
)
# Define a function to restart the interface
def restart_interface():
    # This function can include any logic needed to reset the app's state
    return gr.update()

# Add a custom button to restart the interface
with gr.Blocks() as app:
    with gr.Row():
        demo.render()
        gr.Button("Restart Space").click(fn=restart_interface, inputs=[], outputs=[demo])

if __name__ == "__main__":
    demo.launch()