Files
wehub-resource-sync 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
chore: import upstream snapshot with attribution
2026-07-13 11:59:26 +08:00

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.")