Start here

Quick start & APIInstallOnline OCRCode generator

Models & pipelines

PP-OCRv6 modelsLanguagesPP-StructureV3PaddleOCR-VL

Deploy & integrate

Serving & APIPaddleOCR.jsMCP server

Fix & upgrade

TroubleshootingMigrate from 2.xReleases

Evaluate

Our benchmarkCompare OCR toolsLicense & cost

Tools

Online OCRInstall command builderCode generatorError fixer2.x → 3.x converterLanguage code finder

Language

English简体中文日本語Try OCR online
Converter · 123-row mapping · tested on 3.7.0

Migrate PaddleOCR 2.x code to 3.x

PaddleOCR 3.x is not backward compatible: use_gpu and show_log now raise errors, ocr(img, cls=True) raises TypeError, draw_ocr is gone and results are objects instead of nested lists. Paste your 2.x code below and get 3.x code plus a list of every change and why.

Checked against PaddleOCR 3.7.0Updated 14 min readRuns in your browser
On this page
  1. 2.x → 3.x code converter
  2. What changed in 3.x, and why
  3. use_angle_cls and the 11 names that still work
  4. use_gpu, show_log, use_onnx, drop_score: errors, not warnings
  5. ocr(img, cls=True) and the new result format
  6. cannot import name 'draw_ocr' from 'paddleocr'
  7. det_model_dir and rec_model_dir: custom models
  8. Defaults that changed silently
  9. PPStructure → PPStructureV3
  10. Command line: paddleocr --image_dir → paddleocr ocr -i
  11. Complete 2.x → 3.x mapping table
  12. Staying on 2.x: pin paddleocr below 3
  13. Migration checklist
  14. Questions

Short answer: rename use_angle_cls to use_textline_orientation, replace use_gpu=True with device='gpu', delete show_log, call ocr.predict(img) without cls=, and read res['rec_texts'], res['rec_scores'] and res['rec_polys'] instead of line[1][0]. Replace draw_ocr with res.save_to_img('output'). The converter below does all of this for you and flags what it can't do safely.

2.x → 3.x code converter#

Paste PaddleOCR 2.x code or a 2.x command#

Runs in your browser
Load a 2.x example
Converts as you type. Your code never leaves this page.

PythonPaddleOCR 3.x

Check by hand

Every change, with the reason and source

The converter is rule-based, not a guess. It rewrites only patterns it understands, cites the PaddleOCR source line for each change, and leaves a # TODO(paddleocr 3.x) comment wherever a human has to decide. We ran its output for the first two examples on PaddleOCR 3.7.0: both ran without errors and read all 27 lines of our test receipt, and the first wrote result.jpg.7

What changed in 3.x, and why#

PaddleOCR 2.x grew from 2021 to early 2025 by adding features to one lightweight code base. The maintainers' upgrade notes say that approach hit a wall: duplicated code, inconsistent interfaces and old dependencies that no longer worked with newer PaddlePaddle. Their answer was "a major, non-backward-compatible upgrade".2 In 3.x the paddleocr package is a thin wrapper around PaddleX pipelines; PaddleOCR wraps the PaddleX OCR pipeline and returns result objects.1

  1. paddleocr 2.7.0.3 — still a common pin in old requirements.txt files.
  2. paddleocr 2.10.0 — the last 2.x release.
  3. paddleocr 3.0.0 — new API on PaddleX.
  4. paddleocr 3.7.0 — current release, PP-OCRv6 models by default.

Dates are first-upload dates on PyPI.6 If you install paddleocr without a version today you get 3.7.0, so 2.x code breaks the moment a fresh environment is built. These are the changes that break it:

Unknown arguments raise#

Only 11 old parameter names are translated. Everything else, including use_gpu and show_log, raises ValueError: Unknown argument.

ocr() lost its switches#

cls, det, rec, bin, inv and slice are gone. ocr() is a deprecated alias of predict().

Results are objects#

One OCRResult per page with parallel lists, not [box, (text, score)] per line. Old indexing raises KeyError: 0.

Helpers and PPStructure removed#

draw_ocr, save_structure_res and friends are gone; results save and draw themselves. PPStructure became PPStructureV3.

Two more changes don't raise anything but change your output: new default models and preprocessing, covered in defaults that changed silently, and the engine install. pip install paddleocr does not install PaddlePaddle in 3.x, and the PyPI paddlepaddle-gpu package stops at 2.6.2 — see our install guide.

use_angle_cls and the 11 names that still work#

3.x keeps a small translation table for old PaddleOCR keyword arguments. This is the complete list, copied from the source:1

pythonpaddleocr/_pipelines/ocr.py, lines 44-56
_DEPRECATED_PARAM_NAME_MAPPING = {
    "det_model_dir": "text_detection_model_dir",
    "det_limit_side_len": "text_det_limit_side_len",
    "det_limit_type": "text_det_limit_type",
    "det_db_thresh": "text_det_thresh",
    "det_db_box_thresh": "text_det_box_thresh",
    "det_db_unclip_ratio": "text_det_unclip_ratio",
    "rec_model_dir": "text_recognition_model_dir",
    "rec_batch_num": "text_recognition_batch_size",
    "use_angle_cls": "use_textline_orientation",
    "cls_model_dir": "textline_orientation_model_dir",
    "cls_batch_num": "textline_orientation_batch_size",
}

Pass one of these and 3.x renames it for you, with a warning. We ran PaddleOCR(lang='en', use_angle_cls=True) on 3.7.0 and got exactly this:7

textOutput
DeprecationWarning: The parameter `use_angle_cls` has been deprecated and will be removed in the future. Please use `use_textline_orientation` instead.

Python hides DeprecationWarning by default unless it is triggered from __main__, so many people never see it. Three rules follow from the code around that table:1

  • Old and new name together is an error. PaddleOCR(use_angle_cls=True, use_textline_orientation=True) raises ValueError: `use_angle_cls` and `use_textline_orientation` are mutually exclusive. (we reproduced it).
  • Only PaddleOCR has the table. PPStructureV3(det_model_dir=...) and PPStructureV3(use_angle_cls=True) raise ValueError: Unknown argument: det_model_dir / use_angle_cls. We reproduced both.
  • "Still works" isn't "same behaviour". In 2.x use_angle_cls defaulted to False. In 3.x, leaving use_textline_orientation unset means the pipeline default, which is True.5

The same 11 exist as CLI flags on paddleocr ocr: --use_angle_cls still works and prints CLIDeprecationWarning: The option `--use_angle_cls` has been deprecated and will be removed in the future. Please refer to the documentation for more details.

use_gpu, show_log, use_onnx, drop_score: errors, not warnings#

Every other leftover keyword hits this loop, which accepts only the 3.x engine options:1

pythonpaddleocr/_common_args.py, lines 52-54
unknown_names = kwargs.keys() - default_vals.keys()
for name in unknown_names:
    raise ValueError(f"Unknown argument: {name}")

Because it raises on the first name it finds, and unknown_names is a set, a constructor with three stale arguments reports only one of them per run. Fix them all at once with the table below, or with the converter. Our reproduction on 3.7.0:7

textPaddleOCR(lang='en', **kw) on paddleocr 3.7.0
use_gpu=True      -> ValueError: Unknown argument: use_gpu
show_log=False    -> ValueError: Unknown argument: show_log
use_onnx=True     -> ValueError: Unknown argument: use_onnx
drop_score=0.5    -> ValueError: Unknown argument: drop_score
2.x3.x replacementNote
use_gpu=Truedevice='gpu'Or 'gpu:1'. Without device, 3.x uses GPU 0 when PaddlePaddle sees a CUDA GPU, else the CPU.
use_gpu=Falsedevice='cpu''cpu:0' is rejected; CPUs take no index.
gpu_id=1device='gpu:1'The id is part of the device string.
gpu_mem=500—No equivalent. For out-of-memory errors, see GPU OOM.
use_xpu / use_npu / use_mlu / use_gcudevice='xpu' etc.Supported device types: cpu, gpu, xpu, npu, mlu, gcu, dcu, iluvatar_gpu, metax_gpu.
show_log=Falsedelete itThe new paddleocr logger is already at ERROR level. For more output: logger.setLevel(logging.INFO).
use_onnx=Trueengine='onnxruntime'PaddleOCR 3.5+. Needs pip install onnxruntime. Our test: 3.7.0 runs with only onnxruntime installed, no PaddlePaddle.
drop_score=0.5text_rec_score_thresh=0.5Not an alias. The 3.x default is 0.0, so nothing is filtered unless you set it.
rec_image_shape='3, 48, 320'text_rec_input_shape=(3, 48, 320)A tuple now, not a string.

A common mistake in the other direction: device='cuda'. PaddleX rejects it with a bare AssertionError; the GPU device type is called gpu.

ocr(img, cls=True) and the new result format#

3.x still has an ocr() method, but it is a deprecated alias that forwards its keyword arguments to predict():1

pythonpaddleocr/_pipelines/ocr.py, lines 239-241
@deprecated("Please use `predict` instead.")
def ocr(self, img, **kwargs):
    return self.predict(img, **kwargs)

predict() has no cls parameter, so the line nearly every 2.x tutorial contains fails. On 3.7.0 we got:7

textocr.ocr('receipt.png', cls=True)
TypeError: PaddleOCR.predict() got an unexpected keyword argument 'cls'

Text-line orientation is now chosen when you build the object (use_textline_orientation=True), or per call with predict(img, use_textline_orientation=False). One catch from the PaddleX source: you can switch it off per call, but turning it on per call when the object was built without it logs an error instead of running.

