PaddleOCR-VL部署(cuda12.0/cuda12.1/cuda12.2、使用docker、服务端及客户端在同一容器、手动安装paddlepaddle、vlm服务端、flash_attn)
这里以Ubuntu22.04为例,所用cuda为12.0,若cuda为11.8或12.8,可直接使用官方方式安装
cuda12.1、12.2等其他版本也适用。
1. 创建并使用虚拟环境paddlevlm
conda activate paddlevlm
python -m pip install "paddleocr[doc-parser]"
pip install opencv-python-headless
paddleocr install_genai_server_deps vllm
注解:
paddleocr install_genai_server_deps 命令用法:
paddleocr install_genai_server_deps <推理加速框架名称>
当前支持的框架名称为 vllm 和 sglang,分别对应 vLLM 和 SGLang。
若您使用的是 NVIDIA 50 系显卡 (Compute Capability >= 12),需要在启动服务前安装指定版本的 FlashAttention:
python -m pip install flash-attn==2.8.3
通过 paddleocr install_genai_server_deps 安装的 vLLM 与 SGLang 均为 CUDA 12.8 版本,请确保本地 GPU 驱动与之兼容。
2. 安装flash_attn
paddleocr install_genai_server_deps vllm方法安装的flash_attn可能报错,也可能直接安装不上。(长时间没反应就是安装失败,它不会有提示,需要使用一个命令参数才会显示告诉你flash_attn安装失败了)
https://github.com/Dao-AILab/flash-attention
pip install flash_attn-2.8.3+cu12torch2.8cxx11abiFALSE-cp312-cp312-linux_x86_64 --no-build-isolation
3. 运行VLM
paddleocr genai_server --model_name PaddleOCR-VL-0.9B --backend vllm --port 8118
运行后会提示
Using official model (PaddleOCR-VL), the model files will be automatically downloaded and saved in `/root/.paddlex/official_models/PaddleOCR-VL`.
这是自动下载的模型路径,记得保存下来
该命令支持的参数如下:
| 参数 | 说明 |
|---|---|
| –model_name | 模型名称 |
| –model_dir | 模型目录 |
| –host | 服务器主机名 |
| –port | 服务器端口号 |
| –backend | 后端名称,即使用的推理加速框架名称,可选 vllm 或 sglang |
| –backend_config | 可指定 YAML 文件,包含后端配置 |
4. 测试VLM是否启动成功
curl -s -X POST "http://localhost:8118/v1/chat/completions" -H "Content-Type: application/json" -d '{"messages":[{"role":"user","content":"你好"}]}'
5. 部署PaddleOCR-VL客户端
创建新环境paddleocrvl,以防环境间影响而安装失败(我没试过,官方文档说服务端和客户端的依赖存在不兼容)
官方paddlepaddle在cuda12以上时只写了12.6、12.8,目前没找到12.0的,只能尝试11.8的
5.1 安装paddlepaddle
python -m pip install paddlepaddle-gpu==3.2.1 -i https://www.paddlepaddle.org.cn/packages/stable/cu118/
5.2 安装paddlex
python -m pip install paddlex
建议用下面这个,印象里上面这个报错缺少东西后我又安装了下面的
python -m pip install "paddlex[ocr]"
5.3 安装safetensors
python -m pip install https://paddle-whl.bj.bcebos.com/nightly/cu126/safetensors/safetensors-0.6.2.dev0-cp38-abi3-linux_x86_64.whl
5.4 安装服务化部署插件
paddlex --install serving
5.5 安装客户端插件
paddlex --install genai-client
5.6 获取产线配置文件并修改
paddlex --get_pipeline_config PaddleOCR-VL
VLRecognition:
...
genai_config:
backend: vllm-server
server_url: http://127.0.0.1:8118/v1
取消页数限制(默认10页PDF,在产线配置中添加配置,将 max_num_input_imgs 设置为 null 可解除页数限制。)
Serving:
extra:
max_num_input_imgs: <新的页数限制,例如 100>
调整并发(这部分我没调过)
PaddleOCR 会将来自单张或多张输入图像中的子图分组并对服务器发起并发请求,因此并发请求数对性能影响显著。
- 对 CLI 和 Python API,可通过 vl_rec_max_concurrency 参数调整最大并发请求数;
- 对服务化部署,可修改配置文件中 VLRecognition.genai_config.max_concurrency 字段。
当客户端与 VLM 推理服务为 1 对 1 且服务端资源充足时,可适当增加并发数以提升性能;若服务端需支持多个客户端或计算资源有限,则应降低并发数,以避免资源过载导致服务异常。
5.7 启动客户端
paddlex --serve --device gpu:0 --pipeline PaddleOCR-VL.yaml --port 21000
运行后会有:
/root/.paddlex/official_models/PP-DocLayoutV2
这是自动下载的权重位置,可在配置文件中用于下载直接加载,以取消下一次启动服务时判断
5.8 测试客户端
import base64
import requests
import pathlib
from time import time
API_URL = "http://localhost:21000/layout-parsing" # 服务URL
#API_URL = "http://172.17.0.5:8118/layout-parsing" # 服务URL
image_path = "1.png"
#image_path = "1.pdf"
# 对本地图像进行Base64编码
with open(image_path, "rb") as file:
image_bytes = file.read()
image_data = base64.b64encode(image_bytes).decode("ascii")
payload = {
"file": image_data, # Base64编码的文件内容或者文件URL
"fileType": 1, # 文件类型,0表示文件,1表示图像文件
'useLayoutDetection': False # 是否启用布局检测,图片一般不建议启用
#'useLayoutDetection': True
}
t1 = time()
# 调用API
response = requests.post(API_URL, json=payload)
t2 = time()
print(f"{t2-t1}s")
print(response)
# 处理接口返回数据
assert response.status_code == 200
result = response.json()["result"]
for i, res in enumerate(result["layoutParsingResults"]):
print(res["prunedResult"])
md_dir = pathlib.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)
img_path.write_bytes(base64.b64decode(img))
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"
pathlib.Path(img_path).parent.mkdir(exist_ok=True)
with open(img_path, "wb") as f:
f.write(base64.b64decode(img))
print(f"Output image saved at {img_path}")
6. 写一个启动脚本
echo "Activating conda environment: paddlevlm"
conda activate paddlevlm
echo "Starting PaddleOCR genai_server..."
paddleocr genai_server --model_name PaddleOCR-VL-0.9B --backend vllm --port 8118 --model_dir /root/.paddlex/official_models/PaddleOCR-VL > paddleocrvl-log.txt 2>&1 &
echo "Waiting 60 seconds for genai_server to initialize..."
sleep 60
echo "Switching to conda environment: paddleocrvl"
conda activate paddleocrvl
echo "Starting PaddleX serve..."
paddlex --serve --device gpu:0 --pipeline PaddleOCR-VL.yaml --port 21000 > paddleocrvl-log.txt 2>&1 &
echo "Both services started. Logs are being written to paddleocrvl-log.txt"
7. 测试
使用5.8的测试脚本即可,其它语言参考官方
https://www.paddleocr.ai/latest/version3.x/pipeline_usage/PaddleOCR-VL.html#42











