背景
ネットワーク>テンソルに、推論が続く、tensor-> numpy.ndarrayプロセスから、その後の結果 - 畳み込みニューラルネットワークのサーバ側は、多くの場合、CV2(numpy.ndarray)からの画像データを必要とする上でPythonのスクリプトが実行されます。
データの前に、フレームpytorch例に読み出しCV2のメモリに格納されたデータは、GPUデータ変換に送られるので、次のように生成されます。
、メモリ内に既にtorch.cuda.FloatTensorは、暗黙的にGPUメモリへのデータはGPU推論前に準備ができてダンプ、メモリ内のメモリダンプデータプロトコル方式.async_copy()関数を呼び出していない場合かどうかを決定しますこれは、多くの場合、時間のかかる部分が必要です。
ソリューション:GPUのビデオメモリに直接オープンスペース
図書館:cupy、dlpack
まず、前処理
次のように一般的に前処理をpytorch:
#メモリ空間に割り当てられたtorch.FloatTensor
batch_input = torch.zeros(LEN(IMAGE_LIST)、3、target_height、target_width)
範囲内のインデックスの(LEN(IMAGE_LIST)):
#イメージ - > numpy.ndarray
IMG = cv2.resize(IMAGE_LIST [インデックス] .copy()、(target_width、target_height))
#uint8->のfloat32
t_img = np.asarray(IMG、np.float32)
#転置
m_img = t_img.transpose((2、0、1))
#Numpy.ndarray-> torch.FloatTensor +画像正則
n_img =変換(torch.from_numpy(m_img))
#組成バッチデータ
batch_input [インデックス:] = n_img
#torch.FloatTensor-> torch.cuda.FloatTensor
batch_input.cuda()
GPUにこのバッチ場合は、図1発生に示すように、データ変換があろう。
アクティブcupyのnumpyの操作を交換するには:
CPとしてインポートcupy
#のGPUのメモリ空間に割り当てられたcupyのbatch_data
batch_input = cp.zeros((LEN(IMAGE_LIST)、3、target_height、target_width)、DTYPE = cp.float32)
範囲内のインデックスの(LEN(IMAGE_LIST)):
#イメージ - > cupy.ndarray
IMG = cv2.resize(IMAGE_LIST [インデックス]、(target_width、target_height))
#numpy.uint8 - > cupy.float32
t_img = cp.asarray(IMG、cp.float32)
#トランス(cupyレベル)
m_img = t_img.transpose((2、0、1))
#イメージ正則
n_img = gpu_transform(m_img)
#組成バッチデータ
batch_input [インデックス:] = n_img
#1 cupy.ndarray - > torch.cuda.FloatTensor
batch_data = from_dlpack(toDlpack(batch_input))。CUDA()
このとき、変換プロセスに:
ポイントのカップル:
1.1 cupy直接GPUメモリスペースを割り当てるため、暗黙的なコール.async_copy()はデータメモリに転送されず、比較して表示されます。
以下に示すように、送信前にGPU暗黙の呼び出し時間:
前に下記非GPU暗黙のコール転送時間:
直接変換、特に変換に続いて、中間dlpackを必要なフォーマット変換する方法torch.cuda.FloatTensor 1.2 cupy.ndarray
ROM cupy.core.dlpackインポートtoDlpack
cupy.core.dlpack輸入fromDlpackから
torch.utils.dlpack輸入to_dlpackから
torch.utils.dlpack輸入from_dlpackから
輸入トーチ鄭州婦人科病院http://www.sptdfk.com/
#tensor-> cupy
cupy_data = fromDlpack(to_dlpack(tensor_data))
#cupy->テンソル
tensor_data = from_dlpack(toDlpack(cupy_data))
1.3 pytorchフレームワーク、いくつかのプロジェクトは、他にはない、画像正則が必要です。必要に応じて画像の送信前に、ネットワークは、(典型的にはマイナス平均および分散添加)である場合、それは一般torchvision.transform使用されます。組み込み関数は、組み込み変換関数を使用することを意味だけtorch.FloatTensorのCPU側を、受け入れる。しかし、あなたは、データ変換が資源の浪費をもたらすためにバインドされ、CPU torch.FloatTensorにcupy GPUデータに有効にする必要があります。変換関数を書き直し:
self.mean = cp.array([102.9801、115.9465、122.7717])
self.std = cp.array([1、1、1])
デフgpu_transform(自己、IMG):
範囲内のインデックスの(img.shape [0]):
IMG [索引,:] - = self.mean [インデックス]
IMG [インデックス:] / = self.std [インデックス]
IMGを返します
上記のプロセスは、すべてのGPUで実行されている、時間はほとんど無視できます
第二に、後処理
このセクションでは、ネットワークを分割するために適用され、即ち、エンドGPUを分配空間以前に必要なマスクが生成されます。Torch.cuda.FloatTensor共通の練習スペース割り当て、GPUへの暗黙の呼び出し.async_copyは()、それはまた、多くの時間を消費します。前工程と同様に、マスクcupy空間、サブtorch.cuda.FloatTensorを生成するために利用することができます。
mask_gpu = from_dlpack(toDlpack(cp.zeros((LEN(IMAGE_LIST)、self.num_classes、ori_img_size [0]、ori_img_size [1])、DTYPE = cp.float32)))。CUDA()
pytorch配布マスク時間
cupy配布マスク時間
三、従来のコントラストによる治療前後のcupy時間