Spaces:
Runtime error
Runtime error
resolve conflicts
Browse files- app.py +56 -29
- examples.py +7 -0
- meta.py +4 -4
- requirements.txt +1 -1
- utils.py +7 -1
app.py
CHANGED
@@ -25,7 +25,7 @@ from utils import (
|
|
25 |
pure_comma_separation
|
26 |
)
|
27 |
|
28 |
-
np.random.seed(42)
|
29 |
|
30 |
|
31 |
class TextGeneration:
|
@@ -33,15 +33,24 @@ class TextGeneration:
|
|
33 |
self.debug = False
|
34 |
self.dummy_output = {
|
35 |
'directions': [
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
],
|
46 |
'ingredients': [
|
47 |
'1 potato',
|
@@ -129,7 +138,7 @@ class TextGeneration:
|
|
129 |
)
|
130 |
# Ingredients
|
131 |
im_editable.text(
|
132 |
-
(100,
|
133 |
"Ingredients",
|
134 |
(61, 61, 70),
|
135 |
font=self.fonts["body_bold"],
|
@@ -138,33 +147,40 @@ class TextGeneration:
|
|
138 |
ingredients = [textwrap.fill(item, 30).replace("\n", "\n ") for item in ingredients]
|
139 |
|
140 |
im_editable.text(
|
141 |
-
(100,
|
142 |
"\n".join([f"{self.point} {item}" for item in ingredients]),
|
143 |
(61, 61, 70),
|
144 |
font=self.fonts["body"],
|
145 |
)
|
146 |
# Directions
|
147 |
im_editable.text(
|
148 |
-
(700,
|
149 |
"Directions",
|
150 |
(61, 61, 70),
|
151 |
font=self.fonts["body_bold"],
|
152 |
)
|
153 |
directions = recipe["directions"]
|
154 |
-
|
155 |
-
directions_col2 = [textwrap.fill(item, 30).replace("\n", "\n ") for item in directions[self.list_division:]]
|
156 |
im_editable.text(
|
157 |
-
(700,
|
158 |
-
"\n".join([f"{i + 1}. {item}" for i, item in enumerate(
|
159 |
-
(61, 61, 70),
|
160 |
-
font=self.fonts["body"],
|
161 |
-
)
|
162 |
-
im_editable.text(
|
163 |
-
(1300, 1130),
|
164 |
-
"\n".join([f"{i + 1 + self.list_division}. {item}" for i, item in enumerate(directions_col2)]).strip(),
|
165 |
(61, 61, 70),
|
166 |
font=self.fonts["body"],
|
167 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
168 |
return frame
|
169 |
|
170 |
def generate(self, items, generation_kwargs):
|
@@ -224,8 +240,11 @@ def main():
|
|
224 |
initial_sidebar_state="expanded"
|
225 |
)
|
226 |
generator = load_text_generator()
|
227 |
-
if
|
228 |
-
|
|
|
|
|
|
|
229 |
|
230 |
local_css("asset/css/style.css")
|
231 |
|
@@ -269,7 +288,11 @@ def main():
|
|
269 |
unsafe_allow_html=True
|
270 |
)
|
271 |
if recipe_button:
|
272 |
-
|
|
|
|
|
|
|
|
|
273 |
entered_items.markdown("**Generate recipe for:** " + items)
|
274 |
with st.spinner("Generating recipe..."):
|
275 |
|
@@ -292,7 +315,11 @@ def main():
|
|
292 |
|
293 |
with r1:
|
294 |
# st.write(st.session_state.get_random_frame)
|
295 |
-
|
|
|
|
|
|
|
|
|
296 |
st.image(
|
297 |
recipe_post,
|
298 |
# width=500,
|
@@ -311,9 +338,9 @@ def main():
|
|
311 |
" ".join([f'<li>{item}</li>' for item in ingredients]),
|
312 |
"</ul>",
|
313 |
"<h3>Directions</h3>",
|
314 |
-
"<
|
315 |
" ".join([f'<li>{item}</li>' for item in directions]),
|
316 |
-
"</
|
317 |
"</div>"
|
318 |
]),
|
319 |
unsafe_allow_html=True
|
25 |
pure_comma_separation
|
26 |
)
|
27 |
|
28 |
+
# np.random.seed(42)
|
29 |
|
30 |
|
31 |
class TextGeneration:
|
33 |
self.debug = False
|
34 |
self.dummy_output = {
|
35 |
'directions': [
|
36 |
+
"for the dough",
|
37 |
+
"in a small bowl, combine the warm water and yeast.",
|
38 |
+
"let it sit for 5 minutes.",
|
39 |
+
"add the flour, salt, and olive oil.",
|
40 |
+
"mix well and knead until the dough is smooth and elastic.",
|
41 |
+
"cover the dough with a damp towel and let it rise for about 1 hour.",
|
42 |
+
"for the filling",
|
43 |
+
"heat a large skillet over medium high heat.",
|
44 |
+
"cook the beef and onion until the beef is browned and the onion is translucent. browned and the onion is translucent.",
|
45 |
+
"drain off any excess grease.",
|
46 |
+
"stir in the pepper and salt and black pepper to taste.",
|
47 |
+
"remove from the heat and set aside.",
|
48 |
+
"preheat the oven to 425 degrees f.",
|
49 |
+
"roll out the dough on a lightly floured surface into a 12 inch circle.",
|
50 |
+
"spread the beef mixture over the dough, leaving a 1 inch border.",
|
51 |
+
"top with the feta, parsley, and lemon juice.",
|
52 |
+
"bake for 20 minutes or until the crust is golden brown.",
|
53 |
+
"cut into wedges and serve.",
|
54 |
],
|
55 |
'ingredients': [
|
56 |
'1 potato',
|
138 |
)
|
139 |
# Ingredients
|
140 |
im_editable.text(
|
141 |
+
(100, 1000),
|
142 |
"Ingredients",
|
143 |
(61, 61, 70),
|
144 |
font=self.fonts["body_bold"],
|
147 |
ingredients = [textwrap.fill(item, 30).replace("\n", "\n ") for item in ingredients]
|
148 |
|
149 |
im_editable.text(
|
150 |
+
(100, 1080),
|
151 |
"\n".join([f"{self.point} {item}" for item in ingredients]),
|
152 |
(61, 61, 70),
|
153 |
font=self.fonts["body"],
|
154 |
)
|
155 |
# Directions
|
156 |
im_editable.text(
|
157 |
+
(700, 1000),
|
158 |
"Directions",
|
159 |
(61, 61, 70),
|
160 |
font=self.fonts["body_bold"],
|
161 |
)
|
162 |
directions = recipe["directions"]
|
163 |
+
directions = [textwrap.fill(item, 80).replace("\n", "\n ") for item in directions]
|
|
|
164 |
im_editable.text(
|
165 |
+
(700, 1080),
|
166 |
+
"\n".join([f"{i + 1}. {item}" for i, item in enumerate(directions)]).strip(),
|
|
|
|
|
|
|
|
|
|
|
|
|
167 |
(61, 61, 70),
|
168 |
font=self.fonts["body"],
|
169 |
)
|
170 |
+
# directions_col1 = [textwrap.fill(item, 30).replace("\n", "\n ") for item in directions[:self.list_division]]
|
171 |
+
# directions_col2 = [textwrap.fill(item, 30).replace("\n", "\n ") for item in directions[self.list_division:]]
|
172 |
+
# im_editable.text(
|
173 |
+
# (700, 1130),
|
174 |
+
# "\n".join([f"{i + 1}. {item}" for i, item in enumerate(directions_col1)]).strip(),
|
175 |
+
# (61, 61, 70),
|
176 |
+
# font=self.fonts["body"],
|
177 |
+
# )
|
178 |
+
# im_editable.text(
|
179 |
+
# (1300, 1130),
|
180 |
+
# "\n".join([f"{i + 1 + self.list_division}. {item}" for i, item in enumerate(directions_col2)]).strip(),
|
181 |
+
# (61, 61, 70),
|
182 |
+
# font=self.fonts["body"],
|
183 |
+
# )
|
184 |
return frame
|
185 |
|
186 |
def generate(self, items, generation_kwargs):
|
240 |
initial_sidebar_state="expanded"
|
241 |
)
|
242 |
generator = load_text_generator()
|
243 |
+
if hasattr(st, "session_state"):
|
244 |
+
if 'get_random_frame' not in st.session_state:
|
245 |
+
st.session_state.get_random_frame = generator.frames[0]
|
246 |
+
else:
|
247 |
+
get_random_frame = generator.frames[0]
|
248 |
|
249 |
local_css("asset/css/style.css")
|
250 |
|
288 |
unsafe_allow_html=True
|
289 |
)
|
290 |
if recipe_button:
|
291 |
+
if hasattr(st, "session_state"):
|
292 |
+
st.session_state.get_random_frame = generator.frames[random.randint(0, len(generator.frames)) - 1]
|
293 |
+
else:
|
294 |
+
get_random_frame = generator.frames[random.randint(0, len(generator.frames)) - 1]
|
295 |
+
|
296 |
entered_items.markdown("**Generate recipe for:** " + items)
|
297 |
with st.spinner("Generating recipe..."):
|
298 |
|
315 |
|
316 |
with r1:
|
317 |
# st.write(st.session_state.get_random_frame)
|
318 |
+
if hasattr(st, "session_state"):
|
319 |
+
recipe_post = generator.generate_frame(generated_recipe, st.session_state.get_random_frame)
|
320 |
+
else:
|
321 |
+
recipe_post = generator.generate_frame(generated_recipe, get_random_frame)
|
322 |
+
|
323 |
st.image(
|
324 |
recipe_post,
|
325 |
# width=500,
|
338 |
" ".join([f'<li>{item}</li>' for item in ingredients]),
|
339 |
"</ul>",
|
340 |
"<h3>Directions</h3>",
|
341 |
+
"<ol class='ingredients-list'>",
|
342 |
" ".join([f'<li>{item}</li>' for item in directions]),
|
343 |
+
"</ol>",
|
344 |
"</div>"
|
345 |
]),
|
346 |
unsafe_allow_html=True
|
examples.py
CHANGED
@@ -1,3 +1,10 @@
|
|
1 |
EXAMPLES = {
|
2 |
"Chocolate Baklava": "phyllo dough, unsalted butter, walnuts, cinnamon, water, honey, melted chocolate",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
}
|
1 |
EXAMPLES = {
|
2 |
"Chocolate Baklava": "phyllo dough, unsalted butter, walnuts, cinnamon, water, honey, melted chocolate",
|
3 |
+
"Ghormeh Sabzi (Persian Herb Stew)": "beef, oil, onion, tomatoes, turmeric powder, limes, water, salt, pepper, red beans, herb",
|
4 |
+
"Kotlet, Persian Cutlet": "beef, potatoes, eggs, onion, flour, turmeric powder, oil, salt, pepper",
|
5 |
+
"Persian Chicken Stew (Fesenjan)": "walnut pieces, onion, boneless skinless chicken thighs, pomegranate molasses, orange juice, chicken stock, cinnamon, salt, pepper, oil",
|
6 |
+
"Pide (Turkish Flatbread)": "water, dry active yeast, flour, salt, olive oil, ground beef, onion, pepper, salt, feta cheese, parsley, lemon",
|
7 |
+
"Korean Pork Chops": "pork chops, soy sauce, honey, garlic, sesame oil, fresh ginger root, sweet chili sauce, olive oil",
|
8 |
+
"Italian Pasta Salad": "rotini pasta, broccoli florets, parmesan cheese, red pepper, onions, black olives",
|
9 |
+
"Authentic German Jägerschnitzel (Hunter Schnitzel with Mushroom Gravy)": "oil, boneless pork chops, salt, pepper, flour, eggs, breadcrumbs, gravy, parsley"
|
10 |
}
|
meta.py
CHANGED
@@ -15,9 +15,9 @@ Chef Giovanni.)</span></p>
|
|
15 |
""".strip()
|
16 |
PROMPT_BOX = "Add custom ingredients here (separated by `,`): "
|
17 |
STORY = """
|
18 |
-
Hello everyone
|
19 |
-
https://huggingface.co/flax-community/t5-recipe-generation#team-members) to
|
20 |
-
I've never been more proud of my students -- both can produce exceptional dishes but I regard Scheherazade as being *creative* while Giovanni is *meticulous*. If you give each of them the same ingredients, they'll
|
21 |
|
22 |
At the start of the program the chefs read cookbooks containing thousands of recipes of varying difficulties and from cultures all over the world. The NLP engineers helped guide the learning process so that the chefs could actually learn which ingredients work well together rather than just memorizing recipes.
|
23 |
In fact, the main way I trained my chefs was by asking them to generate a title, a list of ingredients (including amounts!), and a list of directions after receiving just a simple list of food items.
|
@@ -34,5 +34,5 @@ In fact, the main way I trained my chefs was by asking them to generate a title,
|
|
34 |
* In the cookbooks (a.k.a dataset), the food items were referred to as NER.
|
35 |
|
36 |
In the span of a week, my chefs went from spitting out nonsense to creating masterpieces. Their learning rate was exceptionally high and each batch of recipes was better than the last. In their final exam, they achieved [high scores](
|
37 |
-
https://huggingface.co/flax-community/t5-recipe-generation#evaluation) in a standardized industry test and established this restaurant
|
38 |
""".strip()
|
15 |
""".strip()
|
16 |
PROMPT_BOX = "Add custom ingredients here (separated by `,`): "
|
17 |
STORY = """
|
18 |
+
Hello everyone 👋, I am **Chef Transformer**, the owner of this restaurant. I was made by a group of [NLP Engineers](
|
19 |
+
https://huggingface.co/flax-community/t5-recipe-generation#team-members) to train my two prodigy recipe creators: **Chef Scheherazade** and **Chef Giovanni**. Both of my students participated in my rigorous culinary program, [T5 fine-tune training](https://huggingface.co/flax-community/t5-recipe-generation), to learn how to prepare exquisite cuisines from a wide variety of ingredients.
|
20 |
+
I've never been more proud of my students -- both can produce exceptional dishes but I regard Scheherazade as being *creative* while Giovanni is *meticulous*. If you give each of them the same ingredients, they'll usually come up with something different.
|
21 |
|
22 |
At the start of the program the chefs read cookbooks containing thousands of recipes of varying difficulties and from cultures all over the world. The NLP engineers helped guide the learning process so that the chefs could actually learn which ingredients work well together rather than just memorizing recipes.
|
23 |
In fact, the main way I trained my chefs was by asking them to generate a title, a list of ingredients (including amounts!), and a list of directions after receiving just a simple list of food items.
|
34 |
* In the cookbooks (a.k.a dataset), the food items were referred to as NER.
|
35 |
|
36 |
In the span of a week, my chefs went from spitting out nonsense to creating masterpieces. Their learning rate was exceptionally high and each batch of recipes was better than the last. In their final exam, they achieved [high scores](
|
37 |
+
https://huggingface.co/flax-community/t5-recipe-generation#evaluation) 💯 in a standardized industry test and established this restaurant 🍲. Please tell your friends and family about us! We create each recipe with a smile on our faces 🤗
|
38 |
""".strip()
|
requirements.txt
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
streamlit
|
2 |
transformers
|
3 |
torch
|
4 |
Pillow
|
1 |
+
streamlit==0.84.1
|
2 |
transformers
|
3 |
torch
|
4 |
Pillow
|
utils.py
CHANGED
@@ -35,8 +35,14 @@ def remote_css(css_url):
|
|
35 |
st.markdown(f'<link href="{css_url}" rel="stylesheet">', unsafe_allow_html=True)
|
36 |
|
37 |
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
def pure_comma_separation(list_str, return_list=True):
|
39 |
-
r = [item.strip() for item in list_str.split(",")]
|
40 |
# r = list(set([x.strip() for x in list_str.strip().split(',') if len(x.strip()) > 0]))
|
41 |
if return_list:
|
42 |
return r
|
35 |
st.markdown(f'<link href="{css_url}" rel="stylesheet">', unsafe_allow_html=True)
|
36 |
|
37 |
|
38 |
+
def unique_list(seq):
|
39 |
+
seen = set()
|
40 |
+
seen_add = seen.add
|
41 |
+
return [x for x in seq if not (x in seen or seen_add(x))]
|
42 |
+
|
43 |
+
|
44 |
def pure_comma_separation(list_str, return_list=True):
|
45 |
+
r = unique_list([item.strip() for item in list_str.lower().split(",") if item.strip()])
|
46 |
# r = list(set([x.strip() for x in list_str.strip().split(',') if len(x.strip()) > 0]))
|
47 |
if return_list:
|
48 |
return r
|