使用 vLLM 原生部署 PaddleOCR-VL:高性能、OpenAI 兼容的多模态 OCR 服务

序言

笔者此前曾撰写过一篇关于使用 Paddle 官方提供的 paddlex-genai-vllm-server 部署 PaddleOCR-VL 模型的文章,其中简要介绍了该模型的特性,并对比了其与 DeepSeek-OCR 的差异。

近期,笔者持续关注 vLLM 官方社区对 PaddleOCR-VL 的支持进展------社区已于 2025 年 10 月 30 日正式合并了对该模型的支持 PR。

因此,本文将介绍如何基于 vLLM 官方版本 直接部署 PaddleOCR-VL 模型。

💡 当前 vLLM 的代码同样支持 DeepSeek-OCR,用户可根据需求灵活选择。

介绍

PaddleOCR-VL 是一个专为文档解析设计的最先进(SOTA)且资源高效 的多模态模型。 其核心组件是 PaddleOCR-VL-0.9B ------ 一个紧凑而强大的视觉-语言模型(VLM),集成了基于 NaViT 风格的动态分辨率视觉编码器ERNIE-4.5-0.3B 语言模型,从而实现对文档中文字、表格、公式等元素的高精度识别。

部署

本文介绍两种部署方式:裸机部署与 Kubernetes(k8s)部署。

裸机部署

bash 复制代码
uv venv
source .venv/bin/activate

# v0.11.1 尚未正式发布,需安装 nightly 版本
uv pip install -U vllm \
    --pre \
    --extra-index-url https://wheels.vllm.ai/nightly \
    --extra-index-url https://download.pytorch.org/whl/cu129 \
    --index-strategy unsafe-best-match

⚠️ 注意:截至本文撰写时,vLLM v0.11.1 尚未发布,因此必须使用 nightly 构建版本以获得 PaddleOCR-VL 支持。

启动服务:

bash 复制代码
vllm serve PaddlePaddle/PaddleOCR-VL \
    --trust-remote-code \
    --max-num-batched-tokens 16384 \
    --no-enable-prefix-caching \
    --mm-processor-cache-gb 0

参数说明:

  • --trust-remote-code:因模型包含自定义代码,需显式启用。
  • --no-enable-prefix-caching:OCR 任务通常无重复前缀,关闭可节省显存。
  • --mm-processor-cache-gb 0:禁用多模态处理器缓存,适用于单次推理场景;若需高频调用,可适当调高此值。

Kubernetes(k8s)部署

在生产环境中,大多数场景采用 Kubernetes 进行部署。以下是基于 k8s 的部署方案。

1. 构建镜像

由于 v0.11.1 尚未正式发布,目前需通过源码构建镜像(也可关注官方 nightly 镜像):

bash 复制代码
git clone https://github.com/vllm-project/vllm.git
cd vllm
docker build -t vllm:latest-test -f docker/Dockerfile .

📌 待 v0.11.1 正式发布后,可直接使用官方 PyPI 或 Docker Hub 镜像,无需手动构建。

2. 创建 Deployment

yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: paddleocr-vl
  labels:
    app: paddleocr-vl
spec:
  replicas: 1
  selector:
    matchLabels:
      app: paddleocr-vl
  template:
    metadata:
      labels:
        app: paddleocr-vl
    spec:
      containers:
        - name: paddleocr-vl
          image: vllm:latest-test
          command: ["vllm"]
          args:
            - "serve"
            - "/models/PaddleOCR-VL"
            - "--served-model-name=PaddleOCR-VL"
            - "--host=0.0.0.0"
            - "--port=8000"
            - "--trust-remote-code"
            - "--revision=v1"
            - "--max-num-batched-tokens=16384"
            - "--no-enable-prefix-caching"
            - "--mm-processor-cache-gb=0"
          ports:
            - containerPort: 8000
              name: http
              protocol: TCP
          resources:
            limits:
              nvidia.com/gpu: 1
              memory: "16Gi"
              cpu: "4"
            requests:
              memory: "12Gi"
              cpu: "2"
              nvidia.com/gpu: 1
          readinessProbe:
            tcpSocket:
              port: 8000
            initialDelaySeconds: 60
            periodSeconds: 10
            failureThreshold: 5
          volumeMounts:
            - name: shm
              mountPath: /dev/shm
            - name: model-storage
              mountPath: /models/PaddleOCR-VL
      volumes:
        - name: shm
          emptyDir:
            medium: Memory
        - name: model-storage
          hostPath:
            path: /mnt/data/paddleocr-vl/models
            type: Directory

