Browse Source

!10 Bump version to 3.3.3
Merge pull request !10 from zhch158/release/3.3

zhch158 1 month ago
parent
commit
3c08d0b64b
100 changed files with 1923 additions and 39 deletions
  1. 2 2
      .github/workflows/deploy_docs.yml
  2. 1 1
      .pre-commit-config.yaml
  3. 19 7
      .precommit/check_imports.py
  4. 4 0
      README.md
  5. 4 0
      README_en.md
  6. 31 0
      api_examples/pipelines/test_pp_ocr_vl.py
  7. 14 0
      deploy/hps/sdk/paddlex-hps-client/src/paddlex_hps_client/__init__.py
  8. 14 0
      deploy/hps/sdk/paddlex-hps-client/src/paddlex_hps_client/constants.py
  9. 14 0
      deploy/hps/sdk/paddlex-hps-client/src/paddlex_hps_client/request.py
  10. 14 0
      deploy/hps/sdk/paddlex-hps-client/src/paddlex_hps_client/utils.py
  11. 16 1
      deploy/hps/sdk/pipelines/3d_bev_detection/client/client.py
  12. 14 0
      deploy/hps/sdk/pipelines/3d_bev_detection/server/model_repo/bev-3d-object-detection/1/model.py
  13. 14 0
      deploy/hps/sdk/pipelines/OCR/client/client.py
  14. 20 1
      deploy/hps/sdk/pipelines/OCR/server/model_repo/ocr/1/model.py
  15. 14 0
      deploy/hps/sdk/pipelines/PP-ChatOCRv3-doc/client/client.py
  16. 14 0
      deploy/hps/sdk/pipelines/PP-ChatOCRv3-doc/server/model_repo/chatocr-chat/1/model.py
  17. 14 0
      deploy/hps/sdk/pipelines/PP-ChatOCRv3-doc/server/model_repo/chatocr-vector/1/model.py
  18. 19 1
      deploy/hps/sdk/pipelines/PP-ChatOCRv3-doc/server/model_repo/chatocr-visual/1/model.py
  19. 14 0
      deploy/hps/sdk/pipelines/PP-ChatOCRv4-doc/client/client.py
  20. 14 0
      deploy/hps/sdk/pipelines/PP-ChatOCRv4-doc/server/model_repo/chatocr-chat/1/model.py
  21. 14 0
      deploy/hps/sdk/pipelines/PP-ChatOCRv4-doc/server/model_repo/chatocr-mllm/1/model.py
  22. 14 0
      deploy/hps/sdk/pipelines/PP-ChatOCRv4-doc/server/model_repo/chatocr-vector/1/model.py
  23. 19 1
      deploy/hps/sdk/pipelines/PP-ChatOCRv4-doc/server/model_repo/chatocr-visual/1/model.py
  24. 14 0
      deploy/hps/sdk/pipelines/PP-DocTranslation/client/client.py
  25. 14 0
      deploy/hps/sdk/pipelines/PP-DocTranslation/server/model_repo/doctrans-translate/1/model.py
  26. 14 0
      deploy/hps/sdk/pipelines/PP-DocTranslation/server/model_repo/doctrans-visual/1/model.py
  27. 14 0
      deploy/hps/sdk/pipelines/PP-ShiTuV2/client/client.py
  28. 14 0
      deploy/hps/sdk/pipelines/PP-ShiTuV2/server/model_repo/shitu-index-add/1/model.py
  29. 14 0
      deploy/hps/sdk/pipelines/PP-ShiTuV2/server/model_repo/shitu-index-build/1/model.py
  30. 14 0
      deploy/hps/sdk/pipelines/PP-ShiTuV2/server/model_repo/shitu-index-remove/1/model.py
  31. 19 1
      deploy/hps/sdk/pipelines/PP-ShiTuV2/server/model_repo/shitu-infer/1/model.py
  32. 13 0
      deploy/hps/sdk/pipelines/PP-ShiTuV2/server/shared_mods/common/__init__.py
  33. 14 0
      deploy/hps/sdk/pipelines/PP-ShiTuV2/server/shared_mods/common/base_model.py
  34. 14 0
      deploy/hps/sdk/pipelines/PP-StructureV3/client/client.py
  35. 20 1
      deploy/hps/sdk/pipelines/PP-StructureV3/server/model_repo/layout-parsing/1/model.py
  36. 1 0
      deploy/hps/sdk/pipelines/PP-StructureV3/server/pipeline_config.yaml
  37. 64 0
      deploy/hps/sdk/pipelines/PaddleOCR-VL/client/client.py
  38. 3 0
      deploy/hps/sdk/pipelines/PaddleOCR-VL/client/requirements.txt
  39. 291 0
      deploy/hps/sdk/pipelines/PaddleOCR-VL/server/model_repo/layout-parsing/1/model.py
  40. 23 0
      deploy/hps/sdk/pipelines/PaddleOCR-VL/server/model_repo/layout-parsing/config_cpu.pbtxt
  41. 24 0
      deploy/hps/sdk/pipelines/PaddleOCR-VL/server/model_repo/layout-parsing/config_gpu.pbtxt
  42. 96 0
      deploy/hps/sdk/pipelines/PaddleOCR-VL/server/pipeline_config.yaml
  43. 14 0
      deploy/hps/sdk/pipelines/anomaly_detection/client/client.py
  44. 19 1
      deploy/hps/sdk/pipelines/anomaly_detection/server/model_repo/anomaly-detection/1/model.py
  45. 14 0
      deploy/hps/sdk/pipelines/doc_preprocessor/client/client.py
  46. 19 1
      deploy/hps/sdk/pipelines/doc_preprocessor/server/model_repo/document-preprocessing/1/model.py
  47. 14 0
      deploy/hps/sdk/pipelines/doc_understanding/client/client.py
  48. 14 0
      deploy/hps/sdk/pipelines/doc_understanding/server/model_repo/document-understanding/1/model.py
  49. 14 0
      deploy/hps/sdk/pipelines/face_recognition/client/client.py
  50. 14 0
      deploy/hps/sdk/pipelines/face_recognition/server/model_repo/face-recognition-index-add/1/model.py
  51. 14 0
      deploy/hps/sdk/pipelines/face_recognition/server/model_repo/face-recognition-index-build/1/model.py
  52. 14 0
      deploy/hps/sdk/pipelines/face_recognition/server/model_repo/face-recognition-index-remove/1/model.py
  53. 19 1
      deploy/hps/sdk/pipelines/face_recognition/server/model_repo/face-recognition-infer/1/model.py
  54. 13 0
      deploy/hps/sdk/pipelines/face_recognition/server/shared_mods/common/__init__.py
  55. 14 0
      deploy/hps/sdk/pipelines/face_recognition/server/shared_mods/common/base_model.py
  56. 14 0
      deploy/hps/sdk/pipelines/formula_recognition/client/client.py
  57. 19 1
      deploy/hps/sdk/pipelines/formula_recognition/server/model_repo/formula-recognition/1/model.py
  58. 14 0
      deploy/hps/sdk/pipelines/human_keypoint_detection/client/client.py
  59. 19 1
      deploy/hps/sdk/pipelines/human_keypoint_detection/server/model_repo/human-keypoint-detection/1/model.py
  60. 14 0
      deploy/hps/sdk/pipelines/image_classification/client/client.py
  61. 19 1
      deploy/hps/sdk/pipelines/image_classification/server/model_repo/image-classification/1/model.py
  62. 14 0
      deploy/hps/sdk/pipelines/image_multilabel_classification/client/client.py
  63. 19 1
      deploy/hps/sdk/pipelines/image_multilabel_classification/server/model_repo/multilabel-image-classification/1/model.py
  64. 14 0
      deploy/hps/sdk/pipelines/instance_segmentation/client/client.py
  65. 19 1
      deploy/hps/sdk/pipelines/instance_segmentation/server/model_repo/instance-segmentation/1/model.py
  66. 14 0
      deploy/hps/sdk/pipelines/layout_parsing/client/client.py
  67. 19 1
      deploy/hps/sdk/pipelines/layout_parsing/server/model_repo/layout-parsing/1/model.py
  68. 14 0
      deploy/hps/sdk/pipelines/multilingual_speech_recognition/client/client.py
  69. 14 0
      deploy/hps/sdk/pipelines/multilingual_speech_recognition/server/model_repo/multilingual-speech-recognition/1/model.py
  70. 14 0
      deploy/hps/sdk/pipelines/object_detection/client/client.py
  71. 19 1
      deploy/hps/sdk/pipelines/object_detection/server/model_repo/object-detection/1/model.py
  72. 14 0
      deploy/hps/sdk/pipelines/open_vocabulary_detection/client/client.py
  73. 19 1
      deploy/hps/sdk/pipelines/open_vocabulary_detection/server/model_repo/open-vocabulary-detection/1/model.py
  74. 14 0
      deploy/hps/sdk/pipelines/open_vocabulary_segmentation/client/client.py
  75. 19 1
      deploy/hps/sdk/pipelines/open_vocabulary_segmentation/server/model_repo/open-vocabulary-segmentation/1/model.py
  76. 14 0
      deploy/hps/sdk/pipelines/pedestrian_attribute_recognition/client/client.py
  77. 19 1
      deploy/hps/sdk/pipelines/pedestrian_attribute_recognition/server/model_repo/pedestrian-attribute-recognition/1/model.py
  78. 14 0
      deploy/hps/sdk/pipelines/rotated_object_detection/client/client.py
  79. 19 1
      deploy/hps/sdk/pipelines/rotated_object_detection/server/model_repo/rotated-object-detection/1/model.py
  80. 14 0
      deploy/hps/sdk/pipelines/seal_recognition/client/client.py
  81. 19 1
      deploy/hps/sdk/pipelines/seal_recognition/server/model_repo/seal-recognition/1/model.py
  82. 14 0
      deploy/hps/sdk/pipelines/semantic_segmentation/client/client.py
  83. 19 1
      deploy/hps/sdk/pipelines/semantic_segmentation/server/model_repo/semantic-segmentation/1/model.py
  84. 14 0
      deploy/hps/sdk/pipelines/small_object_detection/client/client.py
  85. 19 1
      deploy/hps/sdk/pipelines/small_object_detection/server/model_repo/small-object-detection/1/model.py
  86. 14 0
      deploy/hps/sdk/pipelines/table_recognition/client/client.py
  87. 19 1
      deploy/hps/sdk/pipelines/table_recognition/server/model_repo/table-recognition/1/model.py
  88. 14 0
      deploy/hps/sdk/pipelines/table_recognition_v2/client/client.py
  89. 19 1
      deploy/hps/sdk/pipelines/table_recognition_v2/server/model_repo/table-recognition/1/model.py
  90. 14 0
      deploy/hps/sdk/pipelines/ts_anomaly_detection/client/client.py
  91. 19 1
      deploy/hps/sdk/pipelines/ts_anomaly_detection/server/model_repo/time-series-anomaly-detection/1/model.py
  92. 14 0
      deploy/hps/sdk/pipelines/ts_classification/client/client.py
  93. 19 1
      deploy/hps/sdk/pipelines/ts_classification/server/model_repo/time-series-classification/1/model.py
  94. 14 0
      deploy/hps/sdk/pipelines/ts_forecast/client/client.py
  95. 19 1
      deploy/hps/sdk/pipelines/ts_forecast/server/model_repo/time-series-forecasting/1/model.py
  96. 14 0
      deploy/hps/sdk/pipelines/vehicle_attribute_recognition/client/client.py
  97. 19 1
      deploy/hps/sdk/pipelines/vehicle_attribute_recognition/server/model_repo/vehicle-attribute-recognition/1/model.py
  98. 14 0
      deploy/hps/sdk/pipelines/video_classification/client/client.py
  99. 14 0
      deploy/hps/sdk/pipelines/video_classification/server/model_repo/video-classification/1/model.py
  100. 14 0
      deploy/hps/sdk/pipelines/video_detection/client/client.py

