OCR Backend and Model Loading#
RAGFlow's document understanding pipeline (deepdoc/vision/) runs three categories of vision models — text detection (det.onnx), text recognition (rec.onnx), and layout/table-structure recognition (layout*.onnx, tsr.onnx) — across three hardware backends: CPU, NVIDIA GPU (CUDA), and Huawei Ascend NPU. The primary abstraction for CPU/GPU is ONNX Runtime; Ascend uses a parallel native stack via ais_bench.
Centralized Model Loading and Caching#
All ONNX models — including layout and table-structure recognizers — are loaded through the single load_model(model_dir, nm, device_id) function in deepdoc/vision/ocr.py.
Caching: A module-level loaded_models dict stores every loaded (InferenceSession, RunOptions) pair. The cache key is the model file path plus device_id , so the same model on two different GPUs is stored independently. On cache hit, the function returns immediately without reloading.
CUDA/CPU provider selection: load_model calls an inner cuda_is_available() that imports torch and checks torch.cuda.is_available() for the target device ID. On success, an ort.InferenceSession is created with CUDAExecutionProvider; otherwise it falls back to CPUExecutionProvider with CPU memory arena shrinkage enabled .
ONNX session options are shared across both providers :
execution_mode = ORT_SEQUENTIALenable_cpu_mem_arena = False- Thread counts from
OCR_INTRA_OP_NUM_THREADS/OCR_INTER_OP_NUM_THREADS(default2)
The Recognizer base class (deepdoc/vision/recognizer.py) delegates directly to load_model and stores the returned session as self.ort_sess. Both LayoutRecognizer and TableStructureRecognizer extend Recognizer and inherit this path. All ONNX model files reside in rag/res/deepdoc/ and are auto-downloaded from InfiniFlow/deepdoc on HuggingFace if absent.
CUDA Environment Variables#
| Variable | Default | Effect |
|---|---|---|
OCR_GPU_MEM_LIMIT_MB | 2048 | VRAM cap per session |
OCR_ARENA_EXTEND_STRATEGY | kNextPowerOfTwo | GPU memory arena growth policy |
OCR_GPUMEM_ARENA_SHRINKAGE | (off) | Set to "1" to release VRAM after each run |
OCR_INTRA_OP_NUM_THREADS | 2 | ONNX intra-op thread count |
OCR_INTER_OP_NUM_THREADS | 2 | ONNX inter-op thread count |
These variables apply to all ONNX-based models: det, rec, layout, and tsr.
Multi-GPU (OCR text pipeline)#
The OCR class checks settings.PARALLEL_DEVICES (set dynamically to torch.cuda.device_count() in common/settings.py ). When PARALLEL_DEVICES > 0, it instantiates one TextDetector and TextRecognizer per GPU device ID (0 through N−1), enabling concurrent per-document processing. Layout and table recognizers do not currently use multi-GPU sharding via this mechanism.
Huawei Ascend NPU Backend#
The Ascend path is a parallel stack that bypasses ONNX Runtime entirely. It applies only to layout and table-structure recognition — OCR text detection and recognition remain ONNX-based.
Backend selection is controlled by two env vars:
| Variable | Default | Values |
|---|---|---|
LAYOUT_RECOGNIZER_TYPE | onnx | onnx, ascend |
TABLE_STRUCTURE_RECOGNIZER_TYPE | onnx | onnx, ascend |
In deepdoc/parser/pdf_parser.py , setting LAYOUT_RECOGNIZER_TYPE=ascend instantiates AscendLayoutRecognizer instead of LayoutRecognizer. For TSR, TABLE_STRUCTURE_RECOGNIZER_TYPE=ascend routes to _run_ascend_tsr().
AscendLayoutRecognizer :
- Loads a compiled
.omfile fromrag/res/deepdoc/{domain}.omviaais_bench.infer.interface.InferSession - Device selected by
ASCEND_LAYOUT_RECOGNIZER_DEVICE_ID(default0) - Does not use the global
loaded_modelscache; session is created per instance
_run_ascend_tsr :
- Loads
rag/res/deepdoc/tsr.omand creates anInferSessionper invocation - Uses the same
ASCEND_LAYOUT_RECOGNIZER_DEVICE_IDenv var
Ascend requires Huawei-compiled .om files; standard .onnx files are incompatible.
Key Source Files#
| File | Role |
|---|---|
deepdoc/vision/ocr.py | load_model(), global cache, TextDetector, TextRecognizer, OCR |
deepdoc/vision/recognizer.py | Recognizer base class — delegates to load_model |
deepdoc/vision/layout_recognizer.py | LayoutRecognizer, AscendLayoutRecognizer |
deepdoc/vision/table_structure_recognizer.py | TableStructureRecognizer, _run_ascend_tsr |
deepdoc/parser/pdf_parser.py | Runtime backend selection via env vars |