Spaces:
Runtime error
Runtime error
init
Browse files
app.py
CHANGED
@@ -4,6 +4,9 @@ import torch
|
|
4 |
from transformers import Qwen2_5_VLForConditionalGeneration, AutoProcessor
|
5 |
import os
|
6 |
from datetime import datetime
|
|
|
|
|
|
|
7 |
|
8 |
# Model setup
|
9 |
processor = AutoProcessor.from_pretrained("deepguess/weather-vlm-qwen2.5-7b", trust_remote_code=True)
|
@@ -79,10 +82,39 @@ MODE_INFO = {
|
|
79 |
"research": "In-depth research perspective"
|
80 |
}
|
81 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
82 |
@spaces.GPU(duration=90)
|
83 |
-
def analyze_weather_image(image, analysis_type, custom_prompt, analysis_mode, temperature, max_tokens, top_p):
|
84 |
-
|
85 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
86 |
|
87 |
# Move model to GPU
|
88 |
model.cuda()
|
@@ -124,7 +156,8 @@ def analyze_weather_image(image, analysis_type, custom_prompt, analysis_mode, te
|
|
124 |
|
125 |
# Add metadata
|
126 |
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S UTC")
|
127 |
-
|
|
|
128 |
|
129 |
return response + metadata
|
130 |
|
@@ -135,18 +168,35 @@ with gr.Blocks(title=TITLE, theme=gr.themes.Base(), css="""
|
|
135 |
#analysis-output { font-family: 'Monaco', 'Menlo', monospace; font-size: 13px; }
|
136 |
.gr-button-primary { background-color: #2563eb; }
|
137 |
.gr-button-primary:hover { background-color: #1e40af; }
|
|
|
138 |
""") as demo:
|
139 |
gr.Markdown(f"# {TITLE}")
|
140 |
gr.Markdown(DESCRIPTION)
|
141 |
|
142 |
with gr.Row():
|
143 |
with gr.Column(scale=1):
|
144 |
-
# Image input
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
150 |
|
151 |
# Analysis type selector
|
152 |
analysis_type = gr.Dropdown(
|
@@ -250,25 +300,6 @@ with gr.Blocks(title=TITLE, theme=gr.themes.Base(), css="""
|
|
250 |
outputs=custom_prompt
|
251 |
)
|
252 |
|
253 |
-
# Examples section
|
254 |
-
example_data = [
|
255 |
-
["examples/500mb_heights.jpg", "Model Output", "technical", 0.7, 512],
|
256 |
-
["examples/sounding.jpg", "Sounding Analysis", "educational", 0.7, 512],
|
257 |
-
["examples/radar_composite.jpg", "Radar/Satellite", "operational", 0.7, 384],
|
258 |
-
["examples/spc_outlook.jpg", "Severe Weather", "operational", 0.7, 512],
|
259 |
-
["examples/ensemble_spaghetti.jpg", "Ensemble Analysis", "research", 0.8, 640],
|
260 |
-
] if os.path.exists("examples") else []
|
261 |
-
|
262 |
-
if example_data:
|
263 |
-
gr.Examples(
|
264 |
-
examples=example_data,
|
265 |
-
inputs=[image_input, analysis_type, analysis_mode, temperature, max_tokens],
|
266 |
-
outputs=output,
|
267 |
-
fn=lambda img, typ, mode, temp, tok: analyze_weather_image(img, typ, "", mode, temp, tok, 0.95),
|
268 |
-
cache_examples=False,
|
269 |
-
label="Example Analyses"
|
270 |
-
)
|
271 |
-
|
272 |
# Tips section
|
273 |
with gr.Accordion("💡 Pro Tips for Best Results", open=False):
|
274 |
gr.Markdown("""
|
@@ -277,6 +308,19 @@ with gr.Blocks(title=TITLE, theme=gr.themes.Base(), css="""
|
|
277 |
- **Clarity**: Ensure text/contours are legible
|
278 |
- **Completeness**: Include colorbars, titles, valid times
|
279 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
280 |
### Analysis Tips by Data Type:
|
281 |
|
282 |
**Model Output (GFS, HRRR, ECMWF, NAM):**
|
@@ -293,17 +337,6 @@ with gr.Blocks(title=TITLE, theme=gr.themes.Base(), css="""
|
|
293 |
- Include timestamp and location
|
294 |
- Specify interest in particular features
|
295 |
- Ask about storm motion or development
|
296 |
-
|
297 |
-
**Surface/Upper Air Charts:**
|
298 |
-
- Ensure contours and labels are clear
|
299 |
-
- Ask about specific features or patterns
|
300 |
-
- Request frontal analysis or jet stream discussion
|
301 |
-
|
302 |
-
### Parameter Settings:
|
303 |
-
- **Temperature 0.3-0.5**: Factual, consistent analysis
|
304 |
-
- **Temperature 0.6-0.8**: Balanced analysis with some interpretation
|
305 |
-
- **Temperature 0.9-1.0**: More speculative, exploring possibilities
|
306 |
-
- **Max Tokens**: Use 256-384 for quick analysis, 512-768 for detailed
|
307 |
""")
|
308 |
|
309 |
# Update mode description when mode changes
|
@@ -316,9 +349,15 @@ with gr.Blocks(title=TITLE, theme=gr.themes.Base(), css="""
|
|
316 |
# Set up event handler
|
317 |
analyze_btn.click(
|
318 |
fn=analyze_weather_image,
|
319 |
-
inputs=[image_input, analysis_type, custom_prompt, analysis_mode, temperature, max_tokens, top_p],
|
320 |
outputs=output
|
321 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
322 |
|
323 |
# Launch the app
|
324 |
if __name__ == "__main__":
|
|
|
4 |
from transformers import Qwen2_5_VLForConditionalGeneration, AutoProcessor
|
5 |
import os
|
6 |
from datetime import datetime
|
7 |
+
from PIL import Image
|
8 |
+
import requests
|
9 |
+
from io import BytesIO
|
10 |
|
11 |
# Model setup
|
12 |
processor = AutoProcessor.from_pretrained("deepguess/weather-vlm-qwen2.5-7b", trust_remote_code=True)
|
|
|
82 |
"research": "In-depth research perspective"
|
83 |
}
|
84 |
|
85 |
+
# Example URLs for different weather data types
|
86 |
+
EXAMPLE_URLS = {
|
87 |
+
"SPC Convective Outlook": "https://www.spc.noaa.gov/products/outlook/day1otlk.gif",
|
88 |
+
"SPC Mesoanalysis (Surface)": "https://inside.nssl.noaa.gov/ewp/wp-content/uploads/sites/22/2019/05/19ZSPCCape.png",
|
89 |
+
"College of DuPage Nexrad": "https://upload.wikimedia.org/wikipedia/commons/9/9b/NEXRAD_radar_of_an_EF2_tornado_in_Kansas_on_March_13%2C_2024.png",
|
90 |
+
"Tropical Tidbits GFS 500mb": "https://sites.gatech.edu/eas-mesoscale-blog/files/2023/04/Hebert_Fig4-768x531.png",
|
91 |
+
"GOES-16 Visible": "https://cdn.star.nesdis.noaa.gov/GOES16/ABI/CONUS/GEOCOLOR/1250x750.jpg",
|
92 |
+
"KOUN Sounding": "https://sharppy.github.io/SHARPpy/_images/gui.sharppy.png",
|
93 |
+
}
|
94 |
+
|
95 |
+
def load_image_from_url(url):
|
96 |
+
"""Load an image from URL."""
|
97 |
+
try:
|
98 |
+
response = requests.get(url, timeout=10, headers={'User-Agent': 'Mozilla/5.0'})
|
99 |
+
response.raise_for_status()
|
100 |
+
img = Image.open(BytesIO(response.content))
|
101 |
+
# Convert to RGB if necessary
|
102 |
+
if img.mode != 'RGB':
|
103 |
+
img = img.convert('RGB')
|
104 |
+
return img
|
105 |
+
except Exception as e:
|
106 |
+
return None, f"Error loading image from URL: {str(e)}"
|
107 |
+
|
108 |
@spaces.GPU(duration=90)
|
109 |
+
def analyze_weather_image(image, image_url, analysis_type, custom_prompt, analysis_mode, temperature, max_tokens, top_p):
|
110 |
+
# Handle image input - either direct upload or URL
|
111 |
+
if image_url and image_url.strip():
|
112 |
+
result = load_image_from_url(image_url.strip())
|
113 |
+
if isinstance(result, tuple): # Error case
|
114 |
+
return result[1]
|
115 |
+
image = result
|
116 |
+
elif image is None:
|
117 |
+
return "Please upload an image or provide an image URL to analyze."
|
118 |
|
119 |
# Move model to GPU
|
120 |
model.cuda()
|
|
|
156 |
|
157 |
# Add metadata
|
158 |
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S UTC")
|
159 |
+
source = "URL" if image_url and image_url.strip() else "Upload"
|
160 |
+
metadata = f"\n\n---\n*Analysis completed: {timestamp} | Mode: {analysis_mode} | Type: {analysis_type} | Source: {source}*"
|
161 |
|
162 |
return response + metadata
|
163 |
|
|
|
168 |
#analysis-output { font-family: 'Monaco', 'Menlo', monospace; font-size: 13px; }
|
169 |
.gr-button-primary { background-color: #2563eb; }
|
170 |
.gr-button-primary:hover { background-color: #1e40af; }
|
171 |
+
.url-button { min-width: 120px; }
|
172 |
""") as demo:
|
173 |
gr.Markdown(f"# {TITLE}")
|
174 |
gr.Markdown(DESCRIPTION)
|
175 |
|
176 |
with gr.Row():
|
177 |
with gr.Column(scale=1):
|
178 |
+
# Image input options
|
179 |
+
with gr.Tabs():
|
180 |
+
with gr.Tab("Upload Image"):
|
181 |
+
image_input = gr.Image(
|
182 |
+
label="Upload Weather Image",
|
183 |
+
type="pil",
|
184 |
+
elem_id="image-upload"
|
185 |
+
)
|
186 |
+
|
187 |
+
with gr.Tab("Image URL"):
|
188 |
+
image_url_input = gr.Textbox(
|
189 |
+
label="Image URL",
|
190 |
+
placeholder="https://example.com/weather-image.jpg",
|
191 |
+
lines=1
|
192 |
+
)
|
193 |
+
|
194 |
+
# Quick URL examples
|
195 |
+
gr.Markdown("**Quick Examples:**")
|
196 |
+
url_buttons = []
|
197 |
+
for name, url in EXAMPLE_URLS.items():
|
198 |
+
btn = gr.Button(name, size="sm", elem_classes="url-button")
|
199 |
+
btn.click(lambda u=url: u, outputs=image_url_input)
|
200 |
|
201 |
# Analysis type selector
|
202 |
analysis_type = gr.Dropdown(
|
|
|
300 |
outputs=custom_prompt
|
301 |
)
|
302 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
303 |
# Tips section
|
304 |
with gr.Accordion("💡 Pro Tips for Best Results", open=False):
|
305 |
gr.Markdown("""
|
|
|
308 |
- **Clarity**: Ensure text/contours are legible
|
309 |
- **Completeness**: Include colorbars, titles, valid times
|
310 |
|
311 |
+
### Using URLs:
|
312 |
+
- Supports direct links to JPG, PNG, GIF images
|
313 |
+
- Some weather sites may block direct access
|
314 |
+
- For best results, use official weather service URLs
|
315 |
+
- Alternative: Save image locally and upload
|
316 |
+
|
317 |
+
### Common Weather Data Sources:
|
318 |
+
- **SPC**: Convective outlooks, mesoanalysis
|
319 |
+
- **College of DuPage**: NEXRAD, model data
|
320 |
+
- **Tropical Tidbits**: Model analysis maps
|
321 |
+
- **GOES Imagery**: Satellite data
|
322 |
+
- **WPC**: Surface analysis, QPF
|
323 |
+
|
324 |
### Analysis Tips by Data Type:
|
325 |
|
326 |
**Model Output (GFS, HRRR, ECMWF, NAM):**
|
|
|
337 |
- Include timestamp and location
|
338 |
- Specify interest in particular features
|
339 |
- Ask about storm motion or development
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
340 |
""")
|
341 |
|
342 |
# Update mode description when mode changes
|
|
|
349 |
# Set up event handler
|
350 |
analyze_btn.click(
|
351 |
fn=analyze_weather_image,
|
352 |
+
inputs=[image_input, image_url_input, analysis_type, custom_prompt, analysis_mode, temperature, max_tokens, top_p],
|
353 |
outputs=output
|
354 |
)
|
355 |
+
|
356 |
+
# Clear image upload when URL is entered
|
357 |
+
image_url_input.change(
|
358 |
+
lambda: None,
|
359 |
+
outputs=image_input
|
360 |
+
)
|
361 |
|
362 |
# Launch the app
|
363 |
if __name__ == "__main__":
|