e904b667c6
PaddleOCR PR Tests GPU / test-pr-gpu (push) Blocked by required conditions
PaddleOCR PR Tests / test-pr (push) Blocked by required conditions
PaddleOCR PR Tests / test-pr-python (3.8) (push) Waiting to run
Build/Publish Develop Docs / deploy (push) Failing after 1s
PaddleOCR Code Style Check / check-code-style (push) Failing after 1s
PaddleOCR PR Tests GPU / detect-changes (push) Failing after 1s
PaddleOCR PR Tests GPU / test-pr-gpu-impl (push) Waiting to run
PaddleOCR PR Tests / detect-changes (push) Failing after 1s
PaddleOCR PR Tests / test-pr-python (3.13) (push) Waiting to run
PaddleOCR PR Tests / test-pr-python (3.9) (push) Waiting to run
203 lines
7.2 KiB
Python
203 lines
7.2 KiB
Python
# Copyright (c) 2026 PaddlePaddle Authors. All Rights Reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
from dataclasses import dataclass, fields
|
|
from enum import Enum
|
|
from typing import Optional, Union
|
|
|
|
from ._naming import snake_to_camel
|
|
from .errors import InvalidRequestError
|
|
|
|
|
|
class Model(str, Enum):
|
|
PP_OCRV5 = "PP-OCRv5"
|
|
PP_OCRV5_LATIN = "PP-OCRv5-latin"
|
|
PP_OCRV6 = "PP-OCRv6"
|
|
PP_STRUCTURE_V3 = "PP-StructureV3"
|
|
PADDLE_OCR_VL = "PaddleOCR-VL"
|
|
PADDLE_OCR_VL_15 = "PaddleOCR-VL-1.5"
|
|
PADDLE_OCR_VL_16 = "PaddleOCR-VL-1.6"
|
|
|
|
|
|
_OCR_MODELS = frozenset({Model.PP_OCRV5, Model.PP_OCRV5_LATIN, Model.PP_OCRV6})
|
|
_DOCUMENT_PARSING_MODELS = frozenset(
|
|
{
|
|
Model.PP_STRUCTURE_V3,
|
|
Model.PADDLE_OCR_VL,
|
|
Model.PADDLE_OCR_VL_15,
|
|
Model.PADDLE_OCR_VL_16,
|
|
}
|
|
)
|
|
_VL_MODELS = frozenset(
|
|
{
|
|
Model.PADDLE_OCR_VL,
|
|
Model.PADDLE_OCR_VL_15,
|
|
Model.PADDLE_OCR_VL_16,
|
|
}
|
|
)
|
|
|
|
|
|
def _coerce_model(model: Union[Model, str]) -> Optional[Model]:
|
|
if isinstance(model, Model):
|
|
return model
|
|
try:
|
|
return Model(model)
|
|
except ValueError:
|
|
return None
|
|
|
|
|
|
def is_ocr_model(model: Union[Model, str]) -> bool:
|
|
return _coerce_model(model) in _OCR_MODELS
|
|
|
|
|
|
def is_document_parsing_model(model: Union[Model, str]) -> bool:
|
|
return _coerce_model(model) in _DOCUMENT_PARSING_MODELS
|
|
|
|
|
|
def is_vl_model(model: Union[Model, str]) -> bool:
|
|
return _coerce_model(model) in _VL_MODELS
|
|
|
|
|
|
@dataclass
|
|
class OCROptions:
|
|
use_doc_orientation_classify: Optional[bool] = None
|
|
use_doc_unwarping: Optional[bool] = None
|
|
use_textline_orientation: Optional[bool] = None
|
|
text_det_limit_side_len: Optional[int] = None
|
|
text_det_limit_type: Optional[str] = None
|
|
text_det_thresh: Optional[float] = None
|
|
text_det_box_thresh: Optional[float] = None
|
|
text_det_unclip_ratio: Optional[float] = None
|
|
text_rec_score_thresh: Optional[float] = None
|
|
visualize: Optional[bool] = None
|
|
extra_options: Optional[dict] = None
|
|
|
|
def to_payload(self) -> dict:
|
|
return _build_payload(self)
|
|
|
|
|
|
@dataclass
|
|
class PPStructureV3Options:
|
|
use_doc_orientation_classify: Optional[bool] = None
|
|
use_doc_unwarping: Optional[bool] = None
|
|
use_textline_orientation: Optional[bool] = None
|
|
use_seal_recognition: Optional[bool] = None
|
|
use_table_recognition: Optional[bool] = None
|
|
use_formula_recognition: Optional[bool] = None
|
|
use_chart_recognition: Optional[bool] = None
|
|
use_region_detection: Optional[bool] = None
|
|
layout_threshold: Optional[Union[float, dict]] = None
|
|
layout_nms: Optional[bool] = None
|
|
layout_unclip_ratio: Optional[Union[float, list, dict]] = None
|
|
layout_merge_bboxes_mode: Optional[Union[str, dict]] = None
|
|
format_block_content: Optional[bool] = None
|
|
text_det_limit_side_len: Optional[int] = None
|
|
text_det_limit_type: Optional[str] = None
|
|
text_det_thresh: Optional[float] = None
|
|
text_det_box_thresh: Optional[float] = None
|
|
text_det_unclip_ratio: Optional[float] = None
|
|
text_rec_score_thresh: Optional[float] = None
|
|
use_wired_table_cells_trans_to_html: Optional[bool] = None
|
|
use_wireless_table_cells_trans_to_html: Optional[bool] = None
|
|
use_table_orientation_classify: Optional[bool] = None
|
|
use_ocr_results_with_table_cells: Optional[bool] = None
|
|
use_e2e_wired_table_rec_model: Optional[bool] = None
|
|
use_e2e_wireless_table_rec_model: Optional[bool] = None
|
|
markdown_ignore_labels: Optional[list] = None
|
|
prettify_markdown: Optional[bool] = None
|
|
show_formula_number: Optional[bool] = None
|
|
return_markdown_images: Optional[bool] = None
|
|
output_formats: Optional[list] = None
|
|
visualize: Optional[bool] = None
|
|
extra_options: Optional[dict] = None
|
|
|
|
def to_payload(self) -> dict:
|
|
return _build_payload(self)
|
|
|
|
|
|
@dataclass
|
|
class PaddleOCRVLOptions:
|
|
use_doc_orientation_classify: Optional[bool] = None
|
|
use_doc_unwarping: Optional[bool] = None
|
|
use_layout_detection: Optional[bool] = None
|
|
use_chart_recognition: Optional[bool] = None
|
|
use_seal_recognition: Optional[bool] = None
|
|
use_ocr_for_image_block: Optional[bool] = None
|
|
layout_threshold: Optional[Union[float, dict]] = None
|
|
layout_nms: Optional[bool] = None
|
|
layout_unclip_ratio: Optional[Union[float, list, dict]] = None
|
|
layout_merge_bboxes_mode: Optional[Union[str, dict]] = None
|
|
layout_shape_mode: Optional[str] = None
|
|
prompt_label: Optional[str] = None
|
|
format_block_content: Optional[bool] = None
|
|
repetition_penalty: Optional[float] = None
|
|
temperature: Optional[float] = None
|
|
top_p: Optional[float] = None
|
|
min_pixels: Optional[int] = None
|
|
max_pixels: Optional[int] = None
|
|
max_new_tokens: Optional[int] = None
|
|
vlm_extra_args: Optional[dict] = None
|
|
merge_layout_blocks: Optional[bool] = None
|
|
markdown_ignore_labels: Optional[list] = None
|
|
prettify_markdown: Optional[bool] = None
|
|
show_formula_number: Optional[bool] = None
|
|
restructure_pages: Optional[bool] = None
|
|
merge_tables: Optional[bool] = None
|
|
relevel_titles: Optional[bool] = None
|
|
return_markdown_images: Optional[bool] = None
|
|
output_formats: Optional[list] = None
|
|
visualize: Optional[bool] = None
|
|
extra_options: Optional[dict] = None
|
|
|
|
def to_payload(self) -> dict:
|
|
_validate_vl_options(self)
|
|
return _build_payload(self)
|
|
|
|
|
|
DocParsingOptions = Union[PPStructureV3Options, PaddleOCRVLOptions]
|
|
|
|
|
|
def _build_payload(options) -> dict:
|
|
payload = {}
|
|
for field in fields(options):
|
|
value = getattr(options, field.name)
|
|
if value is None:
|
|
continue
|
|
if field.name == "extra_options":
|
|
payload.update(value)
|
|
else:
|
|
payload[snake_to_camel(field.name)] = value
|
|
return payload
|
|
|
|
|
|
def _validate_vl_options(options: PaddleOCRVLOptions) -> None:
|
|
if options.top_p is not None and not (0 < options.top_p <= 1):
|
|
raise InvalidRequestError(
|
|
"top_p must be greater than 0 and less than or equal to 1."
|
|
)
|
|
if options.temperature is not None and options.temperature < 0:
|
|
raise InvalidRequestError("temperature must be greater than or equal to 0.")
|
|
if options.repetition_penalty is not None and options.repetition_penalty <= 0:
|
|
raise InvalidRequestError("repetition_penalty must be greater than 0.")
|
|
if options.min_pixels is not None and options.min_pixels <= 0:
|
|
raise InvalidRequestError("min_pixels must be greater than 0.")
|
|
if options.max_pixels is not None and options.max_pixels <= 0:
|
|
raise InvalidRequestError("max_pixels must be greater than 0.")
|
|
if (
|
|
options.min_pixels is not None
|
|
and options.max_pixels is not None
|
|
and options.min_pixels > options.max_pixels
|
|
):
|
|
raise InvalidRequestError("min_pixels cannot be greater than max_pixels.")
|