+ 2 - 2
.github/workflows/deploy_docs.yml

@@ -2,7 +2,7 @@ name: Develop Docs
 on:
   push:
     branches: #设置更新哪个分支会更新站点
-      - release/3.2
+      - release/3.3
 permissions:
   contents: write
 jobs:
@@ -27,5 +27,5 @@ jobs:
       - run: pip install mike mkdocs-material jieba mkdocs-git-revision-date-localized-plugin mkdocs-git-committers-plugin-2 mkdocs-git-authors-plugin mkdocs-static-i18n mkdocs-minify-plugin 
       - run: |
           git fetch origin gh-pages --depth=1
-          mike deploy --push --update-aliases 3.2 latest
+          mike deploy --push --update-aliases 3.3 latest
           mike set-default --push latest

+ 1 - 1
.pre-commit-config.yaml

@@ -55,7 +55,7 @@ repos:
     -   id: isort
         args:
             - --profile=black
-        exclude: ^deploy/ultra-infer/python/ultra_infer/
+        files: ^paddlex/
 
 # check license
 -   repo: local

+ 19 - 7
.precommit/check_imports.py

@@ -24,13 +24,13 @@ from collections import deque
 from stdlib_list import stdlib_list
 
 sys.path.append(str(pathlib.Path(__file__).parent.parent))
