Kilos1 commited on
Commit
d66422e
·
verified ·
1 Parent(s): 2d136e2

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +125 -0
app.py ADDED
@@ -0,0 +1,125 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+ import re
3
+ import base64
4
+ import os
5
+ from transformers import AutoModelForCausalLM, AutoTokenizer
6
+ from PIL import Image
7
+ from flask import Flask, render_template, request, redirect, url_for, flash
8
+
9
+ app = Flask(__name__)
10
+
11
+ # Load the Hugging Face model and tokenizer
12
+ model_id = "meta-llama/llama-3-2-90b-vision-instruct"
13
+ tokenizer = AutoTokenizer.from_pretrained(model_id)
14
+ model = AutoModelForCausalLM.from_pretrained(model_id)
15
+
16
+ def input_image_setup(uploaded_file):
17
+ """
18
+ Encodes the uploaded image file into a base64 string to be used with AI models.
19
+
20
+ Parameters:
21
+ - uploaded_file: File-like object uploaded via a file uploader
22
+
23
+ Returns:
24
+ - encoded_image (str): Base64 encoded string of the image data
25
+ """
26
+ if uploaded_file is not None:
27
+ bytes_data = uploaded_file.read()
28
+ encoded_image = base64.b64encode(bytes_data).decode("utf-8")
29
+ return encoded_image
30
+ else:
31
+ raise FileNotFoundError("No file uploaded")
32
+
33
+ def format_response(response_text):
34
+ """
35
+ Formats the model response to display each item on a new line as a list.
36
+ Converts numbered items into HTML `<ul>` and `<li>` format.
37
+ """
38
+ response_text = re.sub(r"\*\*(.*?)\*\*", r"<p><strong>\1</strong></p>", response_text)
39
+ response_text = re.sub(r"(?m)^\s*\*\s(.*)", r"<li>\1</li>", response_text)
40
+ response_text = re.sub(r"(<li>.*?</li>)+", lambda match: f"<ul>{match.group(0)}</ul>", response_text, flags=re.DOTALL)
41
+ response_text = re.sub(r"</p>(?=<p>)", r"</p><br>", response_text)
42
+ response_text = re.sub(r"(\n|\\n)+", r"<br>", response_text)
43
+ return response_text
44
+
45
+ def generate_model_response(encoded_image, user_query, assistant_prompt):
46
+ """
47
+ Sends an image and a query to the model and retrieves the description or answer.
48
+ Formats the response using HTML elements for better presentation.
49
+ """
50
+ # Prepare input for the model
51
+ input_text = assistant_prompt + "\n\n" + user_query + "\n![Image](data:image/jpeg;base64," + encoded_image + ")"
52
+
53
+ inputs = tokenizer(input_text, return_tensors="pt")
54
+
55
+ try:
56
+ # Generate the model's response
57
+ outputs = model.generate(**inputs)
58
+ raw_response = tokenizer.decode(outputs[0], skip_special_tokens=True)
59
+
60
+ # Format the raw response text using the format_response function
61
+ formatted_response = format_response(raw_response)
62
+ return formatted_response
63
+ except Exception as e:
64
+ print(f"Error in generating response: {e}")
65
+ return "<p>An error occurred while generating the response.</p>"
66
+
67
+ @app.route("/", methods=["GET", "POST"])
68
+ def index():
69
+ if request.method == "POST":
70
+ user_query = request.form.get("user_query")
71
+ uploaded_file = request.files.get("file")
72
+
73
+ if uploaded_file:
74
+ encoded_image = input_image_setup(uploaded_file)
75
+
76
+ if not encoded_image:
77
+ flash("Error processing the image. Please try again.", "danger")
78
+ return redirect(url_for("index"))
79
+
80
+ assistant_prompt = """
81
+ You are an expert nutritionist. Your task is to analyze the food items displayed in the image and provide a detailed nutritional assessment using the following format:
82
+
83
+ 1. **Identification**: List each identified food item clearly, one per line.
84
+ 2. **Portion Size & Calorie Estimation**: For each identified food item, specify the portion size and provide an estimated number of calories. Use bullet points with the following structure:
85
+ - **[Food Item]**: [Portion Size], [Number of Calories] calories
86
+
87
+ Example:
88
+ * **Salmon**: 6 ounces, 210 calories
89
+ * **Asparagus**: 3 spears, 25 calories
90
+
91
+ 3. **Total Calories**: Provide the total number of calories for all food items.
92
+
93
+ Example:
94
+ Total Calories: [Number of Calories]
95
+
96
+ 4. **Nutrient Breakdown**: Include a breakdown of key nutrients such as **Protein**, **Carbohydrates**, **Fats**, **Vitamins**, and **Minerals**. Use bullet points, and for each nutrient provide details about the contribution of each food item.
97
+
98
+ Example:
99
+ * **Protein**: Salmon (35g), Asparagus (3g), Tomatoes (1g) = [Total Protein]
100
+
101
+ 5. **Health Evaluation**: Evaluate the healthiness of the meal in one paragraph.
102
+
103
+ 6. **Disclaimer**: Include the following exact text as a disclaimer:
104
+
105
+ The nutritional information and calorie estimates provided are approximate and are based on general food data.
106
+ Actual values may vary depending on factors such as portion size, specific ingredients, preparation methods, and individual variations.
107
+ For precise dietary advice or medical guidance, consult a qualified nutritionist or healthcare provider.
108
+
109
+ Format your response exactly like the template above to ensure consistency.
110
+ """
111
+
112
+ # Generate the model's response
113
+ response = generate_model_response(encoded_image, user_query, assistant_prompt)
114
+
115
+ # Render the result
116
+ return render_template("index.html", user_query=user_query, response=response)
117
+
118
+ else:
119
+ flash("Please upload an image file.", "danger")
120
+ return redirect(url_for("index"))
121
+
122
+ return render_template("index.html")
123
+
124
+ if __name__ == "__main__":
125
+ app.run(debug=True)