_cli.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. # Copyright (c) 2025 PaddlePaddle Authors. All Rights Reserved.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. import argparse
  15. import logging
  16. import subprocess
  17. import sys
  18. import time
  19. import warnings
  20. from threading import Thread
  21. import requests
  22. from ._models import (
  23. ChartParsing,
  24. DocImgOrientationClassification,
  25. DocVLM,
  26. FormulaRecognition,
  27. LayoutDetection,
  28. SealTextDetection,
  29. TableCellsDetection,
  30. TableClassification,
  31. TableStructureRecognition,
  32. TextDetection,
  33. TextImageUnwarping,
  34. TextLineOrientationClassification,
  35. TextRecognition,
  36. )
  37. from ._pipelines import (
  38. DocPreprocessor,
  39. DocUnderstanding,
  40. FormulaRecognitionPipeline,
  41. PaddleOCR,
  42. PaddleOCRVL,
  43. PPChatOCRv4Doc,
  44. PPDocTranslation,
  45. PPStructureV3,
  46. SealRecognition,
  47. TableRecognitionPipelineV2,
  48. )
  49. from ._version import version
  50. from ._utils.deprecation import CLIDeprecationWarning
  51. from ._utils.logging import logger
  52. def _register_pipelines(subparsers):
  53. for cls in [
  54. DocPreprocessor,
  55. DocUnderstanding,
  56. FormulaRecognitionPipeline,
  57. PaddleOCR,
  58. PaddleOCRVL,
  59. PPChatOCRv4Doc,
  60. PPDocTranslation,
  61. PPStructureV3,
  62. SealRecognition,
  63. TableRecognitionPipelineV2,
  64. ]:
  65. subcommand_executor = cls.get_cli_subcommand_executor()
  66. subparser = subcommand_executor.add_subparser(subparsers)
  67. subparser.set_defaults(executor=subcommand_executor.execute_with_args)
  68. def _register_models(subparsers):
  69. for cls in [
  70. ChartParsing,
  71. DocImgOrientationClassification,
  72. DocVLM,
  73. FormulaRecognition,
  74. LayoutDetection,
  75. SealTextDetection,
  76. TableCellsDetection,
  77. TableClassification,
  78. TableStructureRecognition,
  79. TextDetection,
  80. TextImageUnwarping,
  81. TextLineOrientationClassification,
  82. TextRecognition,
  83. ]:
  84. subcommand_executor = cls.get_cli_subcommand_executor()
  85. subparser = subcommand_executor.add_subparser(subparsers)
  86. subparser.set_defaults(executor=subcommand_executor.execute_with_args)
  87. def _register_install_hpi_deps_command(subparsers):
  88. def _install_hpi_deps(args):
  89. hpip = f"hpi-{args.variant}"
  90. try:
  91. subprocess.check_call(["paddlex", "--install", hpip])
  92. subprocess.check_call(["paddlex", "--install", "paddle2onnx"])
  93. except subprocess.CalledProcessError:
  94. sys.exit("Failed to install dependencies")
  95. subparser = subparsers.add_parser("install_hpi_deps")
  96. subparser.add_argument("variant", type=str, choices=["cpu", "gpu", "npu"])
  97. subparser.set_defaults(executor=_install_hpi_deps)
  98. def _register_install_genai_server_deps_command(subparsers):
  99. def _install_genai_server_deps(args):
  100. try:
  101. subprocess.check_call(
  102. ["paddlex", "--install", f"genai-{args.variant}-server"]
  103. )
  104. except subprocess.CalledProcessError:
  105. sys.exit("Failed to install dependencies")
  106. subparser = subparsers.add_parser("install_genai_server_deps")
  107. subparser.add_argument(
  108. "variant", type=str, choices=["vllm", "sglang", "fastdeploy"]
  109. )
  110. subparser.set_defaults(executor=_install_genai_server_deps)
  111. def _register_genai_server_command(subparsers):
  112. # TODO: Register the subparser whether the plugin is installed or not
  113. try:
  114. from paddlex.inference.genai.server import get_arg_parser, run_genai_server
  115. except RuntimeError:
  116. return
  117. def _show_prompt_when_server_is_running(host, port, backend):
  118. if host == "0.0.0.0":
  119. host = "localhost"
  120. while True:
  121. try:
  122. resp = requests.get(f"http://{host}:{port}/health", timeout=1)
  123. if resp.status_code == 200:
  124. break
  125. except (requests.exceptions.ConnectionError, requests.exceptions.Timeout):
  126. pass
  127. time.sleep(1)
  128. prompt = f"""The PaddleOCR GenAI server has been started. You can either:
  129. 1. Set the server URL in the module or pipeline configuration and call the PaddleOCR CLI or Python API. For example:
  130. paddleocr doc_parser --input demo.png --vl_rec_backend {backend}-server --vl_rec_server_url http://{host}:{port}/v1
  131. 2. Make HTTP requests directly, or using the OpenAI client library."""
  132. logger.info(prompt)
  133. def _run_genai_server(args):
  134. Thread(
  135. target=_show_prompt_when_server_is_running,
  136. args=(args.host, args.port, args.backend),
  137. daemon=True,
  138. ).start()
  139. try:
  140. run_genai_server(args)
  141. except subprocess.CalledProcessError:
  142. sys.exit("Failed to run the server")
  143. paddlex_parser = get_arg_parser()
  144. subparser = subparsers.add_parser(
  145. "genai_server", parents=[paddlex_parser], conflict_handler="resolve"
  146. )
  147. subparser.set_defaults(executor=_run_genai_server)
  148. def _get_parser():
  149. parser = argparse.ArgumentParser(prog="paddleocr")
  150. parser.add_argument(
  151. "-v", "--version", action="version", version=f"%(prog)s {version}"
  152. )
  153. subparsers = parser.add_subparsers(dest="subcommand")
  154. _register_pipelines(subparsers)
  155. _register_models(subparsers)
  156. _register_install_hpi_deps_command(subparsers)
  157. _register_install_genai_server_deps_command(subparsers)
  158. _register_genai_server_command(subparsers)
  159. return parser
  160. def _execute(args):
  161. args.executor(args)
  162. def main():
  163. logger.setLevel(logging.INFO)
  164. warnings.filterwarnings("default", category=CLIDeprecationWarning)
  165. parser = _get_parser()
  166. args = parser.parse_args()
  167. if args.subcommand is None:
  168. parser.print_usage(sys.stderr)
  169. sys.exit(2)
  170. _execute(args)