docling-project / docling-project/docling
RapidOCR onnx backend crashes on any Latin-script lang with default PP-OCRv6 (Unsupported rec.lang_type='latin')
- 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
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