Spaces:
Runtime error
Runtime error
title: Chef Transformer | |
emoji: 🍲 | |
colorFrom: blue | |
colorTo: red | |
sdk: streamlit | |
app_file: app.py | |
pinned: false | |
# Chef Transformer (T5) | |
> This is part of the [Flax/Jax Community Week](https://discuss.huggingface.co/t/recipe-generation-model/7475), organized by [HuggingFace](https://huggingface.co/) and TPU usage sponsored by Google. | |
Want to give it a try? Then what's the wait, head over to the demo [here](https://share.streamlit.io/chef-transformer/chef-transformer/main/app.py). | |
## Team Members | |
- Mehrdad Farahani ([m3hrdadfi](https://huggingface.co/m3hrdadfi)) | |
- Kartik Godawat ([dk-crazydiv](https://huggingface.co/dk-crazydiv)) | |
- Haswanth Aekula ([hassiahk](https://huggingface.co/hassiahk)) | |
- Deepak Pandian ([rays2pix](https://huggingface.co/rays2pix)) | |
- Nicholas Broad ([nbroad](https://huggingface.co/nbroad)) | |
## Dataset | |
[RecipeNLG: A Cooking Recipes Dataset for Semi-Structured Text Generation](https://recipenlg.cs.put.poznan.pl/). This dataset contains **2,231,142** cooking recipes (>2 millions) with size of **2.14 GB**. It's processed in more careful way. | |
### Example | |
```json | |
{ | |
"NER": [ | |
"oyster crackers", | |
"salad dressing", | |
"lemon pepper", | |
"dill weed", | |
"garlic powder", | |
"salad oil" | |
], | |
"directions": [ | |
"Combine salad dressing mix and oil.", | |
"Add dill weed, garlic powder and lemon pepper.", | |
"Pour over crackers; stir to coat.", | |
"Place in warm oven.", | |
"Use very low temperature for 15 to 20 minutes." | |
], | |
"ingredients": [ | |
"12 to 16 oz. plain oyster crackers", | |
"1 pkg. Hidden Valley Ranch salad dressing mix", | |
"1/4 tsp. lemon pepper", | |
"1/2 to 1 tsp. dill weed", | |
"1/4 tsp. garlic powder", | |
"3/4 to 1 c. salad oil" | |
], | |
"link": "www.cookbooks.com/Recipe-Details.aspx?id=648947", | |
"source": "Gathered", | |
"title": "Hidden Valley Ranch Oyster Crackers" | |
} | |
``` | |
## How To Use | |
```bash | |
# Installing requirements | |
pip install transformers | |
``` | |
```python | |
from transformers import FlaxAutoModelForSeq2SeqLM | |
from transformers import AutoTokenizer | |
MODEL_NAME_OR_PATH = "flax-community/t5-recipe-generation" | |
tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME_OR_PATH, use_fast=True) | |
model = FlaxAutoModelForSeq2SeqLM.from_pretrained(MODEL_NAME_OR_PATH) | |
prefix = "items: " | |
# generation_kwargs = { | |
# "max_length": 1024, | |
# "min_length": 128, | |
# "no_repeat_ngram_size": 3, | |
# "do_sample": True, | |
# "top_k": 60, | |
# "top_p": 0.95 | |
# } | |
generation_kwargs = { | |
"max_length": 512, | |
"min_length": 64, | |
"no_repeat_ngram_size": 3, | |
"early_stopping": True, | |
"num_beams": 5, | |
"length_penalty": 1.5, | |
} | |
special_tokens = tokenizer.all_special_tokens | |
tokens_map = { | |
"<sep>": "--", | |
"<section>": "\n" | |
} | |
def skip_special_tokens(text, special_tokens): | |
for token in special_tokens: | |
text = text.replace(token, "") | |
return text | |
def target_postprocessing(texts, special_tokens): | |
if not isinstance(texts, list): | |
texts = [texts] | |
new_texts = [] | |
for text in texts: | |
text = skip_special_tokens(text, special_tokens) | |
for k, v in tokens_map.items(): | |
text = text.replace(k, v) | |
new_texts.append(text) | |
return new_texts | |
def generation_function(texts): | |
_inputs = texts if isinstance(texts, list) else [texts] | |
inputs = [prefix + inp for inp in _inputs] | |
inputs = tokenizer( | |
inputs, | |
max_length=256, | |
padding="max_length", | |
truncation=True, | |
return_tensors="jax" | |
) | |
input_ids = inputs.input_ids | |
attention_mask = inputs.attention_mask | |
output_ids = model.generate( | |
input_ids=input_ids, | |
attention_mask=attention_mask, | |
**generation_kwargs | |
) | |
generated = output_ids.sequences | |
generated_recipe = target_postprocessing( | |
tokenizer.batch_decode(generated, skip_special_tokens=False), | |
special_tokens | |
) | |
return generated_recipe | |
``` | |
```python | |
items = [ | |
"macaroni, butter, salt, bacon, milk, flour, pepper, cream corn", | |
"provolone cheese, bacon, bread, ginger" | |
] | |
generated = generation_function(items) | |
for text in generated: | |
sections = text.split("\n") | |
for section in sections: | |
section = section.strip() | |
if section.startswith("title:"): | |
section = section.replace("title:", "") | |
headline = "TITLE" | |
elif section.startswith("ingredients:"): | |
section = section.replace("ingredients:", "") | |
headline = "INGREDIENTS" | |
elif section.startswith("directions:"): | |
section = section.replace("directions:", "") | |
headline = "DIRECTIONS" | |
if headline == "TITLE": | |
print(f"[{headline}]: {section.strip().capitalize()}") | |
else: | |
section_info = [f" - {i+1}: {info.strip().capitalize()}" for i, info in enumerate(section.split("--"))] | |
print(f"[{headline}]:") | |
print("\n".join(section_info)) | |
print("-" * 130) | |
``` | |
Output: | |
```text | |
[TITLE]: Macaroni and corn | |
[INGREDIENTS]: | |
- 1: 2 c. macaroni | |
- 2: 2 tbsp. butter | |
- 3: 1 tsp. salt | |
- 4: 4 slices bacon | |
- 5: 2 c. milk | |
- 6: 2 tbsp. flour | |
- 7: 1/4 tsp. pepper | |
- 8: 1 can cream corn | |
[DIRECTIONS]: | |
- 1: Cook macaroni in boiling salted water until tender. | |
- 2: Drain. | |
- 3: Melt butter in saucepan. | |
- 4: Blend in flour, salt and pepper. | |
- 5: Add milk all at once. | |
- 6: Cook and stir until thickened and bubbly. | |
- 7: Stir in corn and bacon. | |
- 8: Pour over macaroni and mix well. | |
---------------------------------------------------------------------------------------------------------------------------------- | |
[TITLE]: Grilled provolone and bacon sandwich | |
[INGREDIENTS]: | |
- 1: 2 slices provolone cheese | |
- 2: 2 slices bacon | |
- 3: 2 slices sourdough bread | |
- 4: 2 slices pickled ginger | |
[DIRECTIONS]: | |
- 1: Place a slice of provolone cheese on one slice of bread. | |
- 2: Top with a slice of bacon. | |
- 3: Top with a slice of pickled ginger. | |
- 4: Top with the other slice of bread. | |
- 5: Heat a skillet over medium heat. | |
- 6: Place the sandwich in the skillet and cook until the cheese is melted and the bread is golden brown. | |
---------------------------------------------------------------------------------------------------------------------------------- | |
``` | |
## Evaluation | |
The following table summarizes the scores obtained by the **Chef Transformer**. Those marked as (*) are the baseline models. | |
| Model | WER | COSIM | ROUGE-2 | | |
| :-------------: | :---: | :---: | :-----: | | |
| Recipe1M+ * | 0.786 | 0.589 | - | | |
| RecipeNLG * | 0.751 | 0.666 | - | | |
| ChefTransformer | 0.709 | 0.714 | 0.290 | | |
## Streamlit demo | |
```bash | |
streamlit run app.py | |
``` | |
## Looking to contribute? | |
Then follow the steps mentioned in this [contributing guide](CONTRIBUTING.md) and you are good to go. | |
## Copyright | |
Special thanks to those who provided these fantastic materials. | |
- [Anatomy](https://www.flaticon.com/free-icon) | |
- [Chef Hat](https://www.vecteezy.com/members/jellyfishwater) | |
- [Moira Nazzari](https://pixabay.com/photos/food-dessert-cake-eggs-butter-3048440/) | |
- [Instagram Post](https://www.freepik.com/free-psd/recipes-ad-social-media-post-template_11520617.htm) | |