-from setup import DEP_SPECS, REQUIRED_DEPS
+from setup import REQUIRED_DEPS
 
 # NOTE: We do not use `importlib.metadata.packages_distributions` here because
 # 1. It is supported only in Python 3.10+.
 # 2. It requires the packages to be installed, but we are doing a static check.
 MOD_TO_DEP = {
-    "aistudio_sdk": "aistudio_sdk",
+    "aistudio_sdk": "aistudio-sdk",
     "aiohttp": "aiohttp",
     "baidubce": "bce-python-sdk",
     "bs4": "beautifulsoup4",
@@ -43,9 +43,10 @@ MOD_TO_DEP = {
     "fastapi": "fastapi",
     "filelock": "filelock",
     "filetype": "filetype",
+    "flash_attn": "flash-attn",
     "ftfy": "ftfy",
     "GPUtil": "GPUtil",
-    "huggingface_hub": "huggingface_hub",
+    "huggingface_hub": "huggingface-hub",
     "imagesize": "imagesize",
     "jinja2": "Jinja2",
     "joblib": "joblib",
@@ -61,6 +62,7 @@ MOD_TO_DEP = {
     "cv2": "opencv-contrib-python",
     "openpyxl": "openpyxl",
     "packaging": "packaging",
+    "paddle2onnx": "paddle2onnx",
     "pandas": "pandas",
     "PIL": "pillow",
     "premailer": "premailer",
@@ -74,22 +76,28 @@ MOD_TO_DEP = {
     "regex": "regex",
     "requests": "requests",
     "ruamel.yaml": "ruamel.yaml",
+    "safetensors": "safetensors",
     "skimage": "scikit-image",
     "sklearn": "scikit-learn",
+    "sentencepiece": "sentencepiece",
+    "sglang": "sglang",
     "shapely": "shapely",
     "soundfile": "soundfile",
     "starlette": "starlette",
     "tiktoken": "tiktoken",
     "tokenizers": "tokenizers",
+    "torch": "torch",
     "tqdm": "tqdm",
+    "transformers": "transformers",
     "typing_extensions": "typing-extensions",
     "ujson": "ujson",
     "uvicorn": "uvicorn",
+    "uvloop": "uvloop",
+    "vllm": "vllm",
+    "xformers": "xformers",
     "yarl": "yarl",
+    "bidi": "python-bidi",
 }
-assert (
-    set(MOD_TO_DEP.values()) == DEP_SPECS.keys()
-), f"`MOD_TO_DEP` should be updated to match `DEP_SPECS`. Symmetric difference: {set(MOD_TO_DEP.values()) ^ DEP_SPECS.keys()}"
 MOD_PATTERN = re.compile(
     rf"^(?:{'|'.join([re.escape(mod) for mod in MOD_TO_DEP])})(?=\.|$)"
 )
@@ -107,7 +115,11 @@ SPECIAL_KNOWN_MODS = {
     "paddle3d",
     "paddlevideo",
 }
-MANUALLY_MANAGED_OPTIONAL_HEAVY_MODS = {"paddle_custom_device", "ultra_infer"}
+MANUALLY_MANAGED_OPTIONAL_HEAVY_MODS = {
+    "paddle_custom_device",
+    "ultra_infer",
+    "fastdeploy",
+}
 
 
 def check(file_path):

+ 4 - 0
README.md

@@ -35,6 +35,10 @@ PaddleX 3.0 是基于飞桨框架构建的低代码开发工具,它集成了
 
 ## 📣 近期更新
 
+🔥🔥 **2025.10.16,发布 PaddleX v3.3.0**,新增能力如下:
+
+- **支持PaddleOCR-VL、PP-OCRv5多语种模型的推理部署能力。**
+
 🔥🔥 **2025.8.20,发布 PaddleX v3.2.0**,新增能力如下:
 
 - **部署能力升级:**

+ 4 - 0
README_en.md

@@ -37,6 +37,10 @@ PaddleX 3.0 is a low-code development tool for AI models built on the PaddlePadd
 
 ## 📣 Recent Updates
 
+🔥🔥 **2025.10.16, PaddleX v3.3.0 Released**
+
+- **Added support for inference and deployment of PaddleOCR-VL and PP-OCRv5 multilingual models.**
+
 🔥🔥 **2025.8.20, PaddleX v3.2.0 Released**
 
 - **Deployment Capability Upgrades:**

+ 31 - 0
api_examples/pipelines/test_pp_ocr_vl.py

@@ -0,0 +1,31 @@
+# Copyright (c) 2024 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 paddlex import create_pipeline
+
+pipeline = create_pipeline(pipeline="PaddleOCR-VL")
+
+output = pipeline.predict(
+    "/paddle/project/PaddleX/demo_paper.png",
+    use_doc_orientation_classify=False,
+    use_doc_unwarping=False,
+)
+
+for res in output:
+    res.print()
+    res.save_to_img("./output")
+    res.save_to_json("./output")
+    res.save_to_xlsx("./output")
+    res.save_to_html("./output")
+    res.save_to_markdown("./output", pretty=False)

+ 14 - 0
deploy/hps/sdk/paddlex-hps-client/src/paddlex_hps_client/__init__.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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 importlib import metadata as _metadata
 
 from .request import triton_request

+ 14 - 0
deploy/hps/sdk/paddlex-hps-client/src/paddlex_hps_client/constants.py

@@ -1,2 +1,16 @@
+# Copyright (c) 2025 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.
+
 INPUT_NAME = "input"
 OUTPUT_NAME = "output"

+ 14 - 0
deploy/hps/sdk/paddlex-hps-client/src/paddlex_hps_client/request.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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.
+
 import json
 
 import numpy as np

+ 14 - 0
deploy/hps/sdk/paddlex-hps-client/src/paddlex_hps_client/utils.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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.
+
 import base64
 import mimetypes
 import shutil

+ 16 - 1
deploy/hps/sdk/pipelines/3d_bev_detection/client/client.py

@@ -1,12 +1,27 @@
 #!/usr/bin/env python
 
+# Copyright (c) 2025 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.
+
 import argparse
 import pprint
 import sys
 
-from paddlex_hps_client import triton_request, utils
 from tritonclient import grpc as triton_grpc
 
+from paddlex_hps_client import triton_request, utils
+
 
 def main():
     parser = argparse.ArgumentParser()

+ 14 - 0
deploy/hps/sdk/pipelines/3d_bev_detection/server/model_repo/bev-3d-object-detection/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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.
+
 import os
 from typing import Any, Dict, List
 

+ 14 - 0
deploy/hps/sdk/pipelines/OCR/client/client.py

@@ -1,5 +1,19 @@
 #!/usr/bin/env python
 
+# Copyright (c) 2025 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.
+
 import argparse
 import sys
 

+ 20 - 1
deploy/hps/sdk/pipelines/OCR/server/model_repo/ocr/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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 typing import Any, Dict, Final, List, Tuple
 
 from paddlex_hps_server import (
@@ -74,7 +88,11 @@ class TritonPythonModel(BaseTritonPythonModel):
                 )
         else:
             file_type = "PDF" if input.fileType == 0 else "IMAGE"
-        visualize_enabled = input.visualize if input.visualize is not None else self.app_config.visualize
+        visualize_enabled = (
+            input.visualize
+            if input.visualize is not None
+            else self.app_config.visualize
+        )
 
         file_bytes = utils.get_raw_bytes(input.file)
         images, data_info = utils.file_to_images(
@@ -95,6 +113,7 @@ class TritonPythonModel(BaseTritonPythonModel):
                 text_det_box_thresh=input.textDetBoxThresh,
                 text_det_unclip_ratio=input.textDetUnclipRatio,
                 text_rec_score_thresh=input.textRecScoreThresh,
+                return_word_box=input.returnWordBox,
             )
         )
 

+ 14 - 0
deploy/hps/sdk/pipelines/PP-ChatOCRv3-doc/client/client.py

@@ -1,5 +1,19 @@
 #!/usr/bin/env python
 
+# Copyright (c) 2025 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.
+
 import argparse
 import sys
 

+ 14 - 0
deploy/hps/sdk/pipelines/PP-ChatOCRv3-doc/server/model_repo/chatocr-chat/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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 paddlex_hps_server import BaseTritonPythonModel, schemas
 
 

+ 14 - 0
deploy/hps/sdk/pipelines/PP-ChatOCRv3-doc/server/model_repo/chatocr-vector/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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 paddlex_hps_server import BaseTritonPythonModel, schemas
 
 

+ 19 - 1
deploy/hps/sdk/pipelines/PP-ChatOCRv3-doc/server/model_repo/chatocr-visual/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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 typing import Any, Dict, Final, List, Tuple
 
 from paddlex_hps_server import (
@@ -74,7 +88,11 @@ class TritonPythonModel(BaseTritonPythonModel):
                 )
         else:
             file_type = "PDF" if input.fileType == 0 else "IMAGE"
-        visualize_enabled = input.visualize if input.visualize is not None else self.app_config.visualize
+        visualize_enabled = (
+            input.visualize
+            if input.visualize is not None
+            else self.app_config.visualize
+        )
 
         file_bytes = utils.get_raw_bytes(input.file)
         images, data_info = utils.file_to_images(

+ 14 - 0
deploy/hps/sdk/pipelines/PP-ChatOCRv4-doc/client/client.py

@@ -1,5 +1,19 @@
 #!/usr/bin/env python
 
+# Copyright (c) 2025 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.
+
 import argparse
 import sys
 

+ 14 - 0
deploy/hps/sdk/pipelines/PP-ChatOCRv4-doc/server/model_repo/chatocr-chat/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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 paddlex_hps_server import BaseTritonPythonModel, schemas
 
 

+ 14 - 0
deploy/hps/sdk/pipelines/PP-ChatOCRv4-doc/server/model_repo/chatocr-mllm/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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 paddlex_hps_server import BaseTritonPythonModel, schemas, utils
 
 

+ 14 - 0
deploy/hps/sdk/pipelines/PP-ChatOCRv4-doc/server/model_repo/chatocr-vector/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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 paddlex_hps_server import BaseTritonPythonModel, schemas
 
 

+ 19 - 1
deploy/hps/sdk/pipelines/PP-ChatOCRv4-doc/server/model_repo/chatocr-visual/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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 typing import Any, Dict, Final, List, Tuple
 
 from paddlex_hps_server import (
@@ -74,7 +88,11 @@ class TritonPythonModel(BaseTritonPythonModel):
                 )
         else:
             file_type = "PDF" if input.fileType == 0 else "IMAGE"
-        visualize_enabled = input.visualize if input.visualize is not None else self.app_config.visualize
+        visualize_enabled = (
+            input.visualize
+            if input.visualize is not None
+            else self.app_config.visualize
+        )
 
         file_bytes = utils.get_raw_bytes(input.file)
         images, data_info = utils.file_to_images(

+ 14 - 0
deploy/hps/sdk/pipelines/PP-DocTranslation/client/client.py

@@ -1,5 +1,19 @@
 #!/usr/bin/env python
 
+# Copyright (c) 2025 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.
+
 import argparse
 import sys
 from pathlib import Path

+ 14 - 0
deploy/hps/sdk/pipelines/PP-DocTranslation/server/model_repo/doctrans-translate/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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 typing import Any, Dict, List
 
 from paddlex_hps_server import BaseTritonPythonModel, schemas

+ 14 - 0
deploy/hps/sdk/pipelines/PP-DocTranslation/server/model_repo/doctrans-visual/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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 typing import Any, Dict, Final, List, Tuple
 
 from paddlex_hps_server import (

+ 14 - 0
deploy/hps/sdk/pipelines/PP-ShiTuV2/client/client.py

@@ -1,5 +1,19 @@
 #!/usr/bin/env python
 
+# Copyright (c) 2025 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.
+
 import argparse
 import pprint
 import sys

+ 14 - 0
deploy/hps/sdk/pipelines/PP-ShiTuV2/server/model_repo/shitu-index-add/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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 operator import attrgetter
 
 from paddlex.inference.pipelines.components import IndexData

+ 14 - 0
deploy/hps/sdk/pipelines/PP-ShiTuV2/server/model_repo/shitu-index-build/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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.
+
 import uuid
 from operator import attrgetter
 

+ 14 - 0
deploy/hps/sdk/pipelines/PP-ShiTuV2/server/model_repo/shitu-index-remove/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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 paddlex.inference.pipelines.components import IndexData
 from paddlex_hps_server import schemas
 

+ 19 - 1
deploy/hps/sdk/pipelines/PP-ShiTuV2/server/model_repo/shitu-infer/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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 typing import Any, Dict, List
 
 from paddlex.inference.pipelines.components import IndexData
@@ -16,7 +30,11 @@ class TritonPythonModel(BaseShiTuModel):
     def run(self, input, log_id):
         image_bytes = utils.get_raw_bytes(input.image)
         image = utils.image_bytes_to_array(image_bytes)
-        visualize_enabled = input.visualize if input.visualize is not None else self.app_config.visualize
+        visualize_enabled = (
+            input.visualize
+            if input.visualize is not None
+            else self.app_config.visualize
+        )
 
         if input.indexKey is not None:
             index_storage = self.context["index_storage"]

+ 13 - 0
deploy/hps/sdk/pipelines/PP-ShiTuV2/server/shared_mods/common/__init__.py

@@ -0,0 +1,13 @@
+# Copyright (c) 2025 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.

+ 14 - 0
deploy/hps/sdk/pipelines/PP-ShiTuV2/server/shared_mods/common/base_model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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 paddlex_hps_server import BaseTritonPythonModel
 from paddlex_hps_server.storage import create_storage
 

+ 14 - 0
deploy/hps/sdk/pipelines/PP-StructureV3/client/client.py

@@ -1,5 +1,19 @@
 #!/usr/bin/env python
 
+# Copyright (c) 2025 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.
+
 import argparse
 import sys
 from pathlib import Path

+ 20 - 1
deploy/hps/sdk/pipelines/PP-StructureV3/server/model_repo/layout-parsing/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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 typing import Any, Dict, Final, List, Tuple
 
 from paddlex_hps_server import (
@@ -74,7 +88,11 @@ class TritonPythonModel(BaseTritonPythonModel):
                 )
         else:
             file_type = "PDF" if input.fileType == 0 else "IMAGE"
-        visualize_enabled = input.visualize if input.visualize is not None else self.app_config.visualize
+        visualize_enabled = (
+            input.visualize
+            if input.visualize is not None
+            else self.app_config.visualize
+        )
 
         file_bytes = utils.get_raw_bytes(input.file)
         images, data_info = utils.file_to_images(
@@ -94,6 +112,7 @@ class TritonPythonModel(BaseTritonPythonModel):
                 use_formula_recognition=input.useFormulaRecognition,
                 use_chart_recognition=input.useChartRecognition,
                 use_region_detection=input.useRegionDetection,
+                format_block_content=input.formatBlockContent,
                 layout_threshold=input.layoutThreshold,
                 layout_nms=input.layoutNms,
                 layout_unclip_ratio=input.layoutUnclipRatio,

+ 1 - 0
deploy/hps/sdk/pipelines/PP-StructureV3/server/pipeline_config.yaml

@@ -9,6 +9,7 @@ use_table_recognition: True
 use_formula_recognition: True
 use_chart_recognition: False
 use_region_detection: True
+format_block_content: False
 
 SubModules:
   LayoutDetection:

+ 64 - 0
deploy/hps/sdk/pipelines/PaddleOCR-VL/client/client.py

@@ -0,0 +1,64 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2025 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.
+
+import argparse
+import sys
+from pathlib import Path
+
+from paddlex_hps_client import triton_request, utils
+from tritonclient import grpc as triton_grpc
+
+
+def main():
+    parser = argparse.ArgumentParser()
+    parser.add_argument("--file", type=str, required=True)
+    parser.add_argument("--file-type", type=int, choices=[0, 1])
+    parser.add_argument("--no-visualization", action="store_true")
+    parser.add_argument("--url", type=str, default="localhost:8001")
+
+    args = parser.parse_args()
+
+    client = triton_grpc.InferenceServerClient(args.url)
+    input_ = {"file": utils.prepare_input_file(args.file)}
+    if args.file_type is not None:
+        input_["fileType"] = args.file_type
+    if args.no_visualization:
+        input_["visualize"] = False
+    output = triton_request(client, "layout-parsing", input_)
+    if output["errorCode"] != 0:
+        print(f"Error code: {output['errorCode']}", file=sys.stderr)
+        print(f"Error message: {output['errorMsg']}", file=sys.stderr)
+        sys.exit(1)
+    result = output["result"]
+    for i, res in enumerate(result["layoutParsingResults"]):
+        print(res["prunedResult"])
+        md_dir = Path(f"markdown_{i}")
+        md_dir.mkdir(exist_ok=True)
+        (md_dir / "doc.md").write_text(res["markdown"]["text"])
+        for img_path, img in res["markdown"]["images"].items():
+            img_path = md_dir / img_path
+            img_path.parent.mkdir(parents=True, exist_ok=True)
+            utils.save_output_file(img, img_path)
+        print(f"Markdown document saved at {md_dir / 'doc.md'}")
+        for img_name, img in res["outputImages"].items():
+            img_path = f"{img_name}_{i}.jpg"
+            Path(img_path).parent.mkdir(exist_ok=True)
+            utils.save_output_file(img, img_path)
+            print(f"Output image saved at {img_path}")
+
+
+if __name__ == "__main__":
+    main()

+ 3 - 0
deploy/hps/sdk/pipelines/PaddleOCR-VL/client/requirements.txt

@@ -0,0 +1,3 @@
+# paddlex-hps-client
+protobuf == 3.19.6
+tritonclient [grpc] == 2.15

+ 291 - 0
deploy/hps/sdk/pipelines/PaddleOCR-VL/server/model_repo/layout-parsing/1/model.py

@@ -0,0 +1,291 @@
+# Copyright (c) 2025 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 concurrent.futures import ThreadPoolExecutor
+from operator import itemgetter
+from typing import Any, Dict, Final, List, Tuple
+
+from paddlex_hps_server import (
+    BaseTritonPythonModel,
+    app_common,
+    protocol,
+    schemas,
+    utils,
+)
+from paddlex_hps_server.storage import SupportsGetURL, create_storage
+
+_DEFAULT_MAX_NUM_INPUT_IMGS: Final[int] = 10
+_DEFAULT_MAX_OUTPUT_IMG_SIZE: Final[Tuple[int, int]] = (2000, 2000)
+
+
+class _SequentialExecutor(object):
+    def map(self, fn, *iterables):
+        return map(fn, *iterables)
+
+    def __enter__(self):
+        return self
+
+    def __exit__(self, exc_type, exc_value, traceback):
+        pass
+
+
+class TritonPythonModel(BaseTritonPythonModel):
+    def initialize(self, args):
+        super().initialize(args)
+        self.context = {}
+        self.context["file_storage"] = None
+        self.context["return_img_urls"] = False
+        self.context["max_num_input_imgs"] = _DEFAULT_MAX_NUM_INPUT_IMGS
+        self.context["max_output_img_size"] = _DEFAULT_MAX_OUTPUT_IMG_SIZE
+        if self.app_config.extra:
+            if "file_storage" in self.app_config.extra:
+                self.context["file_storage"] = create_storage(
+                    self.app_config.extra["file_storage"]
+                )
+            if "return_img_urls" in self.app_config.extra:
+                self.context["return_img_urls"] = self.app_config.extra[
+                    "return_img_urls"
+                ]
+            if "max_num_input_imgs" in self.app_config.extra:
+                self.context["max_num_input_imgs"] = self.app_config.extra[
+                    "max_num_input_imgs"
+                ]
+            if "max_output_img_size" in self.app_config.extra:
+                self.context["max_output_img_size"] = self.app_config.extra[
+                    "max_output_img_size"
+                ]
+        if self.context["return_img_urls"]:
+            file_storage = self.context["file_storage"]
+            if not file_storage:
+                raise ValueError(
+                    "The file storage must be properly configured when URLs need to be returned."
+                )
+            if not isinstance(file_storage, SupportsGetURL):
+                raise TypeError(f"{type(file_storage)} does not support getting URLs.")
+
+    def get_input_model_type(self):
+        return schemas.paddleocr_vl.InferRequest
+
+    def get_result_model_type(self):
+        return schemas.paddleocr_vl.InferResult
+
+    def run(self, input, log_id):
+        return self.run_batch([input], [log_id])
+
+    def run_batch(self, inputs, log_ids, batch_id):
+        result_or_output_dic = {}
+
+        input_groups = self._group_inputs(inputs)
+
+        max_group_size = max(map(len, input_groups))
+        if max_group_size > 1:
+            executor = ThreadPoolExecutor(max_workers=max_group_size)
+        else:
+            executor = _SequentialExecutor()
+
+        with executor:
+            for input_group in input_groups:
+                input_ids_g = list(map(itemgetter(0), input_group))
+                inputs_g = list(map(itemgetter(1), input_group))
+
+                log_ids_g = [log_ids[i] for i in input_ids_g]
+
+                ret = executor.map(self._preprocess, inputs_g, log_ids_g)
+                ind_img_lsts, ind_data_info_lst, ind_visualize_enabled_lst = [], [], []
+                for i, item in enumerate(ret):
+                    if isinstance(item, tuple):
+                        assert len(item) == 3, len(item)
+                        ind_img_lsts.append(item[0])
+                        ind_data_info_lst.append(item[1])
+                        ind_visualize_enabled_lst.append(item[2])
+                    else:
+                        input_id = input_ids_g[i]
+                        result_or_output_dic[input_id] = item
+
+                if len(ind_img_lsts):
+                    images = [img for item in ind_img_lsts for img in item]
+                    preds = list(
+                        self.pipeline(
+                            images,
+                            use_doc_orientation_classify=inputs_g[
+                                0
+                            ].useDocOrientationClassify,
+                            use_doc_unwarping=inputs_g[0].useDocUnwarping,
+                            use_layout_detection=inputs_g[0].useLayoutDetection,
+                            use_chart_recognition=inputs_g[0].useChartRecognition,
+                            layout_threshold=inputs_g[0].layoutThreshold,
+                            layout_nms=inputs_g[0].layoutNms,
+                            layout_unclip_ratio=inputs_g[0].layoutUnclipRatio,
+                            layout_merge_bboxes_mode=inputs_g[0].layoutMergeBboxesMode,
+                            prompt_label=inputs_g[0].promptLabel,
+                            format_block_content=inputs_g[0].formatBlockContent,
+                            repetition_penalty=inputs_g[0].repetitionPenalty,
+                            temperature=inputs_g[0].temperature,
+                            top_p=inputs_g[0].topP,
+                            min_pixels=inputs_g[0].minPixels,
+                            max_pixels=inputs_g[0].maxPixels,
+                        )
+                    )
+
+                    if len(preds) != len(images):
+                        raise RuntimeError(
+                            f"The number of predictions ({len(preds)}) is not the same as the number of input images ({len(images)})."
+                        )
+
+                    start_idx = 0
+                    ind_preds = []
+                    for item in ind_img_lsts:
+                        ind_preds.append(preds[start_idx : start_idx + len(item)])
+                        start_idx += len(item)
+
+                    for i, result in zip(
+                        input_ids_g,
+                        executor.map(
+                            self._postprocess,
+                            ind_img_lsts,
+                            ind_data_info_lst,
+                            ind_visualize_enabled_lst,
+                            ind_preds,
+                            log_ids_g,
+                            inputs_g,
+                        ),
+                    ):
+                        result_or_output_dic[i] = result
+
+            assert len(result_or_output_dic) == len(
+                inputs
+            ), f"Expected {len(inputs)} results or outputs, but got {len(result_or_output_dic)}"
+
+            return [result_or_output_dic[i] for i in range(len(inputs))]
+
+    def _group_inputs(self, inputs):
+        def _hash(input):
+            return hash(
+                (
+                    input.useDocOrientationClassify,
+                    input.useDocUnwarping,
+                    input.useLayoutDetection,
+                    input.useChartRecognition,
+                    input.layoutThreshold,
+                    input.layoutNms,
+                    input.layoutUnclipRatio,
+                    input.layoutMergeBboxesMode,
+                    input.promptLabel,
+                    input.formatBlockContent,
+                    input.repetitionPenalty,
+                    input.temperature,
+                    input.topP,
+                    input.minPixels,
+                    input.maxPixels,
+                )
+            )
+
+        groups = {}
+        for i, inp in enumerate(inputs):
+            group_key = _hash(inp)
+            if group_key not in groups:
+                groups[group_key] = []
+            groups[group_key].append((i, inp))
+
+        return list(groups.values())
+
+    def _preprocess(self, input, log_id):
+        if input.fileType is None:
+            if utils.is_url(input.file):
+                maybe_file_type = utils.infer_file_type(input.file)
+                if maybe_file_type is None or not (
+                    maybe_file_type == "PDF" or maybe_file_type == "IMAGE"
+                ):
+                    return protocol.create_aistudio_output_without_result(
+                        422,
+                        "Unsupported file type",
+                        log_id=log_id,
+                    )
+                file_type = maybe_file_type
+            else:
+                return protocol.create_aistudio_output_without_result(
+                    422,
+                    "File type cannot be determined",
+                    log_id=log_id,
+                )
+        else:
+            file_type = "PDF" if input.fileType == 0 else "IMAGE"
+        visualize_enabled = (
+            input.visualize
+            if input.visualize is not None
+            else self.app_config.visualize
+        )
+
+        file_bytes = utils.get_raw_bytes(input.file)
+        images, data_info = utils.file_to_images(
+            file_bytes,
+            file_type,
+            max_num_imgs=self.context["max_num_input_imgs"],
+        )
+
+        return images, data_info, visualize_enabled
+
+    def _postprocess(self, images, data_info, visualize_enabled, preds, log_id, input):
+        layout_parsing_results: List[Dict[str, Any]] = []
+        for i, (img, item) in enumerate(zip(images, preds)):
+            pruned_res = app_common.prune_result(item.json["res"])
+            # XXX
+            md_data = item._to_markdown(
+                pretty=input.prettifyMarkdown,
+                show_formula_number=input.showFormulaNumber,
+            )
+            md_text = md_data["markdown_texts"]
+            md_imgs = app_common.postprocess_images(
+                md_data["markdown_images"],
+                log_id,
+                filename_template=f"markdown_{i}/{{key}}",
+                file_storage=self.context["file_storage"],
+                return_urls=self.context["return_img_urls"],
+                max_img_size=self.context["max_output_img_size"],
+            )
+            if visualize_enabled:
+                imgs = {
+                    "input_img": img,
+                    **item.img,
+                }
+                imgs = app_common.postprocess_images(
+                    imgs,
+                    log_id,
+                    filename_template=f"{{key}}_{i}.jpg",
+                    file_storage=self.context["file_storage"],
+                    return_urls=self.context["return_img_urls"],
+                    max_img_size=self.context["max_output_img_size"],
+                )
+            else:
+                imgs = {}
+            layout_parsing_results.append(
+                dict(
+                    prunedResult=pruned_res,
+                    markdown=dict(
+                        text=md_text,
+                        images=md_imgs,
+                    ),
+                    outputImages=(
+                        {k: v for k, v in imgs.items() if k != "input_img"}
+                        if imgs
+                        else None
+                    ),
+                    inputImage=imgs.get("input_img"),
+                )
+            )
+
+        return schemas.paddleocr_vl.InferResult(
+            layoutParsingResults=layout_parsing_results,
+            dataInfo=data_info,
+        )

+ 23 - 0
deploy/hps/sdk/pipelines/PaddleOCR-VL/server/model_repo/layout-parsing/config_cpu.pbtxt

@@ -0,0 +1,23 @@
+backend: "python"
+max_batch_size: 8
+input [
+  {
+    name: "input"
+    data_type: TYPE_STRING
+    dims: [ -1 ]
+  }
+]
+output [
+  {
+    name: "output"
+    data_type: TYPE_STRING
+    dims: [ -1 ]
+  }
+]
+instance_group [
+  {
+      count: 1
+      kind: KIND_CPU
+  }
+]
+dynamic_batching { }

+ 24 - 0
deploy/hps/sdk/pipelines/PaddleOCR-VL/server/model_repo/layout-parsing/config_gpu.pbtxt

@@ -0,0 +1,24 @@
+backend: "python"
+max_batch_size: 8
+input [
+  {
+    name: "input"
+    data_type: TYPE_STRING
+    dims: [ -1 ]
+  }
+]
+output [
+  {
+    name: "output"
+    data_type: TYPE_STRING
+    dims: [ -1 ]
+  }
+]
+instance_group [
+  {
+      count: 1
+      kind: KIND_GPU
+      gpus: [ 0 ]
+  }
+]
+dynamic_batching { }

+ 96 - 0
deploy/hps/sdk/pipelines/PaddleOCR-VL/server/pipeline_config.yaml

@@ -0,0 +1,96 @@
+
+pipeline_name: PaddleOCR-VL
+
+batch_size: 64
+
+use_queues: True
+
+use_doc_preprocessor: False
+use_layout_detection: True
+use_chart_recognition: False
+format_block_content: False
+
+SubModules:
+  LayoutDetection:
+    module_name: layout_detection
+    model_name: PP-DocLayoutV2
+    model_dir: null
+    batch_size: 8
+    threshold: 
+      0: 0.5 # abstract
+      1: 0.5 # algorithm
+      2: 0.5 # aside_text
+      3: 0.5 # chart
+      4: 0.5 # content
+      5: 0.4 # formula
+      6: 0.4 # doc_title
+      7: 0.5 # figure_title
+      8: 0.5 # footer
+      9: 0.5 # footer
+      10: 0.5 # footnote
+      11: 0.5 # formula_number
+      12: 0.5 # header
+      13: 0.5 # header
+      14: 0.5 # image
+      15: 0.4 # formula
+      16: 0.5 # number
+      17: 0.4 # paragraph_title
+      18: 0.5 # reference
+      19: 0.5 # reference_content
+      20: 0.45 # seal
+      21: 0.5 # table
+      22: 0.4 # text
+      23: 0.4 # text
+      24: 0.5 # vision_footnote
+    layout_nms: True
+    layout_unclip_ratio: [1.0, 1.0] 
+    layout_merge_bboxes_mode: 
+      0: "union" # abstract
+      1: "union" # algorithm
+      2: "union" # aside_text
+      3: "large" # chart
+      4: "union" # content
+      5: "large" # display_formula
+      6: "large" # doc_title
+      7: "union" # figure_title
+      8: "union" # footer
+      9: "union" # footer
+      10: "union" # footnote
+      11: "union" # formula_number
+      12: "union" # header
+      13: "union" # header
+      14: "union" # image
+      15: "large" # inline_formula
+      16: "union" # number
+      17: "large" # paragraph_title
+      18: "union" # reference
+      19: "union" # reference_content
+      20: "union" # seal
+      21: "union" # table
+      22: "union" # text
+      23: "union" # text
+      24: "union" # vision_footnote
+  VLRecognition:
+    module_name: vl_recognition
+    model_name: PaddleOCR-VL-0.9B
+    model_dir: null
+    batch_size: 2048
+    genai_config:
+      backend: native
+
+SubPipelines:
+  DocPreprocessor:
+    pipeline_name: doc_preprocessor
+    batch_size: 8
+    use_doc_orientation_classify: True
+    use_doc_unwarping: True
+    SubModules:
+      DocOrientationClassify:
+        module_name: doc_text_orientation
+        model_name: PP-LCNet_x1_0_doc_ori
+        model_dir: null
+        batch_size: 8
+      DocUnwarping:
+        module_name: image_unwarping
+        model_name: UVDoc
+        model_dir: null

+ 14 - 0
deploy/hps/sdk/pipelines/anomaly_detection/client/client.py

@@ -1,5 +1,19 @@
 #!/usr/bin/env python
 
+# Copyright (c) 2025 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.
+
 import argparse
 import sys
 

+ 19 - 1
deploy/hps/sdk/pipelines/anomaly_detection/server/model_repo/anomaly-detection/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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 paddlex_hps_server import BaseTritonPythonModel, schemas, utils
 
 
@@ -17,7 +31,11 @@ class TritonPythonModel(BaseTritonPythonModel):
         pred = result["pred"][0].tolist()
         size = [len(pred), len(pred[0])]
         label_map = [item for sublist in pred for item in sublist]
-        visualize_enabled = input.visualize if input.visualize is not None else self.app_config.visualize
+        visualize_enabled = (
+            input.visualize
+            if input.visualize is not None
+            else self.app_config.visualize
+        )
 
         if visualize_enabled:
             output_image_base64 = utils.base64_encode(

+ 14 - 0
deploy/hps/sdk/pipelines/doc_preprocessor/client/client.py

@@ -1,5 +1,19 @@
 #!/usr/bin/env python
 
+# Copyright (c) 2025 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.
+
 import argparse
 import sys
 

+ 19 - 1
deploy/hps/sdk/pipelines/doc_preprocessor/server/model_repo/document-preprocessing/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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 typing import Any, Dict, Final, List, Tuple
 
 from paddlex_hps_server import (
@@ -89,7 +103,11 @@ class TritonPythonModel(BaseTritonPythonModel):
                 use_doc_unwarping=input.useDocUnwarping,
             )
         )
-        visualize_enabled = input.visualize if input.visualize is not None else self.app_config.visualize
+        visualize_enabled = (
+            input.visualize
+            if input.visualize is not None
+            else self.app_config.visualize
+        )
 
         doc_pp_results: List[Dict[str, Any]] = []
         for i, (img, item) in enumerate(zip(images, result)):

+ 14 - 0
deploy/hps/sdk/pipelines/doc_understanding/client/client.py

@@ -1,5 +1,19 @@
 #!/usr/bin/env python
 
+# Copyright (c) 2025 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.
+
 import argparse
 import sys
 

+ 14 - 0
deploy/hps/sdk/pipelines/doc_understanding/server/model_repo/document-understanding/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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.
+
 import math
 import time
 from typing import List

+ 14 - 0
deploy/hps/sdk/pipelines/face_recognition/client/client.py

@@ -1,5 +1,19 @@
 #!/usr/bin/env python
 
+# Copyright (c) 2025 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.
+
 import argparse
 import pprint
 import sys

+ 14 - 0
deploy/hps/sdk/pipelines/face_recognition/server/model_repo/face-recognition-index-add/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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 operator import attrgetter
 
 from paddlex.inference.pipelines.components import IndexData

+ 14 - 0
deploy/hps/sdk/pipelines/face_recognition/server/model_repo/face-recognition-index-build/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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.
+
 import uuid
 from operator import attrgetter
 

+ 14 - 0
deploy/hps/sdk/pipelines/face_recognition/server/model_repo/face-recognition-index-remove/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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 paddlex.inference.pipelines.components import IndexData
 from paddlex_hps_server import schemas
 

+ 19 - 1
deploy/hps/sdk/pipelines/face_recognition/server/model_repo/face-recognition-infer/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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 typing import Any, Dict, List
 
 from paddlex.inference.pipelines.components import IndexData
@@ -23,7 +37,11 @@ class TritonPythonModel(BaseFaceRecognitionModel):
             index_data = IndexData.from_bytes(index_data_bytes)
         else:
             index_data = None
-        visualize_enabled = input.visualize if input.visualize is not None else self.app_config.visualize
+        visualize_enabled = (
+            input.visualize
+            if input.visualize is not None
+            else self.app_config.visualize
+        )
 
         result = list(
             self.pipeline(

+ 13 - 0
deploy/hps/sdk/pipelines/face_recognition/server/shared_mods/common/__init__.py

@@ -0,0 +1,13 @@
+# Copyright (c) 2025 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.

+ 14 - 0
deploy/hps/sdk/pipelines/face_recognition/server/shared_mods/common/base_model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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 paddlex_hps_server import BaseTritonPythonModel
 from paddlex_hps_server.storage import create_storage
 

+ 14 - 0
deploy/hps/sdk/pipelines/formula_recognition/client/client.py

@@ -1,5 +1,19 @@
 #!/usr/bin/env python
 
+# Copyright (c) 2025 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.
+
 import argparse
 import sys
 

+ 19 - 1
deploy/hps/sdk/pipelines/formula_recognition/server/model_repo/formula-recognition/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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 typing import Any, Dict, Final, List, Tuple
 
 from paddlex_hps_server import (
@@ -74,7 +88,11 @@ class TritonPythonModel(BaseTritonPythonModel):
                 )
         else:
             file_type = "PDF" if input.fileType == 0 else "IMAGE"
-        visualize_enabled = input.visualize if input.visualize is not None else self.app_config.visualize
+        visualize_enabled = (
+            input.visualize
+            if input.visualize is not None
+            else self.app_config.visualize
+        )
 
         file_bytes = utils.get_raw_bytes(input.file)
         images, data_info = utils.file_to_images(

+ 14 - 0
deploy/hps/sdk/pipelines/human_keypoint_detection/client/client.py

@@ -1,5 +1,19 @@
 #!/usr/bin/env python
 
+# Copyright (c) 2025 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.
+
 import argparse
 import pprint
 import sys

+ 19 - 1
deploy/hps/sdk/pipelines/human_keypoint_detection/server/model_repo/human-keypoint-detection/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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 typing import Any, Dict, List
 
 from paddlex_hps_server import BaseTritonPythonModel, schemas, utils
@@ -13,7 +27,11 @@ class TritonPythonModel(BaseTritonPythonModel):
     def run(self, input, log_id):
         file_bytes = utils.get_raw_bytes(input.image)
         image = utils.image_bytes_to_array(file_bytes)
-        visualize_enabled = input.visualize if input.visualize is not None else self.app_config.visualize
+        visualize_enabled = (
+            input.visualize
+            if input.visualize is not None
+            else self.app_config.visualize
+        )
 
         result = list(
             self.pipeline.predict(

+ 14 - 0
deploy/hps/sdk/pipelines/image_classification/client/client.py

@@ -1,5 +1,19 @@
 #!/usr/bin/env python
 
+# Copyright (c) 2025 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.
+
 import argparse
 import pprint
 import sys

+ 19 - 1
deploy/hps/sdk/pipelines/image_classification/server/model_repo/image-classification/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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 typing import Any, Dict, List
 
 from paddlex_hps_server import BaseTritonPythonModel, schemas, utils
@@ -13,7 +27,11 @@ class TritonPythonModel(BaseTritonPythonModel):
     def run(self, input, log_id):
         file_bytes = utils.get_raw_bytes(input.image)
         image = utils.image_bytes_to_array(file_bytes)
-        visualize_enabled = input.visualize if input.visualize is not None else self.app_config.visualize
+        visualize_enabled = (
+            input.visualize
+            if input.visualize is not None
+            else self.app_config.visualize
+        )
 
         result = list(self.pipeline.predict(image, topk=input.topk))[0]
         if "label_names" in result:

+ 14 - 0
deploy/hps/sdk/pipelines/image_multilabel_classification/client/client.py

@@ -1,5 +1,19 @@
 #!/usr/bin/env python
 
+# Copyright (c) 2025 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.
+
 import argparse
 import pprint
 import sys

+ 19 - 1
deploy/hps/sdk/pipelines/image_multilabel_classification/server/model_repo/multilabel-image-classification/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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 typing import Any, Dict, List
 
 from paddlex_hps_server import BaseTritonPythonModel, schemas, utils
@@ -13,7 +27,11 @@ class TritonPythonModel(BaseTritonPythonModel):
     def run(self, input, log_id):
         file_bytes = utils.get_raw_bytes(input.image)
         image = utils.image_bytes_to_array(file_bytes)
-        visualize_enabled = input.visualize if input.visualize is not None else self.app_config.visualize
+        visualize_enabled = (
+            input.visualize
+            if input.visualize is not None
+            else self.app_config.visualize
+        )
 
         result = list(self.pipeline.predict(image, threshold=input.threshold))[0]
 

+ 14 - 0
deploy/hps/sdk/pipelines/instance_segmentation/client/client.py

@@ -1,5 +1,19 @@
 #!/usr/bin/env python
 
+# Copyright (c) 2025 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.
+
 import argparse
 import pprint
 import sys

+ 19 - 1
deploy/hps/sdk/pipelines/instance_segmentation/server/model_repo/instance-segmentation/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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 typing import Any, Dict, List
 
 import numpy as np
@@ -20,7 +34,11 @@ class TritonPythonModel(BaseTritonPythonModel):
     def run(self, input, log_id):
         file_bytes = utils.get_raw_bytes(input.image)
         image = utils.image_bytes_to_array(file_bytes)
-        visualize_enabled = input.visualize if input.visualize is not None else self.app_config.visualize
+        visualize_enabled = (
+            input.visualize
+            if input.visualize is not None
+            else self.app_config.visualize
+        )
 
         result = list(self.pipeline.predict(image, threshold=input.threshold))[0]
 

+ 14 - 0
deploy/hps/sdk/pipelines/layout_parsing/client/client.py

@@ -1,5 +1,19 @@
 #!/usr/bin/env python
 
+# Copyright (c) 2025 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.
+
 import argparse
 import sys
 

+ 19 - 1
deploy/hps/sdk/pipelines/layout_parsing/server/model_repo/layout-parsing/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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 typing import Any, Dict, Final, List, Tuple
 
 from paddlex_hps_server import (
@@ -74,7 +88,11 @@ class TritonPythonModel(BaseTritonPythonModel):
                 )
         else:
             file_type = "PDF" if input.fileType == 0 else "IMAGE"
-        visualize_enabled = input.visualize if input.visualize is not None else self.app_config.visualize
+        visualize_enabled = (
+            input.visualize
+            if input.visualize is not None
+            else self.app_config.visualize
+        )
 
         file_bytes = utils.get_raw_bytes(input.file)
         images, data_info = utils.file_to_images(

+ 14 - 0
deploy/hps/sdk/pipelines/multilingual_speech_recognition/client/client.py

@@ -1,5 +1,19 @@
 #!/usr/bin/env python
 
+# Copyright (c) 2025 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.
+
 import argparse
 import pprint
 import sys

+ 14 - 0
deploy/hps/sdk/pipelines/multilingual_speech_recognition/server/model_repo/multilingual-speech-recognition/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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.
+
 import os
 from typing import Any, Dict, List
 

+ 14 - 0
deploy/hps/sdk/pipelines/object_detection/client/client.py

@@ -1,5 +1,19 @@
 #!/usr/bin/env python
 
+# Copyright (c) 2025 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.
+
 import argparse
 import pprint
 import sys

+ 19 - 1
deploy/hps/sdk/pipelines/object_detection/server/model_repo/object-detection/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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 typing import Any, Dict, List
 
 from paddlex_hps_server import BaseTritonPythonModel, schemas, utils
@@ -15,7 +29,11 @@ class TritonPythonModel(BaseTritonPythonModel):
         image = utils.image_bytes_to_array(file_bytes)
 
         result = list(self.pipeline.predict(image, threshold=input.threshold))[0]
-        visualize_enabled = input.visualize if input.visualize is not None else self.app_config.visualize
+        visualize_enabled = (
+            input.visualize
+            if input.visualize is not None
+            else self.app_config.visualize
+        )
 
         objects: List[Dict[str, Any]] = []
         for obj in result["boxes"]:

+ 14 - 0
deploy/hps/sdk/pipelines/open_vocabulary_detection/client/client.py

@@ -1,5 +1,19 @@
 #!/usr/bin/env python
 
+# Copyright (c) 2025 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.
+
 import argparse
 import pprint
 import sys

+ 19 - 1
deploy/hps/sdk/pipelines/open_vocabulary_detection/server/model_repo/open-vocabulary-detection/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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 typing import Any, Dict, List
 
 from paddlex_hps_server import BaseTritonPythonModel, schemas, utils
@@ -13,7 +27,11 @@ class TritonPythonModel(BaseTritonPythonModel):
     def run(self, input, log_id):
         file_bytes = utils.get_raw_bytes(input.image)
         image = utils.image_bytes_to_array(file_bytes)
-        visualize_enabled = input.visualize if input.visualize is not None else self.app_config.visualize
+        visualize_enabled = (
+            input.visualize
+            if input.visualize is not None
+            else self.app_config.visualize
+        )
 
         result = list(
             self.pipeline.predict(

+ 14 - 0
deploy/hps/sdk/pipelines/open_vocabulary_segmentation/client/client.py

@@ -1,5 +1,19 @@
 #!/usr/bin/env python
 
+# Copyright (c) 2025 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.
+
 import argparse
 import pprint
 import sys

+ 19 - 1
deploy/hps/sdk/pipelines/open_vocabulary_segmentation/server/model_repo/open-vocabulary-segmentation/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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.
+
 import numpy as np
 import pycocotools.mask as mask_util
 from paddlex_hps_server import BaseTritonPythonModel, schemas, utils
@@ -18,7 +32,11 @@ class TritonPythonModel(BaseTritonPythonModel):
     def run(self, input, log_id):
         file_bytes = utils.get_raw_bytes(input.image)
         image = utils.image_bytes_to_array(file_bytes)
-        visualize_enabled = input.visualize if input.visualize is not None else self.app_config.visualize
+        visualize_enabled = (
+            input.visualize
+            if input.visualize is not None
+            else self.app_config.visualize
+        )
 
         result = list(
             self.pipeline.predict(

+ 14 - 0
deploy/hps/sdk/pipelines/pedestrian_attribute_recognition/client/client.py

@@ -1,5 +1,19 @@
 #!/usr/bin/env python
 
+# Copyright (c) 2025 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.
+
 import argparse
 import pprint
 import sys

+ 19 - 1
deploy/hps/sdk/pipelines/pedestrian_attribute_recognition/server/model_repo/pedestrian-attribute-recognition/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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 typing import Any, Dict, List
 
 from paddlex_hps_server import BaseTritonPythonModel, schemas, utils
@@ -13,7 +27,11 @@ class TritonPythonModel(BaseTritonPythonModel):
     def run(self, input, log_id):
         file_bytes = utils.get_raw_bytes(input.image)
         image = utils.image_bytes_to_array(file_bytes)
-        visualize_enabled = input.visualize if input.visualize is not None else self.app_config.visualize
+        visualize_enabled = (
+            input.visualize
+            if input.visualize is not None
+            else self.app_config.visualize
+        )
 
         result = list(
             self.pipeline.predict(

+ 14 - 0
deploy/hps/sdk/pipelines/rotated_object_detection/client/client.py

@@ -1,5 +1,19 @@
 #!/usr/bin/env python
 
+# Copyright (c) 2025 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.
+
 import argparse
 import pprint
 import sys

+ 19 - 1
deploy/hps/sdk/pipelines/rotated_object_detection/server/model_repo/rotated-object-detection/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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 typing import Any, Dict, List
 
 from paddlex_hps_server import BaseTritonPythonModel, schemas, utils
@@ -13,7 +27,11 @@ class TritonPythonModel(BaseTritonPythonModel):
     def run(self, input, log_id):
         file_bytes = utils.get_raw_bytes(input.image)
         image = utils.image_bytes_to_array(file_bytes)
-        visualize_enabled = input.visualize if input.visualize is not None else self.app_config.visualize
+        visualize_enabled = (
+            input.visualize
+            if input.visualize is not None
+            else self.app_config.visualize
+        )
 
         result = list(self.pipeline.predict(image, threshold=input.threshold))[0]
 

+ 14 - 0
deploy/hps/sdk/pipelines/seal_recognition/client/client.py

@@ -1,5 +1,19 @@
 #!/usr/bin/env python
 
+# Copyright (c) 2025 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.
+
 import argparse
 import sys
 

+ 19 - 1
deploy/hps/sdk/pipelines/seal_recognition/server/model_repo/seal-recognition/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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 typing import Any, Dict, Final, List, Tuple
 
 from paddlex_hps_server import (
@@ -74,7 +88,11 @@ class TritonPythonModel(BaseTritonPythonModel):
                 )
         else:
             file_type = "PDF" if input.fileType == 0 else "IMAGE"
-        visualize_enabled = input.visualize if input.visualize is not None else self.app_config.visualize
+        visualize_enabled = (
+            input.visualize
+            if input.visualize is not None
+            else self.app_config.visualize
+        )
 
         file_bytes = utils.get_raw_bytes(input.file)
         images, data_info = utils.file_to_images(

+ 14 - 0
deploy/hps/sdk/pipelines/semantic_segmentation/client/client.py

@@ -1,5 +1,19 @@
 #!/usr/bin/env python
 
+# Copyright (c) 2025 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.
+
 import argparse
 import sys
 

+ 19 - 1
deploy/hps/sdk/pipelines/semantic_segmentation/server/model_repo/semantic-segmentation/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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 paddlex_hps_server import BaseTritonPythonModel, schemas, utils
 
 
@@ -11,7 +25,11 @@ class TritonPythonModel(BaseTritonPythonModel):
     def run(self, input, log_id):
         file_bytes = utils.get_raw_bytes(input.image)
         image = utils.image_bytes_to_array(file_bytes)
-        visualize_enabled = input.visualize if input.visualize is not None else self.app_config.visualize
+        visualize_enabled = (
+            input.visualize
+            if input.visualize is not None
+            else self.app_config.visualize
+        )
 
         result = list(self.pipeline.predict(image, target_size=input.targetSize))[0]
 

+ 14 - 0
deploy/hps/sdk/pipelines/small_object_detection/client/client.py

@@ -1,5 +1,19 @@
 #!/usr/bin/env python
 
+# Copyright (c) 2025 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.
+
 import argparse
 import pprint
 import sys

+ 19 - 1
deploy/hps/sdk/pipelines/small_object_detection/server/model_repo/small-object-detection/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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 typing import Any, Dict, List
 
 from paddlex_hps_server import BaseTritonPythonModel, schemas, utils
@@ -13,7 +27,11 @@ class TritonPythonModel(BaseTritonPythonModel):
     def run(self, input, log_id):
         file_bytes = utils.get_raw_bytes(input.image)
         image = utils.image_bytes_to_array(file_bytes)
-        visualize_enabled = input.visualize if input.visualize is not None else self.app_config.visualize
+        visualize_enabled = (
+            input.visualize
+            if input.visualize is not None
+            else self.app_config.visualize
+        )
 
         result = list(self.pipeline.predict(image, threshold=input.threshold))[0]
 

+ 14 - 0
deploy/hps/sdk/pipelines/table_recognition/client/client.py

@@ -1,5 +1,19 @@
 #!/usr/bin/env python
 
+# Copyright (c) 2025 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.
+
 import argparse
 import sys
 

+ 19 - 1
deploy/hps/sdk/pipelines/table_recognition/server/model_repo/table-recognition/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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 typing import Any, Dict, Final, List, Tuple
 
 from paddlex_hps_server import (
@@ -74,7 +88,11 @@ class TritonPythonModel(BaseTritonPythonModel):
                 )
         else:
             file_type = "PDF" if input.fileType == 0 else "IMAGE"
-        visualize_enabled = input.visualize if input.visualize is not None else self.app_config.visualize
+        visualize_enabled = (
+            input.visualize
+            if input.visualize is not None
+            else self.app_config.visualize
+        )
 
         file_bytes = utils.get_raw_bytes(input.file)
         images, data_info = utils.file_to_images(

+ 14 - 0
deploy/hps/sdk/pipelines/table_recognition_v2/client/client.py

@@ -1,5 +1,19 @@
 #!/usr/bin/env python
 
+# Copyright (c) 2025 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.
+
 import argparse
 import sys
 

+ 19 - 1
deploy/hps/sdk/pipelines/table_recognition_v2/server/model_repo/table-recognition/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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 typing import Any, Dict, Final, List, Tuple
 
 from paddlex_hps_server import (
@@ -74,7 +88,11 @@ class TritonPythonModel(BaseTritonPythonModel):
                 )
         else:
             file_type = "PDF" if input.fileType == 0 else "IMAGE"
-        visualize_enabled = input.visualize if input.visualize is not None else self.app_config.visualize
+        visualize_enabled = (
+            input.visualize
+            if input.visualize is not None
+            else self.app_config.visualize
+        )
 
         file_bytes = utils.get_raw_bytes(input.file)
         images, data_info = utils.file_to_images(

+ 14 - 0
deploy/hps/sdk/pipelines/ts_anomaly_detection/client/client.py

@@ -1,5 +1,19 @@
 #!/usr/bin/env python
 
+# Copyright (c) 2025 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.
+
 import argparse
 import sys
 

+ 19 - 1
deploy/hps/sdk/pipelines/ts_anomaly_detection/server/model_repo/time-series-anomaly-detection/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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 paddlex_hps_server import BaseTritonPythonModel, schemas, utils
 
 
@@ -11,7 +25,11 @@ class TritonPythonModel(BaseTritonPythonModel):
     def run(self, input, log_id):
         file_bytes = utils.get_raw_bytes(input.csv)
         df = utils.csv_bytes_to_data_frame(file_bytes)
-        visualize_enabled = input.visualize if input.visualize is not None else self.app_config.visualize
+        visualize_enabled = (
+            input.visualize
+            if input.visualize is not None
+            else self.app_config.visualize
+        )
 
         result = list(self.pipeline.predict(df))[0]
 

+ 14 - 0
deploy/hps/sdk/pipelines/ts_classification/client/client.py

@@ -1,5 +1,19 @@
 #!/usr/bin/env python
 
+# Copyright (c) 2025 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.
+
 import argparse
 import sys
 

+ 19 - 1
deploy/hps/sdk/pipelines/ts_classification/server/model_repo/time-series-classification/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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 paddlex_hps_server import BaseTritonPythonModel, schemas, utils
 
 
@@ -11,7 +25,11 @@ class TritonPythonModel(BaseTritonPythonModel):
     def run(self, input, log_id):
         file_bytes = utils.get_raw_bytes(input.csv)
         df = utils.csv_bytes_to_data_frame(file_bytes)
-        visualize_enabled = input.visualize if input.visualize is not None else self.app_config.visualize
+        visualize_enabled = (
+            input.visualize
+            if input.visualize is not None
+            else self.app_config.visualize
+        )
 
         result = list(self.pipeline.predict(df))[0]
 

+ 14 - 0
deploy/hps/sdk/pipelines/ts_forecast/client/client.py

@@ -1,5 +1,19 @@
 #!/usr/bin/env python
 
+# Copyright (c) 2025 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.
+
 import argparse
 import sys
 

+ 19 - 1
deploy/hps/sdk/pipelines/ts_forecast/server/model_repo/time-series-forecasting/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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 paddlex_hps_server import BaseTritonPythonModel, schemas, utils
 
 
@@ -11,7 +25,11 @@ class TritonPythonModel(BaseTritonPythonModel):
     def run(self, input, log_id):
         file_bytes = utils.get_raw_bytes(input.csv)
         df = utils.csv_bytes_to_data_frame(file_bytes)
-        visualize_enabled = input.visualize if input.visualize is not None else self.app_config.visualize
+        visualize_enabled = (
+            input.visualize
+            if input.visualize is not None
+            else self.app_config.visualize
+        )
 
         result = list(self.pipeline.predict(df))[0]
 

+ 14 - 0
deploy/hps/sdk/pipelines/vehicle_attribute_recognition/client/client.py

@@ -1,5 +1,19 @@
 #!/usr/bin/env python
 
+# Copyright (c) 2025 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.
+
 import argparse
 import pprint
 import sys

+ 19 - 1
deploy/hps/sdk/pipelines/vehicle_attribute_recognition/server/model_repo/vehicle-attribute-recognition/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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 typing import Any, Dict, List
 
 from paddlex_hps_server import BaseTritonPythonModel, schemas, utils
@@ -13,7 +27,11 @@ class TritonPythonModel(BaseTritonPythonModel):
     def run(self, input, log_id):
         file_bytes = utils.get_raw_bytes(input.image)
         image = utils.image_bytes_to_array(file_bytes)
-        visualize_enabled = input.visualize if input.visualize is not None else self.app_config.visualize
+        visualize_enabled = (
+            input.visualize
+            if input.visualize is not None
+            else self.app_config.visualize
+        )
 
         result = list(
             self.pipeline.predict(

+ 14 - 0
deploy/hps/sdk/pipelines/video_classification/client/client.py

@@ -1,5 +1,19 @@
 #!/usr/bin/env python
 
+# Copyright (c) 2025 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.
+
 import argparse
 import pprint
 import sys

+ 14 - 0
deploy/hps/sdk/pipelines/video_classification/server/model_repo/video-classification/1/model.py

@@ -1,3 +1,17 @@
+# Copyright (c) 2025 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.
+
 import os
 from typing import Any, Dict, List
 

+ 14 - 0
deploy/hps/sdk/pipelines/video_detection/client/client.py

@@ -1,5 +1,19 @@
 #!/usr/bin/env python
 
+# Copyright (c) 2025 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.
+
 import argparse
 import pprint
 import sys

Some files were not shown because too many files changed in this diff