# Florence-2

El potente modelo visual de Microsoft para subtitulado, detección, segmentación y más.

{% hint style="success" %}
Todos los ejemplos se pueden ejecutar en servidores GPU alquilados a través de [CLORE.AI Marketplace](https://clore.ai/marketplace).
{% endhint %}

{% hint style="info" %}
Todos los ejemplos en esta guía se pueden ejecutar en servidores GPU alquilados a través de [CLORE.AI Marketplace](https://clore.ai/marketplace) mercado.
{% endhint %}

## Alquilar en CLORE.AI

1. Visita [CLORE.AI Marketplace](https://clore.ai/marketplace)
2. Filtrar por tipo de GPU, VRAM y precio
3. Elegir **Bajo demanda** (tarifa fija) o **Spot** (precio de puja)
4. Configura tu pedido:
   * Selecciona imagen Docker
   * Establece puertos (TCP para SSH, HTTP para interfaces web)
   * Agrega variables de entorno si es necesario
   * Introduce el comando de inicio
5. Selecciona pago: **CLORE**, **BTC**, o **USDT/USDC**
6. Crea el pedido y espera el despliegue

### Accede a tu servidor

* Encuentra los detalles de conexión en **Mis Pedidos**
* Interfaces web: Usa la URL del puerto HTTP
* SSH: `ssh -p <port> root@<proxy-address>`

## ¿Qué es Florence-2?

Florence-2 de Microsoft es un modelo base de visión que maneja:

* Generación de subtítulos para imágenes (breve y detallado)
* Detección y localización de objetos
* Subtitulado denso de regiones
* Comprensión de expresiones referenciales
* OCR y reconocimiento de texto
* Respuesta visual a preguntas

## Recursos

* **HuggingFace:** [microsoft/Florence-2-large](https://huggingface.co/microsoft/Florence-2-large)
* **Artículo:** [Artículo de Florence-2](https://arxiv.org/abs/2311.06242)
* **GitHub:** [microsoft/Florence-2](https://github.com/microsoft/Florence-2)
* **Demostración:** [Espacio de HuggingFace](https://huggingface.co/spaces/microsoft/Florence-2)

## Hardware recomendado

| Componente     | Mínimo        | Recomendado   | Óptimo        |
| -------------- | ------------- | ------------- | ------------- |
| GPU            | RTX 3060 12GB | RTX 4080 16GB | RTX 4090 24GB |
| VRAM           | 8GB           | 12GB          | 16GB          |
| CPU            | 4 núcleos     | 8 núcleos     | 16 núcleos    |
| RAM            | 16GB          | 32GB          | 64GB          |
| Almacenamiento | 30GB SSD      | 50GB NVMe     | 100GB NVMe    |
| Internet       | 100 Mbps      | 500 Mbps      | 1 Gbps        |

## Despliegue rápido en CLORE.AI

**Imagen Docker:**

```
pytorch/pytorch:2.5.1-cuda12.4-cudnn9-devel
```

**Puertos:**

```
22/tcp
7860/http
```

**Comando:**

```bash
pip install transformers accelerate einops timm gradio && \
python -c "
import gradio as gr
from transformers import AutoProcessor, AutoModelForCausalLM
import torch
from PIL import Image

model = AutoModelForCausalLM.from_pretrained('microsoft/Florence-2-large', torch_dtype=torch.float16, trust_remote_code=True).to('cuda')
processor = AutoProcessor.from_pretrained('microsoft/Florence-2-large', trust_remote_code=True)

def process(image, task):
    inputs = processor(text=task, images=image, return_tensors='pt').to('cuda', torch.float16)
    generated_ids = model.generate(input_ids=inputs['input_ids'], pixel_values=inputs['pixel_values'], max_new_tokens=1024)
    result = processor.batch_decode(generated_ids, skip_special_tokens=False)[0]
    return processor.post_process_generation(result, task=task, image_size=image.size)

gr.Interface(fn=process, inputs=[gr.Image(type='pil'), gr.Dropdown(['<CAPTION>', '<DETAILED_CAPTION>', '<OD>'])], outputs='json').launch(server_name='0.0.0.0')
"
```

## Accediendo a tu servicio

Después del despliegue, encuentra tu `http_pub` URL en **Mis Pedidos**:

1. Ir a **Mis Pedidos** página
2. Haz clic en tu pedido
3. Encuentra la `http_pub` URL (por ejemplo, `abc123.clorecloud.net`)

Usa `https://TU_HTTP_PUB_URL` en lugar de `localhost` en los ejemplos abajo.

## Instalación

```bash
pip install transformers accelerate einops timm
pip install flash-attn --no-build-isolation  # Opcional, para inferencia más rápida
```

## Lo que puedes crear

### Análisis de contenido

* Generar descripciones de imágenes automáticamente
* Extraer texto de imágenes (OCR)
* Analizar contenido visual a gran escala

### Anotación de datos

* Etiquetar conjuntos de datos automáticamente con subtítulos
* Generar cuadros delimitadores para objetos
* Crear anotaciones densas

### Accesibilidad

* Generar texto alternativo para imágenes
* Describir imágenes para personas con discapacidad visual
* Crear descripciones de audio

### Búsqueda y descubrimiento

* Indexar imágenes por contenido
* Construir sistemas de búsqueda visual
* Moderación de contenido

### Procesamiento de documentos

* Extraer texto de documentos
* Entender gráficos y diagramas
* Procesar materiales escaneados

## Uso básico

### Generación de subtítulos para imágenes

```python
from transformers import AutoProcessor, AutoModelForCausalLM
from PIL import Image
import torch

model = AutoModelForCausalLM.from_pretrained(
    "microsoft/Florence-2-large",
    torch_dtype=torch.float16,
    trust_remote_code=True
).to("cuda")

processor = AutoProcessor.from_pretrained(
    "microsoft/Florence-2-large",
    trust_remote_code=True
)

image = Image.open("photo.jpg")

# Subtítulo breve
task = "<CAPTION>"
inputs = processor(text=task, images=image, return_tensors="pt").to("cuda", torch.float16)
generated_ids = model.generate(
    input_ids=inputs["input_ids"],
    pixel_values=inputs["pixel_values"],
    max_new_tokens=1024
)
result = processor.batch_decode(generated_ids, skip_special_tokens=False)[0]
caption = processor.post_process_generation(result, task=task, image_size=image.size)
print(caption)

# Salida: {'<CAPTION>': 'Un perro jugando en el parque'}

# Subtítulo detallado
task = "<DETAILED_CAPTION>"
inputs = processor(text=task, images=image, return_tensors="pt").to("cuda", torch.float16)
generated_ids = model.generate(
    input_ids=inputs["input_ids"],
    pixel_values=inputs["pixel_values"],
    max_new_tokens=1024
)
result = processor.batch_decode(generated_ids, skip_special_tokens=False)[0]
detailed = processor.post_process_generation(result, task=task, image_size=image.size)
print(detailed)
```

### Detección de objetos

```python
task = "<OD>"  # Detección de objetos
inputs = processor(text=task, images=image, return_tensors="pt").to("cuda", torch.float16)
generated_ids = model.generate(
    input_ids=inputs["input_ids"],
    pixel_values=inputs["pixel_values"],
    max_new_tokens=1024
)
result = processor.batch_decode(generated_ids, skip_special_tokens=False)[0]
detections = processor.post_process_generation(result, task=task, image_size=image.size)

# Salida: {'<OD>': {'bboxes': [[x1, y1, x2, y2], ...], 'labels': ['perro', 'pelota', ...]}}
```

### OCR (Reconocimiento de texto)

```python
task = "<OCR>"
inputs = processor(text=task, images=image, return_tensors="pt").to("cuda", torch.float16)
generated_ids = model.generate(
    input_ids=inputs["input_ids"],
    pixel_values=inputs["pixel_values"],
    max_new_tokens=1024
)
result = processor.batch_decode(generated_ids, skip_special_tokens=False)[0]
text = processor.post_process_generation(result, task=task, image_size=image.size)
print(text)

# Salida: {'<OCR>': 'Texto encontrado en la imagen...'}
```

### Subtitulado denso de regiones

```python
task = "<DENSE_REGION_CAPTION>"
inputs = processor(text=task, images=image, return_tensors="pt").to("cuda", torch.float16)
generated_ids = model.generate(
    input_ids=inputs["input_ids"],
    pixel_values=inputs["pixel_values"],
    max_new_tokens=1024
)
result = processor.batch_decode(generated_ids, skip_special_tokens=False)[0]
regions = processor.post_process_generation(result, task=task, image_size=image.size)

# Salida: {'<DENSE_REGION_CAPTION>': {'bboxes': [...], 'labels': ['un perro marrón corriendo', 'hierba verde', ...]}}
```

### Comprensión de expresiones referenciales

Encontrar objetos basados en descripciones de texto:

```python
task = "<CAPTION_TO_PHRASE_GROUNDING>"
text_input = "el coche rojo a la izquierda"

inputs = processor(
    text=task + text_input,
    images=image,
    return_tensors="pt"
).to("cuda", torch.float16)

generated_ids = model.generate(
    input_ids=inputs["input_ids"],
    pixel_values=inputs["pixel_values"],
    max_new_tokens=1024
)
result = processor.batch_decode(generated_ids, skip_special_tokens=False)[0]
grounding = processor.post_process_generation(result, task=task, image_size=image.size)

# Devuelve el cuadro delimitador de "el coche rojo a la izquierda"
```

## Todas las tareas disponibles

```python
TASKS = [
    "<CAPTION>",                    # Subtítulo breve
    "<DETAILED_CAPTION>",           # Descripción detallada
    "<MORE_DETAILED_CAPTION>",      # Descripción muy detallada
    "<OD>",                          # Detección de objetos
    "<DENSE_REGION_CAPTION>",       # Descripciones de regiones
    "<REGION_PROPOSAL>",            # Proponer regiones de interés
    "<CAPTION_TO_PHRASE_GROUNDING>", # Encontrar objetos desde texto
    "<REFERRING_EXPRESSION_SEGMENTATION>", # Segmentar desde texto
    "<REGION_TO_SEGMENTATION>",     # Segmentar región especificada
    "<OPEN_VOCABULARY_DETECTION>",  # Detectar con etiquetas de texto
    "<REGION_TO_CATEGORY>",         # Clasificar región
    "<REGION_TO_DESCRIPTION>",      # Describir región
    "<OCR>",                         # Extraer texto
    "<OCR_WITH_REGION>",            # Extraer texto con ubicaciones
]
```

## Procesamiento por lotes

```python
import os
from transformers import AutoProcessor, AutoModelForCausalLM
from PIL import Image
import torch
import json

model = AutoModelForCausalLM.from_pretrained(
    "microsoft/Florence-2-large",
    torch_dtype=torch.float16,
    trust_remote_code=True
).to("cuda")
processor = AutoProcessor.from_pretrained("microsoft/Florence-2-large", trust_remote_code=True)

def process_image(image_path, task):
    image = Image.open(image_path)
    inputs = processor(text=task, images=image, return_tensors="pt").to("cuda", torch.float16)
    generated_ids = model.generate(
        input_ids=inputs["input_ids"],
        pixel_values=inputs["pixel_values"],
        max_new_tokens=1024
    )
    result = processor.batch_decode(generated_ids, skip_special_tokens=False)[0]
    return processor.post_process_generation(result, task=task, image_size=image.size)

# Procesar directorio
input_dir = "./images"
results = {}

for filename in os.listdir(input_dir):
    if not filename.endswith(('.jpg', '.png')):
        continue

    path = os.path.join(input_dir, filename)
    results[filename] = {
        "caption": process_image(path, "<CAPTION>"),
        "objects": process_image(path, "<OD>"),
        "text": process_image(path, "<OCR>")
    }
    print(f"Procesado: {filename}")

with open("results.json", "w") as f:
    json.dump(results, f, indent=2)
```

## Interfaz Gradio

```python
import gradio as gr
from transformers import AutoProcessor, AutoModelForCausalLM
from PIL import Image, ImageDraw
import torch

model = AutoModelForCausalLM.from_pretrained(
    "microsoft/Florence-2-large",
    torch_dtype=torch.float16,
    trust_remote_code=True
).to("cuda")
processor = AutoProcessor.from_pretrained("microsoft/Florence-2-large", trust_remote_code=True)

def run_task(image, task):
    inputs = processor(text=task, images=image, return_tensors="pt").to("cuda", torch.float16)
    generated_ids = model.generate(
        input_ids=inputs["input_ids"],
        pixel_values=inputs["pixel_values"],
        max_new_tokens=1024
    )
    result = processor.batch_decode(generated_ids, skip_special_tokens=False)[0]
    parsed = processor.post_process_generation(result, task=task, image_size=image.size)

    # Dibujar cuadros si la tarea es detección
    output_image = image.copy()
    if task in ["<OD>", "<DENSE_REGION_CAPTION>"]:
        draw = ImageDraw.Draw(output_image)
        if "bboxes" in parsed.get(task, {}):
            for box, label in zip(parsed[task]["bboxes"], parsed[task]["labels"]):
                draw.rectangle(box, outline="red", width=2)
                draw.text((box[0], box[1]-15), label, fill="red")

    return output_image, str(parsed)

demo = gr.Interface(
    fn=run_task,
    inputs=[
        gr.Image(type="pil", label="Imagen de entrada"),
        gr.Dropdown(
            choices=["<CAPTION>", "<DETAILED_CAPTION>", "<OD>", "<DENSE_REGION_CAPTION>", "<OCR>"],
            value="<CAPTION>",
            label="Tarea"
        )
    ],
    outputs=[
        gr.Image(label="Resultado"),
        gr.Textbox(label="Salida", lines=10)
    ],
    title="Florence-2 Vision AI",
    description="Modelo de visión multitarea. Ejecutándose en servidores GPU de CLORE.AI."
)

demo.launch(server_name="0.0.0.0", server_port=7860)
```

## Rendimiento

| Tarea                | Resolución | GPU      | Velocidad |
| -------------------- | ---------- | -------- | --------- |
| Subtítulo            | 768x768    | RTX 3090 | 200ms     |
| Subtítulo            | 768x768    | RTX 4090 | 120ms     |
| Detección de objetos | 768x768    | RTX 4090 | 150ms     |
| OCR                  | 768x768    | RTX 4090 | 180ms     |
| Subtítulo denso      | 768x768    | A100     | 100ms     |

## Variantes de modelo

| Modelo              | Parámetros | VRAM | Velocidad |
| ------------------- | ---------- | ---- | --------- |
| Florence-2-base     | 232M       | 4GB  | Rápido    |
| Florence-2-large    | 771M       | 8GB  | Medio     |
| Florence-2-base-ft  | 232M       | 4GB  | Rápido    |
| Florence-2-large-ft | 771M       | 8GB  | Medio     |

## Problemas comunes y soluciones

### Memoria insuficiente

**Problema:** Error de OOM en CUDA

**Soluciones:**

```python

# Usar el modelo base en lugar del grande
model = AutoModelForCausalLM.from_pretrained(
    "microsoft/Florence-2-base",
    torch_dtype=torch.float16,
    trust_remote_code=True
).to("cuda")

# O habilitar descarga a CPU
model = AutoModelForCausalLM.from_pretrained(
    "microsoft/Florence-2-large",
    torch_dtype=torch.float16,
    trust_remote_code=True,
    device_map="auto"
)
```

### Inferencia lenta

**Problema:** El procesamiento tarda demasiado

**Soluciones:**

* Usar Florence-2-base para inferencia más rápida
* Instalar flash-attention para acelerar
* Procesar múltiples imágenes en lote
* Usar GPU A100 para producción

```bash
pip install flash-attn --no-build-isolation
```

### Resultados pobres de OCR

**Problema:** El reconocimiento de texto es inexacto

**Soluciones:**

* Asegúrese de que la imagen tenga alta resolución (al menos 768px)
* Usa `<OCR_WITH_REGION>` para una mejor localización
* Preprocesamiento: mejorar contraste, enderezar la imagen
* Recortar las regiones de texto antes del OCR

### Detección: objetos faltantes

**Problema:** Objetos no detectados

**Soluciones:**

* Usa `<DENSE_REGION_CAPTION>` para más regiones
* Intenta `<OPEN_VOCABULARY_DETECTION>` con etiquetas específicas
* Combinar con GroundingDINO para objetos específicos

## Solución de problemas

### La tarea no funciona

* Verifique la sintaxis exacta del nombre de la tarea
* Algunas tareas requieren un formato de entrada específico
* Verifique que la versión del modelo coincida con la tarea

### Formato de salida inesperado

* Diferentes tareas devuelven diferentes formatos
* Analice la salida según el tipo de tarea
* Consulte la documentación para las salidas de las tareas

### Problemas de memoria de CUDA

* Florence-2-large necesita \~8GB de VRAM
* Usar Florence-2-base para menos memoria
* Habilitar gradient checkpointing

### Procesamiento lento

* Usar inferencia por lotes cuando sea posible
* Habilitar modo FP16
* Considerar la optimización con TensorRT

## Estimación de costos

Tarifas típicas del marketplace de CLORE.AI (a fecha de 2024):

| GPU       | Tarifa por hora | Tarifa diaria | Sesión de 4 horas |
| --------- | --------------- | ------------- | ----------------- |
| RTX 3060  | \~$0.03         | \~$0.70       | \~$0.12           |
| RTX 3090  | \~$0.06         | \~$1.50       | \~$0.25           |
| RTX 4090  | \~$0.10         | \~$2.30       | \~$0.40           |
| A100 40GB | \~$0.17         | \~$4.00       | \~$0.70           |
| A100 80GB | \~$0.25         | \~$6.00       | \~$1.00           |

*Los precios varían según el proveedor y la demanda. Consulta* [*CLORE.AI Marketplace*](https://clore.ai/marketplace) *para las tarifas actuales.*

**Ahorra dinero:**

* Usa **Spot** market para cargas de trabajo flexibles (a menudo 30-50% más barato)
* Paga con **CLORE** tokens
* Compara precios entre diferentes proveedores

## Próximos pasos

* [LLaVA](https://docs.clore.ai/guides/guides_v2-es/modelos-de-vision/llava-vision-language) - Chat visual y preguntas y respuestas
* [GroundingDINO](https://docs.clore.ai/guides/guides_v2-es/modelos-de-vision/groundingdino) - Detección sin entrenamiento (zero-shot)
* [SAM2](https://docs.clore.ai/guides/guides_v2-es/modelos-de-vision/sam2-video) - Segmentar objetos detectados
