DeepDoc Model Path Resolution#
DeepDoc's vision models (det.onnx, rec.onnx, layout.onnx, tsr.onnx, ocr.res) are resolved through a layered path system that adapts across three deployment modes: embedded in the main RAGFlow process, standalone microservice, and Docker container. The canonical model directory is <project_base>/rag/res/deepdoc/, computed at runtime rather than hardcoded.
The key files are:
common/file_utils.py— providesget_project_base_directory()deepdoc/vision/ocr.py—load_model()+OCR.__init__()with HuggingFace fallbackdeepdoc/vision/recognizer.py—Recognizerbase class, delegates toload_model()deepdoc/server/docker_stubs.py— replacescommon/at Docker build time
Path Resolution Logic#
Resolution flows through three layers from most general to most specific:
1. get_project_base_directory() — common/file_utils.py
Checks RAG_PROJECT_BASE or RAG_DEPLOY_BASE environment variables first. If neither is set, computes the project root as one directory above the common/ package (i.e., relative to __file__). This means in a standard checkout the project base is the repo root.
2. Recognizer.__init__ — deepdoc/vision/recognizer.py
If model_dir is None (the default for all callers that don't pass an explicit path), it falls back to os.path.join(get_project_base_directory(), "rag/res/deepdoc"). This is the path used by LayoutRecognizer, TableStructureRecognizer, and any subclass.
3. OCR.__init__ — deepdoc/vision/ocr.py
Same default path, but with an additional HuggingFace snapshot fallback: if loading the local path raises an exception (e.g., files missing), it calls snapshot_download(repo_id="InfiniFlow/deepdoc", local_dir=...) to fetch the entire model snapshot . This fallback applies only to OCR, not to Recognizer subclasses.
load_model() validation — deepdoc/vision/ocr.py
Constructs the full path as os.path.join(model_dir, nm + ".onnx") and raises ValueError immediately if the file does not exist. A module-level loaded_models dict caches sessions keyed by (file_path, device_id), so repeated calls for the same model and device skip re-loading .
Deployment Modes#
Embedded (default, main RAGFlow process)#
get_project_base_directory() computes the repo root from common/file_utils.py's location . The effective model path is {repo_root}/rag/res/deepdoc/. Model files are excluded from git (they are not committed); on first use OCR.__init__ auto-downloads them via snapshot_download. Set HF_ENDPOINT=https://hf-mirror.com to use a mirror.
Override the base at any time with:
RAG_PROJECT_BASE=/custom/path # or RAG_DEPLOY_BASE
Standalone Microservice (deepdoc_server.py)#
The server accepts a --model-dir CLI argument . Its default value is a relative path resolved from deepdoc_server.py's own __file__:
deepdoc/server/deepdoc_server.py → ../../../rag/res/deepdoc
This resolves to the same repo-root model path in a standard checkout. In any deployment the path is converted to an absolute path via os.path.abspath() before being passed to the endpoint constructors .
Docker (Dockerfile_deepdoc_oss)#
The Docker image bakes models in at build time and bypasses all runtime path computation:
download_deps.pydownloads all five model files into/app/rag/res/deepdocduring the build .docker_stubs.pygenerates a replacementcommon/file_utils.pythat always returns/app(or$RAGFLOW_PROJECT_BASEif set), ignoring__file__-based computation .- The entrypoint explicitly passes
--model-dir /app/rag/res/deepdoc, overriding the default path entirely .
The result is that the path /app/rag/res/deepdoc is consistent whether reached via the stub's get_project_base_directory() or the explicit --model-dir flag.
Model Download Strategies#
Two strategies exist, targeting different lifecycle stages:
Build-time: download_deps.py
Used inside Dockerfile_deepdoc_oss. Downloads exactly five files from InfiniFlow/deepdoc on HuggingFace: layout.onnx, det.onnx, rec.onnx, tsr.onnx, ocr.res. Skips any file already present. Respects HF_ENDPOINT for mirror support (set to https://hf-mirror.com when NEED_MIRROR=1 in the Docker build arg). Can be run standalone:
python download_deps.py /path/to/model/dir
Runtime: snapshot_download fallback
Only triggered in OCR.__init__ when the local model directory fails to load (e.g., first run in a fresh checkout without pre-downloaded models). Downloads the entire InfiniFlow/deepdoc HuggingFace repo snapshot into <project_base>/rag/res/deepdoc. This fallback is not present in Recognizer.__init__, meaning LayoutRecognizer and TableStructureRecognizer will raise ValueError if their models are missing rather than auto-downloading.
Docker Stubs for Common Imports#
The vision modules (ocr.py, recognizer.py, etc.) import from common, rag, and deepdoc at module level. In the full RAGFlow environment these pull in heavy dependencies (torch, pdfplumber, database connectors, beartype) that are unnecessary in the ONNX-only Docker image.
docker_stubs.py generates lightweight replacement modules under /app at build time. The critical stub for path resolution:
common/file_utils.py: readsRAGFLOW_PROJECT_BASEenv var, defaults to/app. No__file__-relative computation.
Other stubs needed to satisfy the import chain:
| Stub | Replaces | Purpose |
|---|---|---|
common/__init__.py | real common.settings | exposes settings.PARALLEL_DEVICES only |
common/misc_utils.py | real misc_utils | pip_install_torch() no-op (lets cuda_is_available() fail gracefully) |
rag/nlp/__init__.py | real NLP stack | stub rag_tokenizer for table_structure_recognizer import |
rag/utils/lazy_image.py | real lazy_image | minimal ensure_pil_image() using PIL directly |
deepdoc/__init__.py | real init (uses beartype) | empty stub |
deepdoc/vision/__init__.py | real init (imports pdfplumber, Ascend) | imports only the 4 ONNX classes |
The stubs are written before server code is copied in. They remain stable as long as the common/file_utils and common/settings interfaces do not change — vision modules themselves require no Docker-specific guards.