Spaces:
Build error
Build error
Update app.py
Browse files
app.py
CHANGED
@@ -1,50 +1,66 @@
|
|
1 |
import gradio as gr
|
2 |
import torch
|
3 |
-
from transformers import
|
4 |
import pandas as pd
|
5 |
import numpy as np
|
6 |
from PIL import Image
|
7 |
|
8 |
-
def
|
9 |
-
"""Inicializa o modelo
|
10 |
device = "cuda" if torch.cuda.is_available() else "cpu"
|
11 |
-
model_name = "
|
12 |
|
13 |
processor = AutoProcessor.from_pretrained(model_name)
|
14 |
-
model = AutoModelForCausalLM.from_pretrained(
|
15 |
-
|
|
|
|
|
|
|
|
|
|
|
16 |
|
17 |
-
return processor,
|
18 |
|
19 |
-
# Base de dados nutricional
|
20 |
NUTRITION_DB = {
|
21 |
"arroz": {"calorias": 130, "proteinas": 2.7, "carboidratos": 28, "gorduras": 0.3},
|
22 |
"feijão": {"calorias": 77, "proteinas": 5.2, "carboidratos": 13.6, "gorduras": 0.5},
|
23 |
"frango": {"calorias": 165, "proteinas": 31, "carboidratos": 0, "gorduras": 3.6},
|
24 |
"salada": {"calorias": 15, "proteinas": 1.4, "carboidratos": 2.9, "gorduras": 0.2},
|
|
|
|
|
|
|
|
|
|
|
25 |
}
|
26 |
|
27 |
def process_image(image, progress=gr.Progress()):
|
28 |
-
"""Processa a imagem
|
29 |
try:
|
30 |
-
progress(0.3, desc="
|
31 |
-
processor,
|
32 |
|
33 |
progress(0.5, desc="Processando imagem...")
|
|
|
34 |
if isinstance(image, np.ndarray):
|
35 |
image = Image.fromarray(image)
|
36 |
|
|
|
|
|
|
|
37 |
# Processa a imagem
|
38 |
-
inputs = processor(images=image, return_tensors="pt").to(device)
|
39 |
|
40 |
progress(0.7, desc="Gerando descrição...")
|
41 |
# Gera a descrição
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
|
|
|
|
48 |
|
49 |
# Decodifica a saída
|
50 |
description = processor.decode(outputs[0], skip_special_tokens=True)
|
@@ -97,17 +113,22 @@ def analyze_foods(description):
|
|
97 |
]
|
98 |
})
|
99 |
|
100 |
-
analysis = f"""###
|
101 |
-
• {', '.join(found_foods)}
|
102 |
-
|
103 |
-
### Descrição do Modelo:
|
104 |
{description}
|
105 |
|
106 |
-
###
|
|
|
|
|
|
|
107 |
• Calorias Totais: {total_nutrients['calorias']:.1f} kcal
|
108 |
• Proteínas: {total_nutrients['proteinas']:.1f}g
|
109 |
• Carboidratos: {total_nutrients['carboidratos']:.1f}g
|
110 |
• Gorduras: {total_nutrients['gorduras']:.1f}g
|
|
|
|
|
|
|
|
|
|
|
111 |
"""
|
112 |
|
113 |
return analysis, table_data, plot_data
|
@@ -132,8 +153,8 @@ def analyze_image(image):
|
|
132 |
# Interface Gradio
|
133 |
with gr.Blocks(theme=gr.themes.Soft()) as iface:
|
134 |
gr.Markdown("""
|
135 |
-
# 🍽️ Análise Nutricional com
|
136 |
-
Faça upload de uma foto do seu prato para análise nutricional.
|
137 |
""")
|
138 |
|
139 |
with gr.Row():
|
@@ -144,26 +165,37 @@ with gr.Blocks(theme=gr.themes.Soft()) as iface:
|
|
144 |
label="Foto do Prato",
|
145 |
sources=["upload", "webcam"]
|
146 |
)
|
147 |
-
analyze_btn = gr.Button("📊 Analisar", variant="primary")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
148 |
|
149 |
# Coluna de Output
|
150 |
with gr.Column():
|
151 |
# Análise textual
|
152 |
-
output_text = gr.Markdown(
|
153 |
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
|
|
|
|
|
|
167 |
|
168 |
# Eventos
|
169 |
analyze_btn.click(
|
@@ -173,4 +205,5 @@ with gr.Blocks(theme=gr.themes.Soft()) as iface:
|
|
173 |
)
|
174 |
|
175 |
if __name__ == "__main__":
|
|
|
176 |
iface.launch()
|
|
|
1 |
import gradio as gr
|
2 |
import torch
|
3 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer, AutoProcessor
|
4 |
import pandas as pd
|
5 |
import numpy as np
|
6 |
from PIL import Image
|
7 |
|
8 |
+
def load_model():
|
9 |
+
"""Inicializa o modelo DeepSeek Multimodal"""
|
10 |
device = "cuda" if torch.cuda.is_available() else "cpu"
|
11 |
+
model_name = "deepseek-ai/deepseek-vl-7b-base"
|
12 |
|
13 |
processor = AutoProcessor.from_pretrained(model_name)
|
14 |
+
model = AutoModelForCausalLM.from_pretrained(
|
15 |
+
model_name,
|
16 |
+
torch_dtype=torch.float16 if device == "cuda" else torch.float32,
|
17 |
+
device_map="auto",
|
18 |
+
trust_remote_code=True
|
19 |
+
)
|
20 |
+
tokenizer = AutoTokenizer.from_pretrained(model_name)
|
21 |
|
22 |
+
return model, processor, tokenizer, device
|
23 |
|
24 |
+
# Base de dados nutricional
|
25 |
NUTRITION_DB = {
|
26 |
"arroz": {"calorias": 130, "proteinas": 2.7, "carboidratos": 28, "gorduras": 0.3},
|
27 |
"feijão": {"calorias": 77, "proteinas": 5.2, "carboidratos": 13.6, "gorduras": 0.5},
|
28 |
"frango": {"calorias": 165, "proteinas": 31, "carboidratos": 0, "gorduras": 3.6},
|
29 |
"salada": {"calorias": 15, "proteinas": 1.4, "carboidratos": 2.9, "gorduras": 0.2},
|
30 |
+
"batata": {"calorias": 93, "proteinas": 2.5, "carboidratos": 21, "gorduras": 0.1},
|
31 |
+
"carne": {"calorias": 250, "proteinas": 26, "carboidratos": 0, "gorduras": 17},
|
32 |
+
"peixe": {"calorias": 206, "proteinas": 22, "carboidratos": 0, "gorduras": 12},
|
33 |
+
"macarrão": {"calorias": 158, "proteinas": 5.8, "carboidratos": 31, "gorduras": 1.2},
|
34 |
+
"ovo": {"calorias": 155, "proteinas": 13, "carboidratos": 1.1, "gorduras": 11},
|
35 |
}
|
36 |
|
37 |
def process_image(image, progress=gr.Progress()):
|
38 |
+
"""Processa a imagem usando DeepSeek Multimodal"""
|
39 |
try:
|
40 |
+
progress(0.3, desc="Inicializando modelo...")
|
41 |
+
model, processor, tokenizer, device = load_model()
|
42 |
|
43 |
progress(0.5, desc="Processando imagem...")
|
44 |
+
# Prepara a imagem
|
45 |
if isinstance(image, np.ndarray):
|
46 |
image = Image.fromarray(image)
|
47 |
|
48 |
+
# Prompt específico para identificação de alimentos
|
49 |
+
prompt = "Analise esta imagem e liste todos os alimentos visíveis. Para cada alimento, informe o tipo e estado (ex: cozido, cru, grelhado)."
|
50 |
+
|
51 |
# Processa a imagem
|
52 |
+
inputs = processor(images=image, text=prompt, return_tensors="pt").to(device)
|
53 |
|
54 |
progress(0.7, desc="Gerando descrição...")
|
55 |
# Gera a descrição
|
56 |
+
with torch.no_grad():
|
57 |
+
outputs = model.generate(
|
58 |
+
**inputs,
|
59 |
+
max_new_tokens=150,
|
60 |
+
do_sample=True,
|
61 |
+
temperature=0.7,
|
62 |
+
top_p=0.9,
|
63 |
+
)
|
64 |
|
65 |
# Decodifica a saída
|
66 |
description = processor.decode(outputs[0], skip_special_tokens=True)
|
|
|
113 |
]
|
114 |
})
|
115 |
|
116 |
+
analysis = f"""### 🍽️ Descrição do Modelo:
|
|
|
|
|
|
|
117 |
{description}
|
118 |
|
119 |
+
### 🔍 Alimentos Identificados:
|
120 |
+
• {', '.join(found_foods)}
|
121 |
+
|
122 |
+
### 📊 Análise Nutricional:
|
123 |
• Calorias Totais: {total_nutrients['calorias']:.1f} kcal
|
124 |
• Proteínas: {total_nutrients['proteinas']:.1f}g
|
125 |
• Carboidratos: {total_nutrients['carboidratos']:.1f}g
|
126 |
• Gorduras: {total_nutrients['gorduras']:.1f}g
|
127 |
+
|
128 |
+
### 💡 Avaliação:
|
129 |
+
{"✅ Refeição balanceada!" if total_nutrients['proteinas'] > 15 else "⚠️ Considere adicionar mais proteínas"}
|
130 |
+
{"✅ Carboidratos adequados" if total_nutrients['carboidratos'] < 60 else "⚠️ Alto teor de carboidratos"}
|
131 |
+
{"✅ Gorduras em nível adequado" if total_nutrients['gorduras'] < 20 else "⚠️ Alto teor de gorduras"}
|
132 |
"""
|
133 |
|
134 |
return analysis, table_data, plot_data
|
|
|
153 |
# Interface Gradio
|
154 |
with gr.Blocks(theme=gr.themes.Soft()) as iface:
|
155 |
gr.Markdown("""
|
156 |
+
# 🍽️ Análise Nutricional com DeepSeek
|
157 |
+
Faça upload de uma foto do seu prato para análise nutricional detalhada.
|
158 |
""")
|
159 |
|
160 |
with gr.Row():
|
|
|
165 |
label="Foto do Prato",
|
166 |
sources=["upload", "webcam"]
|
167 |
)
|
168 |
+
analyze_btn = gr.Button("📊 Analisar", variant="primary", size="lg")
|
169 |
+
|
170 |
+
with gr.Accordion("📝 Dicas", open=False):
|
171 |
+
gr.Markdown("""
|
172 |
+
- Use fotos bem iluminadas
|
173 |
+
- Fotografe de cima para baixo
|
174 |
+
- Certifique-se que todos os alimentos estão visíveis
|
175 |
+
- Evite sombras ou reflexos fortes
|
176 |
+
""")
|
177 |
|
178 |
# Coluna de Output
|
179 |
with gr.Column():
|
180 |
# Análise textual
|
181 |
+
output_text = gr.Markdown()
|
182 |
|
183 |
+
with gr.Row():
|
184 |
+
# Tabela nutricional
|
185 |
+
output_table = gr.Dataframe(
|
186 |
+
headers=["Nutriente", "Quantidade"],
|
187 |
+
label="Informação Nutricional",
|
188 |
+
wrap=True
|
189 |
+
)
|
190 |
+
|
191 |
+
# Gráfico
|
192 |
+
output_plot = gr.BarPlot(
|
193 |
+
x="Nutriente",
|
194 |
+
y="Quantidade",
|
195 |
+
title="Macronutrientes (g)",
|
196 |
+
height=300,
|
197 |
+
tooltip=["Nutriente", "Quantidade"]
|
198 |
+
)
|
199 |
|
200 |
# Eventos
|
201 |
analyze_btn.click(
|
|
|
205 |
)
|
206 |
|
207 |
if __name__ == "__main__":
|
208 |
+
print(f"Usando dispositivo: {'CUDA' if torch.cuda.is_available() else 'CPU'}")
|
209 |
iface.launch()
|