deepguess commited on
Commit
22f9a57
·
1 Parent(s): 18008a3
Files changed (1) hide show
  1. app.py +322 -4
app.py CHANGED
@@ -1,7 +1,325 @@
1
  import gradio as gr
 
 
 
 
 
2
 
3
- def greet(name):
4
- return "Hello " + name + "!!"
 
 
 
 
 
 
5
 
6
- demo = gr.Interface(fn=greet, inputs="text", outputs="text")
7
- demo.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import gradio as gr
2
+ import spaces
3
+ 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)
10
+ model = Qwen2_5_VLForConditionalGeneration.from_pretrained(
11
+ "deepguess/weather-vlm-qwen2.5-7b",
12
+ torch_dtype=torch.float16,
13
+ trust_remote_code=True
14
+ )
15
+ model.eval()
16
 
17
+ # Title and description
18
+ TITLE = "🌦️ Weather Analysis VLM (Qwen2.5-VL-7B Fine-tuned)"
19
+
20
+ DESCRIPTION = """
21
+ ## Advanced Weather Image Analysis
22
+
23
+ This model specializes in analyzing weather data including:
24
+ - **Model Outputs**: GFS, HRRR, ECMWF, NAM analysis
25
+ - **Soundings**: Skew-T diagrams, hodographs, SHARPpy analysis
26
+ - **Observations**: Surface obs, satellite, radar imagery
27
+ - **Forecasts**: Deterministic and ensemble model outputs
28
+ - **Severe Weather**: Convective parameters, SPC outlooks
29
+
30
+ ### ⚠️ Disclaimer
31
+ **For educational and research purposes only. Not for operational forecasting.**
32
+ """
33
+
34
+ # Enhanced prompts based on your data categories
35
+ PROMPT_TEMPLATES = {
36
+ "Quick Analysis": "Describe the weather in this image.",
37
+ "Model Output": "Analyze this model output. What patterns and features are shown?",
38
+ "Sounding Analysis": "Analyze this sounding. Discuss stability, shear, and severe potential.",
39
+ "Radar/Satellite": "Describe the features in this radar or satellite image.",
40
+ "Severe Weather": "Assess severe weather potential based on this image.",
41
+ "Technical Deep Dive": "Provide detailed technical analysis including parameters and meteorological significance.",
42
+ "Forecast Discussion": "Based on this image, what weather evolution is expected?",
43
+ "Pattern Recognition": "Identify synoptic patterns, jet streaks, troughs, ridges, and fronts.",
44
+ "Ensemble Analysis": "Analyze ensemble spread, uncertainty, and most likely scenarios.",
45
+ "Winter Weather": "Analyze precipitation type, accumulation potential, and impacts.",
46
+ }
47
+
48
+ # System prompts for different analysis modes
49
+ SYSTEM_PROMPTS = {
50
+ "technical": """You are an expert meteorologist providing technical analysis. Focus on:
51
+ - Specific parameter values and thresholds
52
+ - Physical processes and dynamics
53
+ - Pattern recognition and anomalies
54
+ - Forecast confidence and uncertainty
55
+ Use technical terminology appropriately.""",
56
+
57
+ "educational": """You are a meteorology instructor. Explain concepts clearly while maintaining accuracy.
58
+ Point out key features and explain their significance. Use some technical terms but define them.""",
59
+
60
+ "operational": """You are providing a weather briefing. Focus on:
61
+ - Current conditions and trends
62
+ - Expected evolution
63
+ - Impacts and hazards
64
+ - Timing of changes
65
+ Be concise but thorough.""",
66
+
67
+ "research": """You are analyzing meteorological data for research purposes. Discuss:
68
+ - Interesting features or anomalies
69
+ - Comparison to climatology
70
+ - Physical mechanisms
71
+ - Uncertainty quantification"""
72
+ }
73
+
74
+ # Analysis mode descriptions
75
+ MODE_INFO = {
76
+ "technical": "Detailed technical analysis for meteorologists",
77
+ "educational": "Clear explanations for learning",
78
+ "operational": "Focused briefing style",
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
+ if image is None:
85
+ return "Please upload an image to analyze."
86
+
87
+ # Move model to GPU
88
+ model.cuda()
89
+
90
+ # Use custom prompt if provided, otherwise use template
91
+ prompt = custom_prompt.strip() if custom_prompt.strip() else PROMPT_TEMPLATES.get(analysis_type, PROMPT_TEMPLATES["Quick Analysis"])
92
+
93
+ # Select system prompt based on mode
94
+ system_content = SYSTEM_PROMPTS.get(analysis_mode, SYSTEM_PROMPTS["technical"])
95
+
96
+ # Prepare messages
97
+ messages = [{
98
+ "role": "system",
99
+ "content": system_content
100
+ }, {
101
+ "role": "user",
102
+ "content": [
103
+ {"type": "text", "text": prompt},
104
+ {"type": "image", "image": image}
105
+ ]
106
+ }]
107
+
108
+ # Process inputs
109
+ text = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
110
+ inputs = processor(text=[text], images=[image], return_tensors="pt").to("cuda")
111
+
112
+ # Generate with specified parameters
113
+ outputs = model.generate(
114
+ **inputs,
115
+ max_new_tokens=max_tokens,
116
+ temperature=temperature,
117
+ do_sample=True,
118
+ top_p=top_p,
119
+ repetition_penalty=1.05
120
+ )
121
+
122
+ # Decode response
123
+ response = processor.batch_decode(outputs[:, inputs.input_ids.shape[1]:], skip_special_tokens=True)[0]
124
+
125
+ # Add metadata
126
+ timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S UTC")
127
+ metadata = f"\n\n---\n*Analysis completed: {timestamp} | Mode: {analysis_mode} | Type: {analysis_type}*"
128
+
129
+ return response + metadata
130
+
131
+ # Create Gradio interface
132
+ with gr.Blocks(title=TITLE, theme=gr.themes.Base(), css="""
133
+ .gradio-container { font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace; }
134
+ .markdown-text { font-size: 14px; }
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
+ image_input = gr.Image(
146
+ label="Upload Weather Image",
147
+ type="pil",
148
+ elem_id="image-upload"
149
+ )
150
+
151
+ # Analysis type selector
152
+ analysis_type = gr.Dropdown(
153
+ label="Analysis Type",
154
+ choices=list(PROMPT_TEMPLATES.keys()),
155
+ value="Quick Analysis",
156
+ info="Select the type of analysis you need"
157
+ )
158
+
159
+ # Analysis mode selector
160
+ analysis_mode = gr.Radio(
161
+ label="Analysis Mode",
162
+ choices=list(MODE_INFO.keys()),
163
+ value="technical",
164
+ info="Choose the style and depth of analysis"
165
+ )
166
+
167
+ # Mode description
168
+ mode_description = gr.Markdown(value=MODE_INFO["technical"], elem_id="mode-desc")
169
+
170
+ # Custom prompt option
171
+ with gr.Accordion("Custom Prompt (Optional)", open=False):
172
+ custom_prompt = gr.Textbox(
173
+ label="Enter your specific question or analysis request",
174
+ placeholder="E.g., 'Focus on the 500mb vorticity patterns' or 'Explain the hodograph curvature'",
175
+ lines=3
176
+ )
177
+
178
+ # Advanced settings
179
+ with gr.Accordion("Advanced Settings", open=False):
180
+ with gr.Row():
181
+ temperature = gr.Slider(
182
+ minimum=0.1,
183
+ maximum=1.0,
184
+ value=0.7,
185
+ step=0.05,
186
+ label="Temperature",
187
+ info="Lower = more focused, Higher = more varied"
188
+ )
189
+
190
+ top_p = gr.Slider(
191
+ minimum=0.5,
192
+ maximum=1.0,
193
+ value=0.95,
194
+ step=0.05,
195
+ label="Top-p",
196
+ info="Nucleus sampling threshold"
197
+ )
198
+
199
+ max_tokens = gr.Slider(
200
+ minimum=128,
201
+ maximum=1024,
202
+ value=512,
203
+ step=64,
204
+ label="Max Output Length",
205
+ info="Longer for detailed analysis"
206
+ )
207
+
208
+ # Analyze button
209
+ analyze_btn = gr.Button("🔍 Analyze Weather", variant="primary", size="lg")
210
+
211
+ with gr.Column(scale=1):
212
+ # Output area
213
+ output = gr.Textbox(
214
+ label="Analysis Results",
215
+ lines=25,
216
+ max_lines=30,
217
+ show_copy_button=True,
218
+ elem_id="analysis-output"
219
+ )
220
+
221
+ # Common weather data categories for quick access
222
+ with gr.Accordion("📊 Quick Templates for Common Data Types", open=False):
223
+ gr.Markdown("""
224
+ ### Click to load analysis templates:
225
+ """)
226
+ with gr.Row():
227
+ gr.Button("500mb Analysis", size="sm").click(
228
+ lambda: "Analyze the 500mb height and wind patterns. Identify troughs, ridges, jet streaks, and vorticity.",
229
+ outputs=custom_prompt
230
+ )
231
+ gr.Button("Sounding Analysis", size="sm").click(
232
+ lambda: "Analyze this sounding for stability, CAPE, shear, LCL, LFC, and severe weather parameters.",
233
+ outputs=custom_prompt
234
+ )
235
+ gr.Button("Composite Reflectivity", size="sm").click(
236
+ lambda: "Analyze radar reflectivity patterns, storm structure, intensity, and movement.",
237
+ outputs=custom_prompt
238
+ )
239
+ with gr.Row():
240
+ gr.Button("Surface Analysis", size="sm").click(
241
+ lambda: "Analyze surface features including fronts, pressure centers, convergence, and boundaries.",
242
+ outputs=custom_prompt
243
+ )
244
+ gr.Button("Ensemble Spread", size="sm").click(
245
+ lambda: "Analyze ensemble spread, clustering, and probabilistic information.",
246
+ outputs=custom_prompt
247
+ )
248
+ gr.Button("Convective Parameters", size="sm").click(
249
+ lambda: "Analyze CAPE, CIN, SRH, bulk shear, and composite parameters for severe potential.",
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("""
275
+ ### Image Guidelines:
276
+ - **Resolution**: Higher resolution images yield better analysis
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):**
283
+ - Include initialization and valid times
284
+ - Specify if you want focus on particular features
285
+ - Ask about ensemble uncertainty if applicable
286
+
287
+ **Soundings (Skew-T, Hodographs):**
288
+ - Ensure all parameters are visible
289
+ - Ask about specific levels or layers
290
+ - Request shear calculations or thermodynamic analysis
291
+
292
+ **Radar/Satellite:**
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
310
+ analysis_mode.change(
311
+ lambda mode: MODE_INFO[mode],
312
+ inputs=analysis_mode,
313
+ outputs=mode_description
314
+ )
315
+
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__":
325
+ demo.launch()