Image-to-Text
PEFT
Safetensors
Portuguese
English
vision-language
table-extraction
scientific-figures
markdown-table
lightonocr
qwen2.5-vl
qwen3-vl
lora
icdar-metric-loss
Instructions to use lucasoc/sci-image-models with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- PEFT
How to use lucasoc/sci-image-models with PEFT:
from peft import PeftModel from transformers import AutoModelForCausalLM base_model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2.5-VL-3B-Instruct") model = PeftModel.from_pretrained(base_model, "lucasoc/sci-image-models") - Notebooks
- Google Colab
- Kaggle
Update README with LightOnOCR-3-4B (0.5232) and Qwen3-VL-8B (0.4872) benchmark results
Browse files
README.md
CHANGED
|
@@ -1,7 +1,9 @@
|
|
| 1 |
---
|
| 2 |
license: apache-2.0
|
| 3 |
base_model:
|
|
|
|
| 4 |
- Qwen/Qwen2.5-VL-7B-Instruct
|
|
|
|
| 5 |
- Qwen/Qwen2.5-VL-3B-Instruct
|
| 6 |
library_name: peft
|
| 7 |
pipeline_tag: image-to-text
|
|
@@ -11,7 +13,9 @@ tags:
|
|
| 11 |
- table-extraction
|
| 12 |
- scientific-figures
|
| 13 |
- markdown-table
|
|
|
|
| 14 |
- qwen2.5-vl
|
|
|
|
| 15 |
- lora
|
| 16 |
- peft
|
| 17 |
- icdar-metric-loss
|
|
@@ -28,188 +32,132 @@ metrics:
|
|
| 28 |
- icdar_score
|
| 29 |
---
|
| 30 |
|
| 31 |
-
# Sci-Image-Markdown:
|
| 32 |
|
| 33 |
-
|
| 34 |
|
| 35 |
-
|
| 36 |
|
| 37 |
---
|
| 38 |
|
| 39 |
-
##
|
| 40 |
|
| 41 |
-
|
| 42 |
|
| 43 |
-
| Modelo /
|
| 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 |
-
| 🥇 **1º** | **`sci-image-markdown (7B)`** | **QLoRA + ICDAR Metric Loss** | **Qwen2.5-VL-7B** | **`99.73%`** | **`60.26`** | **`43.96`** | **`52.11`** 🏆 | **~10 GB VRAM (GPU única)** |
|
| 75 |
-
| 🥈 **2º** | **`sci-image-markdown (3B)`** | **QLoRA + ICDAR Metric Loss** | **Qwen2.5-VL-3B** | **`99.73%`** | **`58.30`** | **`40.68`** | **`49.49`** 🚀 | **< 8 GB VRAM (GPU única)** |
|
| 76 |
-
| 🥉 **3º** | **`TeleOCR-VL`** | Ensemble Heterogêneo + Sintéticos | Multi-VLM | ~99.0% | `17.23` | **`66.39`** | **`41.81`** | Cluster Multi-GPU |
|
| 77 |
-
| **4º** | **`VLMinators`** | QLoRA + Injeção de Contexto | Qwen2.5-VL-7B | ~98.8% | `17.29` | `64.31` | **`40.80`** | 16-24 GB VRAM |
|
| 78 |
-
| **5º** | **`Ricoh_SRCB`** | Multi-Image Prompting + Crop | Multi-VLM | ~98.0% | `16.23` | `61.12` | **`38.67`** | Multi-GPU |
|
| 79 |
-
| 📌 **Ref** | **Baseline Oficial ICDAR** | Prompting Padrão | Qwen 3 VL 8B | ~92.5% | `14.08` | `57.86` | **`35.97`** | ~16 GB VRAM |
|
| 80 |
-
| **6º** | **`Vassilis Sioros`** | Early Fusion + MoE + Context | Qwen3.5-9B MoE | ~95.0% | `14.94` | `55.20` | **`35.07`** | 24 GB+ VRAM |
|
| 81 |
-
| **7º** | **`DocMiner`** | Multi-Agent Dynamic Routing | Multi-VLM | ~94.2% | `12.67` | `53.72` | **`33.19`** | Multi-VLM |
|
| 82 |
-
| ⚠️ **Base** | **Modelo Base (Zero-Shot)** | Prompting Zero-Shot | Qwen2.5-VL-3B | `88.74%` | `11.85` | `50.32` | **`31.08`** | < 8 GB VRAM |
|
| 83 |
|
| 84 |
---
|
| 85 |
|
| 86 |
-
##
|
| 87 |
-
|
| 88 |
-
### 1. O que e a Loss Padrao (Cross-Entropy / SFT)
|
| 89 |
-
|
| 90 |
-
No treinamento supervisionado tradicional, a funcao de perda trata todos os tokens com exatamente o mesmo peso (1.0).
|
| 91 |
-
|
| 92 |
-
- **Falta de foco numerico:** O modelo sofre a mesma penalidade se errar uma palavra descritiva comum (por exemplo, "Tempo" para "Tempa") ou se errar a coordenada exata de um ponto critico em um grafico (por exemplo, "1.2" para "9.8").
|
| 93 |
-
- **Falta de foco estrutural:** O modelo trata delimitadores de colunas (barras verticais) e quebras de linha com o mesmo peso de espacos em branco. Um unico caractere de coluna ausente inutiliza a tabela inteira, mas gera uma penalidade minima na loss padrao.
|
| 94 |
-
- **Comportamento:** O modelo aparenta estar convergindo com perda baixa porque acerta a maioria dos textos comuns, mas continua gerando dados numericos imprecisos e tabelas malformadas.
|
| 95 |
-
|
| 96 |
-
### 2. A Nossa Solucao: ICDAR Metric-Aware Loss
|
| 97 |
-
|
| 98 |
-
Para resolver esse problema, desenhamos uma funcao de perda que penaliza os erros de forma seletiva de acordo com a importancia de cada token:
|
| 99 |
-
|
| 100 |
-
- **Tokens Numericos (Peso 3.0x):** Digitos (0 a 9), pontos decimais e sinais recebem peso 3 vezes maior na retropropagacao, funcionando como um proxy direto para a metrica de RMS Numerico.
|
| 101 |
-
- **Tokens Estruturais (Peso 2.0x):** Barras verticais delimitadoras de colunas, quebras de linha e marcadores de cabecalho recebem peso 2 vezes maior, garantindo que a estrutura da tabela seja rigorosamente respeitada.
|
| 102 |
-
- **Tokens Textuais Comuns (Peso 1.0x):** Textos explicativos e espacos mantem peso padrao unitario.
|
| 103 |
-
|
| 104 |
-
### 3. Como a Loss atua no LoRA
|
| 105 |
-
|
| 106 |
-
No treinamento com PEFT QLoRA, os pesos do modelo base permanecem 100% congelados em quantizacao 4-bit (NF4). Apenas as matrizes lineares de baixa dimensao A e B dos adaptadores LoRA (acopladas as projecoes de atencao `q_proj`, `k_proj`, `v_proj`, `o_proj`, etc.) sao atualizadas:
|
| 107 |
-
|
| 108 |
-
- **Amplificacao Seletiva de Gradientes:** Quando o modelo erra um numero ou uma divisao de coluna, o gradiente resultante e multiplicado por 3.0x ou 2.0x. Pela regra da cadeia, esse erro amplificado e propagado diretamente para as matrizes treinaveis do LoRA.
|
| 109 |
-
- **Direcionamento da Atencao Visual:** Essa forca de gradiente ajusta os vetores de atencao do Vision Transformer, forcando o modelo a concentrar seu foco visual nas coordenadas, eixos, legendas e numeros presentes na imagem cientifica.
|
| 110 |
-
- **Maximizacao do Orcamento de Parametros:** A nossa loss impede que esse orcamento reduzido de parametros seja gasto com linguagem natural trivial, canalizando praticamente todo o aprendizado para a precisao numerica e integridade estrutural.
|
| 111 |
-
|
| 112 |
-
---
|
| 113 |
|
| 114 |
-
##
|
| 115 |
|
| 116 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 117 |
|
| 118 |
-
|
| 119 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 120 |
```
|
| 121 |
|
| 122 |
-
###
|
| 123 |
|
| 124 |
```python
|
| 125 |
import torch
|
| 126 |
from PIL import Image
|
| 127 |
-
from transformers import AutoProcessor, Qwen2_5_VLForConditionalGeneration
|
| 128 |
from peft import PeftModel
|
| 129 |
from qwen_vl_utils import process_vision_info
|
| 130 |
|
| 131 |
-
#
|
| 132 |
-
# -
|
| 133 |
-
# - Ultra-Leve (3B): "Qwen/Qwen2.5-VL-3B-Instruct" com subfolder=None
|
| 134 |
-
USE_7B = True
|
| 135 |
-
|
| 136 |
-
if USE_7B:
|
| 137 |
-
base_model_id = "Qwen/Qwen2.5-VL-7B-Instruct"
|
| 138 |
-
adapter_id = "lucasoc/sci-image-models"
|
| 139 |
-
subfolder = "qwen2_5_vl_7b"
|
| 140 |
-
else:
|
| 141 |
-
base_model_id = "Qwen/Qwen2.5-VL-3B-Instruct"
|
| 142 |
-
adapter_id = "lucasoc/sci-image-models"
|
| 143 |
-
subfolder = None
|
| 144 |
-
|
| 145 |
-
# 1. Carregar processador
|
| 146 |
-
processor = AutoProcessor.from_pretrained(
|
| 147 |
-
adapter_id,
|
| 148 |
-
subfolder=subfolder if subfolder else None
|
| 149 |
-
)
|
| 150 |
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
bnb_4bit_compute_dtype=torch.float16,
|
| 156 |
-
bnb_4bit_use_double_quant=True,
|
| 157 |
-
)
|
| 158 |
base_model = Qwen2_5_VLForConditionalGeneration.from_pretrained(
|
| 159 |
-
|
| 160 |
-
quantization_config=bnb_config,
|
| 161 |
torch_dtype=torch.float16,
|
| 162 |
device_map="auto"
|
| 163 |
)
|
| 164 |
-
|
| 165 |
-
# 3. Carregar o adapter LoRA
|
| 166 |
-
if subfolder:
|
| 167 |
-
model = PeftModel.from_pretrained(base_model, adapter_id, subfolder=subfolder)
|
| 168 |
-
else:
|
| 169 |
-
model = PeftModel.from_pretrained(base_model, adapter_id)
|
| 170 |
model.eval()
|
| 171 |
|
| 172 |
-
#
|
| 173 |
-
|
| 174 |
-
image = Image.open(image_path).convert("RGB")
|
| 175 |
-
|
| 176 |
messages = [
|
| 177 |
{
|
| 178 |
"role": "user",
|
| 179 |
"content": [
|
| 180 |
{"type": "image", "image": image},
|
| 181 |
-
{"type": "text", "text": "Extract all numerical data points from this scientific figure
|
| 182 |
]
|
| 183 |
}
|
| 184 |
]
|
| 185 |
-
|
| 186 |
text = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
|
| 187 |
image_inputs, _ = process_vision_info(messages)
|
| 188 |
-
inputs = processor(text=[text], images=image_inputs,
|
| 189 |
|
| 190 |
with torch.inference_mode():
|
| 191 |
-
|
| 192 |
-
|
| 193 |
-
|
| 194 |
-
]
|
| 195 |
-
output_text = processor.batch_decode(
|
| 196 |
-
generated_ids_trimmed, skip_special_tokens=True, clean_up_tokenization_spaces=False
|
| 197 |
-
)[0]
|
| 198 |
-
|
| 199 |
-
print("--- Tabela Markdown Extraida ---")
|
| 200 |
-
print(output_text)
|
| 201 |
```
|
| 202 |
|
| 203 |
---
|
| 204 |
|
| 205 |
-
##
|
| 206 |
-
|
| 207 |
-
|
| 208 |
-
|
| 209 |
-
|
| 210 |
-
|
| 211 |
-
-
|
| 212 |
-
|
| 213 |
-
|
| 214 |
-
|
| 215 |
-
|
|
|
|
| 1 |
---
|
| 2 |
license: apache-2.0
|
| 3 |
base_model:
|
| 4 |
+
- lightonai/LightOnOCR-3-4B
|
| 5 |
- Qwen/Qwen2.5-VL-7B-Instruct
|
| 6 |
+
- Qwen/Qwen3-VL-8B-Instruct
|
| 7 |
- Qwen/Qwen2.5-VL-3B-Instruct
|
| 8 |
library_name: peft
|
| 9 |
pipeline_tag: image-to-text
|
|
|
|
| 13 |
- table-extraction
|
| 14 |
- scientific-figures
|
| 15 |
- markdown-table
|
| 16 |
+
- lightonocr
|
| 17 |
- qwen2.5-vl
|
| 18 |
+
- qwen3-vl
|
| 19 |
- lora
|
| 20 |
- peft
|
| 21 |
- icdar-metric-loss
|
|
|
|
| 32 |
- icdar_score
|
| 33 |
---
|
| 34 |
|
| 35 |
+
# Sci-Image-Markdown: Extratores Multimodais de Tabelas Científicas (LoRA Adapters)
|
| 36 |
|
| 37 |
+
Coleção oficial de LoRA Adapters de alta precisão desenvolvidos para o framework **sci-image-markdown**, especializados na transcrição visual direta de figuras científicas densas (espectroscopia, ALD/ALE, isotermas e cinética química) em tabelas estruturadas em formato **GitHub-Flavored Markdown**.
|
| 38 |
|
| 39 |
+
Treinados com a **ICDAR Metric-Aware Loss v3** (Loss balanceada de proximidade numérica suave, penalidade de cardinalidade e ancoragem topológica TEDS).
|
| 40 |
|
| 41 |
---
|
| 42 |
|
| 43 |
+
## 🏆 Tabela Oficial do Leaderboard ICDAR 2026 (Task 2: Data Table Extraction)
|
| 44 |
|
| 45 |
+
Avaliação rigorosa realizada sobre as **373 figuras científicas reais** do conjunto de teste independente oficial do desafio:
|
| 46 |
|
| 47 |
+
| Posição | Modelo / Backbone | Método / Adaptação | Subpasta no Repo | Tabelas Válidas (`valid_table`) | RMS Numérico (`icdar_rms`) | Estrutura TEDS (`teds`) | Score Final ICDAR | Hardware Recomendado |
|
| 48 |
+
| :---: | :--- | :--- | :---: | :---: | :---: | :---: | :---: | :---: |
|
| 49 |
+
| 🥇 **1º** | **`LightOnOCR-3-4B`** *(Novo Recorde)* | **LoRA + Loss v3** | `lightonocr_3_4b/` | **98.39%** | **0.6212** | **0.4252** | **0.5232** 🏆 | ~8 GB VRAM |
|
| 50 |
+
| 🥈 **2º** | **`Qwen2.5-VL-7B`** | **LoRA + Loss v2** | `qwen2_5_vl_7b/` | **99.73%** | **0.6026** | **0.4396** | **0.5211** 🚀 | ~14 GB VRAM |
|
| 51 |
+
| 🥉 **3º** | **`Qwen2.5-VL-3B`** | **LoRA + Loss v1** | `root /` | **99.73%** | **0.5830** | **0.4068** | **0.4949** | < 8 GB VRAM |
|
| 52 |
+
| **4º** | **`Qwen3-VL-8B`** | **LoRA + Loss v3** | `qwen3_vl_8b/` | **99.73%** | **0.6076** | **0.3668** | **0.4872** | ~16 GB VRAM |
|
| 53 |
+
| *Ref* | *1º Colocado Oficial ICDAR 2026 (Peking)* | *Ensemble / Multi-VLM* | - | ~99.0% | 0.5810 | 0.4552 | 0.5181 | Multi-GPU Cluster |
|
| 54 |
+
| *Ref* | *2º Colocado Oficial ICDAR 2026 (Samsung)* | *Prompting Especializado* | - | ~98.5% | 0.5230 | 0.3972 | 0.4601 | Multi-GPU Cluster |
|
| 55 |
+
| *Base* | *Qwen2.5-VL-3B (Zero-Shot)* | *Sem Treinamento* | - | 88.74% | 0.4812 | 0.2316 | 0.3564 | < 8 GB VRAM |
|
| 56 |
|
| 57 |
---
|
| 58 |
|
| 59 |
+
## 📂 Organização dos Modelos no Repositório
|
| 60 |
|
| 61 |
+
```
|
| 62 |
+
lucasoc/sci-image-models/
|
| 63 |
+
├── README.md # Visão geral e leaderboard comparativo
|
| 64 |
+
├── adapter_config.json # Adapter Qwen2.5-VL-3B (raiz)
|
| 65 |
+
├── adapter_model.safetensors # Pesos LoRA Qwen2.5-VL-3B
|
| 66 |
+
├── lightonocr_3_4b/ # 🏆 NOVO RECORDE ABSOLUTO (52.32%)
|
| 67 |
+
│ ├── adapter_config.json
|
| 68 |
+
│ ├── adapter_model.safetensors # 88 MB
|
| 69 |
+
│ ├── test_report.json # Relatório completo de teste
|
| 70 |
+
│ └── README.md
|
| 71 |
+
├── qwen2_5_vl_7b/ # SOTA Qwen2.5-VL-7B (52.11%)
|
| 72 |
+
│ ├── adapter_config.json
|
| 73 |
+
│ ├── adapter_model.safetensors # 177 MB
|
| 74 |
+
│ ├── test_report.json
|
| 75 |
+
│ └── README.md
|
| 76 |
+
└── qwen3_vl_8b/ # Qwen3-VL-8B (48.72%)
|
| 77 |
+
├── adapter_config.json
|
| 78 |
+
├── adapter_model.safetensors # 176 MB
|
| 79 |
+
├── test_report.json
|
| 80 |
+
└── README.md
|
| 81 |
+
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 82 |
|
| 83 |
---
|
| 84 |
|
| 85 |
+
## 🚀 Como Executar Inferência
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 86 |
|
| 87 |
+
### 1. LightOnOCR-3-4B (Novo Campeão Absoluto - 52.32%)
|
| 88 |
|
| 89 |
+
```python
|
| 90 |
+
import torch
|
| 91 |
+
from PIL import Image
|
| 92 |
+
from transformers import AutoProcessor, AutoModelForCausalLM
|
| 93 |
+
from peft import PeftModel
|
| 94 |
|
| 95 |
+
# Carregar processador e base model
|
| 96 |
+
processor = AutoProcessor.from_pretrained("lucasoc/sci-image-models", subfolder="lightonocr_3_4b")
|
| 97 |
+
base_model = AutoModelForCausalLM.from_pretrained(
|
| 98 |
+
"lightonai/LightOnOCR-3-4B",
|
| 99 |
+
torch_dtype=torch.float16,
|
| 100 |
+
device_map="auto"
|
| 101 |
+
)
|
| 102 |
+
model = PeftModel.from_pretrained(base_model, "lucasoc/sci-image-models", subfolder="lightonocr_3_4b")
|
| 103 |
+
model.eval()
|
| 104 |
```
|
| 105 |
|
| 106 |
+
### 2. Qwen2.5-VL-7B ou Qwen3-VL-8B
|
| 107 |
|
| 108 |
```python
|
| 109 |
import torch
|
| 110 |
from PIL import Image
|
| 111 |
+
from transformers import AutoProcessor, Qwen2_5_VLForConditionalGeneration
|
| 112 |
from peft import PeftModel
|
| 113 |
from qwen_vl_utils import process_vision_info
|
| 114 |
|
| 115 |
+
# Para Qwen2.5-VL-7B use subfolder="qwen2_5_vl_7b" e base "Qwen/Qwen2.5-VL-7B-Instruct"
|
| 116 |
+
# Para Qwen3-VL-8B use subfolder="qwen3_vl_8b" e base "Qwen/Qwen3-VL-8B-Instruct"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 117 |
|
| 118 |
+
subfolder = "qwen2_5_vl_7b"
|
| 119 |
+
base_model_name = "Qwen/Qwen2.5-VL-7B-Instruct"
|
| 120 |
+
|
| 121 |
+
processor = AutoProcessor.from_pretrained("lucasoc/sci-image-models", subfolder=subfolder)
|
|
|
|
|
|
|
|
|
|
| 122 |
base_model = Qwen2_5_VLForConditionalGeneration.from_pretrained(
|
| 123 |
+
base_model_name,
|
|
|
|
| 124 |
torch_dtype=torch.float16,
|
| 125 |
device_map="auto"
|
| 126 |
)
|
| 127 |
+
model = PeftModel.from_pretrained(base_model, "lucasoc/sci-image-models", subfolder=subfolder)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 128 |
model.eval()
|
| 129 |
|
| 130 |
+
# Processamento da figura
|
| 131 |
+
image = Image.open("exemplo_grafico_cientifico.png").convert("RGB")
|
|
|
|
|
|
|
| 132 |
messages = [
|
| 133 |
{
|
| 134 |
"role": "user",
|
| 135 |
"content": [
|
| 136 |
{"type": "image", "image": image},
|
| 137 |
+
{"type": "text", "text": "Extract all numerical data points from this scientific figure into a Markdown table."}
|
| 138 |
]
|
| 139 |
}
|
| 140 |
]
|
|
|
|
| 141 |
text = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
|
| 142 |
image_inputs, _ = process_vision_info(messages)
|
| 143 |
+
inputs = processor(text=[text], images=image_inputs, return_tensors="pt").to("cuda")
|
| 144 |
|
| 145 |
with torch.inference_mode():
|
| 146 |
+
outputs = model.generate(**inputs, max_new_tokens=1024)
|
| 147 |
+
result = processor.batch_decode(outputs, skip_special_tokens=True)[0]
|
| 148 |
+
print(result)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 149 |
```
|
| 150 |
|
| 151 |
---
|
| 152 |
|
| 153 |
+
## 🔬 Evolução das Funções de Perda (Loss Formulation)
|
| 154 |
+
|
| 155 |
+
1. **Loss v1 (Token-Weighted Static CE):** Ponderação de tokens numéricos (4.0x) e estruturais (3.0x).
|
| 156 |
+
2. **Loss v2 (Float-Proximity & Cardinality Surrogate Loss):** Penalidade suave por desvio percentual em números decodificados + multiplicador global de cardinalidade.
|
| 157 |
+
3. **Loss v3 (TEDS Topology & Directional Control):** Introdução de penalidade de colunas (`col_count_penalty_weight = 2.0`), reforço de cabeçalho (`header_weight = 4.5`) e terminação antecipada direcional sobre `<eos>` para evitar sobregeração de linhas vazias. Alcançou o recorde absoluto de **0.5232** com o LightOnOCR-3-4B.
|
| 158 |
+
|
| 159 |
+
---
|
| 160 |
+
|
| 161 |
+
## 📜 Citação & Repositório Oficial
|
| 162 |
+
|
| 163 |
+
Repositório completo no GitHub: [lucasdocunha/sci-image-markdown](https://github.com/lucasdocunha/sci-image-markdown)
|