配置说明:

  • /models/PaddleOCR-VL:模型本地挂载路径,请根据实际环境调整。
  • --no-enable-prefix-caching:OCR 场景通常不需要前缀缓存,关闭可减少内存开销。
  • --mm-processor-cache-gb:控制多模态预处理缓存大小,设为 0 表示禁用。

🔔 建议在 GPU 节点上部署,并确保已安装 NVIDIA Device Plugin。

测试

测试用例参考自 vLLM 官方社区文档,代码如下:

python 复制代码
from openai import OpenAI

client = OpenAI(
    api_key="EMPTY",
    base_url="http://localhost:8000/v1",
    timeout=3600
)

# 任务类型提示词
TASKS = {
    "ocr": "OCR:",
    "table": "Table Recognition:",
    "formula": "Formula Recognition:",
    "chart": "Chart Recognition:",
}

messages = [
    {
        "role": "user",
        "content": [
            {
                "type": "image_url",
                "image_url": {
                    "url": "https://ofasys-multimodal-wlcb-3-toshanghai.oss-accelerate.aliyuncs.com/wpf272043/keepme/image/receipt.png"
                }
            },
            {
                "type": "text",
                "text": TASKS["ocr"]
            }
        ]
    }
]

response = client.chat.completions.create(
    model="PaddlePaddle/PaddleOCR-VL",
    messages=messages,
    temperature=0.0,
)
print(f"识别结果: {response.choices[0].message.content}")

✅ 该接口完全兼容 OpenAI 格式,可无缝集成到现有 AI 应用栈中。

总结

通过原生 vLLM 部署 PaddleOCR-VL 模型,具备以下显著优势:

  • OpenAI API 兼容 :自动提供 /v1/chat/completions 接口,可直接接入企业现有的 AI 网关(如 Kong、Traefik、自研网关等)。
  • 高性能推理 :依托 vLLM 的 PagedAttention、连续批处理(continuous batching)等优化技术,实现高吞吐、低延迟的 OCR 服务。
  • 灵活部署:支持裸机、Docker、Kubernetes 等多种部署形态,适配开发、测试与生产全链路。
  • 社区驱动:作为 vLLM 官方支持的模型,未来将持续获得性能优化与新功能更新。
相关推荐
aigcapi4 小时前
RAG 系统的黑盒测试:从算法对齐视角解析 GEO 优化的技术指标体系
大数据·人工智能·算法
上进小菜猪5 小时前
基于深度学习的河道垃圾检测系统设计(YOLOv8)
人工智能
上天夭5 小时前
模型训练篇
人工智能·深度学习·机器学习
小徐Chao努力5 小时前
【Langchain4j-Java AI开发】09-Agent智能体工作流
java·开发语言·人工智能
Blossom.1185 小时前
AI编译器实战:从零手写算子融合与自动调度系统
人工智能·python·深度学习·机器学习·flask·transformer·tornado
Coder_Boy_5 小时前
SpringAI与LangChain4j的智能应用-(理论篇2)
人工智能·spring boot·langchain·springai
却道天凉_好个秋5 小时前
OpenCV(四十八):图像查找
人工智能·opencv·计算机视觉
Coder_Boy_5 小时前
SpringAI与LangChain4j的智能应用-(理论篇3)
java·人工智能·spring boot·langchain
GetcharZp6 小时前
工地“火眼金睛”!手把手带你用 YOLO11 实现安全帽佩戴检测
人工智能·计算机视觉
Codebee6 小时前
Ooder A2UI架构白皮书
人工智能·响应式编程