PaddleX
PaddleX copied to clipboard
C# 两个线程不同时调用同一个模型推理报错,第一个线程用后,第二个线程无法使用?
问题类型:其它
PaddleX版本
您使用的PaddleX版本
2.0.0
问题描述
如题
是否有初始化两个实例(比如初始化两个model, 一个线程使用一个model实例)? 多线程情况下,如果只有一个推理实例,一次只有一个线程能调用该实例(不能有多个线程访问同一个实例)。
两个线程一个model,但是线程1调用时,线程2不用。不会出现冲突的问题。有办法解决这个问题吗?不然调试起来太麻烦。因为我们自动运行是一个线程,调试是一个线程
您好,请问您这个问题解决了吗?我也遇到同样的问题。
@heliqi 按这个说法,意思是每个model得绑定到一个固定线程去吗?Code-WHappy的应用场景其实已经是单线程访问了,只不过是多个线程分时访问同一个模型,如果这样无法支持,就只能理解为一个model得绑定到一个线程了。
但这样就太方便了,多个线程分时访问的需求太多了,难道没有解决方案吗?
还没有解决,官方还没给出解决方案
这是最终定位到的错误
- 可以分时调用,必须要加锁,保证多个线程不能同时访问同一个实例
- 需要使用线程池或者让线程while住,一直保持存在(也就是线程id一直不变)。线程不能不断创建销毁,否则会引发底层cuda问题
@ximitiejiang
推荐使用这个pr里的线程池:https://github.com/PaddlePaddle/PaddleX/pull/1179 对c++的dll接口进行封装,线程池使用参照multi_thread_infer2.cpp。 c#端调用初始化函数初始化model和线程池,推理时只需要调用submit函数(也可再封装这个接口)提交多线程任务即可
我看了下你们这个multi_thread_infer2.cpp,这是推理的时候多线程同时推理,然后再合并结果。我们需要的是,一个推理一个线程即可,但是需要在线程ID变化的情况下也能用。也就是说线程1调用后,线程2在调用也可以
你看错demo了吧? multi_thread_infer2.cpp这个例子,你改成只初始化model1, 然后调用下面的语句不就是你想要的两次调用么?我怀疑你看到的是multi_thread_infer.cpp的例子,这个针对batch的,所以才会合并结果。 auto future1 = pool.submit(infer, model1, ref(imgs), &results1, 1); auto future2 = pool.submit(infer, model1, ref(imgs), &results2, 1); future1.get(); std::cout << "result1:" << results1[0] << std::endl;
future2.get(); std::cout << "result1:" << results2[0] << std::endl;
是否有初始化两个实例(比如初始化两个model, 一个线程使用一个model实例)? 多线程情况下,如果只有一个推理实例,一次只有一个线程能调用该实例(不能有多个线程访问同一个实例)。
你好,我最近用多个线程调用不同的模型,但是还是会出现线程冲突的情况,我把model_infer.dll更改名字都不行。也已经实例化了多个model。引用代码如下: class Classify { [DllImport("model_infer.dll", EntryPoint = "InitModel")] // Model unified initialization method: need yml、pdmodel、pdiparams public static extern IntPtr InitModel(string model_filename, string params_filename, string cfg_file, bool use_gpu);
[DllImport("model_infer.dll", EntryPoint = "Cls_ModelPredict")] // PaddleClas Model reasoning method
public static extern void Cls_ModelPredict(IntPtr model, IntPtr img, int W, int H, int C, ref float score, ref byte category, ref int category_id);
[DllImport("model_infer.dll", EntryPoint = "DestructModel")] // Segmentation, detection, identification model destruction method
public static extern void DestructModel(IntPtr model);
}
推测model_infer.dll会引用paddle_inference.dll的网络,导致同时访问的时候冲突。 用线程池并不能解决我的需求: 第一,我用多线程是为了加快处理速度 第二,我各个线程的模型不尽相同 这个如何解决?