File size: 18,942 Bytes
c81423a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
05b175c
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
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
import gradio as gr
import torch
import cv2
import numpy as np
from matplotlib import pyplot as plt
from PIL import Image, ImageDraw
from transformers import AutoProcessor
from modeling_florence2 import Florence2ForConditionalGeneration
import io
import matplotlib.pyplot as plt
import matplotlib.patches as patches
from matplotlib.patches import Polygon  
import numpy as np
import random
import json


with open("config.json", "r") as f:
    config = json.load(f)

d_model = config['text_config']['d_model']
num_layers = config['text_config']['encoder_layers']
attention_heads = config['text_config']['encoder_attention_heads']
vocab_size = config['text_config']['vocab_size']
max_length = config['text_config']['max_length']
beam_size = config['text_config']['num_beams']
dropout = config['text_config']['dropout']
activation_function = config['text_config']['activation_function']
no_repeat_ngram_size = config['text_config']['no_repeat_ngram_size']
patch_size = config['vision_config']['patch_size'][0]
temporal_embeddings = config['vision_config']['visual_temporal_embedding']['max_temporal_embeddings']

title = """# 🙋🏻‍♂️Bem-vindo ao ÓUSI PREMIUM/florence"""
description = """
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.

### Uso e Flexibilidade do Modelo

- **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.
- **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.

📸📈✍🏻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.

### **Como Usar**:
1. **Faça o Upload de uma Imagem**: Selecione uma imagem para processamento.
2. **Escolha uma Tarefa**: Escolha uma tarefa no menu suspenso, como "Legenda", "Detecção de Objetos", "OCR", etc.
3. **Processar**: Clique no botão "Processar" para permitir que ÓUSI PREMIUM/florence analise a imagem e gere a saída.
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).

Você pode redefinir a interface a qualquer momento clicando no botão **Redefinir**.

### **Tarefas Disponíveis**:
- **✍🏻Legenda**: Gere uma descrição concisa da imagem.
- **📸Detecção de Objetos**: Identifique e rotule objetos dentro da imagem.
- **📸✍🏻OCR**: Extraia texto da imagem.
- **📸Proposta de Região**: Detecte regiões-chave na imagem para legendagem detalhada.
"""

model_presentation = f"""
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.

### Principais Características

- **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}**.
- **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.
- **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.
- **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.
- **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.
- **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.
- **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.

### Integração de Visão

Além das tarefas de texto, ÓUSI PREMIUM/florence também incorpora **capacidades de visão**:
- **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}**.
- **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.
"""

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.
"""
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:

### Top-k (Padrão: 50)
A amostragem top-k limita a seleção do próximo token aos k tokens mais prováveis.

- **Valores mais baixos** (por exemplo, 10) tornam a saída mais focada e determinística.
- **Valores mais altos** (por exemplo, 100) permitem saídas mais diversificadas.

**Exemplo:** Para uma tarefa de escrita criativa, tente definir top-k para 80 para uma linguagem mais variada.

### Top-p (Padrão: 1.0)
A amostragem top-p (ou nucleus) seleciona do menor conjunto de tokens cuja probabilidade cumulativa excede p.

- **Valores mais baixos** (por exemplo, 0.5) tornam a saída mais focada e coerente.
- **Valores mais altos** (por exemplo, 0.9) permitem saídas mais diversificadas e potencialmente criativas.

**Exemplo:** Para uma legenda factual, defina top-p para 0.7 para equilibrar precisão e criatividade.

### Penalidade de Repetição (Padrão: 1.0)
Esta penaliza a repetição no texto gerado.

- **Valores próximos a 1.0** têm efeito mínimo na repetição.
- **Valores mais altos** (por exemplo, 1.5) desencorajam mais fortemente a repetição.

**Exemplo:** Se você notar frases repetidas, tente aumentar para 1.2 para um texto mais variado.

### Número de Feixes (Padrão: 3)
A busca em feixe explora múltiplas sequências possíveis em paralelo.

- **Valores mais altos** (por exemplo, 5) podem levar a melhor qualidade, mas geração mais lenta.
- **Valores mais baixos** (por exemplo, 1) são mais rápidos, mas podem produzir resultados de menor qualidade.

**Exemplo:** Para tarefas complexas como legendagem densa, tente aumentar para 5 feixes.

### Máximo de Tokens (Padrão: 512)
Define o comprimento máximo do texto gerado.

- **Valores mais baixos** (por exemplo, 100) para saídas concisas.
- **Valores mais altos** (por exemplo, 1000) para descrições mais detalhadas.

**Exemplo:** Para uma descrição detalhada da imagem, defina o máximo de tokens para 800 para uma saída abrangente.

Lembre-se, essas configurações interagem entre si, então experimentar diferentes combinações pode levar a resultados interessantes!
"""
device = "cuda" if torch.cuda.is_available() else "cpu"
torch_dtype = torch.float16 if torch.cuda.is_available() else torch.float32

