PHOCR OCR Toolkit

repository·main·Indexed 43 days ago

https://github.com/puhuilab/phocr

A high-performance Optical Character Recognition (OCR) toolkit featuring the PH-OCRv1 recognition model. It supports multi-language text recognition (including Chinese, English, Japanese, Korean, and Russian) with sub-0.x% character error rates. The toolkit includes components for text detection (TextDetector), orientation classification (TextClassifier), and precise bounding box calculation (CalRecBoxes), with specific optimizations for Transformer inference using ONNX Runtime.

Tokens
7.7K
Snippets
20
Records
29
Agent score
55%

What's inside PHOCR

  1. Enable KV caching for high-performance inference

    main
    For advanced users using PyTorch (CUDA), you can enable global KV caching to allow for larger batch sizes. This is configured via the use_cache=True parameter in ORTSeq2Seq.
  2. Transformer inference optimization techniques

    main

    To improve performance and reduce memory overhead during Transformer inference (especially during Beam Search), the following optimizations are implemented:

    1. Cross Attention KV Projection: Move the $K$ and $V$ projection calculations from the Decoder to the Encoder. The Encoder now outputs cross_attn_kvs with shape (num_layers, batch_size, head_size, src_len, 2 * head_dim).
    2. Lazy Broadcasting for Beam Search: Instead of repeating cross_attn_kvs along the batch_size dimension (which consumes significant VRAM), the Attention calculation is modified to use lazy broadcasting. The input to the Decoder remains un-repeated.
    3. Top-K Optimization: In Beam Search, the first Top-K operation (per beam) is moved into the Decoder's internal logic to avoid expensive CPU-based Top-K calculations. The outer Beam Search logic only handles the second Top-K operation (across all beams).
    4. KV Cache Merging: All self-attention KV caches in the Decoder are merged into a single merged_self_attn_kvs output.
    5. IO Binding: Use ONNX Runtime IO binding to ensure inputs and outputs remain on the closest computing device (e.g., keeping merged_self_attn_kvs on the GPU).
  3. Quickstart: Perform OCR and visualize results

    main

    To use PHOCR, initialize the PHOCR engine and pass an image path to the instance. The engine returns a result object that supports visualization and Markdown export.

    from phocr import PHOCR
    
    # Initialize OCR engine
    engine = PHOCR()
    
    # Perform OCR on an image
    result = engine("path/to/image.jpg")
    print(result)
    
    # Visualize the results and save to a file
    result.vis("output.jpg")
    
    # Export results to Markdown format
    print(result.to_markdown())
  4. Run performance benchmarks

    main

    PHOCR includes scripts to run recognition benchmarks and calculate the Character Error Rate (CER) using standardized datasets (e.g., zh_en_rec_bench, jp_rec_bench).

    # Run the full benchmark process
    sh benchmark/run_recognition.sh
    
    # Calculate the Character Error Rate (CER)
    sh benchmark/run_score.sh
  5. Run PHOCR Benchmarks

    main

    PHOCR includes scripts to run comprehensive benchmarks and evaluate model performance using standardized datasets.

    To run the complete benchmark pipeline:

    sh benchmark/run_recognition.sh

    To calculate the Character Error Rate (CER) for model predictions:

    sh benchmark/run_score.sh
    sh benchmark/run_recognition.sh
    sh benchmark/run_score.sh
  6. Install PHOCR with CPU or GPU support

    main

    PHOCR offers three installation methods depending on your hardware requirements and how you want to manage ONNX Runtime. Choose one of the following:

    Method 1: CPU Version

    Install the version optimized for CPU usage using ONNX Runtime.

    Method 2: GPU Version

    Install the version optimized for CUDA. Requirement: You must have the CUDA Toolkit and cuDNN library correctly installed on your system. You can install these via conda or manually.

    Method 3: Manual ONNX Runtime Management

    If you want to manage your own onnxruntime or onnxruntime-gpu installation, install the base package.

    # Method 1: CPU version
    pip install phocr[cpu]
    
    # Method 2: GPU version
    pip install phocr[cuda]
    # (Optional) Install dependencies via conda if needed:
    # conda install -c nvidia cuda-runtime=12.1 cudnn=9
    
    # Method 3: Manual management
    pip install phocr
  7. Optimize Transformer inference with ONNX Runtime

    main
    PHOCR provides optimizations for Transformer models running in ONNX Runtime to minimize third-party dependencies and maximize inference performance. The optimization strategy focuses on the relationship between the Encoder and Decoder, specifically how the Encoder's output is used by the Decoder during Cross Attention.
  8. Quick Start with PHOCR

    main

    To perform OCR on an image using the PHOCR Python API, initialize the PHOCR engine and pass the image path to the engine instance. The resulting object allows for visualization and exporting results to Markdown format.

    from phocr import PHOCR
    
    # Initialize OCR engine
    engine = PHOCR()
    
    # Perform OCR on image
    result = engine("path/to/image.jpg")
    print(result)
    
    # Visualize results
    result.vis("output.jpg")
    print(result.to_markdown())
  9. Install PHOCR

    main

    PHOCR can be installed using one of three methods depending on your hardware requirements and ONNX Runtime preference. Choose the method that best fits your environment:

    Method 1: CPU Version

    For standard CPU-based inference:

    pip install phocr[cpu]

    Method 2: GPU Version (CUDA)

    For hardware-accelerated inference. Note: You must have the CUDA toolkit and cuDNN library properly installed on your system. You can install them via conda:

    conda install -c nvidia cuda-runtime=12.1 cudnn=9

    Then install PHOCR with CUDA support:

    pip install phocr[cuda]

    Method 3: Manual ONNX Runtime Management

    If you prefer to manage onnxruntime or onnxruntime-gpu yourself, install the base package:

    pip install phocr
    pip install phocr[cpu]
    # OR
    pip install phocr[cuda]
    # OR
    pip install phocr
  10. Manage KV Cache memory with Torch and IO Binding

    main

    Because ONNX Runtime's automatic memory allocation can be inefficient, you can manually manage KV cache space for better performance:

    1. Pre-allocation: Use PyTorch to pre-allocate a block of memory on CUDA with the shape (num_layers, batchxbeam, head_num, max_seq_len, 2 * head_dim).
    2. IO Binding: Use this pre-allocated space for inference via IO binding.

    Warning: When using IO binding, you cannot bind raw pointers obtained directly from cudaMalloc. You must use the memory managed by the framework (e.g., via PyTorch tensors).

    # Conceptual approach for pre-allocating KV cache space
    # Shape: (num_layers, batchxbeam, head_num, max_seq_len, 2 * head_dim)
    kv_cache_space = torch.empty((num_layers, batchxbeam, head_num, max_seq_len, 2 * head_dim), device='cuda') 
    
    # Use kv_cache_space with ONNX Runtime IO binding for inference
  11. Understand PHOCR output formats

    main

    The return type of the PHOCR call depends on which stages are enabled. If all stages are enabled, it returns a PHOCROutput object.

    PHOCROutput Fields:

    • img: The original input image (np.ndarray).
    • boxes: Bounding boxes for detected text (coordinates mapped back to original image scale).
    • txts: A tuple of recognized text strings.
    • scores: A tuple of confidence scores corresponding to the text.
    • elapse_list: A list containing the execution time for [det, cls, rec] stages.
    • lang_type: The language type used for recognition (from config).

    Conditional Returns:

    • If only detection is enabled: Returns TextDetOutput.
    • If only classification is enabled: Returns TextClsOutput.
    • If only recognition is enabled: Returns TextRecOutput.
    • If no text is found or detection fails: Returns an empty PHOCROutput object.
  12. How ImageSegmenter splits long images

    main

    The ImageSegmenter is used to handle images that are too wide for the recognition model by splitting them into manageable patches.

    It works by:

    1. Resizing the image to a standard height (h=32).
    2. Identifying 'patch points' based on the standard deviation of grayscale intensity. It looks for areas of low variance (stable regions) to determine where to split the image.
    3. Returning a list of patch indices (to track which patch belongs to which original image) and the list of image patches.

    This ensures that text spanning across a large width is processed in chunks while maintaining the context of the original image structure.