首先,我想提一下,这是我们第一个规模更大的项目,因此我们并不知道一切,但我们学得很快。
我们开发了一个用于图像识别的代码。我们用 raspberry pi 4b 进行了尝试,但很快就发现这是整体减慢速度的一种方式。目前我们使用的是 NVIDIA Jetson Nano。第一次识别没问题(大约 30 秒),第二次尝试更好(大约 6-7 秒)。第一次花了很长时间,因为模型将是第一次加载。通过 API 可以触发图像识别,来自 AI 模型的元数据将作为响应。我们为此使用快速 API。
但是现在有一个问题,如果我在分类文件的开头(在导入时加载)将我的 CNN 作为全局变量加载并在线程中使用它,我需要使用 mp.set_start_method('spawn') 否则我会收到以下错误:
“RuntimeError:无法在分叉子进程中重新初始化 CUDA。要将 CUDA 与多处理一起使用,您必须使用‘spawn’启动方法”
现在这当然很容易解决。只需在开始我的线程之前添加上面的方法。的确,这是可行的,但同时出现了另一个挑战。将启动方法设置为“生成”后,错误消失了,但 Jetson 开始分配大量内存。
由于开销和预加载的 CNN 模型,在线程启动之前 RAM 大约为 2.5Gig。启动后它不会停止分配 RAM,它会消耗所有 4Gig 的 RAM 以及整个 6Gig Swap。在此之后,整个 API 进程终止并出现此错误:“无法分配内存”,这是显而易见的。
我也设法通过在分类函数中加载 CNN 模型来解决这个问题。(不像之前的两种情况那样在 GPU 上预加载它)。但是,在这里我也遇到了问题。将模型加载到 GPU 的过程大约需要 15 秒到 20 秒,每次识别开始时都会如此。这不适合我们,我们想知道为什么在两次图像识别之后我们不能在不杀死整个事物的情况下预加载模型。我们的目标是控制在 5 秒以内。
#clasify
import torchvision.transforms as transforms
from skimage import io
import time
from torch.utils.data import Dataset
from .loader import *
from .ResNet import *
#if this part is in the classify() function than no allocation problem occurs
net = ResNet152(num_classes=25)
net = net.to('cuda')
save_file = torch.load("./model.pt", map_location=torch.device('cuda'))
net.load_state_dict(save_file)
def classify(imgp=""):
#do some classification with the net
pass
if __name__ == '__main__':
mp.set_start_method('spawn') #if commented out the first error ocours
manager = mp.Manager()
return_dict = manager.dict()
p = mp.Process(target=classify, args=('./bild.jpg', return_dict))
p.start()
p.join()
print(return_dict.values())
这里的任何帮助将不胜感激。谢谢你。