The bigger change is what comes back. In 2.x, ocr() returned one list per image holding [box, (text, score)] per line, or None when no text was found.3 In 3.x, predict() returns one OCRResult per image or PDF page. It is a dict with parallel lists:5

KeyContents
rec_textsRecognized text per line (lines at or above text_rec_score_thresh)
rec_scoresConfidence per line
rec_polysPolygon per line: a (4, 2) int16 NumPy array
rec_boxesAxis-aligned boxes, shape (n, 4): [x_min, y_min, x_max, y_max]
dt_polysEvery detected box (the score filter does not apply)
input_path, page_indexWhere the result came from

What the old loop does against this object is worth knowing, because the error doesn't mention PaddleOCR at all. for line in result[0] now iterates the dict's keys, so the first line is the string 'input_path', and box, (text, score) = line raises ValueError: too many values to unpack (expected 2). Indexing like result[0][0][1][0] raises KeyError: 0. We reproduced both.7

result = ocr.ocr(img_path, cls=True)
for line in result[0]:
    box, (text, score) = line
    print(text, score, box)
result = ocr.predict(img_path)
for res in result:  # one OCRResult per image / PDF page
    for box, text, score in zip(res['rec_polys'], res['rec_texts'], res['rec_scores']):
        print(text, score, box.tolist())

Three details trip people up after converting. The polygons are NumPy arrays, so call .tolist() before json.dumps (or use res.json). A page without text gives empty lists, not None, so if result[0] is None never fires — test if not res['rec_texts']. And with the default use_doc_unwarping=True, coordinates refer to the unwarped image: on our receipt the first line was [[119,11],[507,8],[507,46],[120,49]] with unwarping and [[128,55],[489,55],[489,82],[128,82]] without.7 More in boxes don't line up.

ocr(img, det=False) and ocr(img, rec=False) have no pipeline equivalent. Use the single-model classes: TextRecognition(model_name="PP-OCRv6_medium_rec").predict(crop) returns rec_text and rec_score; TextDetection(model_name="PP-OCRv6_medium_det").predict(img) returns dt_polys and dt_scores. The converter marks these calls with a TODO rather than guess how your crops are produced.

cannot import name 'draw_ocr' from 'paddleocr'#

draw_ocr was exported by paddleocr 2.10.0 and is not in the 3.x package, so the import fails:7

text
ImportError: cannot import name 'draw_ocr' from 'paddleocr'

Results draw themselves now. The upgrade notes replace the whole visualization block with one call:2

from PIL import Image
from paddleocr import draw_ocr
result = result[0]
image = Image.open(img_path).convert('RGB')
boxes = [line[0] for line in result]
txts = [line[1][0] for line in result]
scores = [line[1][1] for line in result]
im_show = draw_ocr(image, boxes, txts, scores, font_path='simfang.ttf')
im_show = Image.fromarray(im_show)
im_show.save('result.jpg')
for res in result:
    res.save_to_img('output')            # writes <name>_ocr_res_img.png (+ preprocessed image)
    pil_image = res.img['ocr_res_img']   # or keep it in memory as a PIL image

On our receipt, save_to_img('output') wrote receipt_ocr_res_img.png and receipt_preprocessed_img.png; res.img has the same two keys.7 To use your own font, set the environment variable PADDLE_PDX_LOCAL_FONT_FILE_PATH instead of passing font_path. The other removed helpers map the same way: save_structure_res → res.save_to_json(), save_to_xlsx(), save_to_html() or save_all(); convert_info_docx → res.save_to_word(); to_excel → res.save_to_xlsx().5

det_model_dir and rec_model_dir: custom models#

det_model_dir, rec_model_dir and cls_model_dir are three of the 11 aliases, so they still work on PaddleOCR. Two things change underneath:

  • Give the model name too. If you set only text_detection_model_dir, the pipeline keeps its default name (PP-OCRv6_medium_det) and PaddleX compares it with the name in the folder's inference.yml: ValueError: Model name mismatch: expected 'PP-OCRv6_medium_det' but config has 'PP-OCRv5_server_det'. Please input the correct model dir.5
  • The folder must be a 3.x export. 3.x looks for inference.json or inference.pdmodel plus inference.pdiparams and an inference.yml. A folder without valid files gives No valid model files were found for engine 'paddle_static'.
  • Training-time options are gone. rec_char_dict_path, rec_algorithm, det_algorithm, use_space_char and max_text_length raise Unknown argument. Models are chosen by name, and per-module settings go in an exported PaddleX config (export_paddlex_config_to_yaml, then paddlex_config=...).
python3.x with your own models
from paddleocr import PaddleOCR

ocr = PaddleOCR(
    text_detection_model_name='PP-OCRv5_server_det',
    text_detection_model_dir='./models/PP-OCRv5_server_det_infer',
    text_recognition_model_name='PP-OCRv5_server_rec',
    text_recognition_model_dir='./models/PP-OCRv5_server_rec_infer',
)

When model names or folders are given, lang and ocr_version are ignored with a UserWarning. Note also that the 2.x script-group values lang='latin', 'arabic', 'cyrillic' and 'devanagari' are not language codes in 3.x: they raise No models are available for lang='latin' and ocr_version=None. Pick a real code from our language list.

Defaults that changed silently#

Code that runs after migration can still give different text, boxes and speed, because the defaults moved:53

Setting2.x default3.x default
ModelsPP-OCRv4PP-OCRv6_medium det + rec
Document orientation—on (use_doc_orientation_classify)
Page unwarping (UVDoc)—on (use_doc_unwarping)
Text-line orientationoff (use_angle_cls=False)on (use_textline_orientation)
Detection resize960, max64, min (max side 4000)
Score filter0.5 (drop_score)0.0 (text_rec_score_thresh)
oneDNN on CPUoffon (enable_mkldnn=True)

The converter's "Keep 2.x behaviour" option adds the four switches the error database recommends for 2.x-like output: use_doc_orientation_classify=False, use_doc_unwarping=False, use_textline_orientation=False and text_rec_score_thresh=0.5. Turning off the preprocessing models also makes 3.x faster. It keeps the new models, which read our five test documents with 123 of 124 items exact (our benchmark).

The oneDNN default bites on new installs. With enable_mkldnn=True and PaddlePaddle 3.3.1 (what pip install paddlepaddle gives today), CPU inference crashes with ConvertPirAttribute2RuntimeAttribute not support [pir::ArrayAttribute<pir::DoubleAttribute>]. Pin paddlepaddle==3.2.0. Details and our timings: the oneDNN fix.

PPStructure → PPStructureV3#

from paddleocr import PPStructure fails in 3.x with ImportError: cannot import name 'PPStructure' from 'paddleocr'. The upgrade notes point to PPStructureV3, which needs an extra install:28

python -m pip install "paddleocr[doc-parser]"

Without it, PPStructureV3() fails with RuntimeError: A dependency error occurred during pipeline creation (fix). The constructor has its own parameters and no alias table, so even names that work on PaddleOCR fail here. We got Unknown argument: use_gpu, det_model_dir, use_angle_cls and show_log from PPStructureV3 on 3.7.0.7

PPStructure (2.x)PPStructureV3 (3.x)
use_gpu=Truedevice='gpu'
table=Falseuse_table_recognition=False
formula=Trueuse_formula_recognition=True (now on by default)
image_orientation=Trueuse_doc_orientation_classify=True
layout_model_dirlayout_detection_model_dir + layout_detection_model_name
table_model_dirsplit: wired_table_structure_recognition_model_dir / wireless_…
recovery=Trueres.save_to_word(dir) / res.save_to_markdown(dir)
layout=False, ocr=Falseno switch: use PaddleOCR or TableRecognitionPipelineV2
mode='kie'PP-ChatOCRv4 (pip install "paddleocr[ie]")
from paddleocr import PPStructure, save_structure_res

table_engine = PPStructure(show_log=True, image_orientation=True, use_gpu=True)
img = cv2.imread(img_path)
result = table_engine(img)
save_structure_res(result, './output', os.path.basename(img_path).split('.')[0])
for line in result:
    line.pop('img')
    print(line)
from paddleocr import PPStructureV3

pipeline = PPStructureV3(use_doc_orientation_classify=True, device='gpu')
output = pipeline.predict(img_path)       # one result per page; PDFs work directly
for res in output:
    res.print()
    res.save_to_json('output')
    res.save_to_markdown('output')        # also: save_to_word, save_to_html, save_to_xlsx, save_to_img

A 2.x structure result was a list of region dicts for one image; a 3.x result is one object per page. Our PP-StructureV3 guide covers the output in depth, including which OCR models it uses by default.

Command line: paddleocr --image_dir → paddleocr ocr -i#

The 3.x CLI needs a subcommand and takes the input with -i. The 2.x form fails in an unhelpful way: argparse treats your file name as the subcommand. Our run on 3.7.0:7

textpaddleocr --image_dir receipt.png --use_angle_cls true --lang en
usage: paddleocr [-h] [-v] COMMAND ...
paddleocr: error: argument COMMAND: invalid choice: 'receipt.png' (choose from 'doc_preprocessor', 'doc_understanding', 'formula_recognition_pipeline', 'ocr', 'doc_parser', 'pp_chatocrv4_doc', 'pp_doctranslation', 'pp_structurev3', ...)
2.x command3.x command
paddleocr --image_dir x.png --use_angle_cls true --lang enpaddleocr ocr -i x.png --use_textline_orientation True --lang en
--use_gpu false--device cpu (--use_gpu gives unrecognized arguments)
--type structure --recovery true --output ./outpaddleocr pp_structurev3 -i x.pdf --save_path ./out
--det falsepaddleocr text_recognition -i crop.png
--rec falsepaddleocr text_detection -i x.png
--use_onnx true--engine onnxruntime
--det_model_dir d --rec_model_dir r--text_detection_model_dir d --text_recognition_model_dir r

Boolean flags accept true/True/1; anything else counts as false. We ran paddleocr ocr on our receipt with --save_path: it printed the result and wrote the JSON plus both images. Paste a whole shell script into the converter; it rewrites paddleocr and pip install lines and leaves the rest alone.

Complete 2.x → 3.x mapping table#

All 123 entries of our verified mapping, generated from the same data the converter uses. "Alias, warns" means the old name still works; "Rename" means it must change; "Replaced" and "Removed" raise errors if left in. Every row links to the file and line we read.135

Imports 13#

2.x3.xWhat happensSource
from paddleocr import PaddleOCRfrom paddleocr import PaddleOCRChanged Same import name; the class is now a wrapper around the PaddleX 'OCR' pipeline and returns result objects instead of nested lists.PaddleOCR/paddleocr/__init__.py:32-43; PaddleOCR/paddleocr/_pipelines/ocr.py:66,175-177
from paddleocr import PPStructurefrom paddleocr import PPStructureV3Replaced PPStructure was removed in 3.x; the upgrade notes recommend PPStructureV3. Needs the doc-parser dependency group: pip install "paddleocr[doc-parser]".PaddleOCR/docs/update/upgrade_notes.en.md:73; PaddleOCR/paddleocr/__init__.py:84-131 (no PPStructure in __all__); PaddleOCR/docs/version3.x/pipeline_usage/PP-StructureV3.en.md:963
from paddleocr import draw_ocr—Removed draw_ocr was exported by paddleocr 2.10.0 but is not exported by 3.x; importing it raises ImportError. See the matching 'util' entry for the replacement.paddleocr-2.10.0/paddleocr/__init__.py:14-24,32-42; PaddleOCR/paddleocr/__init__.py:84-131
from paddleocr import draw_structure_result—Removed draw_structure_result was exported by paddleocr 2.10.0 but is not exported by 3.x; importing it raises ImportError. See the matching 'util' entry for the replacement.paddleocr-2.10.0/paddleocr/__init__.py:14-24,32-42; PaddleOCR/paddleocr/__init__.py:84-131
from paddleocr import save_structure_res—Removed save_structure_res was exported by paddleocr 2.10.0 but is not exported by 3.x; importing it raises ImportError. See the matching 'util' entry for the replacement.paddleocr-2.10.0/paddleocr/__init__.py:14-24,32-42; PaddleOCR/paddleocr/__init__.py:84-131
from paddleocr import download_with_progressbar—Removed download_with_progressbar was exported by paddleocr 2.10.0 but is not exported by 3.x; importing it raises ImportError. See the matching 'util' entry for the replacement.paddleocr-2.10.0/paddleocr/__init__.py:14-24,32-42; PaddleOCR/paddleocr/__init__.py:84-131
from paddleocr import sorted_layout_boxes—Removed sorted_layout_boxes was exported by paddleocr 2.10.0 but is not exported by 3.x; importing it raises ImportError. See the matching 'util' entry for the replacement.paddleocr-2.10.0/paddleocr/__init__.py:14-24,32-42; PaddleOCR/paddleocr/__init__.py:84-131
from paddleocr import convert_info_docx—Removed convert_info_docx was exported by paddleocr 2.10.0 but is not exported by 3.x; importing it raises ImportError. See the matching 'util' entry for the replacement.paddleocr-2.10.0/paddleocr/__init__.py:14-24,32-42; PaddleOCR/paddleocr/__init__.py:84-131
from paddleocr import to_excel—Removed to_excel was exported by paddleocr 2.10.0 but is not exported by 3.x; importing it raises ImportError. See the matching 'util' entry for the replacement.paddleocr-2.10.0/paddleocr/__init__.py:14-24,32-42; PaddleOCR/paddleocr/__init__.py:84-131
from paddleocr import convert_info_markdown—Removed Listed in 2.10.0 paddleocr.py __all__ (not re-exported by the package __init__). No 3.x export; use PPStructureV3 result .save_to_markdown().paddleocr-2.10.0/paddleocr/paddleocr.py:73-84; PaddleOCR/paddleocr/__init__.py:84-131
from paddleocr.tools.infer.utility import ... / from paddleocr.ppocr... / from paddleocr.ppstructure...—Removed The 2.x wheel bundled tools/, ppocr/ and ppstructure/ inside the paddleocr package. The 3.x package only contains paddleocr/ (setuptools include = paddleocr, paddleocr.*), whose public API is the __all__ list.paddleocr-2.10.0/paddleocr/(wheel contains paddleocr/tools, paddleocr/ppocr, paddleocr/ppstructure); PaddleOCR/pyproject.toml:61-64; PaddleOCR/paddleocr/__init__.py:84-131
(new in 3.x) module classesfrom paddleocr import TextDetection, TextRecognition, TextLineOrientationClassification, LayoutDetection, ...Changed 3.x exposes single-model classes used to replace ocr(det=False) / ocr(rec=False).PaddleOCR/paddleocr/__init__.py:17-31
from paddleocr import logger (did not exist in 2.x; 2.x used show_log)from paddleocr import loggerChanged 3.x uses a single logging.Logger named 'paddleocr', level ERROR by default.PaddleOCR/paddleocr/__init__.py:66; PaddleOCR/paddleocr/_utils/logging.py:19-36; PaddleOCR/docs/version3.x/logging.en.md:9-11

PaddleOCR constructor parameters 47#

