Nofarsagi123 commited on
Commit
6d2260c
·
verified ·
1 Parent(s): 4ceaaa9

Upload 3 files

Browse files
Files changed (4) hide show
  1. .gitattributes +1 -0
  2. app (2).py +199 -0
  3. recipe_index.faiss +3 -0
  4. requirements (2).txt +8 -0
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ recipe_index.faiss filter=lfs diff=lfs merge=lfs -text
app (2).py ADDED
@@ -0,0 +1,199 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from datasets import load_dataset
3
+ from sentence_transformers import SentenceTransformer
4
+ import faiss
5
+ import numpy as np
6
+ from transformers import pipeline
7
+ import time
8
+
9
+ # --- 1. DATA LOADING AND PREPROCESSING (FINAL FIX) ---
10
+ print("===== Application Startup =====")
11
+ start_time = time.time()
12
+
13
+ # Load dataset and limit to the first 20,000 rows
14
+ dataset = load_dataset("corbt/all-recipes", split="train[:20000]")
15
+
16
+ # Preprocessing functions to extract features from the raw text
17
+ def extract_title_and_ingredients(sample):
18
+ extraction = sample['input'][:sample['input'].find("Directions")]
19
+ return {"text_for_embedding": extraction}
20
+
21
+ def extract_each_feature(sample):
22
+ """
23
+ FIXED: More robustly extracts recipe features and cleans duplicated content.
24
+ """
25
+ full_text = sample['input']
26
+
27
+ # Extract Title
28
+ title = full_text[:full_text.find("\\n")]
29
+
30
+ # Extract Ingredients
31
+ ingredients = "Not available"
32
+ if "Ingredients:" in full_text:
33
+ start_ing = full_text.find("Ingredients:") + len("Ingredients:")
34
+ end_ing = full_text.find("Directions:")
35
+ if end_ing > start_ing:
36
+ ingredients = full_text[start_ing:end_ing].strip()
37
+
38
+ # Extract and clean Directions
39
+ directions = "Not available"
40
+ if "Directions:" in full_text:
41
+ start_dir = full_text.find("Directions:") + len("Directions:")
42
+ # Take the text after the first "Directions:"
43
+ temp_directions = full_text[start_dir:].strip()
44
+ # If "Ingredients:" appears again, it's a duplicate. Cut it off.
45
+ if "Ingredients:" in temp_directions:
46
+ end_dir = temp_directions.find("Ingredients:")
47
+ directions = temp_directions[:end_dir].strip()
48
+ else:
49
+ directions = temp_directions
50
+
51
+ return {
52
+ "title": title,
53
+ "ingredients": ingredients,
54
+ "directions": directions,
55
+ }
56
+
57
+
58
+ # Apply preprocessing
59
+ dataset = dataset.map(extract_title_and_ingredients)
60
+ dataset = dataset.map(extract_each_feature)
61
+
62
+ # --- 2. EMBEDDING AND RECOMMENDATION ENGINE ---
63
+ print("Loading embedding model...")
64
+ model_name = "all-MiniLM-L6-v2"
65
+ embedding_model = SentenceTransformer(f"sentence-transformers/{model_name}")
66
+
67
+ print("Generating embeddings...")
68
+ embeddings = embedding_model.encode(dataset['text_for_embedding'], show_progress_bar=True)
69
+ embeddings = np.array(embeddings, dtype=np.float32)
70
+
71
+ print("Building FAISS index...")
72
+ dimension = embeddings.shape[1]
73
+ index = faiss.IndexFlatL2(dimension)
74
+ index.add(embeddings)
75
+ print(f"Index is ready. Total vectors in index: {index.ntotal}")
76
+
77
+ # --- 3. SYNTHETIC GENERATION (IMPROVED MODEL AND PROMPT) ---
78
+ print("Loading generative model...")
79
+ # Switched back to gpt2 for better instruction following
80
+ generator = pipeline('text-generation', model='gpt2')
81
+
82
+ def get_recommendations_and_generate(query_ingredients, k=3):
83
+ # 1. Get Recommendations
84
+ query_vector = embedding_model.encode([query_ingredients])
85
+ query_vector = np.array(query_vector, dtype=np.float32)
86
+ distances, indices = index.search(query_vector, k)
87
+
88
+ results = []
89
+ for idx_numpy in indices[0]:
90
+ idx = int(idx_numpy)
91
+ recipe = {
92
+ "title": dataset[idx]['title'],
93
+ "ingredients": dataset[idx]['ingredients'],
94
+ "directions": dataset[idx]['directions']
95
+ }
96
+ results.append(recipe)
97
+
98
+ # 2. Generate a new recipe with a better "few-shot" prompt
99
+ prompt = f"""Given the ingredients: {query_ingredients}, create a complete recipe.
100
+
101
+ ### Title ###
102
+ [A creative recipe title]
103
+
104
+ ### Ingredients ###
105
+ - [List of ingredients]
106
+
107
+ ### Directions ###
108
+ 1. [First step]
109
+ 2. [Second step]
110
+ 3. [And so on...]
111
+
112
+ ### Title ###
113
+ """
114
+ # Generate the recipe text
115
+ generated_outputs = generator(prompt, max_new_tokens=250, num_return_sequences=1, pad_token_id=50256)
116
+ generated_text = generated_outputs[0]['generated_text'].replace(prompt, "").strip()
117
+
118
+ # 3. More robustly parse the generated text
119
+ try:
120
+ title = "AI Generated Recipe"
121
+ ingredients = ""
122
+ directions = ""
123
+
124
+ if "### Ingredients ###" in generated_text:
125
+ parts = generated_text.split("### Ingredients ###")
126
+ title = parts[0].strip()
127
+ rest = parts[1]
128
+ if "### Directions ###" in rest:
129
+ dir_parts = rest.split("### Directions ###")
130
+ ingredients = dir_parts[0].strip()
131
+ directions = dir_parts[1].strip()
132
+ else:
133
+ ingredients = rest.strip()
134
+ else:
135
+ directions = generated_text # Fallback
136
+
137
+ generated_recipe = {
138
+ "title": title,
139
+ "ingredients": ingredients,
140
+ "directions": directions
141
+ }
142
+ except Exception as e:
143
+ print(f"Error parsing generated text: {e}")
144
+ generated_recipe = {
145
+ "title": "AI Generated Recipe (Parsing Error)",
146
+ "ingredients": "Could not determine ingredients.",
147
+ "directions": generated_text
148
+ }
149
+
150
+ return results[0], results[1], results[2], generated_recipe
151
+
152
+ # --- 4. GRADIO USER INTERFACE ---
153
+ def format_recipe(recipe):
154
+ if not recipe or not recipe['title']:
155
+ return "### No recipe found."
156
+ return f"### {recipe['title']}\n**Ingredients:**\n{recipe['ingredients']}\n\n**Directions:**\n{recipe['directions']}"
157
+
158
+ def recipe_wizard(ingredients):
159
+ rec1, rec2, rec3, gen_rec = get_recommendations_and_generate(ingredients)
160
+ return format_recipe(rec1), format_recipe(rec2), format_recipe(rec3), format_recipe(gen_rec)
161
+
162
+ end_time = time.time()
163
+ print(f"Models and data loaded in {end_time - start_time:.2f} seconds.")
164
+
165
+ # Gradio Interface
166
+ with gr.Blocks(theme=gr.themes.Soft()) as demo:
167
+ gr.Markdown("# 🍳 RecipeWizard AI")
168
+ gr.Markdown("Enter the ingredients you have, and get recipe recommendations plus a new AI-generated idea!")
169
+
170
+ with gr.Row():
171
+ ingredient_input = gr.Textbox(label="Your Ingredients", placeholder="e.g., chicken, rice, tomatoes, garlic")
172
+ submit_btn = gr.Button("Get Recipes")
173
+
174
+ with gr.Row():
175
+ with gr.Column(scale=2):
176
+ gr.Markdown("### Recommended Recipes")
177
+ output_rec1 = gr.Markdown()
178
+ output_rec2 = gr.Markdown()
179
+ output_rec3 = gr.Markdown()
180
+ with gr.Column(scale=1):
181
+ gr.Markdown("### ✨ AI-Generated Idea")
182
+ output_gen = gr.Markdown()
183
+
184
+ submit_btn.click(
185
+ fn=recipe_wizard,
186
+ inputs=ingredient_input,
187
+ outputs=[output_rec1, output_rec2, output_rec3, output_gen]
188
+ )
189
+
190
+ gr.Examples(
191
+ examples=[
192
+ ["chicken, broccoli, cheese"],
193
+ ["ground beef, potatoes, onions"],
194
+ ["flour, sugar, eggs, butter"]
195
+ ],
196
+ inputs=ingredient_input
197
+ )
198
+
199
+ demo.launch()
recipe_index.faiss ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:90b9a5c8797e28a0fe4130d9af7ccdb897d0849110ea43765aee3b7b670b14ef
3
+ size 30720045
requirements (2).txt ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ torch==2.1.0
2
+ faiss-cpu==1.7.4
3
+ gradio==4.8.0
4
+ pyarrow==14.0.1
5
+ datasets==2.15.0
6
+ transformers==4.35.2
7
+ sentence-transformers==2.3.1
8
+ huggingface-hub==0.19.4