model = Florence2ForConditionalGeneration.from_pretrained("PleIAs/Florence-PDF", torch_dtype=torch_dtype, trust_remote_code=True).to(device)
processor = AutoProcessor.from_pretrained("PleIAs/Florence-PDF", trust_remote_code=True)

TASK_PROMPTS = {
    "✍🏻Caption": "<CAPTION>",
    "✍🏻✍🏻Caption": "<DETAILED_CAPTION>",
    "✍🏻✍🏻✍🏻Caption": "<MORE_DETAILED_CAPTION>",
    "📸Object Detection": "<OD>",
    "📸Dense Region Caption": "<DENSE_REGION_CAPTION>",
    "📸✍🏻OCR": "<OCR>",
    "📸✍🏻OCR with Region": "<OCR_WITH_REGION>",
    "📸Region Proposal": "<REGION_PROPOSAL>",
    "📸✍🏻Object Detection with Description": "<OD>",  # Start with Object Detection
    # We will handle the detailed description separately in the code
}

# Update IMAGE_TASKS and TEXT_TASKS
IMAGE_TASKS = ["📸Object Detection", "📸Dense Region Caption", "📸Region Proposal", "📸✍🏻OCR with Region", "📸✍🏻Object Detection with Description"]
TEXT_TASKS = ["✍🏻Caption", "✍🏻✍🏻Caption", "✍🏻✍🏻✍🏻Caption", "📸✍🏻OCR", "📸✍🏻OCR with Region", "📸✍🏻Object Detection with Description"]

colormap = ['blue','orange','green','purple','brown','pink','gray','olive','cyan','red',
            'lime','indigo','violet','aqua','magenta','coral','gold','tan','skyblue']

def fig_to_pil(fig):
    buf = io.BytesIO()
    fig.savefig(buf, format='png')
    buf.seek(0)
    return Image.open(buf)

def plot_bbox(image, data, use_quad_boxes=False):
    fig, ax = plt.subplots()
    ax.imshow(image)

    if use_quad_boxes:
        for quad_box, label in zip(data.get('quad_boxes', []), data.get('labels', [])):
            quad_box = np.array(quad_box).reshape(-1, 2)
            poly = Polygon(quad_box, linewidth=1, edgecolor='r', facecolor='none')
            ax.add_patch(poly)
            plt.text(quad_box[0][0], quad_box[0][1], label, color='white', fontsize=8,
                     bbox=dict(facecolor='red', alpha=0.5))
    else:
        bboxes = data.get('bboxes', [])
        labels = data.get('labels', [])
        for bbox, label in zip(bboxes, labels):
            x1, y1, x2, y2 = bbox
            rect = patches.Rectangle((x1, y1), x2 - x1, y2 - y1, linewidth=1, edgecolor='r', facecolor='none')
            ax.add_patch(rect)
            plt.text(x1, y1, label, color='white', fontsize=8, bbox=dict(facecolor='red', alpha=0.5))

    ax.axis('off')

    return fig

