PaddlePaddle / Paddle

PArallel Distributed Deep LEarning: Machine Learning Framework from Industrial Practice (『飞桨』核心框架,深度学习&机器学习高性能单机、分布式训练和跨平台部署)
http://www.paddlepaddle.org/
Apache License 2.0
22.13k stars 5.55k forks source link

多线程并发情况下时不时的出现这个问题: 概率15% (PreconditionNotMet) Tensor holds no memory. Call Tensor::mutable_data firstly. [Hint: holder_ should not be null.] (at ..\paddle\phi\core\dense_tensor_impl.cc:44) #64885

Open haike-1213 opened 4 months ago

haike-1213 commented 4 months ago

请提出你的问题 Please ask your question

多线程并发情况下时不时的出现这个问题: 概率15% (PreconditionNotMet) Tensor holds no memory. Call Tensor::mutabledata firstly. [Hint: holder should not be null.] (at ..\paddle\phi\core\dense_tensor_impl.cc:44)

wanghuancoder commented 4 months ago

你好,你的描述过于简单,我无法指导你调试。

  1. 你在什么场景下,运行多线程?训练?推理?什么模型?
  2. 运行前执行export FLAGS_call_stack_level=2可以看到更多崩溃信息。
haike-1213 commented 4 months ago

你好,你的描述过于简单,我无法指导你调试。

  1. 你在什么场景下,运行多线程?训练?推理?什么模型?
  2. 运行前执行export FLAGS_call_stack_level=2可以看到更多崩溃信息。

在这个方法上加了一个多线程 def extract_images(image_path): """ 图片文字提取 """ try: loader = UnstructuredImageLoader(image_path)

按页加载的序列

    docs = loader.load()
    log.info(f"图片解析成功 {image_path}")
    return docs[0]
except Exception as e:
    log.error(f"图片解析失败: {e}")
    return Document(page_content="", metadata={"source": image_path, "page": 0})
haike-1213 commented 4 months ago

用的这个模型 os.environ['OCR_AGENT'] = "unstructured.partition.utils.ocr_models.paddle_ocr.OCRAgentPaddle"

haike-1213 commented 4 months ago

报错: index 143 is out of bounds for axis 0 with size 143

wanghuancoder commented 4 months ago

这个多线程看起来是你自己代码里的多线程,并不是Paddle的多线程。也没有用多线程执行Paddle代码。只是用多线程在加载图片。所以你还是要考虑你自己代码多线程多临界区处理的问题。

wanghuancoder commented 4 months ago

Paddle的DataLoader不能使用多线程。要使用多进程。通过设置多个worker,多进程加载数据。

haike-1213 commented 4 months ago

我用的这个 with ThreadPoolExecutor(max_workers=max_workers) as executor:

使用submit()将每个图像路径作为一个任务提交到线程池

            future_to_image = {}
            for path in self.dir['image_paths']:
                # 提交任务并存储到字典中  任务已经提交到线程池
                future = executor.submit(process_image, path[0], path[1], self.file_path)
                future_to_image[future] = path
            log.info(f"页数{len(self.dir['image_paths'])} 等待提取图片信息 {future_to_image}")
            # 使用as_completed()获取完成的任务结果
            Documents = []
            for future in concurrent.futures.as_completed(future_to_image):
                image_path = future_to_image[future]
                try:
                    result = future.result()
                    Documents.append(result)
                except Exception as exc:
                    log.error(f'Failed to process image {image_path}: {exc}')
haike-1213 commented 4 months ago

Paddle的DataLoader不能使用多线程。要使用多进程。通过设置多个worker,多进程加载数据。

是lanchain的一个图片识别方法 UnstructuredImageLoader 使用多线程调用这个, 这个方法里面调用的是飞桨

wanghuancoder commented 4 months ago

这个你还是要考虑使用多进程~

Tpinion commented 2 months ago

我也遇到了相同的问题,感觉应该不是算法层面的错误。因为仅在线上高负载的环境下稳定复现。线下的并发测试,并没有发现问题,可能是压力还没上足。

我是把PaddleOCR又做了一层线程安全的单例的封装。我本来以为是,Paddle设置的可用显存低了。

请问,从问题的大方向上来说,这个错可以归类为,线程级的高并发导致的吗?

因为,如果我在问题大方向上的判断没问题,我可以先通过简单扩容我的服务进程来解决。

loneWolf1127 commented 2 months ago

@wanghuancoder 你好,多线程,单GPU卡,每个线程单独执行 PaddleOCR(use_gpu=True, lang='en'),模型数据是会被重复加载的吧?