我的代码如下:
from joblib import Parallel, delayed
# prediction model - 10s of megabytes on disk
LARGE_MODEL = load_model('path/to/model')
file_paths = glob('path/to/files/*')
def do_thing(file_path):
pred = LARGE_MODEL.predict(load_image(file_path))
return pred
Parallel(n_jobs=2)(delayed(do_thing)(fp) for fp in file_paths)
我的问题是,LARGE_MODEL
是否将在循环的每次迭代中被酸洗/未酸洗。如果是这样,我如何确保每个工作人员都对其进行缓存(如果可能的话)?
答案 0 :(得分:3)
TLDR
父流程对大型模型进行一次酸洗。通过确保大型模型是支持到memfile的numpy数组,可以提高性能。工作者可以
load_temporary_memmap
比磁盘快得多。
您的工作是并行的,可能正在使用joblibs._parallel_backends.LokyBackend
。
在joblib.parallel.Parallel.__call__
中,当LokyBackend
设置为count greater than 1时,joblib尝试初始化后端以使用n_jobs
。
LokyBackend
对同一Parallel
对象使用一个共享的临时文件夹。这与修改默认酸洗行为的还原剂有关。
现在,LokyBackend
将shares this folder的MemmappingExecutor
配置为reducers
。
如果您有numpy installed,并且模型是干净的numpy array,则可以保证使用ArrayMemmapForwardReducer将其作为映射文件进行酸洗一次从父进程传递到子进程。
否则,将其using the default pickling腌制为bytes
对象。
您可以知道如何在父流程中对模型进行酸洗,并从joblib中读取调试日志。
每个工作人员都会“解开”大型模型,因此在那里缓存大型模型确实没有意义。
您只能通过将模型作为memory mapped file进行备份来改善从工人中加载腌制大型模型的源。