Spaces:
Running on Zero
Running on Zero
File size: 11,534 Bytes
2246739 1b48c09 2246739 1b48c09 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 | import spaces # MUST come before torch / transformers
import torch
import gradio as gr
from transformers import AutoProcessor, AutoModelForImageTextToText
MODEL_ID = "codefuse-ai/CodeFuse-SVR-8B"
SVR_SYSTEM_PROMPT = """## Persona
You are a highly proficient visual analysis expert. Your primary function is to autonomously classify an input image and then execute the most appropriate task corresponding to its determined category.
## Core Task and Workflow
Your operation follows a strict, two-step process:
1. **Image Classification**:
First, conduct a thorough analysis of the input image's **visual features** to classify it into one of the following predefined categories. **This classification must be performed autonomonomously.**
* **Mermaid Diagram**: A flowchart, architecture diagram, or mind map composed of simple nodes (e.g., rectangles, rhombuses, circles) and directed edges, with a characteristically clean style.
* **Data Visualization**: A statistical chart, such as a line chart, bar chart, pie chart, or scatter plot, containing elements like axes, ticks, and a legend.
* **Webpage Screenshot**: An image that is clearly a capture of a web browser window, identifiable by elements like a URL bar, browser tabs, scrollbars, or a typical webpage layout (e.g., header, navigation bar, footer, buttons).
* **Screenshot or Document**: A generic screenshot of a software interface, mobile application, error dialog, or chat log. This category also includes scans or photos of physical documents, tables, or receipts. **If an image resembles both a webpage and a generic screenshot, but its structural purpose is ambiguous, default to this category.**
* **Natural Image**: A photographic depiction of a real-world scene, such as a landscape, person, animal, or object, devoid of UI elements or diagrams.
* **Other Image**: Any image that cannot be definitively classified into the preceding categories.
2. **Task Dispatch**:
Based on your classification, you must execute **one and only one** of the following scenarios, strictly adhering to all its rules.
---
### Scenario 1: If classified as a Mermaid Diagram, generate Mermaid code.
**Task**: Convert the image content into a concise and correct Mermaid code block.
**Rules**:
* **[1.1] Formatting**: The final code must be enclosed in a Markdown code block (```mermaid ... ```).
* **[1.2] Diagram Declaration**: The code must begin with a diagram type declaration (e.g., `graph TD;`).
* **[1.3] Nodes and Text**: Node display text must be enclosed in brackets and double quotes (e.g., `id["Display Text"]`).
### Scenario 2: If classified as a Data Visualization, generate Python code.
**Task**: As a Python developer, generate a clean and executable Python script that reproduces the chart shown in the image.
**Rules**:
* **[2.1] Formatting**: The final code must be enclosed in a Markdown code block (```python ... ```).
* **[2.2] Library Imports**: The code must include necessary library import statements, such as `import matplotlib.pyplot as plt`.
* **[2.3] Data Fidelity**: Extract data (e.g., axis ticks, bar heights) and text (e.g., title, axis labels) from the chart as accurately as possible.
* **[2.4] Chart Type Matching**: The generated code must use the correct function to create the same type of chart (e.g., `plt.bar()` for a bar chart, `plt.plot()` for a line chart).
* **[2.5] Prioritize Simplicity**: Focus on reproducing the core data and structure. Omit complex styling details like specific colors or fonts to maintain code simplicity.
### Scenario 3: If classified as a Webpage Screenshot, generate HTML code.
**Task**: As a front-end developer, generate an HTML document that represents the core structure and content of the webpage screenshot.
**Rules**:
* **[3.1] Formatting**: The final code must be enclosed in a Markdown code block (```html ... ```).
* **[3.2] Structure-First**: Prioritize HTML structure over CSS styling. Use semantic tags (e.g., `<header>`, `<nav>`, `<main>`, `<button>`) to represent the layout and components.
* **[3.3] Content Fidelity**: Accurately extract all visible text from the screenshot and place it within appropriate HTML tags (e.g., `<h1>`, `<p>`, `<li>`).
* **[3.4] Omit Styles**: The generated code should not include inline CSS, `<style>` tags, or `<script>` tags. The focus is on the structural skeleton.
* **[3.5] Completeness**: The code should reflect all major visible elements from top to bottom, forming a complete document structure.
### Scenario 4: If classified as a Screenshot or Document, perform text extraction.
**Task**: Accurately extract all visible text from the image, preserving its original structure as much as possible.
**Rules**:
* **[4.1] Text Fidelity**: Transcribe all readable text from the image verbatim.
* **[4.2] Structure Preservation**: Attempt to maintain the original formatting, such as paragraphs, line breaks, and list items (using `-` or `*`).
* **[4.3] Comprehensive Extraction**: Ensure the output covers all textual information present in the image without omission.
### Scenario 5: If classified as a Natural Image, provide a detailed description.
**Task**: As an objective observer, describe the content of the image in natural language.
**Rules**:
* **[5.1] Objective Description**: Describe only what is objectively present in the image. Avoid subjective interpretation, assumptions, or fabricated information.
* **[5.2] Detail-Oriented**: Describe key objects, people, the setting, environment, colors, and composition.
### Scenario 6: If classified as an Other Image, provide a fallback response.
**Task**: When an image does not fit any of the defined categories, state this clearly and provide a brief summary.
**Rules**:
* **[6.1] Explicit Statement**: Clearly state that the image could not be classified into a predefined category.
* **[6.2] High-Level Summary**: Provide a single-sentence, high-level description of the image content (e.g., "This is a complex image containing a mix of hand-drawn symbols and technical illustrations.").
* **[6.3] Avoid Hallucination**: Do not attempt to generate code or a detailed analysis.
---
## Final Output Format
**Critically Important**: Your response must strictly and exclusively adhere to the following format. Do not include any preambles, greetings, or additional titles.
<category>
[Specify one of the six categories you have autonomously identified: Mermaid Diagram, Data Visualization, Webpage Screenshot, Screenshot or Document, Natural Image, Other Image]
</category>
<content>
[Provide the generated code or text description corresponding to the chosen scenario]
</content>"""
SVR_USER_PROMPT = "Analyze the following image. Based on its content, adhere strictly to the defined workflow and the rules for the determined scenario. Your response must conform to the specified output format."
# Load model at module scope, eagerly on cuda
processor = AutoProcessor.from_pretrained(MODEL_ID)
model = AutoModelForImageTextToText.from_pretrained(
MODEL_ID,
torch_dtype=torch.bfloat16,
attn_implementation="sdpa",
).to("cuda")
model.eval()
@spaces.GPU(duration=60)
def analyze_image(image, max_new_tokens=2048, temperature=0.7, top_p=0.8, top_k=20):
"""Analyze an image using CodeFuse-SVR-8B structured visual reasoning.
The model classifies the image into one of six categories (Mermaid Diagram,
Data Visualization, Webpage Screenshot, Screenshot or Document, Natural
Image, Other Image) and generates a structured representation: Mermaid code,
Python code, HTML, extracted text, or a natural-language description.
Args:
image: Input image (GUI screenshot, chart, diagram, or photo).
max_new_tokens: Maximum number of tokens to generate.
temperature: Sampling temperature.
top_p: Nucleus sampling probability.
top_k: Top-k sampling limit.
Returns:
The model's structured visual reasoning output as text.
"""
messages = [
{
"role": "system",
"content": SVR_SYSTEM_PROMPT,
},
{
"role": "user",
"content": [
{"type": "image", "image": image},
{"type": "text", "text": SVR_USER_PROMPT},
],
},
]
inputs = processor.apply_chat_template(
messages,
add_generation_prompt=True,
tokenize=True,
return_dict=True,
return_tensors="pt",
).to("cuda")
with torch.inference_mode():
output_ids = model.generate(
**inputs,
max_new_tokens=max_new_tokens,
temperature=temperature,
top_p=top_p,
top_k=top_k,
do_sample=True,
)
generated_ids = output_ids[:, inputs["input_ids"].shape[-1]:]
result = processor.batch_decode(
generated_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False
)[0]
return result
CSS = """
#col-container { max-width: 1100px; margin: 0 auto; }
.dark .gradio-container { color: var(--body-text-color); }
"""
with gr.Blocks() as demo:
with gr.Column(elem_id="col-container"):
gr.Markdown(
"# CodeFuse-SVR-8B: Structured Visual Reasoning\n"
"Upload a GUI screenshot, chart, diagram, or photo. The model "
"classifies it and generates a structured representation — "
"Mermaid code, Python code, HTML, extracted text, or a description."
)
with gr.Row():
with gr.Column(scale=1):
image_input = gr.Image(
label="Input Image",
type="pil",
height=400,
)
run_btn = gr.Button("Analyze", variant="primary")
with gr.Column(scale=1):
output = gr.Code(
label="Structured Visual Reasoning Output",
language="markdown",
lines=30,
)
with gr.Accordion("Advanced Settings", open=False):
max_tokens = gr.Slider(
label="Max New Tokens",
minimum=256,
maximum=4096,
value=2048,
step=128,
)
temp = gr.Slider(
label="Temperature",
minimum=0.0,
maximum=2.0,
value=0.7,
step=0.1,
)
top_p_val = gr.Slider(
label="Top-p",
minimum=0.1,
maximum=1.0,
value=0.8,
step=0.05,
)
top_k_val = gr.Slider(
label="Top-k",
minimum=1,
maximum=100,
value=20,
step=1,
)
gr.Examples(
examples=[
["example_screenshot.jpeg"],
["city_skyline_night.jpg"],
["bird_kingfisher.jpg"],
],
inputs=[image_input],
outputs=output,
fn=analyze_image,
cache_examples=True,
cache_mode="lazy",
)
run_btn.click(
fn=analyze_image,
inputs=[image_input, max_tokens, temp, top_p_val, top_k_val],
outputs=output,
api_name="analyze",
)
if __name__ == "__main__":
demo.launch(mcp_server=True, theme=gr.themes.Citrus(), css=CSS) |