2.x3.xWhat happensSource
use_angle_clsuse_textline_orientationAlias, warns Old name still works on PaddleOCR only, with a DeprecationWarning. Passing both names raises ValueError; PPStructureV3 raises Unknown argument. 2.x default False (utility.py:124). 3.x pipeline default is True (paddlex OCR.yaml:7) when not set.PaddleOCR/paddleocr/_pipelines/ocr.py:44-56,155-169; PaddleOCR/paddleocr/_utils/deprecation.py:36-42; paddleocr-2.10.0/paddleocr/tools/infer/utility.py:124; paddlex-3.7.2/paddlex/configs/pipelines/OCR.yaml
det_model_dirtext_detection_model_dirAlias, warns Old name still works on PaddleOCR only, with a DeprecationWarning. Passing both names raises ValueError; PPStructureV3 raises Unknown argument. Also set text_detection_model_name to the model's real name, otherwise the default PP-OCRv6_medium_det name is kept and PaddleX raises 'Model name mismatch' if the directory's inference.yml names another model.PaddleOCR/paddleocr/_pipelines/ocr.py:44-56,155-169; PaddleOCR/paddleocr/_utils/deprecation.py:36-42; paddleocr-2.10.0/paddleocr/tools/infer/utility.py:61; paddlex-3.7.2/paddlex/configs/pipelines/OCR.yaml
rec_model_dirtext_recognition_model_dirAlias, warns Old name still works on PaddleOCR only, with a DeprecationWarning. Passing both names raises ValueError; PPStructureV3 raises Unknown argument. Also set text_recognition_model_name (see det_model_dir note).PaddleOCR/paddleocr/_pipelines/ocr.py:44-56,155-169; PaddleOCR/paddleocr/_utils/deprecation.py:36-42; paddleocr-2.10.0/paddleocr/tools/infer/utility.py:97; paddlex-3.7.2/paddlex/configs/pipelines/OCR.yaml
cls_model_dirtextline_orientation_model_dirAlias, warns Old name still works on PaddleOCR only, with a DeprecationWarning. Passing both names raises ValueError; PPStructureV3 raises Unknown argument. Also set textline_orientation_model_name if not the default.PaddleOCR/paddleocr/_pipelines/ocr.py:44-56,155-169; PaddleOCR/paddleocr/_utils/deprecation.py:36-42; paddleocr-2.10.0/paddleocr/tools/infer/utility.py:125; paddlex-3.7.2/paddlex/configs/pipelines/OCR.yaml
det_db_threshtext_det_threshAlias, warns Old name still works on PaddleOCR only, with a DeprecationWarning. Passing both names raises ValueError; PPStructureV3 raises Unknown argument. 2.x default 0.3; 3.x YAML default 0.3 (paddlex configs/pipelines/OCR.yaml:32).PaddleOCR/paddleocr/_pipelines/ocr.py:44-56,155-169; PaddleOCR/paddleocr/_utils/deprecation.py:36-42; paddleocr-2.10.0/paddleocr/tools/infer/utility.py:67; paddlex-3.7.2/paddlex/configs/pipelines/OCR.yaml
det_db_box_threshtext_det_box_threshAlias, warns Old name still works on PaddleOCR only, with a DeprecationWarning. Passing both names raises ValueError; PPStructureV3 raises Unknown argument. 2.x default 0.6; 3.x YAML default 0.6.PaddleOCR/paddleocr/_pipelines/ocr.py:44-56,155-169; PaddleOCR/paddleocr/_utils/deprecation.py:36-42; paddleocr-2.10.0/paddleocr/tools/infer/utility.py:68; paddlex-3.7.2/paddlex/configs/pipelines/OCR.yaml
det_db_unclip_ratiotext_det_unclip_ratioAlias, warns Old name still works on PaddleOCR only, with a DeprecationWarning. Passing both names raises ValueError; PPStructureV3 raises Unknown argument. 2.x default 1.5; 3.x YAML default 1.5.PaddleOCR/paddleocr/_pipelines/ocr.py:44-56,155-169; PaddleOCR/paddleocr/_utils/deprecation.py:36-42; paddleocr-2.10.0/paddleocr/tools/infer/utility.py:69; paddlex-3.7.2/paddlex/configs/pipelines/OCR.yaml
det_limit_side_lentext_det_limit_side_lenAlias, warns Old name still works on PaddleOCR only, with a DeprecationWarning. Passing both names raises ValueError; PPStructureV3 raises Unknown argument. Default CHANGED: 2.x 960 with limit_type 'max'; 3.x YAML 64 with limit_type 'min' and max_side_limit 4000 (paddlex configs/pipelines/OCR.yaml:29-31). CLI type is int in 3.x (2.x float).PaddleOCR/paddleocr/_pipelines/ocr.py:44-56,155-169; PaddleOCR/paddleocr/_utils/deprecation.py:36-42; paddleocr-2.10.0/paddleocr/tools/infer/utility.py:62; paddlex-3.7.2/paddlex/configs/pipelines/OCR.yaml
det_limit_typetext_det_limit_typeAlias, warns Old name still works on PaddleOCR only, with a DeprecationWarning. Passing both names raises ValueError; PPStructureV3 raises Unknown argument. Default CHANGED: 2.x 'max'; 3.x YAML 'min'.PaddleOCR/paddleocr/_pipelines/ocr.py:44-56,155-169; PaddleOCR/paddleocr/_utils/deprecation.py:36-42; paddleocr-2.10.0/paddleocr/tools/infer/utility.py:63; paddlex-3.7.2/paddlex/configs/pipelines/OCR.yaml
rec_batch_numtext_recognition_batch_sizeAlias, warns Old name still works on PaddleOCR only, with a DeprecationWarning. Passing both names raises ValueError; PPStructureV3 raises Unknown argument. 2.x default 6; 3.x YAML default 6.PaddleOCR/paddleocr/_pipelines/ocr.py:44-56,155-169; PaddleOCR/paddleocr/_utils/deprecation.py:36-42; paddleocr-2.10.0/paddleocr/tools/infer/utility.py:100; paddlex-3.7.2/paddlex/configs/pipelines/OCR.yaml
cls_batch_numtextline_orientation_batch_sizeAlias, warns Old name still works on PaddleOCR only, with a DeprecationWarning. Passing both names raises ValueError; PPStructureV3 raises Unknown argument. 2.x default 6; 3.x YAML default 6.PaddleOCR/paddleocr/_pipelines/ocr.py:44-56,155-169; PaddleOCR/paddleocr/_utils/deprecation.py:36-42; paddleocr-2.10.0/paddleocr/tools/infer/utility.py:128; paddlex-3.7.2/paddlex/configs/pipelines/OCR.yaml
langlangChanged Same name. Model selection logic changed: lang=None and ocr_version=None -> PP-OCRv6_medium_det/rec. 2.x script-group values 'latin', 'arabic', 'cyrillic', 'devanagari', 'ch_doc', 'structure' are not language codes in 3.x and give ValueError "No models are available for lang='latin' and ocr_version=None." Use a real code (e.g. 'fr', 'de', 'ru', 'ar', 'hi'); 'french' and 'german' are still accepted. Ignored with a warning when model names/dirs are given.PaddleOCR/paddleocr/_pipelines/ocr.py:113-127,318-353; PaddleOCR/paddleocr/_utils/langs.py:17-60; paddleocr-2.10.0/paddleocr/paddleocr.py:506-527
ocr_version='PP-OCR' | 'PP-OCRv2' | 'PP-OCRv3' | 'PP-OCRv4'ocr_version='PP-OCRv3' | 'PP-OCRv4' | 'PP-OCRv5' | 'PP-OCRv6'Changed 2.x choices PP-OCR, PP-OCRv2, PP-OCRv3, PP-OCRv4 (default PP-OCRv4). 3.x PaddleOCR accepts PP-OCRv3..PP-OCRv6; anything else raises ValueError "Invalid OCR version: PP-OCRv2. Supported values are ['PP-OCRv3', 'PP-OCRv4', 'PP-OCRv5', 'PP-OCRv6']." PPStructureV3 accepts only PP-OCRv3..PP-OCRv5. PP-OCRv4 in 3.x only supports lang 'ch' and 'en'.paddleocr-2.10.0/paddleocr/paddleocr.py:90-91; PaddleOCR/paddleocr/_pipelines/ocr.py:58,97-100,393-399; PaddleOCR/paddleocr/_pipelines/pp_structurev3.py:28,103-106
use_gpu=True|Falsedevice='gpu' | 'gpu:0' | 'cpu'Replaced use_gpu is not accepted: ValueError "Unknown argument: use_gpu". Use device. If device is not set, GPU 0 is used when available, else CPU. If device='gpu' but Paddle has no CUDA, PaddleX logs 'The specified device (GPU) is not available! Switching to CPU instead.'PaddleOCR/paddleocr/_common_args.py:52-54 (raises ValueError(f"Unknown argument: {name}")); PaddleOCR/paddleocr/_common_args.py:38-50,102-106; paddlex-3.7.2/paddlex/utils/device.py:55-75; paddlex-3.7.2/paddlex/inference/models/runners/paddle_static/config/pp_option.py:97-115; paddleocr-2.10.0/paddleocr/tools/infer/utility.py:40
gpu_id=Ndevice='gpu:N'Replaced Raises 'Unknown argument: gpu_id'. Device id is part of the device string.PaddleOCR/paddleocr/_common_args.py:52-54 (raises ValueError(f"Unknown argument: {name}")); paddlex-3.7.2/paddlex/utils/device.py:78-100; paddleocr-2.10.0/paddleocr/tools/infer/utility.py:55
gpu_mem=500—Removed Raises 'Unknown argument: gpu_mem'. No equivalent parameter in 3.x. (Note: the repo FAQ still suggests gpu_mem=200 for OOM; that advice is 2.x-only.)PaddleOCR/paddleocr/_common_args.py:52-54 (raises ValueError(f"Unknown argument: {name}")); paddleocr-2.10.0/paddleocr/tools/infer/utility.py:54; PaddleOCR/docs/FAQ.en.md:91
use_xpu=Truedevice='xpu' (or 'xpu:0')Replaced Raises 'Unknown argument: use_xpu'. Supported device types: cpu, gpu, xpu, npu, mlu, gcu, dcu, iluvatar_gpu, metax_gpu.PaddleOCR/paddleocr/_common_args.py:52-54 (raises ValueError(f"Unknown argument: {name}")); paddlex-3.7.2/paddlex/utils/device.py:31-41; paddleocr-2.10.0/paddleocr/tools/infer/utility.py:41
use_npu=Truedevice='npu' (or 'npu:0')Replaced Raises 'Unknown argument: use_npu'. Supported device types: cpu, gpu, xpu, npu, mlu, gcu, dcu, iluvatar_gpu, metax_gpu.PaddleOCR/paddleocr/_common_args.py:52-54 (raises ValueError(f"Unknown argument: {name}")); paddlex-3.7.2/paddlex/utils/device.py:31-41; paddleocr-2.10.0/paddleocr/tools/infer/utility.py:42
use_mlu=Truedevice='mlu' (or 'mlu:0')Replaced Raises 'Unknown argument: use_mlu'. Supported device types: cpu, gpu, xpu, npu, mlu, gcu, dcu, iluvatar_gpu, metax_gpu.PaddleOCR/paddleocr/_common_args.py:52-54 (raises ValueError(f"Unknown argument: {name}")); paddlex-3.7.2/paddlex/utils/device.py:31-41; paddleocr-2.10.0/paddleocr/tools/infer/utility.py:43
use_gcu=Truedevice='gcu' (or 'gcu:0')Replaced Raises 'Unknown argument: use_gcu'. Supported device types: cpu, gpu, xpu, npu, mlu, gcu, dcu, iluvatar_gpu, metax_gpu.PaddleOCR/paddleocr/_common_args.py:52-54 (raises ValueError(f"Unknown argument: {name}")); paddlex-3.7.2/paddlex/utils/device.py:31-41; paddleocr-2.10.0/paddleocr/tools/infer/utility.py:45
use_tensorrtuse_tensorrtChanged Same name, still a constructor/CLI option. Ignored if engine_config is passed explicitly.PaddleOCR/paddleocr/_common_args.py:44,71,77-89,152-157; paddleocr-2.10.0/paddleocr/tools/infer/utility.py:51; PaddleOCR/docs/version3.x/inference_deployment/local_inference/inference_engine.en.md:152
precision='fp32'|'fp16'|'int8'precision='fp32'|'fp16'Changed Same name; only fp32 and fp16 accepted. Others raise ValueError "Invalid precision: int8. Supported values are: ['fp32', 'fp16']." Applies to TensorRT (use_tensorrt=True).PaddleOCR/paddleocr/_common_args.py:66-69; PaddleOCR/paddleocr/_constants.py:17,21; paddleocr-2.10.0/paddleocr/tools/infer/utility.py:53
enable_mkldnnenable_mkldnnChanged Same name; default CHANGED from False (2.x) to True (3.x). enable_mkldnn=False makes the CPU run_mode 'paddle' instead of the oneDNN path.paddleocr-2.10.0/paddleocr/tools/infer/utility.py:131; PaddleOCR/paddleocr/_constants.py:18; PaddleOCR/paddleocr/_common_args.py:90-95
(new) mkldnn_cache_capacitymkldnn_cache_capacityChanged New in 3.x, default 10.PaddleOCR/paddleocr/_common_args.py:47; PaddleOCR/paddleocr/_constants.py:19
cpu_threadscpu_threadsChanged Same name, default 10 in both.paddleocr-2.10.0/paddleocr/tools/infer/utility.py:132; PaddleOCR/paddleocr/_constants.py:20
ir_optim / min_subgraph_size—Removed Raise 'Unknown argument: ...'. Low-level Paddle Inference options now go through engine_config (paddle_static fields: run_mode, delete_pass, enable_new_ir, trt_* ...).PaddleOCR/paddleocr/_common_args.py:52-54 (raises ValueError(f"Unknown argument: {name}")); paddleocr-2.10.0/paddleocr/tools/infer/utility.py:50,52; PaddleOCR/docs/version3.x/inference_deployment/local_inference/inference_engine.en.md:79-97
use_onnx=Trueengine='onnxruntime' (3.5+) or enable_hpi=TrueReplaced Raises 'Unknown argument: use_onnx'. Upgrade notes: use_onnx replaced by high-performance inference (enable_hpi). The 3.5+ inference-engine doc adds engine='onnxruntime' (requires pip install onnxruntime / onnxruntime-gpu).PaddleOCR/paddleocr/_common_args.py:52-54 (raises ValueError(f"Unknown argument: {name}")); PaddleOCR/docs/update/upgrade_notes.en.md:71; PaddleOCR/paddleocr/_common_args.py:29-35; PaddleOCR/docs/version3.x/inference_deployment/local_inference/inference_engine.en.md:20-30,50-58; paddleocr-2.10.0/paddleocr/tools/infer/utility.py:155
onnx_providers=[...]engine='onnxruntime', engine_config={'providers': [...]}Replaced Raises 'Unknown argument: onnx_providers'. engine_config field 'providers' documented for onnxruntime.PaddleOCR/paddleocr/_common_args.py:52-54 (raises ValueError(f"Unknown argument: {name}")); paddleocr-2.10.0/paddleocr/tools/infer/utility.py:156; PaddleOCR/docs/version3.x/inference_deployment/local_inference/inference_engine.en.md:118-132
onnx_sess_optionsengine='onnxruntime', engine_config={'session_options': ...}Replaced Raises 'Unknown argument: onnx_sess_options'.PaddleOCR/paddleocr/_common_args.py:52-54 (raises ValueError(f"Unknown argument: {name}")); paddleocr-2.10.0/paddleocr/tools/infer/utility.py:157; PaddleOCR/docs/version3.x/inference_deployment/local_inference/inference_engine.en.md:132
(new) engine / engine_configengine=None|'paddle'|'paddle_static'|'paddle_dynamic'|'transformers'|'onnxruntime', engine_config={...}Changed New in 3.5+. Default None ~ 'paddle' (PaddlePaddle). Invalid value -> ValueError "Invalid engine: X. Supported values are: [...]".PaddleOCR/paddleocr/_common_args.py:29-35,58-64; PaddleOCR/docs/version3.x/inference_deployment/local_inference/inference_engine.en.md:60-73
show_log=Falseimport logging; from paddleocr import logger; logger.setLevel(logging.ERROR)Replaced Raises 'Unknown argument: show_log'. Upgrade notes: show_log replaced by a new logging system. Default level is already ERROR. PaddleX has its own separate logger.PaddleOCR/paddleocr/_common_args.py:52-54 (raises ValueError(f"Unknown argument: {name}")); PaddleOCR/docs/update/upgrade_notes.en.md:69; PaddleOCR/docs/version3.x/logging.en.md:9-26; PaddleOCR/paddleocr/_utils/logging.py:24-36; paddleocr-2.10.0/paddleocr/tools/infer/utility.py:154
drop_score=0.5text_rec_score_threshRename drop_score is NOT in the deprecation map, so PaddleOCR(drop_score=...) raises 'Unknown argument: drop_score'. Equivalent filter is text_rec_score_thresh (constructor or predict()). Default CHANGED: 2.x 0.5, 3.x 0.0 (no filtering).PaddleOCR/paddleocr/_common_args.py:52-54 (raises ValueError(f"Unknown argument: {name}")); paddleocr-2.10.0/paddleocr/tools/infer/utility.py:107; paddleocr-2.10.0/paddleocr/tools/infer/predict_system.py:56,152; PaddleOCR/paddleocr/_pipelines/ocr.py:90,191; paddlex-3.7.2/paddlex/configs/pipelines/OCR.yaml:45
rec_image_shape='3, 48, 320'text_rec_input_shape=(3, 48, 320)Rename Not auto-mapped: rec_image_shape raises 'Unknown argument'. New param takes C,H,W (CLI: --text_rec_input_shape C H W).PaddleOCR/paddleocr/_common_args.py:52-54 (raises ValueError(f"Unknown argument: {name}")); paddleocr-2.10.0/paddleocr/tools/infer/utility.py:99; PaddleOCR/paddleocr/_pipelines/ocr.py:92,550-556
(new) text_det_input_shapetext_det_input_shape=(C, H, W)Changed New in 3.x.PaddleOCR/paddleocr/_pipelines/ocr.py:89,533-539
return_word_boxreturn_word_boxChanged Same name (constructor and predict()).paddleocr-2.10.0/paddleocr/tools/infer/utility.py:161; PaddleOCR/paddleocr/_pipelines/ocr.py:91,192
cls_thresh / cls_image_shape / label_list—Removed Raise 'Unknown argument'. No constructor equivalent; advanced per-module settings can be edited in an exported PaddleX pipeline config (export_paddlex_config_to_yaml + paddlex_config=...).PaddleOCR/paddleocr/_common_args.py:52-54 (raises ValueError(f"Unknown argument: {name}")); paddleocr-2.10.0/paddleocr/tools/infer/utility.py:126-129; PaddleOCR/paddleocr/_pipelines/base.py:74-77; PaddleOCR/docs/version3.x/paddleocr_and_paddlex.en.md:58-60
det_algorithm / rec_algorithm / det_box_type / use_dilation / det_db_score_mode / max_batch_size / det_east_* / det_sast_* / det_pse_* / scales / alpha / beta / fourier_degree—Removed Raise 'Unknown argument'. Models are chosen by name: text_detection_model_name / text_recognition_model_name.PaddleOCR/paddleocr/_common_args.py:52-54 (raises ValueError(f"Unknown argument: {name}")); paddleocr-2.10.0/paddleocr/tools/infer/utility.py:60,64,70-93,96; PaddleOCR/paddleocr/_pipelines/ocr.py:73-80
rec_char_dict_path / use_space_char / max_text_length / rec_image_inverse / vis_font_path—Removed Raise 'Unknown argument'. For visualization font, PaddleX reads env PADDLE_PDX_LOCAL_FONT_FILE_PATH.PaddleOCR/paddleocr/_common_args.py:52-54 (raises ValueError(f"Unknown argument: {name}")); paddleocr-2.10.0/paddleocr/tools/infer/utility.py:98,101-106; PaddleOCR/docs/FAQ.en.md:195-197; paddlex-3.7.2/paddlex/utils/flags.py:64
e2e_* / sr_* params—Removed Raise 'Unknown argument'. End-to-end (PGNet) and super-resolution inference are not part of the 3.x PaddleOCR class.PaddleOCR/paddleocr/_common_args.py:52-54 (raises ValueError(f"Unknown argument: {name}")); paddleocr-2.10.0/paddleocr/tools/infer/utility.py:110-121,137-139
draw_img_save_dir / save_crop_res / crop_res_save_dir / save_log_pathres.save_to_img(path) / res.save_to_json(path)Replaced Raise 'Unknown argument'. Saving is done per result object.PaddleOCR/paddleocr/_common_args.py:52-54 (raises ValueError(f"Unknown argument: {name}")); paddleocr-2.10.0/paddleocr/tools/infer/utility.py:142-144,152; PaddleOCR/docs/version3.x/pipeline_usage/OCR.en.md:1311-1315,1856-1857
use_mp / total_process_num / process_iddevice='gpu:0,1,...' or multi-process exampleReplaced Raise 'Unknown argument'. Docs describe multi-device device strings and a multi-process parallel inference example.PaddleOCR/paddleocr/_common_args.py:52-54 (raises ValueError(f"Unknown argument: {name}")); paddleocr-2.10.0/paddleocr/tools/infer/utility.py:147-149; PaddleOCR/docs/version3.x/algorithm/PP-StructureV3/PP-StructureV3.en.md:1514; PaddleOCR/docs/version3.x/inference_deployment/local_inference/parallel_inference.en.md
use_pdserving / warmup / benchmark—Removed Raise 'Unknown argument'.PaddleOCR/paddleocr/_common_args.py:52-54 (raises ValueError(f"Unknown argument: {name}")); paddleocr-2.10.0/paddleocr/tools/infer/utility.py:133-134,151
page_num—Removed Raises 'Unknown argument'. 3.x predict() accepts a PDF path directly and yields one result per page (page_index field).PaddleOCR/paddleocr/_common_args.py:52-54 (raises ValueError(f"Unknown argument: {name}")); paddleocr-2.10.0/paddleocr/tools/infer/utility.py:59; PaddleOCR/docs/version3.x/pipeline_usage/OCR.en.md:857-866,1817
image_dir (kwarg / CLI)predict(input) / CLI -i, --inputRename Input is passed to predict(); accepts image path, PDF path, URL, directory of images, numpy array or list.paddleocr-2.10.0/paddleocr/tools/infer/utility.py:58; PaddleOCR/paddleocr/_utils/cli.py:31-45; PaddleOCR/docs/version3.x/pipeline_usage/OCR.en.md:857
(new) use_doc_orientation_classify / use_doc_unwarpinguse_doc_orientation_classify=False, use_doc_unwarping=FalseChanged New in 3.x and ON by default in the OCR pipeline YAML (use_doc_preprocessor True). Official examples set both to False for plain OCR; set them False to get 2.x-like behaviour/speed.PaddleOCR/paddleocr/_pipelines/ocr.py:81-82,285-292; paddlex-3.7.2/paddlex/configs/pipelines/OCR.yaml:6-13; PaddleOCR/docs/version3.x/pipeline_usage/OCR.en.md:1293-1298
(new) text_detection_model_name / text_recognition_model_name / textline_orientation_model_namee.g. text_detection_model_name='PP-OCRv5_mobile_det'Changed New in 3.x: models chosen by official name; auto-downloaded.PaddleOCR/paddleocr/_pipelines/ocr.py:73-80; PaddleOCR/docs/version3.x/pipeline_usage/OCR.en.md:1304-1310
(new) paddlex_configpaddlex_config='ocr_config.yaml'Changed Load an edited PaddleX pipeline YAML; export current config with export_paddlex_config_to_yaml().PaddleOCR/paddleocr/_pipelines/base.py:54-100; PaddleOCR/docs/version3.x/inference_deployment/local_inference/inference_engine.en.md:215-245