def draw_ocr_bboxes(image, prediction):
    scale = 1
    draw = ImageDraw.Draw(image)
    bboxes, labels = prediction['quad_boxes'], prediction['labels']
    for box, label in zip(bboxes, labels):
        color = random.choice(colormap)
        new_box = (np.array(box) * scale).tolist()
        draw.polygon(new_box, width=3, outline=color)
        draw.text((new_box[0]+8, new_box[1]+2),
                  "{}".format(label),
                  align="right",
                  fill=color)
        
    return image

def draw_bounding_boxes(image, quad_boxes, labels, color=(0, 255, 0), thickness=2):
    """
    Draws quadrilateral bounding boxes on the image.
    """
    for i, quad in enumerate(quad_boxes):
        points = np.array(quad, dtype=np.int32).reshape((-1, 1, 2))  # Reshape the quad points for drawing
        image = cv2.polylines(image, [points], isClosed=True, color=color, thickness=thickness)
        label_pos = (int(quad[0]), int(quad[1]) - 10)  
        cv2.putText(image, labels[i], label_pos, cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, thickness)

    return image

def process_image(image, task):
    prompt = TASK_PROMPTS[task]
    inputs = processor(text=prompt, images=image, return_tensors="pt").to(device, torch_dtype)
    generated_ids = model.generate(
        **inputs,
        max_new_tokens=1024,
        num_beams=3,
        do_sample=False
    )

    generated_text = processor.batch_decode(generated_ids, skip_special_tokens=False)[0]
    parsed_answer = processor.post_process_generation(generated_text, task=prompt, image_size=(image.width, image.height))

    return parsed_answer


def main_process(image, task, top_k, top_p, repetition_penalty, num_beams, max_tokens):
    prompt = TASK_PROMPTS[task]
    inputs = processor(text=prompt, images=image, return_tensors="pt").to(device, torch_dtype)
    generated_ids = model.generate(
        **inputs,
        max_new_tokens=max_tokens,
        num_beams=num_beams,
        do_sample=True,
        top_k=top_k,
        top_p=top_p,
        repetition_penalty=repetition_penalty
    )

    generated_text = processor.batch_decode(generated_ids, skip_special_tokens=False)[0]
    parsed_answer = processor.post_process_generation(generated_text, task=prompt, image_size=(image.width, image.height))
    return parsed_answer

def process_and_update(image, task, top_k, top_p, repetition_penalty, num_beams, max_tokens):
    if image is None:
        return None, gr.update(visible=False), "Please upload an image first.", gr.update(visible=True)
    
    if task == "📸✍🏻Object Detection with Description":
        # Perform Object Detection first
        od_prompt = TASK_PROMPTS["📸Object Detection"]
        od_inputs = processor(text=od_prompt, images=image, return_tensors="pt").to(device, torch_dtype)
        od_generated_ids = model.generate(
            **od_inputs,
            max_new_tokens=max_tokens,
            num_beams=num_beams,
            do_sample=True,
            top_k=top_k,
            top_p=top_p,
            repetition_penalty=repetition_penalty
        )
        od_generated_text = processor.batch_decode(od_generated_ids, skip_special_tokens=False)[0]
        od_parsed_answer = processor.post_process_generation(od_generated_text, task=od_prompt, image_size=(image.width, image.height))
        
        # Display Bounding Boxes
        fig = plot_bbox(image, od_parsed_answer.get('<OD>', {}))
        output_image = fig_to_pil(fig)
        
        # Then perform Detailed Description
        dd_prompt = TASK_PROMPTS["✍🏻✍🏻✍🏻Caption"]
        dd_inputs = processor(text=dd_prompt, images=image, return_tensors="pt").to(device, torch_dtype)
        dd_generated_ids = model.generate(
            **dd_inputs,
            max_new_tokens=max_tokens,
            num_beams=num_beams,
            do_sample=True,
            top_k=top_k,
            top_p=top_p,
            repetition_penalty=repetition_penalty
        )
        dd_generated_text = processor.batch_decode(dd_generated_ids, skip_special_tokens=False)[0]
        dd_parsed_answer = processor.post_process_generation(dd_generated_text, task=dd_prompt, image_size=(image.width, image.height))
        text_output = str(dd_parsed_answer)
        
        return output_image, gr.update(visible=True), text_output, gr.update(visible=True)
    else:
        # Existing processing for other tasks
        result = main_process(image, task, top_k, top_p, repetition_penalty, num_beams, max_tokens)
        
        if task in IMAGE_TASKS:
            if task == "📸✍🏻OCR with Region":
                fig = plot_bbox(image, result.get('<OCR_WITH_REGION>', {}), use_quad_boxes=True)
                output_image = fig_to_pil(fig)
                text_output = result.get('<OCR_WITH_REGION>', {}).get('recognized_text', 'No text found')
                return output_image, gr.update(visible=True), text_output, gr.update(visible=True)
            else:
                fig = plot_bbox(image, result.get(TASK_PROMPTS[task], {}))
                output_image = fig_to_pil(fig)
                return output_image, gr.update(visible=True), None, gr.update(visible=False)
        else:
            return None, gr.update(visible=False), str(result), gr.update(visible=True)

