免费获取学习方案
ARTICLE DETAIL

资讯详情

深耕编程基础知识与建站技术分享的一线实战洞察。

PaddleOCR 产线多设备并行推理实战:从 device 多卡配置到多进程加速

PaddleOCR 产线多设备并行推理实战:从 device 多卡配置到多进程加速 PaddleOCR 产线多设备并行推理实战从 device 多卡配置到多进程加速【免费下载链接】PaddleOCRTurn any PDF or image document into structured data for your AI. A powerful, lightweight OCR toolkit that bridges the gap between images/PDFs and LLMs. Supports 100 languages.项目地址: https://gitcode.com/GitHub_Trending/pa/PaddleOCRPaddleOCR 3.x 的产线Pipeline体系为文档图像处理提供了两种并行推理路径一是内置的多设备并行推理通过--device gpu:0,1,2,3一条参数即可将输入分发到多块 GPU二是基于 Python 多进程自行封装产线调用的多卡 × 多实例方案适合追求更高吞吐的批处理场景。本文以 产线并行推理官方文档 为骨架结合 PaddleOCR 产线基类源码 与 测试用例 深入讲解两种方案的原理、完整可运行的示例代码与参数细节读完后你可以直接在自己的多卡服务器上搭建并行的 OCR / 版面解析批处理服务。一、为什么需要产线并行推理在 PaddleOCR 3.x 中单模型推理如文本检测、文本识别与产线推理如文档图像预处理、通用版面解析 v3走的是两套不同的封装单模型 Predictor以 PaddleXPredictorWrapper 为核心其 CLI 参数解析在 base.py 中固定传入allow_multiple_devicesFalse因此单模型只支持单个设备如gpu:0不提供多卡并行能力。产线 Pipeline以 PaddleXPipelineWrapper 为核心CLI 参数解析在 base.py 中传入allow_multiple_devicesTrue支持gpu:0,1,2,3这种多设备写法。当指定多个设备时产线初始化会在每个设备上分别创建一个底层产线类对象实例随后把接收到的输入并行分发到这些实例上进行推理。这正是本文要讲解的第一种并行方式内置多设备并行推理。它的核心价值是零改造——只要产线支持把device参数从gpu:0改成gpu:0,1,2,3即可获得多卡并行能力推理接口本身与单设备完全一致。二、方式一指定多个推理设备内置并行对于部分产线的 CLI 和 Python APIPaddleOCR 支持同时指定多个推理设备。以文档图像预处理产线DocPreprocessor为例2.1 CLI 命令行方式paddleocr doc_preprocessor \ --input input_images/ \ --device gpu:0,1,2,3 \ --use_doc_orientation_classify True \ --use_doc_unwarping True \ --save_path ./output2.2 Python API 方式from paddleocr import DocPreprocessor pipeline DocPreprocessor(devicegpu:0,1,2,3) output pipeline.predict( inputinput_images/, use_doc_orientation_classifyTrue, use_doc_unwarpingTrue)以上两个示例均使用 4 块 GPU编号为 0、1、2、3对input_images/目录下的图片进行并行推理。use_doc_orientation_classify控制是否启用文档方向分类use_doc_unwarping控制是否启用文档图像矫正二者在 DocPreprocessor.predict 中透传到底层产线对应源码中的_get_paddlex_config_overrides会将这些参数合并进 PaddleX 产线配置见 doc_preprocessor.py。2.3 device 参数的完整格式device参数支持以下写法来自 add_common_cli_opts 的参数说明写法含义cpu使用 CPUgpu默认使用 GPU 0可用时否则回退 CPUgpu:0使用单块 GPU 0gpu:0,1,2,3使用 4 块 GPU产线并行推理gpu:0,2使用 GPU 0 和 GPU 2可跳号npu/npu:0,1昇腾 NPU 设备同样支持多设备写法指定多个设备时推理接口仍然与指定单设备时保持一致产线初始化阶段会完成多实例创建predict/predict_iter的调用方式不变。注意并非所有产线都支持多设备并行推理。具体某一产线是否支持请以该产线的使用教程为准可通过paddleocr 子命令 --help查看--device的帮助文案多设备说明会明确写入其中。三、方式二多进程并行推理多卡 × 多实例内置的多设备并行推理对多数场景已经够用但如果你的任务是长时间批量处理整个目录的大量文件希望获得每块 GPU 上再叠加多个产线实例的更激进加速可以使用 Python 多进程对产线 API 进行封装实现多卡、多实例并行处理。3.1 完整示例脚本将以下脚本保存为infer_mp.pyimport argparse import sys from multiprocessing import Manager, Process from pathlib import Path from queue import Empty import paddleocr def load_pipeline(class_name: str, device: str): if not hasattr(paddleocr, class_name): raise ValueError(fClass {class_name} not found in paddleocr module.) cls getattr(paddleocr, class_name) return cls(devicedevice) def worker(pipeline_class_path, device, task_queue, batch_size, output_dir): pipeline load_pipeline(pipeline_class_path, device) should_end False batch [] while not should_end: try: input_path task_queue.get_nowait() except Empty: should_end True else: batch.append(input_path) if batch and (len(batch) batch_size or should_end): try: for result in pipeline.predict(batch): input_path Path(result[input_path]) if result.get(page_index) is not None: output_path f{input_path.stem}_{result[page_index]}.json else: output_path f{input_path.stem}.json output_path str(Path(output_dir, output_path)) result.save_to_json(output_path) print(fProcessed {repr(str(input_path))}) except Exception as e: print( fError processing {batch} on {repr(device)}: {e}, filesys.stderr ) batch.clear() def main(): parser argparse.ArgumentParser() parser.add_argument( --pipeline, typestr, requiredTrue, helpPaddleOCR pipeline, e.g. DocPreprocessor., ) parser.add_argument( --input_dir, typestr, requiredTrue, helpInput directory. ) parser.add_argument( --device, typestr, requiredTrue, helpSpecifies the devices for performing parallel inference., ) parser.add_argument( --output_dir, typestr, defaultoutput, helpOutput directory. ) parser.add_argument( --instances_per_device, typeint, default1, helpNumber of pipeline instances per device., ) parser.add_argument( --batch_size, typeint, default1, helpInference batch size for each pipeline instance., ) parser.add_argument( --input_glob_pattern, typestr, default*, helpPattern to find the input files., ) args parser.parse_args() input_dir Path(args.input_dir) if not input_dir.exists(): print(fThe input directory does not exist: {input_dir}, filesys.stderr) return 2 if not input_dir.is_dir(): print(f{repr(str(input_dir))} is not a directory., filesys.stderr) return 2 output_dir Path(args.output_dir) if output_dir.exists() and not output_dir.is_dir(): print(f{repr(str(output_dir))} is not a directory., filesys.stderr) return 2 output_dir.mkdir(parentsTrue, exist_okTrue) from paddlex.utils.device import constr_device, parse_device device_type, device_ids parse_device(args.device) if device_ids is None or len(device_ids) 1: print( Please specify at least two devices for performing parallel inference., filesys.stderr, ) return 2 if args.batch_size 0: print(Batch size must be greater than 0., filesys.stderr) return 2 with Manager() as manager: task_queue manager.Queue() for img_path in input_dir.glob(args.input_glob_pattern): task_queue.put(str(img_path)) processes [] for device_id in device_ids: for _ in range(args.instances_per_device): device constr_device(device_type, [device_id]) p Process( targetworker, args( args.pipeline, device, task_queue, args.batch_size, str(output_dir), ), ) p.start() processes.append(p) for p in processes: p.join() print(All done) return 0 if __name__ __main__: sys.exit(main())3.2 脚本工作机制拆解任务分发主进程使用multiprocessing.Manager().Queue()创建进程间共享的任务队列按input_glob_pattern匹配input_dir下的文件路径并全部入队支持后缀过滤如*.jpg。进程编排parse_device(args.device)将gpu:0,1,2,3解析为设备类型gpu与设备 ID 列表[0, 1, 2, 3]然后对每个设备 ID 创建instances_per_device个进程每个进程通过constr_device(device_type, [device_id])绑定到单个确定设备。这里的parse_device/constr_device来自 PaddleX 的设备工具模块用于设备字符串的解析与构造。Worker 消费每个 worker 进程内通过load_pipeline动态加载产线类getattr(paddleocr, class_name)从队列中批量取任务攒够batch_size或队列清空时调用pipeline.predict(batch)批量推理。结果保存遍历每条结果依据result[input_path]还原原始文件名若结果含page_index多页 PDF 场景输出文件命名为原文件名_页码.json否则为原文件名.json统一写入output_dir使用result.save_to_json()落盘。3.3 参数说明参数必填默认值说明--pipeline是无产线 Python 类名如DocPreprocessor、PPStructureV3。需确认该产线脚本方式的导入类名称例如通用版面解析 v3 产线对应PPStructureV3--input_dir是无输入图片目录需存在且为目录否则返回退出码 2--device是无多设备字符串如gpu:0,1,2,3至少指定两个设备否则报错退出--output_dir否output输出目录不存在时自动递归创建--instances_per_device否1每块设备上启动的产线实例进程数--batch_size否1每个产线实例单次推理的批量大小必须大于 0--input_glob_pattern否*匹配输入文件的 glob 模式如*.jpg、*.png3.4 调用示例假设将脚本存储为infer_mp.py以下是文档给出的两个典型调用# 确定 --pipeline 参数需查看其产线 **脚本方式** 导入类名称 # 此处为通用版面解析 v3 产线对应 PPStructureV3 # 处理 input_images 目录中所有文件 # 使用 GPU 0、1、2、3每块 GPU 上 1 个产线实例每个实例一次处理 1 个输入文件 python infer_mp.py \ --pipeline PPStructureV3 \ --input_dir input_images/ \ --device gpu:0,1,2,3 \ --output_dir output # 通用版面解析 v3 产线 # 处理 input_images 目录中所有后缀为 .jpg 的文件 # 使用 GPU 0、2每块 GPU 上 2 个产线实例每个实例一次处理 4 个输入文件 python infer_mp.py \ --pipeline PPStructureV3 \ --input_dir input_images/ \ --device gpu:0,2 \ --output_dir output \ --instances_per_device 2 \ --batch_size 4 \ --input_glob_pattern *.jpg第二个示例中GPU 0 和 GPU 2 各启动 2 个实例共 4 个 worker 进程并行消费队列每个实例每次批量处理 4 个文件适合大目录批处理的吞吐优化。四、两种并行方式的选型建议维度内置多设备并行方式一多进程并行方式二改造成本极低仅需修改device参数需要维护一段多进程脚本适用场景交互式推理、单次/少量输入目录级大批量、持续批处理任务实例粒度每设备 1 个产线实例每设备可叠多个实例instances_per_device批量能力取决于产线自身可显式控制batch_size攒批结果输出--save_path由产线统一保存每个结果单独save_to_json落盘如果只是临时用多卡跑一批文件优先选方式一如果是常驻的批处理流水线且单卡单实例无法吃满显存/算力可叠加方式二获得更充分的资源利用率。两种方式还可以组合使用——在多进程脚本中给每个 worker 的产线传入多设备参数实现进程 × 设备的多层并行。五、源码级机制与注意事项5.1 底层如何一参多卡从源码看产线包装类的初始化链路为PaddleXPipelineWrapper.__init__→parse_common_args解析 device 等公共参数 →_get_merged_paddlex_config合并产线默认配置与子类覆盖项如 DocPreprocessor 的配置覆盖 和 PPStructureV3 的配置覆盖→_create_paddlex_pipeline调用 PaddleX 的create_pipeline完成底层产线实例化见 base.py。多设备场景下PaddleX 会在每个指定设备上创建实例并对输入做并行推理因此 Python API 侧只需把devicegpu:0,1,2,3传入即可。CLI 侧则经由 PipelineCLISubcommandExecutor 注册--device等公共参数最终由 perform_simple_inference 统一完成初始化、迭代推理与res.save_all(save_path)保存。5.2 测试验证仓库在 tests/pipelines/test_doc_preprocessor.py 与 tests/pipelines/test_pp_structurev3.py 中分别对DocPreprocessor与PPStructureV3产线进行了端到端验证from paddleocr import DocPreprocessor / PPStructureV3确认这两个产线类可从paddleocr顶层导入——这正是多进程脚本中load_pipeline动态加载的前提。5.3 注意事项汇总--pipeline填的是脚本导入时的类名如DocPreprocessor、PPStructureV3而非 CLI 子命令名例如 CLI 子命令是pp_structurev3但脚本类名是PPStructureV3见 pp_structurev3.py。多进程脚本要求--device至少指定两个设备--batch_size必须大于 0否则脚本返回退出码 2。多页输入如 PDF的结果会带有page_index输出文件会以文件名_页码.json命名避免同页覆盖。内置多设备并行并非所有产线都支持使用前务必查阅目标产线的使用教程或其--help中--device的说明。单模型推理Predictor不提供多设备并行能力需要并行加速时应选用产线封装或自行做多进程编排。【免费下载链接】PaddleOCRTurn any PDF or image document into structured data for your AI. A powerful, lightweight OCR toolkit that bridges the gap between images/PDFs and LLMs. Supports 100 languages.项目地址: https://gitcode.com/GitHub_Trending/pa/PaddleOCR创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表