PPStructure → PPStructureV3 parameters 18#

2.x3.xWhat happensSource
PPStructure(structure_version='PP-StructureV2')—Removed Raises 'Unknown argument: structure_version' on PPStructureV3.PaddleOCR/paddleocr/_common_args.py:52-54 (raises ValueError(f"Unknown argument: {name}")); paddleocr-2.10.0/paddleocr/paddleocr.py:92-93,820-824
PPStructure(layout=False)PaddleOCR(...) for OCR-only, or TableRecognitionPipelineV2 for table-onlyReplaced PPStructureV3 has no switch to disable layout detection ('Unknown argument: layout').PaddleOCR/paddleocr/_common_args.py:52-54 (raises ValueError(f"Unknown argument: {name}")); paddleocr-2.10.0/paddleocr/ppstructure/utility.py:90-95; PaddleOCR/paddleocr/_pipelines/pp_structurev3.py:32-101; PaddleOCR/paddleocr/__init__.py:42
PPStructure(table=True|False)PPStructureV3(use_table_recognition=True|False)Rename Not auto-mapped ('Unknown argument: table'). 3.x default True.paddleocr-2.10.0/paddleocr/ppstructure/utility.py:96-101; PaddleOCR/paddleocr/_pipelines/pp_structurev3.py:93; PaddleOCR/docs/version3.x/pipeline_usage/PP-StructureV3.en.md:2342
PPStructure(formula=True|False)PPStructureV3(use_formula_recognition=True|False)Rename Not auto-mapped. Default CHANGED: 2.x False, 3.x True.paddleocr-2.10.0/paddleocr/ppstructure/utility.py:102-107; PaddleOCR/paddleocr/_pipelines/pp_structurev3.py:94; PaddleOCR/docs/version3.x/pipeline_usage/PP-StructureV3.en.md:2350
PPStructure(ocr=True|False)—Removed No equivalent switch on PPStructureV3 ('Unknown argument: ocr').PaddleOCR/paddleocr/_common_args.py:52-54 (raises ValueError(f"Unknown argument: {name}")); paddleocr-2.10.0/paddleocr/ppstructure/utility.py:108-113; PaddleOCR/paddleocr/_pipelines/pp_structurev3.py:32-101
PPStructure(image_orientation=True)PPStructureV3(use_doc_orientation_classify=True)Rename Not auto-mapped. 3.x default False for PPStructureV3.paddleocr-2.10.0/paddleocr/ppstructure/utility.py:84-89; PaddleOCR/paddleocr/_pipelines/pp_structurev3.py:89; PaddleOCR/docs/version3.x/pipeline_usage/PP-StructureV3.en.md:2310
PPStructure(recovery=True)res.save_to_word(save_path) / res.save_to_markdown(save_path)Replaced Layout recovery is done via result methods on PPStructureV3 results.paddleocr-2.10.0/paddleocr/ppstructure/utility.py:115-120; paddlex-3.7.2/paddlex/inference/common/result/mixin.py:69,797; PaddleOCR/docs/version3.x/pipeline_usage/PP-StructureV3.en.md:1694-1700
PPStructure(recovery_to_markdown=True)res.save_to_markdown(save_path); pipeline.concatenate_markdown_pages(markdown_list)Replaced paddleocr-2.10.0/paddleocr/ppstructure/utility.py:121-126; PaddleOCR/paddleocr/_pipelines/pp_structurev3.py:300-301; PaddleOCR/docs/version3.x/pipeline_usage/PP-StructureV3.en.md:1766,2827-2851
PPStructure(use_pdf2docx_api=True)—Removed No equivalent.paddleocr-2.10.0/paddleocr/ppstructure/utility.py; paddleocr-2.10.0/paddleocr/paddleocr.py:1002-1011
PPStructure(layout_model_dir=...)PPStructureV3(layout_detection_model_dir=..., layout_detection_model_name=...)Rename Not auto-mapped.paddleocr-2.10.0/paddleocr/ppstructure/utility.py:53; PaddleOCR/paddleocr/_pipelines/pp_structurev3.py:34-35
PPStructure(table_model_dir=...)PPStructureV3(wired_table_structure_recognition_model_dir=..., wireless_table_structure_recognition_model_dir=...)Rename Not auto-mapped. 3.x splits table structure models into wired/wireless.paddleocr-2.10.0/paddleocr/ppstructure/utility.py:36; PaddleOCR/paddleocr/_pipelines/pp_structurev3.py:65-68
PPStructure(formula_model_dir=...)PPStructureV3(formula_recognition_model_dir=..., formula_recognition_model_name=...)Rename Not auto-mapped.paddleocr-2.10.0/paddleocr/ppstructure/utility.py:45; PaddleOCR/paddleocr/_pipelines/pp_structurev3.py:86-87
PPStructure(layout_score_threshold=0.5)PPStructureV3(layout_threshold=0.5)Rename Not auto-mapped. Accepts float or {class_id: thresh} dict.paddleocr-2.10.0/paddleocr/ppstructure/utility.py:59-61; PaddleOCR/paddleocr/_pipelines/pp_structurev3.py:36; PaddleOCR/docs/version3.x/pipeline_usage/PP-StructureV3.en.md:1820
PPStructure(layout_nms_threshold=0.5)PPStructureV3(layout_nms=True|False)Changed Not auto-mapped. 3.x param is a bool switch, not a threshold.paddleocr-2.10.0/paddleocr/ppstructure/utility.py:62-64; PaddleOCR/paddleocr/_pipelines/pp_structurev3.py:37; PaddleOCR/docs/version3.x/pipeline_usage/PP-StructureV3.en.md:1833
PPStructure(det_model_dir=..., rec_model_dir=..., use_angle_cls=...)PPStructureV3(text_detection_model_dir=..., text_recognition_model_dir=..., use_textline_orientation=...)Rename PPStructureV3 has NO deprecated-name mapping: old names raise 'Unknown argument'.PaddleOCR/paddleocr/_common_args.py:52-54 (raises ValueError(f"Unknown argument: {name}")); PaddleOCR/paddleocr/_pipelines/pp_structurev3.py:50-61,91,129-143
PPStructure(mode='kie', ser_model_dir=..., re_model_dir=..., kie_algorithm=...)PPChatOCRv4Doc (pip install "paddleocr[ie]")Replaced KIE mode removed from the structure class; 3.x information-extraction pipeline is PP-ChatOCRv4 (dependency group 'ie').paddleocr-2.10.0/paddleocr/ppstructure/utility.py:66-83; PaddleOCR/paddleocr/__init__.py:38; PaddleOCR/docs/version3.x/installation.en.md:39-45
PPStructure(show_log=..., use_gpu=...)logger / device=...Replaced Same as PaddleOCR: 'Unknown argument'.PaddleOCR/paddleocr/_common_args.py:52-54 (raises ValueError(f"Unknown argument: {name}"))
PPStructure(...)(img, return_ocr_result_in_table=True)—Removed __call__ no longer exists; use predict().paddleocr-2.10.0/paddleocr/paddleocr.py:902-933; PaddleOCR/paddleocr/_pipelines/pp_structurev3.py:223

