Repository navigation
Replies: 1 comment
|
The serving code does serialize calls by default: the flag defaults to Your lock covers the full shared-handle sequence: reshape, input copy, run, and output copy. Locking only It doesn't protect shared pipeline state outside that function. For the production check, compare request-tagged outputs against the serialized baseline using mixed image dimensions and multi-page PDFs. Successful HTTP responses alone won't catch results accidentally crossing between requests. Your short tests don't establish that the entire pipeline is safe to call concurrently. For parallel predictor execution, the Paddle Inference example gives each worker its own cloned predictor or PredictorPool entry. Adapting that to PaddleOCR-VL also requires isolating any shared pipeline state. Until that is checked, keeping the default serialization preserves the upstream execution behavior. |
Uh oh!
There was an error while loading. Please reload this page.
镜像 / 版本 / 硬件(生产与改造实例)
ccr-2vdh3abv-pub.cnc.bj.baidubce.com/paddlepaddle/paddleocr-vl:latest-nvidia-gpu-offlineccr-2vdh3abv-pub.cnc.bj.baidubce.com/paddlepaddle/paddleocr-genai-vllm-server:latest-nvidia-gpu-offline1. 问题背景
ZeroCopyTensor持有区导致的 tensor 内存损坏:pipeline.py:1179的cvworker 线程):PreconditionNotMetError: Tensor holds no memory. Call Tensor::mutable_data firstly. [Hint: holder_ should not be null.](dense_tensor_impl.cc:43),同族Tensor not initialized yet when DenseTensor::place()(:62)。free(): invalid pointer+SIGABRT(FatalError: Process abort signal),伴随vector<bool>::_M_range_check、(NotFound) Var(...) should not be nullptr等变体。ZeroCopyTensor持有器非线程安全;use_queues: True的 input/cv/vlm 多线程流水线与请求级并发叠加时,多个线程同时attach/copy_from_cpu/predictor.run()竞争同一持有器。2. A/B 测试结果
SERIAL=true,无锁)SERIAL=falseSERIAL=falseSERIAL=false+ predictor 加锁一些问题:
SERIAL=false(无锁):多请求真正并发,但触发静态图 predictor tensor 持有器竞态 → HTTP 500(并发 4 为 3 个 500,并发 2 出现过 SIGABRT 进程崩溃)。SERIAL=false+ predictor 加锁:在本次测试中并发成立且无崩溃,并发 1→8 平均延迟几乎不劣化(4.42→5.54s)。这是因为单次测试的文件较小,8份文件产生的chunk依旧能被vllm服务开的并发数吃下,对于解析出的chunk数更大的文件不会有什么加速效果。3. 我们尝试的方案
改动均在容器内文件:
给
paddle_static/runner.py的reshape / copy_from_cpu / run / copy_to_cpu加进程级锁/usr/local/lib/python3.10/site-packages/paddlex/inference/models/runners/paddle_static/runner.pythreading.Lock,并用with包住PaddleRunnerChainLegacy.__call__里真正碰 GPU tensor holder 的那一段,最小化锁粒度。Triton 动态批处理 / 多实例隔离」是不同路线。具体修改(diff)如下:
关闭文档级串行:
PADDLE_PDX_SERVING_SERIAL_PIPELINE_CALLS=false,让多请求并发进predict(),各自 layout → vLLM,交给 vLLM 自身的 continuous batching 排队批处理。重要说明:以上是我们为应对线上故障而做的 workaround,不确定是否符合社区推荐用法,也没有覆盖到多实例/多进程的社区方案,故提交此 issue 请社区确认。
4. 希望社区确认的问题
附录. 服务端崩溃日志(无锁 +
SERIAL=false)1. 主错误:
holder_ should not be null(sh 参数并发 4,logs/paddle-holder.log)同族变体:
Tensor not initialized yet when DenseTensor::place() ... holder_ should not be null(dense_tensor_impl.cc:62)。触发入口(
paddleocr_vl/pipeline.py的cvworker 线程):2. 进程级崩溃:
SIGABRT(并发 2,logs/paddle-error.log)崩溃前后的业务层 tensor 内存损坏变体:
All reactions