PaddleOCR-VL 高性能服务化部署(HPS)实战指南:FastAPI + Triton + vLLM 架构解析与并发调优
PaddleOCR-VL 高性能服务化部署HPS实战指南FastAPI Triton vLLM 架构解析与并发调优【免费下载链接】PaddleOCR飞桨多语言OCR工具包实用超轻量OCR系统支持80种语言识别提供数据标注与合成工具支持服务器、移动端、嵌入式及IoT设备端的训练与部署 Awesome multilingual OCR toolkits based on PaddlePaddle (practical ultra lightweight OCR system, support 80 languages recognition, provide data annotation and synthesis tools, support training and deployment among server, mobile, embedded and IoT devices)项目地址: https://gitcode.com/paddlepaddle/PaddleOCRPaddleOCR-VL 系列含PaddleOCR-VL、PaddleOCR-VL-1.5、PaddleOCR-VL-1.6是飞桨 OCR 工具包中的文档智能DocVLM管线。为了支撑文档解析类业务的高并发请求仓库在 deploy/paddleocr_vl_docker/hps 目录下提供了**高性能服务化部署High-Performance ServingHPS**方案以 FastAPI 网关统一收口外部调用以 Triton 承载版面分析模型与管线编排以 vLLM 承载 VLM 连续批处理推理。阅读本文后你将掌握该方案的架构组成、容器化快速启动流程、全部环境变量与管线配置项以及并发数、动态批处理、实例数等关键性能参数的调优方法和常见故障排查手段。方案概览与适用场景该方案面向需要将 PaddleOCR-VL 文档解析能力以服务形式对外开放的生产场景核心诉求是统一接入点客户端只需面对一个 FastAPI 网关无需感知内部 Triton 与 vLLM 的差异并发控制网关对推理类与非推理类请求分别做信号量限流避免下游被压垮吞吐与延迟可控借助 Triton 的动态批处理与 vLLM 的连续批处理在单卡上尽量榨取推理设备利用率。需要特别说明的是该方案目前仅支持 NVIDIA GPU其他推理设备的支持仍在开发中见 README_en.md如需 AMD GPU、华为昇腾 NPU、寒武纪、海光 DCU 等加速卡方案可参考同目录上级 deploy/paddleocr_vl_docker/accelerators 下对应的 Dockerfile 与 compose 文件。架构Client → FastAPI Gateway → Triton Server → vLLM Server整体请求链路如下Client → FastAPI Gateway → Triton Server → vLLM Server三个组件的职责划分对应 README_en.md 中的架构表组件职责FastAPI Gateway统一接入点简化客户端调用负责并发控制与超时管理Triton Server运行版面分析模型如 PP-DocLayoutV3与管线编排负责模型管理、动态批处理、推理调度vLLM Server承载 VLM视觉语言模型提供连续批处理continuous batching推理Triton 内置两个模型模型部署设备说明layout-parsing推理设备如 GPU版面解析推理restructure-pagesCPU多页结果后处理跨页表格合并、标题层级重排值得注意的是两个模型“一 GPU 一 CPU”的分工layout-parsing消耗 GPU 资源属于推理类操作restructure-pages不消耗推理设备资源属于非推理类操作。这一区分直接决定了后文并发参数的独立设计。从仓库源码可以印证网关的实现细节。网关应用位于 gateway/app.py通过triton_grpc_aio.InferenceServerClient建立到 Triton 的异步 gRPC 连接app.state.triton_client并在应用生命周期lifespan启动/关闭时初始化和清理用两个独立的asyncio.Semaphore分别约束推理类与非推理类请求的并发上限app.state.inference_semaphore与app.state.non_inference_semaphore对外暴露/layout-parsing与/restructure-pages两个 POST 接口分别转发到 Triton 的对应模型且各自复用对应的信号量。环境要求开始部署前请确认宿主机满足以下条件来源README_en.md 的 Requirements 一节x64 CPUNVIDIA GPUCompute Capability ≥ 8.0 且 10.0即 Ampere 及之后的消费级/专业级卡型不含 Blackwell 上限外的早期架构NVIDIA 驱动支持 CUDA 12.6Docker ≥ 19.03Docker Compose ≥ 2.0。其中 Compute Capability 与 CUDA 版本约束对应了基础镜像paddlex{hps_paddlex_version}-gpu的运行时要求GPU 通过 compose 的deploy.resources.reservations.devices以 NVIDIA Container Toolkit 方式挂载进容器。快速启动第一步克隆仓库并进入目录git clone https://github.com/PaddlePaddle/PaddleOCR.git cd PaddleOCR/deploy/paddleocr_vl_docker/hps第二步准备必要文件cp .env.example .env # 如需切换 PaddleOCR-VL 版本编辑 .env 中的 HPS_PIPELINE_NAME bash prepare.shprepare.shprepare.sh会完成三件事下载高稳定性 Serving SDK从paddle-model-ecology.bj.bcebos.com拉取${HPS_SDK_DIR}.tar.gz归档并解压SDK 目录遵循paddlex_hps_${HPS_PIPELINE_NAME}_sdk命名改写 Triton 管线配置在解压出的server/pipeline_config.yaml中若检测到backend: native则自动替换为backend: vllm-server并写入server_url: ${HPS_VLM_URL}/v1从而让 Triton 管线把 VLM 部分代理到独立的 vLLM 服务回写环境变量把HPS_PIPELINE_NAME、HPS_SDK_DIR、HPS_VLM_URL写回.env保证后续 compose 启动时参数一致。从源码看prepare.sh还会通过_extract_vlm_name从pipeline_config.yaml的module_name: vl_recognition段中解析出 VLM 的model_name该名称将用于 vLLM 服务的启动参数见下文genai_server_entrypoint.sh。第三步启动服务docker compose up该命令将按依赖顺序启动 3 个容器服务名说明端口paddleocr-vl-apiFastAPI 网关外部入口8080paddleocr-vl-pipeline运行管线的 Triton 推理服务8000内部paddleocr-vlm-server基于 vLLM 的 VLM 推理服务8080内部首次启动会自动下载并构建镜像耗时较长后续启动会复用本地镜像速度更快。从 compose.yaml 可以看到容器间的依赖关系与健康检查paddleocr-vl-api依赖paddleocr-vl-pipeline的service_healthy状态健康检查命中网关/healthpaddleocr-vl-pipeline依赖paddleocr-vlm-server的service_healthy状态vLLM 服务健康检查命中其/healthstart_period为 300s因 VLM 加载较慢Triton 容器自身的健康检查为http://localhost:8000/v2/health/readystart_period为 60s管线容器设置了shm_size: 4gb默认值OOM 排查时会再提到。三个容器的构建方式也可以从 Dockerfile 确认gateway.Dockerfile 基于python:3.10-slim安装gateway/requirements.txt中的fastapi0.123.6、uvicorn0.35.0与paddlex[serving]3.4.0并通过--mounttypebind把 SDK 的client目录挂入构建上下文安装paddlex_hps_clientwheel 作为 Triton 客户端依赖最终以uvicorn --host 0.0.0.0 --port 8080 --workers ${HPS_UVICORN_WORKERS} app:app启动pipeline.Dockerfile 基于ccr-2vdh3abv-pub.cnc.bj.baidubce.com/paddlex/hps:paddlex${HPS_PADDLEX_VERSION}-gpu基础镜像把 SDK 的server目录拷入/app并通过PADDLEX_HPS_DEVICE_TYPE环境变量声明设备类型最后执行server.shpaddleocr-vlm-server使用镜像paddlepaddle/paddleocr-genai-vllm-server:latest-nvidia-gpu将 SDK 内的server/pipeline_config.yaml只读挂载为/config/pipeline_config.yaml入口脚本为 genai_server_entrypoint.sh —— 它同样解析 VLM 的model_name然后执行exec paddleocr genai_server \ --model_name $VLM_NAME \ --host 0.0.0.0 \ --port 8080 \ --backend vllm即 vLLM 服务端以paddleocr genai_server命令、--backend vllm方式拉起。配置详解环境变量总览复制.env.example为.env后按需修改cp .env.example .env你也可以不使用.env文件而是直接以环境变量的方式注入例如export HPS_MAX_CONCURRENT_INFERENCE_REQUESTS8管线与 SDK 配置以下变量用于选择 PaddleOCR-VL 系列的具体发布版本。修改后需要重新运行prepare.sh并重建镜像本方案复用了 PaddleX 的高稳定性 ServingHigh-Stability ServingSDK作为 Triton 模型仓库基底与客户端依赖并在其上叠加了 PaddleOCR-VL 专属的 FastAPI 网关与 vLLM 服务编排。变量默认值说明HPS_PIPELINE_NAMEPaddleOCR-VL-1.6管线名称HPS_PADDLEX_VERSION3.6PaddleX 版本仅取 major.minor如3.6。该变量同时驱动 Triton 基础镜像 tagpaddlex${HPS_PADDLEX_VERSION}-gpu与 SDK 发布目录v${HPS_PADDLEX_VERSION}保证两者同步HPS_SDK_DIRpaddlex_hps_PaddleOCR-VL-1.6_sdkSDK 解压目录遵循paddlex_hps_${HPS_PIPELINE_NAME}_sdk常见版本组合目标发布版HPS_PIPELINE_NAMEHPS_SDK_DIRPaddleOCR-VL-1.6PaddleOCR-VL-1.6paddlex_hps_PaddleOCR-VL-1.6_sdkPaddleOCR-VL-1.5PaddleOCR-VL-1.5paddlex_hps_PaddleOCR-VL-1.5_sdkPaddleOCR-VLv1PaddleOCR-VLpaddlex_hps_PaddleOCR-VL_sdk结合 prepare.sh 源码可以看到SDK 下载 URL 的组装方式为SDK_URLhttps://paddle-model-ecology.bj.bcebos.com/paddlex/PaddleX3.0/deploy/paddlex_hps/public/sdks/v${HPS_PADDLEX_VERSION}/${HPS_SDK_DIR}.tar.gz因此HPS_PADDLEX_VERSION直接决定了从哪个 SDK 发布目录下载修改版本后 SDK 目录名也要一并调整这正是HPS_SDK_DIR存在的意义。网关与设备配置变量默认值说明HPS_MAX_CONCURRENT_INFERENCE_REQUESTS16最大并发推理请求数版面解析HPS_MAX_CONCURRENT_NON_INFERENCE_REQUESTS64最大并发非推理请求数页面重组HPS_INFERENCE_TIMEOUT600请求超时秒HPS_HEALTH_CHECK_TIMEOUT5健康检查超时秒HPS_VLM_URLhttp://paddleocr-vlm-server:8080VLM 服务地址HPS_LOG_LEVELINFO日志级别DEBUG、INFO、WARNING、ERRORHPS_FILTER_HEALTH_ACCESS_LOGtrue是否过滤健康检查访问日志HPS_UVICORN_WORKERS4网关 Worker 进程数HPS_DEVICE_ID0使用的推理设备 ID这些变量在 gateway/app.py 中均有对应的os.getenv读取逻辑含默认值并与 compose.yaml 中environment段的${VAR:-default}写法一一对应。其中HPS_DEVICE_ID通过device_ids: [${HPS_DEVICE_ID:-0}]同时作用于 Triton 与 vLLM 两个 GPU 容器。管线配置如需调整管线配置如模型路径、batch size、部署设备等请参考仓库内的PaddleOCR-VL 使用教程管线配置章节见 docs/version3.x/pipeline_usage/PaddleOCR-VL.en.md中文版见 docs/version3.x/pipeline_usage/PaddleOCR-VL.md。Triton 侧的具体模型参数max_batch_size、instance_group则通过 SDK 模型仓库中每个模型目录下的config.pbtxt控制详见下文“性能调优”。API 使用文档解析服务的调用方式与 PaddleOCR-VL 使用教程中的**客户端调用Client-Side Invocation**一致参见 docs/version3.x/pipeline_usage/PaddleOCR-VL.en.md。服务接受PDF 或图片文件包括TIFF格式多页 TIFF 会逐页处理此时需使用fileType1。健康检查网关提供两个健康检查端点# 存活检查Liveness网关进程是否存活 curl http://localhost:8080/health # 就绪检查ReadinessTriton 与 VLM 服务是否已就绪、可处理请求 curl http://localhost:8080/health/ready两者的语义差异可以从 gateway/app.py 的实现看出/health仅返回AIStudioNoResultResponse(0, Healthy)代表网关进程自身存活/health/ready会依次检查 Triton 服务器就绪状态is_server_ready、layout-parsing与restructure-pages两个模型是否就绪is_model_ready并异步请求 VLM 服务的/health通过_check_vlm_ready受HPS_HEALTH_CHECK_TIMEOUT约束任一环节失败都会返回 503超时返回 504。这就是 compose 中容器healthcheck以及 Kubernetes 类平台探针可以直接复用的两个端点。性能调优并发设置网关对推理类与非推理类操作的并发是独立控制的这是本方案最重要的调优维度HPS_MAX_CONCURRENT_INFERENCE_REQUESTS默认 16控制layout-parsing版面解析这类推理操作的并发。过低如 4推理设备利用率不足请求无谓排队过高如 64可能压垮 Triton导致 OOM 或超时默认值 16在当前批次处理期间允许足够多的请求排队以凑齐下一批动态批处理若推理设备资源紧张应适当调低。HPS_MAX_CONCURRENT_NON_INFERENCE_REQUESTS默认 64控制restructure-pages页面重组这类非推理操作的并发。非推理操作不消耗推理设备资源可以设置更高的并发依据 CPU 核数与可用内存进行调整。实现层面这两个上限正是 gateway/app.py 中两个独立asyncio.Semaphore的容量请求在async with semaphore:块内被限流超限请求会等待而不是被直接拒绝。高吞吐配置示例适合批量文档解析、对时延不敏感# .env HPS_MAX_CONCURRENT_INFERENCE_REQUESTS32 HPS_MAX_CONCURRENT_NON_INFERENCE_REQUESTS128 HPS_UVICORN_WORKERS8低延迟配置示例适合交互式/准实时场景# .env HPS_MAX_CONCURRENT_INFERENCE_REQUESTS8 HPS_MAX_CONCURRENT_NON_INFERENCE_REQUESTS32 HPS_INFERENCE_TIMEOUT300 HPS_UVICORN_WORKERS2Worker 进程数每个 Uvicorn Worker 是拥有独立事件循环的独立进程启动命令见 gateway.Dockerfile 的CMD uvicorn ... --workers ${HPS_UVICORN_WORKERS} app:app1 个 Worker简单直接但只有单进程能力4 个 Worker适合大多数场景默认值8 个 Worker适合小请求多、高并发的场景。需要说明的是由于并发上限由进程内的信号量控制增加 Worker 数量相当于放大了整体并发窗口因此调高HPS_UVICORN_WORKERS时应同步评估下游 Triton 的承受能力。Triton 动态批处理Triton 会自动对到达的请求做批处理以提升推理设备利用率。最大批大小由模型配置文件中的max_batch_size参数控制默认8该文件位于模型仓库中每个模型目录下的config.pbtxt例如model_repo/layout-parsing/config.pbtxt动态批处理的作用是当并发请求到达时Triton 会把这些请求合并成一个 batch 并行执行从而摊薄 kernel 启动与调度开销。Triton 实例数每个 Triton 模型的并行推理实例数通过config.pbtxt的instance_group段配置默认1。增加实例数可提高并行度但会消耗更多设备资源。示例# model_repo/layout-parsing/config.pbtxt instance_group [ { count: 1 # 实例数提高并行度可调大 kind: KIND_GPU gpus: [ 0 ] } ]实例数与动态批处理之间存在权衡单实例count: 1动态批处理把多个请求合并为一个 batch 并行执行但同一 batch 内的所有请求都必须等待最慢的那个完成后才能返回可能增加较快请求的延迟此外单个实例同一时刻只能处理一个 batch后续请求必须排队直到当前 batch 完成。最适合 GPU 显存有限、或各请求处理时间相近的场景多实例count: 2多个实例可以同时处理不同的 batch容纳更多请求并发减少排队时间、改善单请求延迟。需要注意每个实例内部依然遵循动态批处理行为同 batch 的请求同时开始、同时结束。同时每增加一个实例都会额外占用一份版面分析模型的 GPU 显存、加大 VLM 推理服务的负载并消耗更多 CPU 与系统内存需要根据推理设备的实际资源调整。对于非推理模型如restructure-pages它运行在 CPU 上实例数可以依据可用 CPU 核数适当增加。故障排查与解决服务启动失败逐个查看各服务的日志定位问题docker compose logs paddleocr-vl-api docker compose logs paddleocr-vl-pipeline docker compose logs paddleocr-vlm-server常见原因包括端口冲突、推理设备不可用、镜像拉取失败。从 compose.yaml 可以看出三个服务都配置了restart: unless-stopped与各自的healthcheck因此如果容器反复重启或长时间处于 unhealthy优先结合docker compose ps观察健康状态再配合上述日志定位根因。超时错误增大HPS_INFERENCE_TIMEOUT适用于复杂文档单请求处理时间较长的场景降低HPS_MAX_CONCURRENT_INFERENCE_REQUESTS适用于推理设备过载、请求排队挤压导致超时的场景。在 gateway/app.py 中超时同时体现在两个层面网关侧triton_request_async(..., timeoutINFERENCE_TIMEOUT)的超时上限以及 gRPC 连接层的keepalive_timeout_msINFERENCE_TIMEOUT * 1000Triton 侧返回 “Deadline Exceeded” 时同样会映射为 504 响应。内存不足OOM降低HPS_MAX_CONCURRENT_INFERENCE_REQUESTS减少同时在途请求对显存/内存的占用确保每台推理设备上只运行一个服务避免多套服务争抢同一设备检查compose.yaml中的shm_size默认4GB必要时调大/dev/shm容量以满足大批量输入的处理需求。小结PaddleOCR-VL 高性能服务化方案通过“FastAPI 网关 Triton 管线 vLLM VLM”的三层架构把文档解析能力封装为对外统一、内部可独立扩缩容的高并发服务。本文覆盖了从环境准备、prepare.shSDK 准备、docker compose up三容器启动到版本切换HPS_PIPELINE_NAME/HPS_PADDLEX_VERSION/HPS_SDK_DIR、并发与批处理调优、健康检查与故障排查的完整链路。相关实现细节可直接在仓库中继续深入网关实现deploy/paddleocr_vl_docker/hps/gateway/app.py编排文件deploy/paddleocr_vl_docker/hps/compose.yamlSDK 准备脚本deploy/paddleocr_vl_docker/hps/prepare.sh构建文件gateway.Dockerfile、pipeline.DockerfilevLLM 启动脚本deploy/paddleocr_vl_docker/hps/genai_server_entrypoint.shPaddleOCR-VL 使用教程管线配置与客户端调用docs/version3.x/pipeline_usage/PaddleOCR-VL.en.md【免费下载链接】PaddleOCR飞桨多语言OCR工具包实用超轻量OCR系统支持80种语言识别提供数据标注与合成工具支持服务器、移动端、嵌入式及IoT设备端的训练与部署 Awesome multilingual OCR toolkits based on PaddlePaddle (practical ultra lightweight OCR system, support 80 languages recognition, provide data annotation and synthesis tools, support training and deployment among server, mobile, embedded and IoT devices)项目地址: https://gitcode.com/paddlepaddle/PaddleOCR创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考