Methods and result format 12#

2.x3.xWhat happensSource
PPStructure(...)PPStructureV3(...)Replaced Class removed; PPStructureV3 is the documented replacement.PaddleOCR/docs/update/upgrade_notes.en.md:73; PaddleOCR/paddleocr/_pipelines/pp_structurev3.py:31
ocr.ocr(img)ocr.predict(img)Changed ocr() still exists but is decorated @deprecated('Please use predict instead.') and forwards **kwargs to predict(). Returns a list of OCRResult objects, one per image/page.PaddleOCR/paddleocr/_pipelines/ocr.py:208-241; PaddleOCR/docs/update/upgrade_notes.en.md:51-67
ocr.ocr(img, cls=True)ocr.predict(img, use_textline_orientation=True) or PaddleOCR(use_textline_orientation=True)Changed predict() has no 'cls' kwarg -> TypeError (Python: "PaddleOCR.predict() got an unexpected keyword argument 'cls'").PaddleOCR/paddleocr/_pipelines/ocr.py:208-241; paddleocr-2.10.0/paddleocr/paddleocr.py:696-706
ocr.ocr(img, det=False) # recognition onlyTextRecognition(model_name=...).predict(img_or_crops)Replaced Upgrade notes: ocr() no longer accepts det/rec; use TextDetection / TextRecognition modules. Default rec model PP-OCRv6_medium_rec.PaddleOCR/docs/update/upgrade_notes.en.md:69; PaddleOCR/paddleocr/_models/text_recognition.py; paddleocr-2.10.0/paddleocr/paddleocr.py:784-799
ocr.ocr(img, rec=False) # detection onlyTextDetection(model_name=...).predict(img)Replaced Default det model PP-OCRv6_medium_det.PaddleOCR/docs/update/upgrade_notes.en.md:69; PaddleOCR/paddleocr/_models/text_detection.py:23-26; paddleocr-2.10.0/paddleocr/paddleocr.py:773-783
ocr.ocr(img, det=False, rec=False) # angle cls onlyTextLineOrientationClassification().predict(img)Replaced Default model PP-LCNet_x0_25_textline_ori.PaddleOCR/paddleocr/_models/textline_orientation_classification.py:21-24; paddleocr-2.10.0/paddleocr/paddleocr.py:784-798
ocr.ocr(img, bin=True, inv=True, alpha_color=..., slice={...})—Removed predict() only takes the keyword args listed in its signature; others raise TypeError.PaddleOCR/paddleocr/_pipelines/ocr.py:208-222; paddleocr-2.10.0/paddleocr/paddleocr.py:696-706
PPStructure()(img)PPStructureV3().predict(img)Changed Returns LayoutParsingResultV2 objects (print, save_to_json, save_to_markdown, save_to_word, save_to_html, save_to_xlsx, save_to_img).PaddleOCR/paddleocr/_pipelines/pp_structurev3.py:223; paddlex-3.7.2/paddlex/inference/pipelines/layout_parsing/result_v2.py:48-49; PaddleOCR/docs/version3.x/pipeline_usage/PP-StructureV3.en.md:2815-2851
(new) predict_iter(input)ocr.predict_iter(img)Changed Generator version of predict().PaddleOCR/paddleocr/_pipelines/ocr.py:179-206
(new) close()ocr.close()Changed Releases the PaddleX pipeline.PaddleOCR/paddleocr/_pipelines/base.py:79-80
result = ocr.ocr(img); result[0] -> [[box, (text, score)], ...] (None if no text)result = ocr.predict(img); res = result[0]; res['rec_texts'], res['rec_scores'], res['rec_polys'], res['rec_boxes'], res['dt_polys']Changed Each item is an OCRResult (a dict subclass). Old indexing like result[0][0][1][0] fails (KeyError: 0). rec_polys: list of (4,2) int16 arrays; rec_boxes: (n,4) [x_min,y_min,x_max,y_max]. res.json returns {'res': {...}} (JSON-safe lists).paddleocr-2.10.0/paddleocr/paddleocr.py:762-772; paddlex-3.7.2/paddlex/inference/pipelines/ocr/result.py:31; paddlex-3.7.2/paddlex/inference/common/result/base_result.py:75; paddlex-3.7.2/paddlex/inference/common/result/mixin.py:197-207; PaddleOCR/docs/version3.x/pipeline_usage/OCR.en.md:1836-1880
for line in result[0]: box, (text, score) = linefor res in result:
for text, score, poly in zip(res['rec_texts'], res['rec_scores'], res['rec_polys']): ...
Changed Code-converter rewrite of the classic 2.x loop. rec_texts/rec_scores/rec_polys are parallel lists filtered by text_rec_score_thresh.PaddleOCR/docs/version3.x/pipeline_usage/OCR.en.md:1850-1853

