docling-project / docling-project/docling

RapidOCR onnx backend crashes on any Latin-script lang with default PP-OCRv6 (Unsupported rec.lang_type='latin')

Open
#3,840 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
66.4k
Forks
4.8k
Avg merge
3d 4h
Merged PRs (30d)
95

Description

With the default onnx RapidOCR backend, requesting any Latin-script language (`lang=["es"]`, `de`, `pt`, `fr`, `it`, …) aborts the whole conversion:

```
ValueError: Unsupported rec.lang_type='latin' for PP-OCRv6 small model
```

**Versions:** docling 2.113.0, docling-core 2.87.1, rapidocr 3.9.1, onnxruntime 1.20.1.

### Reproduction

```python
from docling.datamodel.pipeline_options import PdfPipelineOptions, RapidOcrOptions
from docling.document_converter import DocumentConverter, PdfFormatOption
from docling.datamodel.base_models import InputFormat

opts = PdfPipelineOptions()
opts.do_ocr = True
opts.ocr_options = RapidOcrOptions(lang=["es"]) # any latin-script language
conv = DocumentConverter(format_options={InputFormat.PDF: PdfFormatOption(pipeline_options=opts)})
conv.convert("any_scanned.pdf") # -> ValueError: Unsupported rec.lang_type='latin' for PP-OCRv6 small model
```

### Root cause (from the installed source, `docling/models/stages/ocr/rapid_ocr_model.py`)

1. `_RAPIDOCR_LANGUAGE_GROUPS` maps `es`/`de`/`pt`/`fr`/`it`/… → `"latin"` (L124-188).
2. `_rapidocr_lang_type_params("latin")` sets `Rec.lang_type = LangRec.LATIN` (L259).
3. PP-OCRv6 (the onnx default) has **no** `latin` set — it exposes per-language sets (`es`, `de`, `pt`, …). `latin` only exists for the older PP-OCRv3/v4 models, so `resolve_model_key` rejects it.
4. The crash is **onnx-only**. For the torch backend, L436-437 additionally applies `_rapidocr_torch_ppocrv4_params()`, which forces `ocr_version = PPOCRV4` (and PP-OCRv4 *does* have a latin set). Nothing lowers `ocr_version` on the onnx path, so it stays on PP-OCRv6 and fails:

```python
# rapid_ocr_model.py:434-437
if det_model_path is None and rec_model_path is None:
params.update(_rapidocr_lang_type_params(ocr_lang)) # -> Rec.lang_type = LATIN
if backend_enum == EngineType.TORCH: # torch only
params.update(_rapidocr_torch_ppocrv4_params()) # lowers to PP-OCRv4 (has latin)
```

### Proposed fix

On the onnx/default path, when the resolved group is `"latin"` under PP-OCRv6, either:
- (a) mirror the torch branch and lower `Det/Rec.ocr_version` to PP-OCRv4, or
- (b) pass the specific language directly to PP-OCRv6 (its `multi_PP-OCRv6_rec` model supports `es`/`de`/`pt`/… per-language) instead of collapsing to the `latin` group.

### Docstring note

`pipeline_options.py` still documents the `lang` field as *"RapidOCR currently supports english and chinese (default)"* — stale since the `latin` group (2.103.0) and the PP-OCRv6 default.

### Workaround (for others hitting this)

User `rapidocr_params` are applied last (L439-442) and win, so passing the specific language directly bypasses the `latin` group:

```python
RapidOcrOptions(lang=["es"], rapidocr_params={"Rec.lang_type": "es"})
```

### Related

- RapidAI/RapidOCR#697 (closed completed — rapidocr's answer is "pass the specific lang, not the `latin` group").
- adrianmazur-dev/ocrmypdf-rapidocr#1 (same crash reproduced in another downstream wrapper).

Contributor guide

Open the contributing guide

Research direction

Start in docling/models/stages/ocr/rapid_ocr_model.py, especially the language-group mapping and the ONNX/TORCH parameter branches around lines 434-442. Reproduce the conversion with RapidOcrOptions(lang=["es"]) and compare the resolved PP-OCRv6 parameters with the torch path. Done means Latin-language OCR no longer raises with the default ONNX backend; review the related lang documentation in pipeline_options.py as part of the change.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
computer-vision
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.