# LayoutLMv3 Document Classification Demo # Based on the CORLIDE inference pipeline import gradio as gr import requests from PIL import Image from io import BytesIO import json import os import tempfile # Mock the inference pipeline for demo purposes class MockInferencePipeline: """ Mock implementation of the inference pipeline for demo purposes. This simulates the behavior of the actual LayoutLMv3 inference pipeline. """ def __init__(self): # Mock label names - update with your actual class labels self.label_names = ["Formulario A", "Formulario B", "Formulario C", "Otros"] def classify_document(self, image, text=""): """ Mock classification function that simulates LayoutLMv3 inference. In a real implementation, this would use the actual model. """ # This is a mock implementation - replace with actual model loading # For demo purposes, we'll return mock results import random confidence = random.uniform(0.7, 0.95) predicted_class_idx = random.randint(0, len(self.label_names) - 1) # Generate mock probabilities probs = [random.uniform(0.05, 0.2) for _ in range(len(self.label_names))] probs[predicted_class_idx] = confidence # Normalize to sum to 1 total = sum(probs) probs = [p/total for p in probs] return { "predicted_class": self.label_names[predicted_class_idx], "confidence": confidence, "all_probabilities": {label: prob for label, prob in zip(self.label_names, probs)} } def classify_document(image_url, text): """ Classify a document using the LayoutLMv3 pipeline. """ try: # Initialize pipeline (in real implementation, load actual model) pipeline = MockInferencePipeline() # Download image from URL response = requests.get(image_url, timeout=10) response.raise_for_status() image = Image.open(BytesIO(response.content)) # Classify (this would use the actual LayoutLMv3 model in production) result = pipeline.classify_document(image, text) return result except Exception as e: return {"error": str(e)} def format_output(result): """ Format the classification result for display. """ if "error" in result: return f"āŒ Error: {result['error']}" output = f"šŸ“„ **Document Classification Results**\n\n" output += f"šŸŽÆ **Predicted Class:** {result['predicted_class']}\n" output += f"šŸ“Š **Confidence:** {result['confidence']:.4f}\n\n" output += "šŸ“ˆ **Class Probabilities:**\n" for label, prob in sorted(result['all_probabilities'].items(), key=lambda x: x[1], reverse=True): output += f"- {label}: {prob:.4f}\n" output += "\nšŸ’” **Note:** This demo runs on CPU, so inference may be slower than with GPU acceleration." output += "\n🚧 **Status:** Version 0.1.0 - Under development (not production-ready)" return output def create_example_inputs(): """Create example inputs for the demo.""" examples = [ [ "https://raw.githubusercontent.com/huggingface/documents/main/source/en/_static/images/readme.png", "Sample document text for classification" ], [ "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/question-answering.png", "Another sample document with different content" ] ] return examples # Create Gradio interface with gr.Blocks(title="LayoutLMv3 Document Classifier Demo", theme=gr.themes.Soft()) as demo: gr.Markdown(""" # šŸ“„ LayoutLMv3 Document Classification Demo This demo showcases a fine-tuned **LayoutLMv3** model for classifying legal documents (expedientes). The model is trained to recognize different types of Colombian government forms. --- ### šŸ”§ Technical Details - **Model:** `jmparejaz/layoutlmv3-base-expedientes` - **Version:** 0.1.0 - **Framework:** Transformers + LayoutLMv3 - **Inference:** CPU-based (slower than GPU) - **Status:** 🚧 Under active development """) with gr.Row(): with gr.Column(scale=1): gr.Markdown("### šŸ“ Input Document") image_input = gr.Textbox( label="Document Image URL", placeholder="Enter URL of document image (PNG/JPG)", lines=2 ) text_input = gr.Textbox( label="Document Text (Optional)", placeholder="Enter extracted text from document", lines=5 ) submit_btn = gr.Button("šŸ” Classify Document", variant="primary", size="lg") gr.Markdown(""" #### šŸ“Œ Example URLs: - `https://raw.githubusercontent.com/huggingface/documents/main/source/en/_static/images/readme.png` - `https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/question-answering.png` """) with gr.Column(scale=1): gr.Markdown("### šŸ“Š Classification Results") output_text = gr.Textbox( label="Results", lines=15, interactive=False ) # Examples gr.Examples( examples=create_example_inputs(), inputs=[image_input, text_input], outputs=output_text, fn=classify_document, cache_examples=True, label="Try these examples:" ) # Main classification flow submit_btn.click( fn=classify_document, inputs=[image_input, text_input], outputs=output_text ).then( fn=format_output, inputs=output_text, outputs=output_text ) gr.Markdown(""" --- ### šŸ“š About This Model This LayoutLMv3 model has been fine-tuned on Colombian legal documents (expedientes) to classify different form types. **Key Features:** - Multimodal: Combines visual layout and text information - Specialized: Trained specifically for legal document classification - Efficient: Optimized for document understanding tasks **Limitations:** - āš ļø **Version 0.1.0**: This is an early development version - āš ļø **CPU Inference**: Demo runs on CPU for accessibility (slower than GPU) - āš ļø **Not Production-Ready**: Model is still undergoing improvements **Model Card:** [jmparejaz/layoutlmv3-base-expedientes](https://huggingface.co/jmparejaz/layoutlmv3-base-expedientes) --- ### šŸ› ļø Implementation Notes This demo uses a mock inference pipeline for demonstration purposes. In production, you would: 1. Load the actual LayoutLMv3 model from Hugging Face 2. Use the LayoutLMv3Processor for proper image/text processing 3. Run inference on GPU for better performance 4. Handle batch processing for multiple documents **Production Code Example:** ```python from transformers import AutoModelForSequenceClassification, LayoutLMv3Processor model = AutoModelForSequenceClassification.from_pretrained("jmparejaz/layoutlmv3-base-expedientes") processor = LayoutLMv3Processor.from_pretrained("jmparejaz/layoutlmv3-base-expedientes") # Process document inputs = processor( images=image, text=text, return_tensors="pt", padding=True, truncation=True ) outputs = model(**inputs) predictions = outputs.logits.argmax(dim=-1) ``` """) if __name__ == "__main__": demo.launch(server_name="0.0.0.0", server_port=7860)