Helper functions 9#

2.x3.xWhat happensSource
draw_ocr(image, boxes, txts, scores, font_path=...)res.save_to_img(save_path) or res.img['ocr_res_img'] (PIL.Image)Replaced Upgrade notes show res.save_to_img('result') replacing draw_ocr. Custom font: env PADDLE_PDX_LOCAL_FONT_FILE_PATH.paddleocr-2.10.0/paddleocr/tools/infer/utility.py:451-458; PaddleOCR/docs/update/upgrade_notes.en.md:38-48,65-66; PaddleOCR/docs/version3.x/pipeline_usage/OCR.en.md:1872-1881; PaddleOCR/docs/FAQ.en.md:197
draw_structure_result(image, result, font_path)res.save_to_img(save_path)Replaced paddleocr-2.10.0/paddleocr/ppstructure/utility.py:159; paddlex-3.7.2/paddlex/inference/common/result/mixin.py:400
save_structure_res(res, save_folder, img_name)res.save_to_json(p) / res.save_to_xlsx(p) / res.save_to_html(p) / res.save_to_img(p) / res.save_all(p)Replaced paddleocr-2.10.0/paddleocr/ppstructure/predict_system.py:274; paddlex-3.7.2/paddlex/inference/common/result/base_result.py:94-105; paddlex-3.7.2/paddlex/inference/common/result/mixin.py:216,400,526,590
sorted_layout_boxes(res, w)res.save_to_markdown(p) / res.markdownReplaced No public 3.x equivalent function; ordered document output is obtained via the markdown result.paddleocr-2.10.0/paddleocr/ppstructure/recovery/recovery_to_doc.py:87; paddlex-3.7.2/paddlex/inference/common/result/mixin.py:789,797
convert_info_docx(img, res, save_folder, img_name)res.save_to_word(save_path)Replaced paddleocr-2.10.0/paddleocr/ppstructure/recovery/recovery_to_doc.py:32; paddlex-3.7.2/paddlex/inference/common/result/mixin.py:69
convert_info_markdown(res, save_folder, img_name)res.save_to_markdown(save_path) + PPStructureV3.concatenate_markdown_pages()Replaced paddleocr-2.10.0/paddleocr/paddleocr.py:69; paddlex-3.7.2/paddlex/inference/common/result/mixin.py:797; PaddleOCR/paddleocr/_pipelines/pp_structurev3.py:300-301
to_excel(html_table, excel_path)res.save_to_xlsx(save_path)Replaced paddleocr-2.10.0/paddleocr/ppstructure/table/predict_table.py:150; paddlex-3.7.2/paddlex/inference/common/result/mixin.py:590
download_with_progressbar(url, path)—Removed Models are downloaded automatically to ~/.paddlex/official_models (PADDLE_PDX_CACHE_HOME); source chosen by PADDLE_PDX_MODEL_SOURCE (huggingface default; modelscope, aistudio, bos).paddleocr-2.10.0/paddleocr/__init__.py:20; paddlex-3.7.2/paddlex/utils/cache.py:28-29; paddlex-3.7.2/paddlex/inference/utils/official_models.py:878-886; paddlex-3.7.2/paddlex/utils/flags.py:72
result printing: print(line)res.print() / res.save_to_json(p)Changed PaddleOCR/docs/update/upgrade_notes.en.md:61-66

Command line 24#

