我们有一个处理图像的代码,其中涉及运行MTCNN和Inception Resnet。
由于我们有数百万个图像,因此我们希望将任务与Dask并行化。我们的问题是,尽管我们设法在图像的子集上运行代码-但在进行扩展(以在具有大量数据的Yarn Cluster
上运行)时,代码崩溃了。
我们尝试以各种方式配置Client
,但找不到正确的配置。
我们的图像存储在实木复合地板文件中(这就是我们收到它们的方式)。波纹管是在客户端上下文管理器中运行的代码:
def hex_to_img(hex_data: str) -> Image:
try:
bin_data = bytes.fromhex(hex_data)
stream = io.BytesIO(bin_data)
img = Image.open(stream).convert('RGB')
except:
img = np.NaN
return img
def get_mtcnn_resnet() -> tuple:
import os
from facenet_pytorch import MTCNN, InceptionResnetV1
os.environ['TORCH_HOME'] = '/opt/data/torch_home' # Yes - this is a local path
device = torch.device('coda:0' if torch.cuda.is_available() else 'cpu')
mtcnn = MTCNN(
image_size=160, margin=0, min_face_size=20,
thresholds=[0.6, 0.7, 0.7], factor=0.709, post_process=True,
device=device
)
resnet = InceptionResnetV1(pretrained='vggface2').eval().to(device)
return mtcnn, resnet
mtcnn, resnet = get_mtcnn_resnet()
def pipeline(path: str):
df = dd.read_parquet(path, engine='pyarrow')
df = dd.concat([df.get_partition(i) for i in range(5)]) # Without this line the code crashes
df = df.assign(Image=df['ImageHex'].map(hex_to_img, meta=('Image', object))).drop('ImageHex', axis=1)
df = df[~df['Image'].isna()]
df = df.assign(MTCNN=df['Image'].map(mtcnn, meta=('MTCNN', object))).drop('Image', axis=1)
df = df[~df['MTCNN'].isna()]
df = df.assign(Embedding=df['MTCNN'].map(lambda x: resnet(torch.stack([x])).detach().numpy(), meta=('Embedding', object))).drop('MTCNN', axis=1)
df = df[~df['Embedding'].isna()]
print(df.compute().head())
由于每个图像都是分别处理的,因此任务是并行的,并且图形非常简单。 在大型木地板文件上运行时,客户端崩溃(请参见dask crash performance_report)。该错误与调度程序和工作人员之间的通信有关,因此该报告似乎没有用。但是,当在镶木地板的一部分上运行并显示以下行时
df = dd.concat([i在范围(5)中的[df.get_partition(i)])
计算成功,但未使用所有可用资源(请参见dask successful performance_report)。从我们看到的结果来看,每个分区都有一个worker
,其余所有分区都处于空闲状态。
我们也在LocalCluster
上运行了代码,并且遇到了同样的问题。该代码只在小规模的数据上运行,但是对大量数据却失败(或花费很长的时间才能完成)(并且没有利用群集上的所有可用资源)。
使用compute(optimize_graph=False)运行并没有帮助。
mtcnn
和resnet
对象必须可供每个工作人员使用,但无法理解为什么Dask无法处理scatter操作?dataframe
中的图像提取为标准的alon文件格式以优化Dask
的计算是否有益?从coiled youtube channel的示例来看,大多数处理过的图像都存储为单独的文件,我们想知道dask array
是否更适合此类任务。