def reset_outputs():
    return None, gr.update(visible=False), None, gr.update(visible=True)

with gr.Blocks(title="Tonic's 🙏🏻PLeIAs/📸📈✍🏻Florence-PDF") as iface:
    with gr.Column():
        with gr.Row():
            gr.Markdown(title)
        with gr.Row():
            with gr.Column(scale=1):
                with gr.Group():                    
                    gr.Markdown(model_presentation)
            with gr.Column(scale=1):
                with gr.Group():
                    gr.Markdown(description)
        with gr.Row():
            with gr.Accordion("🫱🏻‍🫲🏻Join Us", open=True):
                gr.Markdown(joinus)
        with gr.Row():
            with gr.Column(scale=1):
                image_input = gr.Image(type="pil", label="Input Image")
                task_dropdown = gr.Dropdown(list(TASK_PROMPTS.keys()), label="Task", value="✍🏻Caption")            
                with gr.Row():
                    submit_button = gr.Button("📸📈✍🏻Process")
                    reset_button = gr.Button("♻️Reset")
                with gr.Accordion("🧪Advanced Settings", open=False):
                    with gr.Accordion("🏗️How To Use", open=True):
                        gr.Markdown(how_to_use)                        
                    top_k = gr.Slider(minimum=1, maximum=100, value=50, step=1, label="Top-k")
                    top_p = gr.Slider(minimum=0.0, maximum=1.0, value=1.0, step=0.01, label="Top-p")
                    repetition_penalty = gr.Slider(minimum=1.0, maximum=2.0, value=1.0, step=0.01, label="Repetition Penalty")
                    num_beams = gr.Slider(minimum=1, maximum=6, value=3, step=1, label="Number of Beams")
                    max_tokens = gr.Slider(minimum=1, maximum=1024, value=1000, step=1, label="Max Tokens")
            with gr.Column(scale=1):    
                output_image = gr.Image(label="ÓUSI PREMIUM/florence", visible=False)
                output_text = gr.Textbox(label="ÓUSI PREMIUM/florence", visible=False)
    
    submit_button.click(
        fn=process_and_update,
        inputs=[image_input, task_dropdown, top_k, top_p, repetition_penalty, num_beams, max_tokens],
        outputs=[output_image, output_image, output_text, output_text]
    )
    
    reset_button.click(
        fn=reset_outputs,
        inputs=[],
        outputs=[output_image, output_image, output_text, output_text]
    )
    
    task_dropdown.change(
        fn=lambda task: (gr.update(visible=task in IMAGE_TASKS), gr.update(visible=task in TEXT_TASKS)),
        inputs=[task_dropdown],
        outputs=[output_image, output_text]
    )

iface.launch()