2.x3.xWhat happensSource
paddleocr --image_dir img.pngpaddleocr ocr -i img.pngChanged 3.x requires a subcommand. Without it argparse treats the path as the COMMAND: "paddleocr: error: argument COMMAND: invalid choice: 'img.png' (choose from ...)".PaddleOCR/paddleocr/_cli.py:281-309; PaddleOCR/paddleocr/_utils/cli.py:31-45; paddleocr-2.10.0/paddleocr/paddleocr.py:936-960
paddleocr --image_dir img.png --use_angle_cls truepaddleocr ocr -i img.png --use_textline_orientation TrueAlias, warns --use_angle_cls is still accepted by 'paddleocr ocr' with a CLIDeprecationWarning "The option --use_angle_cls has been deprecated and will be removed in the future. ..."PaddleOCR/paddleocr/_pipelines/ocr.py:503-506,567-588; PaddleOCR/paddleocr/_utils/deprecation.py:26-33
--det_model_dir--text_detection_model_dirAlias, warns Deprecated alias on 'paddleocr ocr' only; giving both prints "--det_model_dir and --text_detection_model_dir are mutually exclusive." and exits 2.PaddleOCR/paddleocr/_pipelines/ocr.py:567-600
--rec_model_dir--text_recognition_model_dirAlias, warns Deprecated alias on 'paddleocr ocr' only; giving both prints "--rec_model_dir and --text_recognition_model_dir are mutually exclusive." and exits 2.PaddleOCR/paddleocr/_pipelines/ocr.py:567-600
--cls_model_dir--textline_orientation_model_dirAlias, warns Deprecated alias on 'paddleocr ocr' only; giving both prints "--cls_model_dir and --textline_orientation_model_dir are mutually exclusive." and exits 2.PaddleOCR/paddleocr/_pipelines/ocr.py:567-600
--det_db_thresh--text_det_threshAlias, warns Deprecated alias on 'paddleocr ocr' only; giving both prints "--det_db_thresh and --text_det_thresh are mutually exclusive." and exits 2.PaddleOCR/paddleocr/_pipelines/ocr.py:567-600
--det_db_box_thresh--text_det_box_threshAlias, warns Deprecated alias on 'paddleocr ocr' only; giving both prints "--det_db_box_thresh and --text_det_box_thresh are mutually exclusive." and exits 2.PaddleOCR/paddleocr/_pipelines/ocr.py:567-600
--det_db_unclip_ratio--text_det_unclip_ratioAlias, warns Deprecated alias on 'paddleocr ocr' only; giving both prints "--det_db_unclip_ratio and --text_det_unclip_ratio are mutually exclusive." and exits 2.PaddleOCR/paddleocr/_pipelines/ocr.py:567-600
--det_limit_side_len--text_det_limit_side_lenAlias, warns Deprecated alias on 'paddleocr ocr' only; giving both prints "--det_limit_side_len and --text_det_limit_side_len are mutually exclusive." and exits 2.PaddleOCR/paddleocr/_pipelines/ocr.py:567-600
--det_limit_type--text_det_limit_typeAlias, warns Deprecated alias on 'paddleocr ocr' only; giving both prints "--det_limit_type and --text_det_limit_type are mutually exclusive." and exits 2.PaddleOCR/paddleocr/_pipelines/ocr.py:567-600
--rec_batch_num--text_recognition_batch_sizeAlias, warns Deprecated alias on 'paddleocr ocr' only; giving both prints "--rec_batch_num and --text_recognition_batch_size are mutually exclusive." and exits 2.PaddleOCR/paddleocr/_pipelines/ocr.py:567-600
--cls_batch_num--textline_orientation_batch_sizeAlias, warns Deprecated alias on 'paddleocr ocr' only; giving both prints "--cls_batch_num and --textline_orientation_batch_size are mutually exclusive." and exits 2.PaddleOCR/paddleocr/_pipelines/ocr.py:567-600
--use_gpu true|false--device gpu|gpu:0|cpuReplaced --use_gpu is not defined in 3.x -> argparse 'unrecognized arguments'.PaddleOCR/paddleocr/_common_args.py:129-139
--type structurepaddleocr pp_structurev3 -i <file>Changed PaddleOCR/paddleocr/_pipelines/pp_structurev3.py:695-696; paddleocr-2.10.0/paddleocr/paddleocr.py:388,963-964
--type structure --recovery truepaddleocr pp_structurev3 -i <file> --save_path out/Changed --save_path calls res.save_all() for each result (all registered save methods).PaddleOCR/paddleocr/_utils/cli.py:41-45,68-73
--det falsepaddleocr text_recognition -i <img>Changed PaddleOCR/paddleocr/_models/text_recognition.py; paddleocr-2.10.0/paddleocr/paddleocr.py:386
--rec falsepaddleocr text_detection -i <img>Changed PaddleOCR/paddleocr/_models/text_detection.py:36-38; paddleocr-2.10.0/paddleocr/paddleocr.py:387
--savefile true --output ./out--save_path ./outRename paddleocr-2.10.0/paddleocr/paddleocr.py:389,990-995; PaddleOCR/paddleocr/_utils/cli.py:41-45
--lang en--lang enChanged Same flag on 'paddleocr ocr'; see 'lang' param note on removed script-group codes.PaddleOCR/paddleocr/_pipelines/ocr.py:557-559
--ocr_version PP-OCRv4--ocr_version PP-OCRv3|PP-OCRv4|PP-OCRv5|PP-OCRv6Changed argparse choices enforced.PaddleOCR/paddleocr/_pipelines/ocr.py:560-565
--use_onnx true--engine onnxruntime (or --enable_hpi True)Replaced PaddleOCR/paddleocr/_common_args.py:140-151
--show_log false—Removed The 3.x CLI sets the paddleocr logger to INFO itself.PaddleOCR/paddleocr/_cli.py:301-303
--enable_mkldnn / --cpu_threads / --use_tensorrt / --precisionsame flagsChanged Still available on every pipeline/model subcommand; enable_mkldnn default now True.PaddleOCR/paddleocr/_common_args.py:152-188
(3.x) subcommandsocr, doc_preprocessor, doc_understanding, formula_recognition_pipeline, doc_parser (PaddleOCR-VL), pp_chatocrv4_doc, pp_doctranslation, pp_structurev3, seal_recognition, table_recognition_v2, chart_parsing, doc_img_orientation_classification, doc_vlm, formula_recognition, layout_detection, seal_text_detection, table_cells_detection, table_classification, table_structure_recognition, text_detection, text_image_unwarping, text_recognition, textline_orientation_classification, install_hpi_deps, install_genai_server_deps, genai_server (only if the PaddleX genai server plugin imports), doc2md, apiChanged Complete list registered by _get_parser(). Pipeline/model subcommands share -i/--input, --save_path, --device, --engine, --enable_hpi, --use_tensorrt, --precision, --enable_mkldnn, --mkldnn_cache_capacity, --cpu_threads, --enable_cinn (pipelines also --paddlex_config).PaddleOCR/paddleocr/_cli.py:57-123,126-165,168-278,281-294; PaddleOCR/paddleocr/_pipelines/*.py subparser_name; PaddleOCR/paddleocr/_models/*.py subparser_name; PaddleOCR/paddleocr/_api_client/cli.py:30-35; PaddleOCR/paddleocr/_pipelines/base.py:118-131

Staying on 2.x: pin paddleocr below 3#

If you can't migrate yet, pin the last 2.x release in its own virtual environment:

python -m pip install "paddleocr<3"

That resolves to 2.10.0. Like 3.x, its wheel does not list PaddlePaddle as a dependency, so you install a framework yourself.3 We have not tested which PaddlePaddle 3.x versions run paddleocr 2.x, so if you already have a working 2.x environment, freeze it (pip freeze > requirements.txt) rather than rebuilding it. Code that imports 2.x internals (paddleocr.tools, paddleocr.ppocr, paddleocr.ppstructure) can only run on 2.x: those modules are not in the 3.x package.

The cost of waiting grows: 2.x gets no new models, while 3.x moved from PP-OCRv5 to PP-OCRv6 and added PaddleOCR-VL.

Migration checklist#

  1. New environment, new engine#

    Create a fresh venv. pip install paddleocr, then paddlepaddle==3.2.0 from the PaddlePaddle index, or onnxruntime. The install builder gives the exact commands for your machine.

  2. Convert the code#

    Run each file through the converter. Resolve every # TODO(paddleocr 3.x).

  3. Turn warnings into errors once#

    Run your tests with python -W error::DeprecationWarning to catch remaining aliases and ocr() calls.

  4. Compare outputs#

    Diff texts on a few real documents. If they differ, try the "Keep 2.x behaviour" switches before blaming the models.

  5. Check the error you hit#

    Paste anything unexpected into the error fixer.

Questions#

Does use_angle_cls still work in PaddleOCR 3.x?

Yes, on PaddleOCR only. It is one of 11 old names that 3.x maps to the new one (use_textline_orientation) with a DeprecationWarning. On PPStructureV3 it raises ValueError: Unknown argument: use_angle_cls, and passing both old and new names raises a "mutually exclusive" error.

How do I use the GPU in PaddleOCR 3.x without use_gpu?

Pass device='gpu' (or 'gpu:0', 'gpu:1'). If you omit device, 3.x picks GPU 0 automatically when the installed PaddlePaddle was built with CUDA. If it still runs on the CPU, you probably have the CPU build of PaddlePaddle: see GPU not used.

Why does ocr(img, cls=True) raise TypeError?

In 3.x ocr() just forwards to predict(), which has no cls parameter. Remove cls=True and set use_textline_orientation=True on the constructor instead. Also switch to predict(); ocr() is deprecated.

What replaces draw_ocr?

Each result draws itself: res.save_to_img('output') writes the visualization to a folder, and res.img['ocr_res_img'] gives it to you as a PIL image. Set PADDLE_PDX_LOCAL_FONT_FILE_PATH for a custom font.

Can I keep using paddleocr==2.7.0.3?

Yes, if you pin it and keep the environment that works. It was released on September 15, 2023; 2.10.0 (March 2025) is the last 2.x. Neither gets new models, and the 2.x API cannot be mixed with 3.x in one environment.

Is the converter safe to run on my code?

It runs entirely in your browser and never sends the code anywhere. It changes only patterns it recognizes, lists every change with the source line that justifies it, and leaves TODO comments where a human must decide. Review the diff like any other code change.

Why are my 3.x results different from 2.x on the same image?

Different default models (PP-OCRv6 instead of PP-OCRv4), new preprocessing (orientation, unwarping) and no 0.5 score filter. Set use_doc_orientation_classify=False, use_doc_unwarping=False, use_textline_orientation=False and text_rec_score_thresh=0.5 for 2.x-like behaviour.

Sources

  1. PaddleOCR source at commit dab3fe3 (2026-09-16), read for this page: paddleocr/_pipelines/ocr.py (alias map lines 44-56, alias handling 155-169, predict()/ocr() 179-241), _common_args.py (lines 38-54), _utils/deprecation.py (26-42), __init__.py (84-131), _cli.py (57-309), _pipelines/pp_structurev3.py (32-143).
  2. Official upgrade notes: docs/update/upgrade_notes.en.md (why 3.x breaks compatibility; ocr/det/rec, show_log, use_onnx and PPStructure changes).
  3. paddleocr 2.10.0 wheel from PyPI (the last 2.x release): paddleocr/paddleocr.py (ocr() signature lines 696-706, return format 762-772), tools/infer/utility.py (2.x defaults), ppstructure/utility.py.
  4. 2.x example code: docs/version2.x/ppocr/blog/whl.en.md and docs/version2.x/ppstructure/quick_start.en.md.
  5. PaddleX 3.7.2 wheel from PyPI: paddlex/configs/pipelines/OCR.yaml (3.x OCR defaults, lines 6-45), paddlex/inference/pipelines/ocr/result.py and common/result/ (result objects, save methods), inference/models/utils/model_resolver.py (Model name mismatch).
  6. PyPI release history for paddleocr, read 2026-10-27: 2.7.0.3 (2023-09-15), 2.10.0 (2025-03-07, last 2.x), 3.0.0 (2025-05-20), 3.7.0 (2026-06-11).
  7. Our tests, 2026-10-27, Linux x86-64, Python 3.13, paddleocr 3.7.0 + paddlex 3.7.2 + paddlepaddle 3.2.0: exact error and warning messages quoted on this page, the old CLI syntax, and running the converter's output for the classic example and the result loop.
  8. PP-StructureV3 usage and the doc-parser extra: PP-StructureV3.en.md; installation.en.md.
  9. OCR pipeline parameters and result fields: OCR.en.md (lines 1293-1315, 1836-1881).
Updated October 27, 2026·How we verify facts