Instructions to use eng-aesr/donut-boletas-peru with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use eng-aesr/donut-boletas-peru with Transformers:
# Use a pipeline as a high-level helper # Warning: Pipeline type "image-to-text" is no longer supported in transformers v5. # You must load the model directly (see below) or downgrade to v4.x with: # 'pip install "transformers<5.0.0' from transformers import pipeline pipe = pipeline("image-to-text", model="eng-aesr/donut-boletas-peru")# Load model directly from transformers import AutoTokenizer, AutoModelForMultimodalLM tokenizer = AutoTokenizer.from_pretrained("eng-aesr/donut-boletas-peru") model = AutoModelForMultimodalLM.from_pretrained("eng-aesr/donut-boletas-peru", device_map="auto") - Notebooks
- Google Colab
- Kaggle
Donut para boletas peruanas
Modelo experimental de extracción estructurada, sin OCR explícito, para imágenes de boletas peruanas. Es una adaptación de bajo recurso de naver-clova-ix/donut-base-finetuned-cord-v2, no un modelo entrenado desde cero.
El modelo recibe una imagen completa y genera una representación que DonutProcessor.token2json convierte al siguiente esquema:
{
"empresa": "",
"ruc": "",
"fecha": "",
"nro_comprobante": "",
"menu": [
{
"nm": "",
"price": ""
}
],
"sub_total": "",
"igv": "",
"total": ""
}
Uso previsto
Este checkpoint está pensado para investigación, demostraciones y prototipos supervisados sobre boletas impresas peruanas en español. Puede servir como punto de partida para nuevas evaluaciones o fine-tuning con datos propios.
No debe utilizarse sin revisión humana para contabilidad, tributación, auditoría, pagos, cumplimiento normativo ni otras decisiones de alto impacto. Tampoco es un extractor universal de comprobantes: no fue validado para facturas, documentos manuscritos, documentos de otros países o imágenes fuera del dominio de entrenamiento.
Uso con Transformers
El checkpoint fue exportado con transformers==5.12.1 y se verificó localmente con transformers==5.15.0. Se recomienda cargar el modelo directamente en lugar de usar pipeline, porque requiere el prompt de tarea específico.
pip install "transformers==5.15.0" "torch>=2.4,<3" "pillow>=10"
from PIL import Image
import torch
from transformers import DonutProcessor, VisionEncoderDecoderModel
model_id = "eng-aesr/donut-boletas-peru"
task_prompt = "<s_receipt_peru>"
processor = DonutProcessor.from_pretrained(model_id)
model = VisionEncoderDecoderModel.from_pretrained(model_id)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device).eval()
image = Image.open("boleta.jpg").convert("RGB")
pixel_values = processor(image, return_tensors="pt").pixel_values.to(device)
decoder_input_ids = processor.tokenizer(
task_prompt,
add_special_tokens=False,
return_tensors="pt",
).input_ids.to(device)
generation_config = model.generation_config
generation_config.max_length = 768
generation_config.num_beams = 1
generation_config.pad_token_id = processor.tokenizer.pad_token_id
generation_config.eos_token_id = processor.tokenizer.eos_token_id
unk_token_id = processor.tokenizer.unk_token_id
bad_words_ids = [[unk_token_id]] if unk_token_id is not None else None
with torch.inference_mode():
output_ids = model.generate(
pixel_values,
decoder_input_ids=decoder_input_ids,
generation_config=generation_config,
bad_words_ids=bad_words_ids,
)
sequence = processor.batch_decode(output_ids, skip_special_tokens=False)[0]
for token in (
task_prompt,
processor.tokenizer.eos_token,
processor.tokenizer.pad_token,
):
if token:
sequence = sequence.replace(token, "")
result = processor.token2json(sequence.strip())
print(result)
Nunca envíes documentos sensibles a servicios de terceros sin una base legal y controles de privacidad adecuados. Para documentos confidenciales, ejecuta el modelo en infraestructura controlada.
Detalles del modelo
| Propiedad | Valor |
|---|---|
| Arquitectura | VisionEncoderDecoderModel (encoder Donut-Swin + decoder mBART) |
| Checkpoint base inmediato | naver-clova-ix/donut-base-finetuned-cord-v2 |
| Parámetros | 201,133,176 |
| Prompt de tarea | <s_receipt_peru> |
| Resolución del procesador | 1280 × 960 píxeles |
| Longitud máxima de generación | 768 tokens |
| Formato de pesos | SafeTensors |
| SHA-256 de los pesos | 27330e48fda6bf3f4ac117b28afc2ae354a039dbae179eb29bfc72b829ea960a |
Datos y entrenamiento
La adaptación utilizó un dataset privado de 140 boletas peruanas anotadas. El dataset y sus imágenes no se distribuyen con este modelo.
El checkpoint base inmediato ya había sido ajustado sobre CORD v2 por sus autores upstream. La etapa descrita aquí corresponde únicamente a la adaptación posterior al dominio peruano.
- Entrenamiento: 100 documentos originales. Se aplicaron tres variantes visuales suaves únicamente a este split (
blur,noiseyrotate), dando 400 registros de entrenamiento pero conservando 100 fuentes independientes. - Validación: 20 documentos reales, sin augmentation; se usaron para seleccionar el checkpoint.
- Test: 20 documentos reales, sin augmentation y sin uso durante la selección.
- Split: por identificador de documento (
source_id), no por empresa o plantilla visual.
Configuración principal de fine-tuning:
| Hiperparámetro | Valor |
|---|---|
| Learning rate | 1e-5 |
| Batch size por dispositivo | 2 |
| Gradient accumulation | 1 |
| Gradient clipping | 1.0 |
| Épocas máximas | 30 |
| Épocas ejecutadas | 10 |
| Early stopping | paciencia 4 |
| Seed | 2022 |
| Selección | menor eval_loss |
El mejor checkpoint fue el step 1200 (época 6), con eval_loss = 1.1445. La ejecución usó Python 3.12.13 y Transformers 5.12.1.
Evaluación
Las métricas se calcularon una sola vez sobre el test privado congelado de 20 documentos. Por el tamaño del test, cada error equivale a 5 puntos porcentuales; los resultados se presentan con conteo y porcentaje.
| Métrica | Resultado |
|---|---|
| JSON parseable | 15/20 (75.0%) |
| Ocho claves de nivel superior presentes | 10/20 (50.0%) |
| Esquema estricto válido (claves y tipos) | 4/20 (20.0%) |
| Normalized edit distance promedio | 0.4297 |
total exacto |
14/20 (70.0%) |
sub_total exacto |
10/20 (50.0%) |
fecha exacta |
9/20 (45.0%) |
ruc exacto |
8/20 (40.0%) |
igv exacto |
8/20 (40.0%) |
nro_comprobante exacto |
5/20 (25.0%) |
empresa exacta |
4/20 (20.0%) |
empresa Token-F1 promedio |
0.3229 |
| Cantidad de ítems correcta | 10.0% |
| Precio de ítems correcto | 16.7% |
| Nombre de ítems Token-F1 promedio | 0.1004 |
| Menú exacto | 0/20 (0.0%) |
Estos números describen este test concreto y no deben interpretarse como una estimación robusta del rendimiento sobre todas las boletas peruanas. No se calcularon intervalos de confianza.
Esquema estricto válido es una auditoría posterior de claves y tipos sobre las mismas predicciones guardadas. El evaluador original solo comprobaba la presencia de las ocho claves. Además, las métricas registradas de menu están sesgadas a la baja porque el evaluador original trataba como lista vacía el objeto que token2json produce para algunos menús de un solo ítem. Se conservan aquí por trazabilidad; no se publican métricas corregidas hasta repetir formalmente la evaluación.
Limitaciones y riesgos
- El dataset es pequeño y puede no representar la diversidad de comercios, impresoras, cámaras, iluminación y diseños presentes en Perú.
- El split evita duplicar el mismo documento entre conjuntos, pero no garantiza separación por empresa o plantilla; puede existir similitud visual entre splits.
- El modelo produce una salida no parseable en 25% del test. Solo 50% incluye las ocho claves de nivel superior y 20% satisface la auditoría estricta de claves y tipos.
- La extracción de listas es especialmente débil: el menú exacto fue 0% en el test registrado.
- Cuando hay un solo ítem,
menupuede generarse como un objeto en vez de una lista. Los consumidores deben preservar la salida cruda, validar tipos y tratar esta normalización explícitamente. - Puede confundir total, subtotal e IGV; copiar texto incorrectamente; omitir campos; o generar valores que no aparecen en la imagen.
- No devuelve una probabilidad calibrada que permita aceptar automáticamente una predicción.
- Los documentos pueden contener identificadores comerciales o personales. Aunque el dataset no se publica, un modelo generativo puede memorizar fragmentos; no debe asumirse que sus salidas están libres de información sensible.
Toda salida debe validarse estructuralmente y contrastarse con la imagen original antes de utilizarla.
Licencia y atribución
El checkpoint base se publica con licencia MIT. Esta adaptación se distribuye bajo la misma licencia; consulta LICENSE. La licencia del modelo no concede derechos sobre las imágenes o documentos que cada usuario procese.
DONUT: OCR-free Document Understanding Transformer fue presentado en:
@article{kim2021donut,
title={OCR-free Document Understanding Transformer},
author={Kim, Geewook and Hong, Teakgyu and Yim, Moonbin and Park, Jinyoung and Yim, Jinyeong and Hwang, Wonseok and Yun, Sangdoo and Han, Dongyoon and Park, Seunghyun},
journal={arXiv preprint arXiv:2111.15664},
year={2021}
}
Contacto
Responsable del repositorio: eng-aesr.
- Downloads last month
- 21
Model tree for eng-aesr/donut-boletas-peru
Base model
naver-clova-ix/donut-base-finetuned-cord-v2Paper for eng-aesr/donut-boletas-peru
Evaluation results
- Total exact match on Test privado de boletas peruanastest set self-reported70.000
- Subtotal exact match on Test privado de boletas peruanastest set self-reported50.000
- RUC exact match on Test privado de boletas peruanastest set self-reported40.000
- Fecha exact match on Test privado de boletas peruanastest set self-reported45.000
- Ocho claves de nivel superior presentes on Test privado de boletas peruanastest set self-reported50.000
- Esquema estricto válido on Test privado de boletas peruanastest set self-reported20.000