Spaces:
Paused
Paused
Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,197 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
openai.api_key = os.environ.getattribute("API_KEY")
|
2 |
+
HUGGINGFACE_TOKEN = os.environ.getattribute("HF_KEY")
|
3 |
+
|
4 |
+
import openai
|
5 |
+
import gradio as gr
|
6 |
+
|
7 |
+
!huggingface-cli login --token $HUGGINGFACE_TOKEN
|
8 |
+
|
9 |
+
from transformers import TFGPT2LMHeadModel, AutoTokenizer
|
10 |
+
|
11 |
+
tokenizer = AutoTokenizer.from_pretrained('Gracoy/ingredients_compatibility_GPT2_S')
|
12 |
+
model = TFGPT2LMHeadModel.from_pretrained('Gracoy/ingredients_compatibility_GPT2_S')
|
13 |
+
|
14 |
+
def assistant(assist_prompt):
|
15 |
+
response = openai.ChatCompletion.create(
|
16 |
+
model='gpt-3.5-turbo',
|
17 |
+
messages=assist_prompt,
|
18 |
+
temperature=0.7)
|
19 |
+
return response["choices"][0]["message"]["content"].strip()
|
20 |
+
|
21 |
+
def proper_ingredient(ingredients, meal):
|
22 |
+
|
23 |
+
if not ingredients:
|
24 |
+
return
|
25 |
+
|
26 |
+
assist_prompt1 = [{"role": "user", "content": f"列出三道使用{ingredients}裡食材適合當{meal}的料理,列舉即可不須詳細說明"}]
|
27 |
+
|
28 |
+
prompt = [
|
29 |
+
{"role": "system", "content": "你是一個烹飪經驗豐富的廚師,知道哪些食材適合拿來搭配來製作平易近人且美味的料理"},
|
30 |
+
{"role": "assistant", "content": assistant(assist_prompt1)},
|
31 |
+
{"role": "user", "content": f"請給我三組在{ingredients}中適合一起烹飪的食材組合,不需要料理名稱只要寫出食材和為何他們適合搭配在一起就好,\
|
32 |
+
列出的食材組合需至少包含一樣原本提供的食材,###輸出格式:至少一樣原本食材+新增食材:為何適合搭配在一起###"}
|
33 |
+
]
|
34 |
+
|
35 |
+
response = openai.ChatCompletion.create(
|
36 |
+
model='gpt-3.5-turbo',
|
37 |
+
messages=prompt,
|
38 |
+
temperature=0.7)
|
39 |
+
|
40 |
+
return response["choices"][0]["message"]["content"].strip()
|
41 |
+
|
42 |
+
def get_ingre(ingredients):
|
43 |
+
final_ingre = ingredients
|
44 |
+
return final_ingre
|
45 |
+
|
46 |
+
def gen_recipe(final_ingredients, flavor, meal):
|
47 |
+
global step
|
48 |
+
global round
|
49 |
+
global history
|
50 |
+
|
51 |
+
step = 9
|
52 |
+
round = 0
|
53 |
+
history = []
|
54 |
+
|
55 |
+
if not final_ingredients:
|
56 |
+
return
|
57 |
+
|
58 |
+
assist_prompt1 = [{"role": "user", "content": f"請用三句話說明料理中的{flavor}風味,列出{flavor}風味常使用的香料及調味料,列舉即可不須詳細說明"}]
|
59 |
+
assist_prompt2 = [{"role": "user", "content": f"列出三樣以{final_ingredients}裡的食材烹調出適合當{meal}的{flavor}風味料理,列舉即可不須詳細說明"}]
|
60 |
+
|
61 |
+
prompt = [
|
62 |
+
{"role": "system", "content": "你是一個烹飪經驗豐富的廚師,擅長使用手邊的食材和簡潔的烹飪步驟來製作平易近人的家庭料理"},
|
63 |
+
{"role": "assistant", "content": assistant(assist_prompt1)},
|
64 |
+
{"role": "assistant", "content": assistant(assist_prompt2)},
|
65 |
+
{"role": "user", "content": f"請在上述料理中選擇一個,並針對此料理給我一份步驟數在{step}步以內的食譜,烹飪方式不要用炒的,食材用量要詳細,\
|
66 |
+
食譜要包含用到的調味料,烹飪步驟要簡潔;###使用食材:{final_ingredients},料理風味:{flavor},餐點:{meal}\
|
67 |
+
###;###輸出格式:料理名稱,使用食材,使用調味料,烹飪步驟,分成三個區塊顯示###"}
|
68 |
+
]
|
69 |
+
|
70 |
+
response = openai.ChatCompletion.create(
|
71 |
+
model='gpt-3.5-turbo',
|
72 |
+
messages=prompt,
|
73 |
+
temperature=0.7)
|
74 |
+
|
75 |
+
round += 1
|
76 |
+
history.append(response["choices"][0]["message"]["content"].strip())
|
77 |
+
return response["choices"][0]["message"]["content"].strip()
|
78 |
+
|
79 |
+
def another_recipe(final_ingredients, flavor, meal):
|
80 |
+
global step
|
81 |
+
global round
|
82 |
+
global history
|
83 |
+
|
84 |
+
if round == 0 or (not final_ingredients):
|
85 |
+
return
|
86 |
+
|
87 |
+
step = 9
|
88 |
+
|
89 |
+
assist_prompt1 = [{"role": "user", "content": f"請用三句話說明料理中的{flavor}風味,列出{flavor}風味常使用的香料及調味料,列舉即可不須詳細說明"}]
|
90 |
+
assist_prompt2 = [{"role": "user", "content": f"你給我的{history[round-1]}料理名稱與食譜我都不喜歡,\
|
91 |
+
請列出其他三樣以{final_ingredients}裡的食材烹調出適合當{meal}的{flavor}風味料理,列舉即可不須詳細說明"}]
|
92 |
+
|
93 |
+
prompt = [
|
94 |
+
{"role": "system", "content": "你是一個烹飪經驗豐富的家庭主婦,擅長使用簡潔的烹飪步驟來製作平易近人的料理"},
|
95 |
+
{"role": "assistant", "content": assistant(assist_prompt1)},
|
96 |
+
{"role": "assistant", "content": assistant(assist_prompt2)},
|
97 |
+
{"role": "user", "content": f"請在上述料理中給我一份料理名稱不在{history}裡且步驟數在{step}步以內的食譜,烹飪方式不要用炒的, \
|
98 |
+
食材用量要詳細,食譜要包含用到的調味料,烹飪步驟的描述要簡潔;###使用食材:{final_ingredients},料理風味:{flavor},餐點:{meal}\
|
99 |
+
###;###輸出格式:料理名稱,使用食材,使用調味料,烹飪步驟,分成三個區塊顯示###"}
|
100 |
+
]
|
101 |
+
|
102 |
+
response = openai.ChatCompletion.create(
|
103 |
+
model='gpt-3.5-turbo',
|
104 |
+
messages=prompt,
|
105 |
+
temperature=0.5)
|
106 |
+
|
107 |
+
round += 1
|
108 |
+
history.append(response["choices"][0]["message"]["content"].strip())
|
109 |
+
return response["choices"][0]["message"]["content"].strip()
|
110 |
+
|
111 |
+
def simpler_recipe(final_ingredients, flavor, meal):
|
112 |
+
global step
|
113 |
+
global round
|
114 |
+
global history
|
115 |
+
|
116 |
+
if round == 0 or (not final_ingredients):
|
117 |
+
return
|
118 |
+
|
119 |
+
step = step - 2 if step > 5 else step
|
120 |
+
|
121 |
+
assist_prompt1 = [{"role": "user", "content": f"請用三句話說明料理中的{flavor}風味,列出{flavor}風味常使用的香料及調味料,列舉即可不須詳細說明"}]
|
122 |
+
assist_prompt2 = [{"role": "user", "content": f"你給我的{history[round-1]}食譜做法太難了,請列出其他三樣以{final_ingredients}裡的食材,\
|
123 |
+
烹調出適合當{meal}的{flavor}風味料理,列舉即可不須詳細說明"}]
|
124 |
+
|
125 |
+
prompt = [
|
126 |
+
{"role": "system", "content": "你是一個烹飪技巧不熟練的新手廚師,只能製作出簡單常見的料理"},
|
127 |
+
{"role": "assistant", "content": assistant(assist_prompt1)},
|
128 |
+
{"role": "assistant", "content": assistant(assist_prompt2)},
|
129 |
+
{"role": "user", "content": f"請給我一份料理名稱不在{history}裡且烹飪步驟在{step}步以內的食譜,先用一句話說明你對{history[round-1]}食譜做了哪些調整,烹飪方式不要用炒的,\
|
130 |
+
食材用量要詳細,最多只能使用三種調味料,烹飪步驟要簡潔;###使用食材:{final_ingredients},料理風味:{flavor},餐點:{meal}\
|
131 |
+
###;###輸出格式:料理名稱,使用食材,使用調味料,烹飪步驟,分成三個區塊顯示###"}
|
132 |
+
]
|
133 |
+
|
134 |
+
response = openai.ChatCompletion.create(
|
135 |
+
model='gpt-3.5-turbo',
|
136 |
+
messages=prompt,
|
137 |
+
temperature=0.7)
|
138 |
+
|
139 |
+
round += 1
|
140 |
+
history.append(response["choices"][0]["message"]["content"].strip())
|
141 |
+
return response["choices"][0]["message"]["content"].strip()
|
142 |
+
|
143 |
+
def compatibility_predict(ingredients):
|
144 |
+
response = openai.ChatCompletion.create(
|
145 |
+
model='gpt-3.5-turbo',
|
146 |
+
messages=[{"role": "user", "content": f"請把以下輸入翻譯成英文:{ingredients}"}]
|
147 |
+
)
|
148 |
+
translated = response['choices'][0]['message']['content'].strip().lower().replace('.', "")
|
149 |
+
|
150 |
+
prefix = 'I want to cook, please select the suitable ingredients from the following list: '
|
151 |
+
prompt = prefix + translated+ '.'
|
152 |
+
input = tokenizer('<BOS>' + prompt, return_tensors='tf')
|
153 |
+
encoded_outputs = model.generate(input['input_ids'], max_length=128, num_beams=3, num_return_sequences=1, early_stopping=True)
|
154 |
+
|
155 |
+
mid = 'The best combinations are: '
|
156 |
+
suffix = '. Enjoy your dish!'
|
157 |
+
res = []
|
158 |
+
for output in encoded_outputs:
|
159 |
+
ans = tokenizer.decode(output, skip_special_tokens=True)
|
160 |
+
ans = ans.replace(prompt, "").strip()
|
161 |
+
ans = ans.replace(mid, "").strip()
|
162 |
+
ans = ans.replace(suffix, "").strip()
|
163 |
+
ans = set(ans.split(', '))
|
164 |
+
res.append(list(ans))
|
165 |
+
|
166 |
+
response = openai.ChatCompletion.create(
|
167 |
+
model='gpt-3.5-turbo',
|
168 |
+
messages=[{"role": "user", "content": f"請把以下輸入翻譯成繁體中文,翻譯時請以台灣(Taiwan)的習慣用詞為準:{', '.join(ans)}"}]
|
169 |
+
)
|
170 |
+
return response["choices"][0]["message"]["content"].strip()
|
171 |
+
|
172 |
+
with gr.Blocks(css="footer{display: none !important;}", theme=gr.themes.Soft(primary_hue="zinc", neutral_hue="sky")) as demo1:
|
173 |
+
gr.Markdown(""" # 今晚我想來點 """)
|
174 |
+
with gr.Row():
|
175 |
+
with gr.Column():
|
176 |
+
ingredients = gr.Textbox(label='手邊有哪些其他食材呢?')
|
177 |
+
#meal = gr.Textbox(label='現在要吃的是早餐,午餐,點心,晚餐,還是宵夜?')
|
178 |
+
meal = gr.Radio(["早餐", "午餐", "晚餐", "點心", "宵夜"], label="你現在要烹煮的是哪一餐?")
|
179 |
+
submit_bnt = gr.Button('請推薦食材組合給我')
|
180 |
+
proper_set = gr.Textbox(label='推薦的食材組合')
|
181 |
+
|
182 |
+
with gr.Column():
|
183 |
+
final_ingredients = gr.Textbox(label="最後想使用的食材有哪些?", info="預設帶入原本輸入的食材,可再自行增減")
|
184 |
+
flavor = gr.Dropdown(['中式','日式','美式','韓式','義式','泰式','都可以'],label='你希望成品帶有哪些風味?', info="請從選單中任選一個")
|
185 |
+
submit_bnt1 = gr.Button('產生食譜吧!')
|
186 |
+
recipe = gr.Textbox(label='食譜')
|
187 |
+
with gr.Row():
|
188 |
+
simpler_btn = gr.Button('太難了')
|
189 |
+
another_btn = gr.Button('不喜歡')
|
190 |
+
|
191 |
+
submit_bnt.click(fn=compatibility_predict, inputs=[ingredients], outputs=[proper_set]) # 這邊把原本的proper_ingredient換成我們model的API, 其他按鈕都沒改
|
192 |
+
submit_bnt.click(fn=get_ingre, inputs=[ingredients], outputs=[final_ingredients])
|
193 |
+
submit_bnt1.click(fn=gen_recipe, inputs=[final_ingredients, flavor, meal], outputs=[recipe])
|
194 |
+
simpler_btn.click(fn=simpler_recipe, inputs=[final_ingredients, flavor, meal], outputs=[recipe])
|
195 |
+
another_btn.click(fn=another_recipe, inputs=[final_ingredients, flavor, meal], outputs=[recipe])
|
196 |
+
|
197 |
+
demo1.launch()
|