Skip to content

Latest commit

 

History

7 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PP-OCRv6 Docker Image for RunPod Serverless

在 RunPod Serverless 上跑 PP-OCRv6 的 OCR 服务,支持图片和 PDF。

模型权重和 Paddle 运行时都在构建时烤进镜像,冷启动只付镜像拉取 + 进程启动的钱, 不会像动态安装方案那样每个新 worker 首次请求要等十分钟。

包含什么

  • 基础镜像nvidia/cuda:12.6.3-cudnn-runtime-ubuntu22.04,Paddle 从官方 wheel 装。 不用 paddlepaddle/paddle 官方镜像:那个镜像压缩后 12.6 GB,在 Serverless 上这不是 便利而是冷启动本身——worker 落到没缓存该镜像的节点时要把它整个拉一遍。
  • 模型PP-OCRv6_small_*PP-OCRv6_medium_* 两档都烤进镜像(合计 171 MB), 运行时可切换,不必为了对比重新构建
  • PDFpypdfium2 逐页渲染后 OCR,与桌面端 pdfium 同源;所有 pdfium 调用串行化 (见 pdf_input.py 顶部说明,这是防进程崩溃的必需品,不是保守起见)
  • 入口:标准 runpod.serverless.start

调用

输入接受 image_url / image_base64 / file_url / file_base64 / 裸 image, PDF 和图片走同一个入口,按内容的 magic bytes 自动分流。

# 图片
curl -X POST "https://api.runpod.ai/v2/$ENDPOINT_ID/run" \
  -H "Authorization: Bearer $RUNPOD_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"input": {"image_base64": "'"$(base64 -i page.png)"'"}}'

# PDF(同一个字段,直接塞 PDF 的 base64)
curl -X POST "https://api.runpod.ai/v2/$ENDPOINT_ID/run" \
  -H "Authorization: Bearer $RUNPOD_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"input": {"file_base64": "'"$(base64 -i doc.pdf)"'"}}'

返回:

{
  "markdown": "全文",
  "layout_json": [{"text": "...", "score": 0.99, "box": [...]}],
  "pages": [{"page_index": 0, "markdown": "...", "processing_ms": 472.07}],
  "meta": {
    "input_type": "pdf", "page_count": 4, "processing_ms": 1888.3,
    "total_ms": 2103.5, "worker_id": "...",
    "det_model": "PP-OCRv6_small_det", "pool_size": 8,
    "import_seconds": 6.1, "process_ready_seconds": 14.3
  }
}

单次请求覆盖检测参数

params 里的键会原样传给 PaddleOCR 的 predict(),只在这一次请求生效:

{"input": {"image_base64": "...", "params": {"text_det_box_thresh": 0.75}}}

支持 text_det_limit_side_lentext_det_limit_typetext_det_threshtext_det_box_threshtext_det_unclip_ratiotext_rec_score_thresh。 传别的键会报错而不是被忽略——调参脚本里打错一个键,应该看到错误,而不是默默测了两遍默认值。

环境变量

变量 默认 说明
OCR_DET_MODEL / OCR_REC_MODEL PP-OCRv6_small_det / _rec 两档权重都在镜像里,改这里即可切换
OCR_LIMIT_SIDE_LEN 960 检测阶段长边上限
OCR_LIMIT_TYPE max 上限作用于长边(min 则作用于短边)
OCR_REC_BATCH_SIZE 16 识别批大小
OCR_POOL_SIZE 8 单卡上的模型副本数,应与 CONCURRENCY 相同
CONCURRENCY 8 worker 内并发处理的请求数
OCR_INPUT_MAX_EDGE 1600 送进检测前先把图缩到这个长边(与桌面端渲染尺度一致)
OCR_INPUT_MAX_PIXELS 4000000 输入图超过 4MP 先等比缩小
OCR_INPUT_MODE ndarray ndarray 直接传数组;file 写 PNG 再传路径(对照用)
OCR_ALLOW_TUNE 0 允许运行时重建模型池,见下节。生产环境保持 0
PDF_MAX_EDGE 1600 PDF 页渲染的目标长边像素
PDF_MAX_PAGES 50 单个 PDF 最多处理多少页
MAX_INPUT_BYTES 10485760 输入大小上限(10MB)
OCR_DEVICE gpu:0 改成 cpu 可在无卡机器上调试

运行时重建模型池(调参用)

权重档位、识别批大小、池大小都是 PaddleOCR 构造期参数,按常规做法扫这些参数要 「改环境变量 → 等滚动更新 → 冷启动」,每个数据点一次冷启动。设 OCR_ALLOW_TUNE=1 后可以直接让热 worker 就地重建:

curl -X POST "https://api.runpod.ai/v2/$ENDPOINT_ID/run" \
  -H "Authorization: Bearer $RUNPOD_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"input": {"tune": {"det_model": "PP-OCRv6_medium_det",
                          "rec_model": "PP-OCRv6_medium_rec",
                          "pool_size": 8, "rec_batch_size": 2}}}'

只改 input_max_edge / input_max_pixels / input_mode 时不重建模型,下一次请求即生效。

这个开关会让任何调用方改变 worker 提供的服务,生产环境必须保持关闭。

本地调试

无 GPU 也能验证输入解析和 PDF 渲染逻辑:

python3 local_test.py path/to/file.pdf --no-ocr

About

Dockerfile for PP-OCRv6 medium OCR (image + PDF) on RunPod Serverless

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages