Spaces:
Sleeping
Sleeping
update: fix app name
Browse files
app.py
CHANGED
@@ -1,353 +1,353 @@
|
|
1 |
-
import gradio as gr
|
2 |
-
import torch
|
3 |
-
import cv2
|
4 |
-
import numpy as np
|
5 |
-
from matplotlib import pyplot as plt
|
6 |
-
from PIL import Image, ImageDraw
|
7 |
-
from transformers import AutoProcessor
|
8 |
-
from modeling_florence2 import Florence2ForConditionalGeneration
|
9 |
-
import io
|
10 |
-
import matplotlib.pyplot as plt
|
11 |
-
import matplotlib.patches as patches
|
12 |
-
from matplotlib.patches import Polygon
|
13 |
-
import numpy as np
|
14 |
-
import random
|
15 |
-
import json
|
16 |
-
|
17 |
-
|
18 |
-
with open("config.json", "r") as f:
|
19 |
-
config = json.load(f)
|
20 |
-
|
21 |
-
d_model = config['text_config']['d_model']
|
22 |
-
num_layers = config['text_config']['encoder_layers']
|
23 |
-
attention_heads = config['text_config']['encoder_attention_heads']
|
24 |
-
vocab_size = config['text_config']['vocab_size']
|
25 |
-
max_length = config['text_config']['max_length']
|
26 |
-
beam_size = config['text_config']['num_beams']
|
27 |
-
dropout = config['text_config']['dropout']
|
28 |
-
activation_function = config['text_config']['activation_function']
|
29 |
-
no_repeat_ngram_size = config['text_config']['no_repeat_ngram_size']
|
30 |
-
patch_size = config['vision_config']['patch_size'][0]
|
31 |
-
temporal_embeddings = config['vision_config']['visual_temporal_embedding']['max_temporal_embeddings']
|
32 |
-
|
33 |
-
title = """# 🙋🏻♂️Bem-vindo ao ÓUSI PREMIUM/florence"""
|
34 |
-
description = """
|
35 |
-
Este aplicativo apresenta o modelo **ÓUSI PREMIUM/florence**, um poderoso sistema de IA projetado para tarefas de **geração de texto e imagem**. O modelo é capaz de lidar com tarefas complexas como detecção de objetos, legendagem de imagens, OCR (Reconhecimento Óptico de Caracteres) e análise detalhada de imagens baseadas em regiões.
|
36 |
-
|
37 |
-
### Uso e Flexibilidade do Modelo
|
38 |
-
|
39 |
-
- **Sem Repetição de N-Gramas**: Para reduzir a repetição na geração de texto, o modelo é configurado com um **no_repeat_ngram_size** de **{no_repeat_ngram_size}**, garantindo saídas mais diversificadas e significativas.
|
40 |
-
- **Estratégias de Amostragem**: ÓUSI PREMIUM/florence oferece estratégias de amostragem flexíveis, incluindo **top-k** e **top-p (nucleus) sampling**, permitindo tanto geração criativa quanto restrita, com base nas necessidades do usuário.
|
41 |
-
|
42 |
-
📸📈✍🏻florence é um modelo robusto capaz de lidar com várias tarefas de **texto e imagem** com alta precisão e flexibilidade, tornando-se uma ferramenta valiosa para pesquisas acadêmicas e aplicações práticas.
|
43 |
-
|
44 |
-
### **Como Usar**:
|
45 |
-
1. **Faça o Upload de uma Imagem**: Selecione uma imagem para processamento.
|
46 |
-
2. **Escolha uma Tarefa**: Escolha uma tarefa no menu suspenso, como "Legenda", "Detecção de Objetos", "OCR", etc.
|
47 |
-
3. **Processar**: Clique no botão "Processar" para permitir que ÓUSI PREMIUM/florence analise a imagem e gere a saída.
|
48 |
-
4. **Ver Resultados**: Dependendo da tarefa, você verá uma imagem processada (por exemplo, com caixas delimitadoras ou rótulos) ou um resultado baseado em texto (por exemplo, uma legenda gerada ou texto extraído).
|
49 |
-
|
50 |
-
Você pode redefinir a interface a qualquer momento clicando no botão **Redefinir**.
|
51 |
-
|
52 |
-
### **Tarefas Disponíveis**:
|
53 |
-
- **✍🏻Legenda**: Gere uma descrição concisa da imagem.
|
54 |
-
- **📸Detecção de Objetos**: Identifique e rotule objetos dentro da imagem.
|
55 |
-
- **📸✍🏻OCR**: Extraia texto da imagem.
|
56 |
-
- **📸Proposta de Região**: Detecte regiões-chave na imagem para legendagem detalhada.
|
57 |
-
"""
|
58 |
-
|
59 |
-
model_presentation = f"""
|
60 |
-
O modelo **ÓUSI PREMIUM/florence** é um modelo de ponta para tarefas de geração condicional, projetado para ser altamente eficaz em tarefas de **texto** e **visão**. É construído como uma arquitetura de **codificador-decodificador**, que permite maior flexibilidade e desempenho na geração de saídas com base em entradas diversificadas.
|
61 |
-
|
62 |
-
### Principais Características
|
63 |
-
|
64 |
-
- **Arquitetura do Modelo**: ÓUSI PREMIUM/florence usa uma estrutura de codificador-decodificador, o que o torna eficaz em tarefas como **geração de texto**, **resumo** e **tradução**. Ele possui **{num_layers} camadas** tanto para o codificador quanto para o decodificador, com uma dimensão do modelo (`d_model`) de **{d_model}**.
|
65 |
-
- **Geração Condicional**: O modelo pode gerar texto condicionalmente, com um comprimento máximo de **{max_length} tokens** para cada sequência gerada, tornando-o ideal para tarefas que exigem saída concisa.
|
66 |
-
- **Busca em Feixe**: ÓUSI PREMIUM/florence suporta **busca em feixe** com até **{beam_size} feixes**, permitindo geração de texto mais diversa e precisa explorando múltiplas potenciais saídas antes de selecionar a melhor.
|
67 |
-
- **Tokenização**: Inclui um tokenizador com um vocabulário de **{vocab_size} tokens**. Tokens especiais como **bos_token_id (0)** e **eos_token_id (2)** ajudam a controlar o processo de geração, marcando o início e o fim de uma sequência.
|
68 |
-
- **Mecanismo de Atenção**: Tanto o codificador quanto o decodificador utilizam **{attention_heads} cabeças de atenção** por camada, garantindo que o modelo possa focar em partes relevantes da entrada ao gerar texto.
|
69 |
-
- **Dropout e Ativação**: ÓUSI PREMIUM/florence emprega uma **função de ativação {activation_function}** e uma **taxa de dropout de {dropout}**, o que melhora o desempenho do modelo prevenindo overfitting e melhorando a generalização.
|
70 |
-
- **Configuração de Treinamento**: O modelo usa precisão **float32** para treinamento e suporta fine-tuning para tarefas específicas ao configurar `finetuning_task` apropriadamente.
|
71 |
-
|
72 |
-
### Integração de Visão
|
73 |
-
|
74 |
-
Além das tarefas de texto, ÓUSI PREMIUM/florence também incorpora **capacidades de visão**:
|
75 |
-
- **Processamento de Imagem Baseado em Patches**: O componente de visão opera em patches de imagem com um tamanho de patch de **{patch_size}x{patch_size}**.
|
76 |
-
- **Embedding Temporal**: Tarefas visuais se beneficiam de embeddings temporais com até **{temporal_embeddings} passos**, tornando o florence bem adequado para análise de vídeo.
|
77 |
-
"""
|
78 |
-
|
79 |
-
joinus = """ÓUSI PREMIUM/florence é um modelo de IA de ponta que oferece uma ampla gama de recursos para tarefas de texto e visão. Se você deseja colaborar, contribuir ou saber mais sobre o projeto, sinta-se à vontade para entrar em contato conosco! Junte-se a nós para explorar o potencial da IA e criar soluções inovadoras para o futuro.
|
80 |
-
"""
|
81 |
-
how_to_use = """As configurações avançadas permitem que você ajuste o processo de geração de texto. Aqui está o que cada configuração faz e como usá-la:
|
82 |
-
|
83 |
-
### Top-k (Padrão: 50)
|
84 |
-
A amostragem top-k limita a seleção do próximo token aos k tokens mais prováveis.
|
85 |
-
|
86 |
-
- **Valores mais baixos** (por exemplo, 10) tornam a saída mais focada e determinística.
|
87 |
-
- **Valores mais altos** (por exemplo, 100) permitem saídas mais diversificadas.
|
88 |
-
|
89 |
-
**Exemplo:** Para uma tarefa de escrita criativa, tente definir top-k para 80 para uma linguagem mais variada.
|
90 |
-
|
91 |
-
### Top-p (Padrão: 1.0)
|
92 |
-
A amostragem top-p (ou nucleus) seleciona do menor conjunto de tokens cuja probabilidade cumulativa excede p.
|
93 |
-
|
94 |
-
- **Valores mais baixos** (por exemplo, 0.5) tornam a saída mais focada e coerente.
|
95 |
-
- **Valores mais altos** (por exemplo, 0.9) permitem saídas mais diversificadas e potencialmente criativas.
|
96 |
-
|
97 |
-
**Exemplo:** Para uma legenda factual, defina top-p para 0.7 para equilibrar precisão e criatividade.
|
98 |
-
|
99 |
-
### Penalidade de Repetição (Padrão: 1.0)
|
100 |
-
Esta penaliza a repetição no texto gerado.
|
101 |
-
|
102 |
-
- **Valores próximos a 1.0** têm efeito mínimo na repetição.
|
103 |
-
- **Valores mais altos** (por exemplo, 1.5) desencorajam mais fortemente a repetição.
|
104 |
-
|
105 |
-
**Exemplo:** Se você notar frases repetidas, tente aumentar para 1.2 para um texto mais variado.
|
106 |
-
|
107 |
-
### Número de Feixes (Padrão: 3)
|
108 |
-
A busca em feixe explora múltiplas sequências possíveis em paralelo.
|
109 |
-
|
110 |
-
- **Valores mais altos** (por exemplo, 5) podem levar a melhor qualidade, mas geração mais lenta.
|
111 |
-
- **Valores mais baixos** (por exemplo, 1) são mais rápidos, mas podem produzir resultados de menor qualidade.
|
112 |
-
|
113 |
-
**Exemplo:** Para tarefas complexas como legendagem densa, tente aumentar para 5 feixes.
|
114 |
-
|
115 |
-
### Máximo de Tokens (Padrão: 512)
|
116 |
-
Define o comprimento máximo do texto gerado.
|
117 |
-
|
118 |
-
- **Valores mais baixos** (por exemplo, 100) para saídas concisas.
|
119 |
-
- **Valores mais altos** (por exemplo, 1000) para descrições mais detalhadas.
|
120 |
-
|
121 |
-
**Exemplo:** Para uma descrição detalhada da imagem, defina o máximo de tokens para 800 para uma saída abrangente.
|
122 |
-
|
123 |
-
Lembre-se, essas configurações interagem entre si, então experimentar diferentes combinações pode levar a resultados interessantes!
|
124 |
-
"""
|
125 |
-
device = "cuda" if torch.cuda.is_available() else "cpu"
|
126 |
-
torch_dtype = torch.float16 if torch.cuda.is_available() else torch.float32
|
127 |
-
|
128 |
-
model = Florence2ForConditionalGeneration.from_pretrained("PleIAs/Florence-PDF", torch_dtype=torch_dtype, trust_remote_code=True).to(device)
|
129 |
-
processor = AutoProcessor.from_pretrained("PleIAs/Florence-PDF", trust_remote_code=True)
|
130 |
-
|
131 |
-
TASK_PROMPTS = {
|
132 |
-
"✍🏻Caption": "<CAPTION>",
|
133 |
-
"✍🏻✍🏻Caption": "<DETAILED_CAPTION>",
|
134 |
-
"✍🏻✍🏻✍🏻Caption": "<MORE_DETAILED_CAPTION>",
|
135 |
-
"📸Object Detection": "<OD>",
|
136 |
-
"📸Dense Region Caption": "<DENSE_REGION_CAPTION>",
|
137 |
-
"📸✍🏻OCR": "<OCR>",
|
138 |
-
"📸✍🏻OCR with Region": "<OCR_WITH_REGION>",
|
139 |
-
"📸Region Proposal": "<REGION_PROPOSAL>",
|
140 |
-
"📸✍🏻Object Detection with Description": "<OD>", # Start with Object Detection
|
141 |
-
# We will handle the detailed description separately in the code
|
142 |
-
}
|
143 |
-
|
144 |
-
# Update IMAGE_TASKS and TEXT_TASKS
|
145 |
-
IMAGE_TASKS = ["📸Object Detection", "📸Dense Region Caption", "📸Region Proposal", "📸✍🏻OCR with Region", "📸✍🏻Object Detection with Description"]
|
146 |
-
TEXT_TASKS = ["✍🏻Caption", "✍🏻✍🏻Caption", "✍🏻✍🏻✍🏻Caption", "📸✍🏻OCR", "📸✍🏻OCR with Region", "📸✍🏻Object Detection with Description"]
|
147 |
-
|
148 |
-
colormap = ['blue','orange','green','purple','brown','pink','gray','olive','cyan','red',
|
149 |
-
'lime','indigo','violet','aqua','magenta','coral','gold','tan','skyblue']
|
150 |
-
|
151 |
-
def fig_to_pil(fig):
|
152 |
-
buf = io.BytesIO()
|
153 |
-
fig.savefig(buf, format='png')
|
154 |
-
buf.seek(0)
|
155 |
-
return Image.open(buf)
|
156 |
-
|
157 |
-
def plot_bbox(image, data, use_quad_boxes=False):
|
158 |
-
fig, ax = plt.subplots()
|
159 |
-
ax.imshow(image)
|
160 |
-
|
161 |
-
if use_quad_boxes:
|
162 |
-
for quad_box, label in zip(data.get('quad_boxes', []), data.get('labels', [])):
|
163 |
-
quad_box = np.array(quad_box).reshape(-1, 2)
|
164 |
-
poly = Polygon(quad_box, linewidth=1, edgecolor='r', facecolor='none')
|
165 |
-
ax.add_patch(poly)
|
166 |
-
plt.text(quad_box[0][0], quad_box[0][1], label, color='white', fontsize=8,
|
167 |
-
bbox=dict(facecolor='red', alpha=0.5))
|
168 |
-
else:
|
169 |
-
bboxes = data.get('bboxes', [])
|
170 |
-
labels = data.get('labels', [])
|
171 |
-
for bbox, label in zip(bboxes, labels):
|
172 |
-
x1, y1, x2, y2 = bbox
|
173 |
-
rect = patches.Rectangle((x1, y1), x2 - x1, y2 - y1, linewidth=1, edgecolor='r', facecolor='none')
|
174 |
-
ax.add_patch(rect)
|
175 |
-
plt.text(x1, y1, label, color='white', fontsize=8, bbox=dict(facecolor='red', alpha=0.5))
|
176 |
-
|
177 |
-
ax.axis('off')
|
178 |
-
|
179 |
-
return fig
|
180 |
-
|
181 |
-
def draw_ocr_bboxes(image, prediction):
|
182 |
-
scale = 1
|
183 |
-
draw = ImageDraw.Draw(image)
|
184 |
-
bboxes, labels = prediction['quad_boxes'], prediction['labels']
|
185 |
-
for box, label in zip(bboxes, labels):
|
186 |
-
color = random.choice(colormap)
|
187 |
-
new_box = (np.array(box) * scale).tolist()
|
188 |
-
draw.polygon(new_box, width=3, outline=color)
|
189 |
-
draw.text((new_box[0]+8, new_box[1]+2),
|
190 |
-
"{}".format(label),
|
191 |
-
align="right",
|
192 |
-
fill=color)
|
193 |
-
|
194 |
-
return image
|
195 |
-
|
196 |
-
def draw_bounding_boxes(image, quad_boxes, labels, color=(0, 255, 0), thickness=2):
|
197 |
-
"""
|
198 |
-
Draws quadrilateral bounding boxes on the image.
|
199 |
-
"""
|
200 |
-
for i, quad in enumerate(quad_boxes):
|
201 |
-
points = np.array(quad, dtype=np.int32).reshape((-1, 1, 2)) # Reshape the quad points for drawing
|
202 |
-
image = cv2.polylines(image, [points], isClosed=True, color=color, thickness=thickness)
|
203 |
-
label_pos = (int(quad[0]), int(quad[1]) - 10)
|
204 |
-
cv2.putText(image, labels[i], label_pos, cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, thickness)
|
205 |
-
|
206 |
-
return image
|
207 |
-
|
208 |
-
def process_image(image, task):
|
209 |
-
prompt = TASK_PROMPTS[task]
|
210 |
-
inputs = processor(text=prompt, images=image, return_tensors="pt").to(device, torch_dtype)
|
211 |
-
generated_ids = model.generate(
|
212 |
-
**inputs,
|
213 |
-
max_new_tokens=1024,
|
214 |
-
num_beams=3,
|
215 |
-
do_sample=False
|
216 |
-
)
|
217 |
-
|
218 |
-
generated_text = processor.batch_decode(generated_ids, skip_special_tokens=False)[0]
|
219 |
-
parsed_answer = processor.post_process_generation(generated_text, task=prompt, image_size=(image.width, image.height))
|
220 |
-
|
221 |
-
return parsed_answer
|
222 |
-
|
223 |
-
|
224 |
-
def main_process(image, task, top_k, top_p, repetition_penalty, num_beams, max_tokens):
|
225 |
-
prompt = TASK_PROMPTS[task]
|
226 |
-
inputs = processor(text=prompt, images=image, return_tensors="pt").to(device, torch_dtype)
|
227 |
-
generated_ids = model.generate(
|
228 |
-
**inputs,
|
229 |
-
max_new_tokens=max_tokens,
|
230 |
-
num_beams=num_beams,
|
231 |
-
do_sample=True,
|
232 |
-
top_k=top_k,
|
233 |
-
top_p=top_p,
|
234 |
-
repetition_penalty=repetition_penalty
|
235 |
-
)
|
236 |
-
|
237 |
-
generated_text = processor.batch_decode(generated_ids, skip_special_tokens=False)[0]
|
238 |
-
parsed_answer = processor.post_process_generation(generated_text, task=prompt, image_size=(image.width, image.height))
|
239 |
-
return parsed_answer
|
240 |
-
|
241 |
-
def process_and_update(image, task, top_k, top_p, repetition_penalty, num_beams, max_tokens):
|
242 |
-
if image is None:
|
243 |
-
return None, gr.update(visible=False), "Please upload an image first.", gr.update(visible=True)
|
244 |
-
|
245 |
-
if task == "📸✍🏻Object Detection with Description":
|
246 |
-
# Perform Object Detection first
|
247 |
-
od_prompt = TASK_PROMPTS["📸Object Detection"]
|
248 |
-
od_inputs = processor(text=od_prompt, images=image, return_tensors="pt").to(device, torch_dtype)
|
249 |
-
od_generated_ids = model.generate(
|
250 |
-
**od_inputs,
|
251 |
-
max_new_tokens=max_tokens,
|
252 |
-
num_beams=num_beams,
|
253 |
-
do_sample=True,
|
254 |
-
top_k=top_k,
|
255 |
-
top_p=top_p,
|
256 |
-
repetition_penalty=repetition_penalty
|
257 |
-
)
|
258 |
-
od_generated_text = processor.batch_decode(od_generated_ids, skip_special_tokens=False)[0]
|
259 |
-
od_parsed_answer = processor.post_process_generation(od_generated_text, task=od_prompt, image_size=(image.width, image.height))
|
260 |
-
|
261 |
-
# Display Bounding Boxes
|
262 |
-
fig = plot_bbox(image, od_parsed_answer.get('<OD>', {}))
|
263 |
-
output_image = fig_to_pil(fig)
|
264 |
-
|
265 |
-
# Then perform Detailed Description
|
266 |
-
dd_prompt = TASK_PROMPTS["✍🏻✍🏻✍🏻Caption"]
|
267 |
-
dd_inputs = processor(text=dd_prompt, images=image, return_tensors="pt").to(device, torch_dtype)
|
268 |
-
dd_generated_ids = model.generate(
|
269 |
-
**dd_inputs,
|
270 |
-
max_new_tokens=max_tokens,
|
271 |
-
num_beams=num_beams,
|
272 |
-
do_sample=True,
|
273 |
-
top_k=top_k,
|
274 |
-
top_p=top_p,
|
275 |
-
repetition_penalty=repetition_penalty
|
276 |
-
)
|
277 |
-
dd_generated_text = processor.batch_decode(dd_generated_ids, skip_special_tokens=False)[0]
|
278 |
-
dd_parsed_answer = processor.post_process_generation(dd_generated_text, task=dd_prompt, image_size=(image.width, image.height))
|
279 |
-
text_output = str(dd_parsed_answer)
|
280 |
-
|
281 |
-
return output_image, gr.update(visible=True), text_output, gr.update(visible=True)
|
282 |
-
else:
|
283 |
-
# Existing processing for other tasks
|
284 |
-
result = main_process(image, task, top_k, top_p, repetition_penalty, num_beams, max_tokens)
|
285 |
-
|
286 |
-
if task in IMAGE_TASKS:
|
287 |
-
if task == "📸✍🏻OCR with Region":
|
288 |
-
fig = plot_bbox(image, result.get('<OCR_WITH_REGION>', {}), use_quad_boxes=True)
|
289 |
-
output_image = fig_to_pil(fig)
|
290 |
-
text_output = result.get('<OCR_WITH_REGION>', {}).get('recognized_text', 'No text found')
|
291 |
-
return output_image, gr.update(visible=True), text_output, gr.update(visible=True)
|
292 |
-
else:
|
293 |
-
fig = plot_bbox(image, result.get(TASK_PROMPTS[task], {}))
|
294 |
-
output_image = fig_to_pil(fig)
|
295 |
-
return output_image, gr.update(visible=True), None, gr.update(visible=False)
|
296 |
-
else:
|
297 |
-
return None, gr.update(visible=False), str(result), gr.update(visible=True)
|
298 |
-
|
299 |
-
def reset_outputs():
|
300 |
-
return None, gr.update(visible=False), None, gr.update(visible=True)
|
301 |
-
|
302 |
-
with gr.Blocks(title="Tonic's 🙏🏻PLeIAs/📸📈✍🏻Florence-PDF") as iface:
|
303 |
-
with gr.Column():
|
304 |
-
with gr.Row():
|
305 |
-
gr.Markdown(title)
|
306 |
-
with gr.Row():
|
307 |
-
with gr.Column(scale=1):
|
308 |
-
with gr.Group():
|
309 |
-
gr.Markdown(model_presentation)
|
310 |
-
with gr.Column(scale=1):
|
311 |
-
with gr.Group():
|
312 |
-
gr.Markdown(description)
|
313 |
-
with gr.Row():
|
314 |
-
with gr.Accordion("🫱🏻🫲🏻Join Us", open=True):
|
315 |
-
gr.Markdown(joinus)
|
316 |
-
with gr.Row():
|
317 |
-
with gr.Column(scale=1):
|
318 |
-
image_input = gr.Image(type="pil", label="Input Image")
|
319 |
-
task_dropdown = gr.Dropdown(list(TASK_PROMPTS.keys()), label="Task", value="✍🏻Caption")
|
320 |
-
with gr.Row():
|
321 |
-
submit_button = gr.Button("📸📈✍🏻Process")
|
322 |
-
reset_button = gr.Button("♻️Reset")
|
323 |
-
with gr.Accordion("🧪Advanced Settings", open=False):
|
324 |
-
with gr.Accordion("🏗️How To Use", open=True):
|
325 |
-
gr.Markdown(how_to_use)
|
326 |
-
top_k = gr.Slider(minimum=1, maximum=100, value=50, step=1, label="Top-k")
|
327 |
-
top_p = gr.Slider(minimum=0.0, maximum=1.0, value=1.0, step=0.01, label="Top-p")
|
328 |
-
repetition_penalty = gr.Slider(minimum=1.0, maximum=2.0, value=1.0, step=0.01, label="Repetition Penalty")
|
329 |
-
num_beams = gr.Slider(minimum=1, maximum=6, value=3, step=1, label="Number of Beams")
|
330 |
-
max_tokens = gr.Slider(minimum=1, maximum=1024, value=1000, step=1, label="Max Tokens")
|
331 |
-
with gr.Column(scale=1):
|
332 |
-
output_image = gr.Image(label="
|
333 |
-
output_text = gr.Textbox(label="
|
334 |
-
|
335 |
-
submit_button.click(
|
336 |
-
fn=process_and_update,
|
337 |
-
inputs=[image_input, task_dropdown, top_k, top_p, repetition_penalty, num_beams, max_tokens],
|
338 |
-
outputs=[output_image, output_image, output_text, output_text]
|
339 |
-
)
|
340 |
-
|
341 |
-
reset_button.click(
|
342 |
-
fn=reset_outputs,
|
343 |
-
inputs=[],
|
344 |
-
outputs=[output_image, output_image, output_text, output_text]
|
345 |
-
)
|
346 |
-
|
347 |
-
task_dropdown.change(
|
348 |
-
fn=lambda task: (gr.update(visible=task in IMAGE_TASKS), gr.update(visible=task in TEXT_TASKS)),
|
349 |
-
inputs=[task_dropdown],
|
350 |
-
outputs=[output_image, output_text]
|
351 |
-
)
|
352 |
-
|
353 |
iface.launch()
|
|
|
1 |
+
import gradio as gr
|
2 |
+
import torch
|
3 |
+
import cv2
|
4 |
+
import numpy as np
|
5 |
+
from matplotlib import pyplot as plt
|
6 |
+
from PIL import Image, ImageDraw
|
7 |
+
from transformers import AutoProcessor
|
8 |
+
from modeling_florence2 import Florence2ForConditionalGeneration
|
9 |
+
import io
|
10 |
+
import matplotlib.pyplot as plt
|
11 |
+
import matplotlib.patches as patches
|
12 |
+
from matplotlib.patches import Polygon
|
13 |
+
import numpy as np
|
14 |
+
import random
|
15 |
+
import json
|
16 |
+
|
17 |
+
|
18 |
+
with open("config.json", "r") as f:
|
19 |
+
config = json.load(f)
|
20 |
+
|
21 |
+
d_model = config['text_config']['d_model']
|
22 |
+
num_layers = config['text_config']['encoder_layers']
|
23 |
+
attention_heads = config['text_config']['encoder_attention_heads']
|
24 |
+
vocab_size = config['text_config']['vocab_size']
|
25 |
+
max_length = config['text_config']['max_length']
|
26 |
+
beam_size = config['text_config']['num_beams']
|
27 |
+
dropout = config['text_config']['dropout']
|
28 |
+
activation_function = config['text_config']['activation_function']
|
29 |
+
no_repeat_ngram_size = config['text_config']['no_repeat_ngram_size']
|
30 |
+
patch_size = config['vision_config']['patch_size'][0]
|
31 |
+
temporal_embeddings = config['vision_config']['visual_temporal_embedding']['max_temporal_embeddings']
|
32 |
+
|
33 |
+
title = """# 🙋🏻♂️Bem-vindo ao ÓUSI PREMIUM/florence"""
|
34 |
+
description = """
|
35 |
+
Este aplicativo apresenta o modelo **ÓUSI PREMIUM/florence**, um poderoso sistema de IA projetado para tarefas de **geração de texto e imagem**. O modelo é capaz de lidar com tarefas complexas como detecção de objetos, legendagem de imagens, OCR (Reconhecimento Óptico de Caracteres) e análise detalhada de imagens baseadas em regiões.
|
36 |
+
|
37 |
+
### Uso e Flexibilidade do Modelo
|
38 |
+
|
39 |
+
- **Sem Repetição de N-Gramas**: Para reduzir a repetição na geração de texto, o modelo é configurado com um **no_repeat_ngram_size** de **{no_repeat_ngram_size}**, garantindo saídas mais diversificadas e significativas.
|
40 |
+
- **Estratégias de Amostragem**: ÓUSI PREMIUM/florence oferece estratégias de amostragem flexíveis, incluindo **top-k** e **top-p (nucleus) sampling**, permitindo tanto geração criativa quanto restrita, com base nas necessidades do usuário.
|
41 |
+
|
42 |
+
📸📈✍🏻florence é um modelo robusto capaz de lidar com várias tarefas de **texto e imagem** com alta precisão e flexibilidade, tornando-se uma ferramenta valiosa para pesquisas acadêmicas e aplicações práticas.
|
43 |
+
|
44 |
+
### **Como Usar**:
|
45 |
+
1. **Faça o Upload de uma Imagem**: Selecione uma imagem para processamento.
|
46 |
+
2. **Escolha uma Tarefa**: Escolha uma tarefa no menu suspenso, como "Legenda", "Detecção de Objetos", "OCR", etc.
|
47 |
+
3. **Processar**: Clique no botão "Processar" para permitir que ÓUSI PREMIUM/florence analise a imagem e gere a saída.
|
48 |
+
4. **Ver Resultados**: Dependendo da tarefa, você verá uma imagem processada (por exemplo, com caixas delimitadoras ou rótulos) ou um resultado baseado em texto (por exemplo, uma legenda gerada ou texto extraído).
|
49 |
+
|
50 |
+
Você pode redefinir a interface a qualquer momento clicando no botão **Redefinir**.
|
51 |
+
|
52 |
+
### **Tarefas Disponíveis**:
|
53 |
+
- **✍🏻Legenda**: Gere uma descrição concisa da imagem.
|
54 |
+
- **📸Detecção de Objetos**: Identifique e rotule objetos dentro da imagem.
|
55 |
+
- **📸✍🏻OCR**: Extraia texto da imagem.
|
56 |
+
- **📸Proposta de Região**: Detecte regiões-chave na imagem para legendagem detalhada.
|
57 |
+
"""
|
58 |
+
|
59 |
+
model_presentation = f"""
|
60 |
+
O modelo **ÓUSI PREMIUM/florence** é um modelo de ponta para tarefas de geração condicional, projetado para ser altamente eficaz em tarefas de **texto** e **visão**. É construído como uma arquitetura de **codificador-decodificador**, que permite maior flexibilidade e desempenho na geração de saídas com base em entradas diversificadas.
|
61 |
+
|
62 |
+
### Principais Características
|
63 |
+
|
64 |
+
- **Arquitetura do Modelo**: ÓUSI PREMIUM/florence usa uma estrutura de codificador-decodificador, o que o torna eficaz em tarefas como **geração de texto**, **resumo** e **tradução**. Ele possui **{num_layers} camadas** tanto para o codificador quanto para o decodificador, com uma dimensão do modelo (`d_model`) de **{d_model}**.
|
65 |
+
- **Geração Condicional**: O modelo pode gerar texto condicionalmente, com um comprimento máximo de **{max_length} tokens** para cada sequência gerada, tornando-o ideal para tarefas que exigem saída concisa.
|
66 |
+
- **Busca em Feixe**: ÓUSI PREMIUM/florence suporta **busca em feixe** com até **{beam_size} feixes**, permitindo geração de texto mais diversa e precisa explorando múltiplas potenciais saídas antes de selecionar a melhor.
|
67 |
+
- **Tokenização**: Inclui um tokenizador com um vocabulário de **{vocab_size} tokens**. Tokens especiais como **bos_token_id (0)** e **eos_token_id (2)** ajudam a controlar o processo de geração, marcando o início e o fim de uma sequência.
|
68 |
+
- **Mecanismo de Atenção**: Tanto o codificador quanto o decodificador utilizam **{attention_heads} cabeças de atenção** por camada, garantindo que o modelo possa focar em partes relevantes da entrada ao gerar texto.
|
69 |
+
- **Dropout e Ativação**: ÓUSI PREMIUM/florence emprega uma **função de ativação {activation_function}** e uma **taxa de dropout de {dropout}**, o que melhora o desempenho do modelo prevenindo overfitting e melhorando a generalização.
|
70 |
+
- **Configuração de Treinamento**: O modelo usa precisão **float32** para treinamento e suporta fine-tuning para tarefas específicas ao configurar `finetuning_task` apropriadamente.
|
71 |
+
|
72 |
+
### Integração de Visão
|
73 |
+
|
74 |
+
Além das tarefas de texto, ÓUSI PREMIUM/florence também incorpora **capacidades de visão**:
|
75 |
+
- **Processamento de Imagem Baseado em Patches**: O componente de visão opera em patches de imagem com um tamanho de patch de **{patch_size}x{patch_size}**.
|
76 |
+
- **Embedding Temporal**: Tarefas visuais se beneficiam de embeddings temporais com até **{temporal_embeddings} passos**, tornando o florence bem adequado para análise de vídeo.
|
77 |
+
"""
|
78 |
+
|
79 |
+
joinus = """ÓUSI PREMIUM/florence é um modelo de IA de ponta que oferece uma ampla gama de recursos para tarefas de texto e visão. Se você deseja colaborar, contribuir ou saber mais sobre o projeto, sinta-se à vontade para entrar em contato conosco! Junte-se a nós para explorar o potencial da IA e criar soluções inovadoras para o futuro.
|
80 |
+
"""
|
81 |
+
how_to_use = """As configurações avançadas permitem que você ajuste o processo de geração de texto. Aqui está o que cada configuração faz e como usá-la:
|
82 |
+
|
83 |
+
### Top-k (Padrão: 50)
|
84 |
+
A amostragem top-k limita a seleção do próximo token aos k tokens mais prováveis.
|
85 |
+
|
86 |
+
- **Valores mais baixos** (por exemplo, 10) tornam a saída mais focada e determinística.
|
87 |
+
- **Valores mais altos** (por exemplo, 100) permitem saídas mais diversificadas.
|
88 |
+
|
89 |
+
**Exemplo:** Para uma tarefa de escrita criativa, tente definir top-k para 80 para uma linguagem mais variada.
|
90 |
+
|
91 |
+
### Top-p (Padrão: 1.0)
|
92 |
+
A amostragem top-p (ou nucleus) seleciona do menor conjunto de tokens cuja probabilidade cumulativa excede p.
|
93 |
+
|
94 |
+
- **Valores mais baixos** (por exemplo, 0.5) tornam a saída mais focada e coerente.
|
95 |
+
- **Valores mais altos** (por exemplo, 0.9) permitem saídas mais diversificadas e potencialmente criativas.
|
96 |
+
|
97 |
+
**Exemplo:** Para uma legenda factual, defina top-p para 0.7 para equilibrar precisão e criatividade.
|
98 |
+
|
99 |
+
### Penalidade de Repetição (Padrão: 1.0)
|
100 |
+
Esta penaliza a repetição no texto gerado.
|
101 |
+
|
102 |
+
- **Valores próximos a 1.0** têm efeito mínimo na repetição.
|
103 |
+
- **Valores mais altos** (por exemplo, 1.5) desencorajam mais fortemente a repetição.
|
104 |
+
|
105 |
+
**Exemplo:** Se você notar frases repetidas, tente aumentar para 1.2 para um texto mais variado.
|
106 |
+
|
107 |
+
### Número de Feixes (Padrão: 3)
|
108 |
+
A busca em feixe explora múltiplas sequências possíveis em paralelo.
|
109 |
+
|
110 |
+
- **Valores mais altos** (por exemplo, 5) podem levar a melhor qualidade, mas geração mais lenta.
|
111 |
+
- **Valores mais baixos** (por exemplo, 1) são mais rápidos, mas podem produzir resultados de menor qualidade.
|
112 |
+
|
113 |
+
**Exemplo:** Para tarefas complexas como legendagem densa, tente aumentar para 5 feixes.
|
114 |
+
|
115 |
+
### Máximo de Tokens (Padrão: 512)
|
116 |
+
Define o comprimento máximo do texto gerado.
|
117 |
+
|
118 |
+
- **Valores mais baixos** (por exemplo, 100) para saídas concisas.
|
119 |
+
- **Valores mais altos** (por exemplo, 1000) para descrições mais detalhadas.
|
120 |
+
|
121 |
+
**Exemplo:** Para uma descrição detalhada da imagem, defina o máximo de tokens para 800 para uma saída abrangente.
|
122 |
+
|
123 |
+
Lembre-se, essas configurações interagem entre si, então experimentar diferentes combinações pode levar a resultados interessantes!
|
124 |
+
"""
|
125 |
+
device = "cuda" if torch.cuda.is_available() else "cpu"
|
126 |
+
torch_dtype = torch.float16 if torch.cuda.is_available() else torch.float32
|
127 |
+
|
128 |
+
model = Florence2ForConditionalGeneration.from_pretrained("PleIAs/Florence-PDF", torch_dtype=torch_dtype, trust_remote_code=True).to(device)
|
129 |
+
processor = AutoProcessor.from_pretrained("PleIAs/Florence-PDF", trust_remote_code=True)
|
130 |
+
|
131 |
+
TASK_PROMPTS = {
|
132 |
+
"✍🏻Caption": "<CAPTION>",
|
133 |
+
"✍🏻✍🏻Caption": "<DETAILED_CAPTION>",
|
134 |
+
"✍🏻✍🏻✍🏻Caption": "<MORE_DETAILED_CAPTION>",
|
135 |
+
"📸Object Detection": "<OD>",
|
136 |
+
"📸Dense Region Caption": "<DENSE_REGION_CAPTION>",
|
137 |
+
"📸✍🏻OCR": "<OCR>",
|
138 |
+
"📸✍🏻OCR with Region": "<OCR_WITH_REGION>",
|
139 |
+
"📸Region Proposal": "<REGION_PROPOSAL>",
|
140 |
+
"📸✍🏻Object Detection with Description": "<OD>", # Start with Object Detection
|
141 |
+
# We will handle the detailed description separately in the code
|
142 |
+
}
|
143 |
+
|
144 |
+
# Update IMAGE_TASKS and TEXT_TASKS
|
145 |
+
IMAGE_TASKS = ["📸Object Detection", "📸Dense Region Caption", "📸Region Proposal", "📸✍🏻OCR with Region", "📸✍🏻Object Detection with Description"]
|
146 |
+
TEXT_TASKS = ["✍🏻Caption", "✍🏻✍🏻Caption", "✍🏻✍🏻✍🏻Caption", "📸✍🏻OCR", "📸✍🏻OCR with Region", "📸✍🏻Object Detection with Description"]
|
147 |
+
|
148 |
+
colormap = ['blue','orange','green','purple','brown','pink','gray','olive','cyan','red',
|
149 |
+
'lime','indigo','violet','aqua','magenta','coral','gold','tan','skyblue']
|
150 |
+
|
151 |
+
def fig_to_pil(fig):
|
152 |
+
buf = io.BytesIO()
|
153 |
+
fig.savefig(buf, format='png')
|
154 |
+
buf.seek(0)
|
155 |
+
return Image.open(buf)
|
156 |
+
|
157 |
+
def plot_bbox(image, data, use_quad_boxes=False):
|
158 |
+
fig, ax = plt.subplots()
|
159 |
+
ax.imshow(image)
|
160 |
+
|
161 |
+
if use_quad_boxes:
|
162 |
+
for quad_box, label in zip(data.get('quad_boxes', []), data.get('labels', [])):
|
163 |
+
quad_box = np.array(quad_box).reshape(-1, 2)
|
164 |
+
poly = Polygon(quad_box, linewidth=1, edgecolor='r', facecolor='none')
|
165 |
+
ax.add_patch(poly)
|
166 |
+
plt.text(quad_box[0][0], quad_box[0][1], label, color='white', fontsize=8,
|
167 |
+
bbox=dict(facecolor='red', alpha=0.5))
|
168 |
+
else:
|
169 |
+
bboxes = data.get('bboxes', [])
|
170 |
+
labels = data.get('labels', [])
|
171 |
+
for bbox, label in zip(bboxes, labels):
|
172 |
+
x1, y1, x2, y2 = bbox
|
173 |
+
rect = patches.Rectangle((x1, y1), x2 - x1, y2 - y1, linewidth=1, edgecolor='r', facecolor='none')
|
174 |
+
ax.add_patch(rect)
|
175 |
+
plt.text(x1, y1, label, color='white', fontsize=8, bbox=dict(facecolor='red', alpha=0.5))
|
176 |
+
|
177 |
+
ax.axis('off')
|
178 |
+
|
179 |
+
return fig
|
180 |
+
|
181 |
+
def draw_ocr_bboxes(image, prediction):
|
182 |
+
scale = 1
|
183 |
+
draw = ImageDraw.Draw(image)
|
184 |
+
bboxes, labels = prediction['quad_boxes'], prediction['labels']
|
185 |
+
for box, label in zip(bboxes, labels):
|
186 |
+
color = random.choice(colormap)
|
187 |
+
new_box = (np.array(box) * scale).tolist()
|
188 |
+
draw.polygon(new_box, width=3, outline=color)
|
189 |
+
draw.text((new_box[0]+8, new_box[1]+2),
|
190 |
+
"{}".format(label),
|
191 |
+
align="right",
|
192 |
+
fill=color)
|
193 |
+
|
194 |
+
return image
|
195 |
+
|
196 |
+
def draw_bounding_boxes(image, quad_boxes, labels, color=(0, 255, 0), thickness=2):
|
197 |
+
"""
|
198 |
+
Draws quadrilateral bounding boxes on the image.
|
199 |
+
"""
|
200 |
+
for i, quad in enumerate(quad_boxes):
|
201 |
+
points = np.array(quad, dtype=np.int32).reshape((-1, 1, 2)) # Reshape the quad points for drawing
|
202 |
+
image = cv2.polylines(image, [points], isClosed=True, color=color, thickness=thickness)
|
203 |
+
label_pos = (int(quad[0]), int(quad[1]) - 10)
|
204 |
+
cv2.putText(image, labels[i], label_pos, cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, thickness)
|
205 |
+
|
206 |
+
return image
|
207 |
+
|
208 |
+
def process_image(image, task):
|
209 |
+
prompt = TASK_PROMPTS[task]
|
210 |
+
inputs = processor(text=prompt, images=image, return_tensors="pt").to(device, torch_dtype)
|
211 |
+
generated_ids = model.generate(
|
212 |
+
**inputs,
|
213 |
+
max_new_tokens=1024,
|
214 |
+
num_beams=3,
|
215 |
+
do_sample=False
|
216 |
+
)
|
217 |
+
|
218 |
+
generated_text = processor.batch_decode(generated_ids, skip_special_tokens=False)[0]
|
219 |
+
parsed_answer = processor.post_process_generation(generated_text, task=prompt, image_size=(image.width, image.height))
|
220 |
+
|
221 |
+
return parsed_answer
|
222 |
+
|
223 |
+
|
224 |
+
def main_process(image, task, top_k, top_p, repetition_penalty, num_beams, max_tokens):
|
225 |
+
prompt = TASK_PROMPTS[task]
|
226 |
+
inputs = processor(text=prompt, images=image, return_tensors="pt").to(device, torch_dtype)
|
227 |
+
generated_ids = model.generate(
|
228 |
+
**inputs,
|
229 |
+
max_new_tokens=max_tokens,
|
230 |
+
num_beams=num_beams,
|
231 |
+
do_sample=True,
|
232 |
+
top_k=top_k,
|
233 |
+
top_p=top_p,
|
234 |
+
repetition_penalty=repetition_penalty
|
235 |
+
)
|
236 |
+
|
237 |
+
generated_text = processor.batch_decode(generated_ids, skip_special_tokens=False)[0]
|
238 |
+
parsed_answer = processor.post_process_generation(generated_text, task=prompt, image_size=(image.width, image.height))
|
239 |
+
return parsed_answer
|
240 |
+
|
241 |
+
def process_and_update(image, task, top_k, top_p, repetition_penalty, num_beams, max_tokens):
|
242 |
+
if image is None:
|
243 |
+
return None, gr.update(visible=False), "Please upload an image first.", gr.update(visible=True)
|
244 |
+
|
245 |
+
if task == "📸✍🏻Object Detection with Description":
|
246 |
+
# Perform Object Detection first
|
247 |
+
od_prompt = TASK_PROMPTS["📸Object Detection"]
|
248 |
+
od_inputs = processor(text=od_prompt, images=image, return_tensors="pt").to(device, torch_dtype)
|
249 |
+
od_generated_ids = model.generate(
|
250 |
+
**od_inputs,
|
251 |
+
max_new_tokens=max_tokens,
|
252 |
+
num_beams=num_beams,
|
253 |
+
do_sample=True,
|
254 |
+
top_k=top_k,
|
255 |
+
top_p=top_p,
|
256 |
+
repetition_penalty=repetition_penalty
|
257 |
+
)
|
258 |
+
od_generated_text = processor.batch_decode(od_generated_ids, skip_special_tokens=False)[0]
|
259 |
+
od_parsed_answer = processor.post_process_generation(od_generated_text, task=od_prompt, image_size=(image.width, image.height))
|
260 |
+
|
261 |
+
# Display Bounding Boxes
|
262 |
+
fig = plot_bbox(image, od_parsed_answer.get('<OD>', {}))
|
263 |
+
output_image = fig_to_pil(fig)
|
264 |
+
|
265 |
+
# Then perform Detailed Description
|
266 |
+
dd_prompt = TASK_PROMPTS["✍🏻✍🏻✍🏻Caption"]
|
267 |
+
dd_inputs = processor(text=dd_prompt, images=image, return_tensors="pt").to(device, torch_dtype)
|
268 |
+
dd_generated_ids = model.generate(
|
269 |
+
**dd_inputs,
|
270 |
+
max_new_tokens=max_tokens,
|
271 |
+
num_beams=num_beams,
|
272 |
+
do_sample=True,
|
273 |
+
top_k=top_k,
|
274 |
+
top_p=top_p,
|
275 |
+
repetition_penalty=repetition_penalty
|
276 |
+
)
|
277 |
+
dd_generated_text = processor.batch_decode(dd_generated_ids, skip_special_tokens=False)[0]
|
278 |
+
dd_parsed_answer = processor.post_process_generation(dd_generated_text, task=dd_prompt, image_size=(image.width, image.height))
|
279 |
+
text_output = str(dd_parsed_answer)
|
280 |
+
|
281 |
+
return output_image, gr.update(visible=True), text_output, gr.update(visible=True)
|
282 |
+
else:
|
283 |
+
# Existing processing for other tasks
|
284 |
+
result = main_process(image, task, top_k, top_p, repetition_penalty, num_beams, max_tokens)
|
285 |
+
|
286 |
+
if task in IMAGE_TASKS:
|
287 |
+
if task == "📸✍🏻OCR with Region":
|
288 |
+
fig = plot_bbox(image, result.get('<OCR_WITH_REGION>', {}), use_quad_boxes=True)
|
289 |
+
output_image = fig_to_pil(fig)
|
290 |
+
text_output = result.get('<OCR_WITH_REGION>', {}).get('recognized_text', 'No text found')
|
291 |
+
return output_image, gr.update(visible=True), text_output, gr.update(visible=True)
|
292 |
+
else:
|
293 |
+
fig = plot_bbox(image, result.get(TASK_PROMPTS[task], {}))
|
294 |
+
output_image = fig_to_pil(fig)
|
295 |
+
return output_image, gr.update(visible=True), None, gr.update(visible=False)
|
296 |
+
else:
|
297 |
+
return None, gr.update(visible=False), str(result), gr.update(visible=True)
|
298 |
+
|
299 |
+
def reset_outputs():
|
300 |
+
return None, gr.update(visible=False), None, gr.update(visible=True)
|
301 |
+
|
302 |
+
with gr.Blocks(title="Tonic's 🙏🏻PLeIAs/📸📈✍🏻Florence-PDF") as iface:
|
303 |
+
with gr.Column():
|
304 |
+
with gr.Row():
|
305 |
+
gr.Markdown(title)
|
306 |
+
with gr.Row():
|
307 |
+
with gr.Column(scale=1):
|
308 |
+
with gr.Group():
|
309 |
+
gr.Markdown(model_presentation)
|
310 |
+
with gr.Column(scale=1):
|
311 |
+
with gr.Group():
|
312 |
+
gr.Markdown(description)
|
313 |
+
with gr.Row():
|
314 |
+
with gr.Accordion("🫱🏻🫲🏻Join Us", open=True):
|
315 |
+
gr.Markdown(joinus)
|
316 |
+
with gr.Row():
|
317 |
+
with gr.Column(scale=1):
|
318 |
+
image_input = gr.Image(type="pil", label="Input Image")
|
319 |
+
task_dropdown = gr.Dropdown(list(TASK_PROMPTS.keys()), label="Task", value="✍🏻Caption")
|
320 |
+
with gr.Row():
|
321 |
+
submit_button = gr.Button("📸📈✍🏻Process")
|
322 |
+
reset_button = gr.Button("♻️Reset")
|
323 |
+
with gr.Accordion("🧪Advanced Settings", open=False):
|
324 |
+
with gr.Accordion("🏗️How To Use", open=True):
|
325 |
+
gr.Markdown(how_to_use)
|
326 |
+
top_k = gr.Slider(minimum=1, maximum=100, value=50, step=1, label="Top-k")
|
327 |
+
top_p = gr.Slider(minimum=0.0, maximum=1.0, value=1.0, step=0.01, label="Top-p")
|
328 |
+
repetition_penalty = gr.Slider(minimum=1.0, maximum=2.0, value=1.0, step=0.01, label="Repetition Penalty")
|
329 |
+
num_beams = gr.Slider(minimum=1, maximum=6, value=3, step=1, label="Number of Beams")
|
330 |
+
max_tokens = gr.Slider(minimum=1, maximum=1024, value=1000, step=1, label="Max Tokens")
|
331 |
+
with gr.Column(scale=1):
|
332 |
+
output_image = gr.Image(label="ÓUSI PREMIUM/florence", visible=False)
|
333 |
+
output_text = gr.Textbox(label="ÓUSI PREMIUM/florence", visible=False)
|
334 |
+
|
335 |
+
submit_button.click(
|
336 |
+
fn=process_and_update,
|
337 |
+
inputs=[image_input, task_dropdown, top_k, top_p, repetition_penalty, num_beams, max_tokens],
|
338 |
+
outputs=[output_image, output_image, output_text, output_text]
|
339 |
+
)
|
340 |
+
|
341 |
+
reset_button.click(
|
342 |
+
fn=reset_outputs,
|
343 |
+
inputs=[],
|
344 |
+
outputs=[output_image, output_image, output_text, output_text]
|
345 |
+
)
|
346 |
+
|
347 |
+
task_dropdown.change(
|
348 |
+
fn=lambda task: (gr.update(visible=task in IMAGE_TASKS), gr.update(visible=task in TEXT_TASKS)),
|
349 |
+
inputs=[task_dropdown],
|
350 |
+
outputs=[output_image, output_text]
|
351 |
+
)
|
352 |
+
|
353 |
iface.launch()
|