十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Hydra Joblib Launcher 插件实战指南:用 Joblib.Parallel 实现进程级并行多任务执行

Hydra Joblib Launcher 插件实战指南:用 Joblib.Parallel 实现进程级并行多任务执行 Hydra Joblib Launcher 插件实战指南用 Joblib.Parallel 实现进程级并行多任务执行【免费下载链接】hydraHydra is a framework for elegantly configuring complex applications项目地址: https://gitcode.com/GitHub_Trending/hyd/hydra本篇指南围绕 Hydra 官方插件hydra-joblib-launcher展开讲解如何以 Joblib.Parallel 为执行引擎把 Hydra 的--multirun批量任务并行化到多核 CPU 上运行。读完本文你将掌握该插件的安装方式、hydra/launcherjoblib的启用方法、全部配置参数的含义与默认值、支持的后端loky / multiprocessing及其适用限制并能结合示例应用与测试用例在真实项目中落地。插件定位为 Hydra 提供基于 Joblib 的并行启动器Hydra 自身提供的默认启动器basic_launcher是串行执行的当使用--multirun发起多次实验时任务会逐个排队运行。而 Joblib Launcher 插件插件源码位于 plugins/hydra_joblib_launcher将 Hydra 的 Launcher 接口对接到了 Joblib.Parallel 之上使多个 sweep 任务能够并行执行从而充分利用机器上的全部 CPU 核心。从实现上看该插件的核心类JoblibLauncher继承自 Hydra 的Launcher抽象基类并实现了setup()与launch()两个关键方法见 joblib_launcher.pysetup()接收HydraContext、任务函数与完整配置在启动前完成上下文注入launch()接收 Joblib 的启动参数job_overrides与initial_job_idx真正的并行调度逻辑委托给同包内的_core.launch()见 _core.py。也就是说Hydra 只负责把每次实验的 override 参数整理成任务列表具体开多少个 worker、用进程还是线程、如何分发任务全部交给 Joblib 完成。安装插件该插件发布为独立的 Python 包通过 pip 直接安装即可pip install hydra-joblib-launcher --upgrade从当前仓库的 setup.py 可以看到它的依赖约束hydra-core1.4.0.dev1,1.5.0.dev0要求 Hydra Core 1.4 及以上版本见 news/3323.api_changejoblib1.5.3。同时需要 Python 3.10 及以上版本。安装完成后插件会通过 Hydra 的插件发现机制自动注册为hydra/launcher配置组下的joblib选项注册逻辑见 config.py测试用例test_discovery也验证了这一点见 test_joblib_launcher.py。快速开始两种启用方式插件安装后有两种方式启用方式一命令行直接指定python your_app.py hydra/launcherjoblib --multirun ...方式二在配置中覆盖 launcherdefaults: - override hydra/launcher: joblib这两种方式等价最终都会把hydra.launcher解析为joblib配置组的实例。插件默认使用基于进程的并行并自动利用机器上的全部可用 CPU 核心你只需要覆盖默认配置中的参数即可限制并发数量或调整分发策略。配置参数详解JobLibLauncherConf 全量字段插件的配置由一个结构化配置类JobLibLauncherConf承载定义在 config.py。运行下面这条命令可以随时查看当前环境中该 launcher 的全部参数及其默认值# package hydra.launcher _target_: hydra_plugins.hydra_joblib_launcher.joblib_launcher.JoblibLauncher n_jobs: 10 backend: null prefer: processes require: null verbose: 0 timeout: null pre_dispatch: 2*n_jobs batch_size: auto temp_folder: null max_nbytes: null mmap_mode: r注意上面输出中的n_jobs: 10来自官方示例应用对配置的覆盖见下文示例小节插件自身的默认值是n_jobs: -1即使用全部 CPU 核心。另外当前仓库版本相比该文档所属的 1.1 版本新增了inner_max_num_threads参数见 news/3185.feature并把默认后端从null回落为 loky调整为显式的loky。各参数的完整含义、默认值与使用建议整理如下参数默认值含义与说明n_jobs-1最大并发任务数-1表示使用全部 CPU 核心。官方示例将其覆盖为10inner_max_num_threadsNone当前版本新增限制每个 worker 进程内部第三方库可使用的线程数仅 loky 后端支持backendloky后端选择loky默认或multiprocessing传入null时在运行期回落为lokypreferprocesses后端选择的软提示processes或threads用于影响 Joblib 选择具体后端requirenull硬性约束null或sharedmemsharedmem会强制选择基于线程的后端verbose0大于 0 时打印进度信息用于观察任务调度过程timeoutnull每个任务执行的超时上限单位取决于后端实现loky 下为毫秒pre_dispatch2*n_jobs预分发的批次数控制任务投递的节奏可以是数字或表达式字符串batch_sizeauto每次派发给单个 worker 的原子任务数量auto由 Joblib 自动决定temp_foldernull用于对大数组做 memmap 共享内存的临时目录路径max_nbytesnull触发自动 memmap 化的数组大小阈值支持如1M这类单位后缀mmap_moder传给 worker 的 NumPy 数组的 memmap 打开模式配置的预处理逻辑见 _core.py值得注意几点pre_dispatch、batch_size、max_nbytes三个字段支持数字字符串或表达式如3*n_jobs、all、1M插件会尝试将其转换为整数转换失败则原样传给 Joblibtimeout对 loky 后端生效毫秒级其他后端可能忽略这些参数最终以keyvalue的形式拼装成Joblib.Parallel(...)的调用参数并打印日志方便核对实际生效值。关于这些参数更底层的语义可以参阅 Joblib 官方对Parallel的文档说明Hydra 侧只负责参数透传与合法性校验不做额外加工。后端支持与限制官方文档明确指出该插件仅支持基于进程的并行后端。结合当前仓库源码受支持的后端集合为{loky, multiprocessing}见 _core.py。loky默认Joblib 默认的进程后端能正确处理不可 pickle 的对象、灵活调整进程池也是该插件最常用的后端multiprocessing标准库 multiprocessing 后端在该插件中做了额外的进程隔离约束见下文threading / sequential / dask 等后端会被直接拒绝。process_joblib_cfg()在运行期做严格校验遇到不支持的 backend 会抛出ValueError: Unsupported Joblib backend ...对应测试见 test_joblib_launcher.py。除了后端白名单插件还会做后端专属参数的交叉校验错误使用会在启动前报错而非静默失效inner_max_num_threads仅 loky 支持multiprocessing 下使用会报错maxtasksperchild仅 multiprocessing 支持loky 下使用会报错multiprocessing 后端强制batch_size1且maxtasksperchild1以保证每个 job 拥有独立的进程、进程间状态完全隔离校验测试见 test_joblib_launcher.py。multiprocessing 后端的进程隔离细节选用hydra.launcher.backendmultiprocessing时插件会在运行期做两类额外处理这是从 _core.py 与 _core.py 可以确认的实现事实任务函数必须定义在模块顶层作用域。multiprocessing 需要序列化任务函数插件会通过sys.modules找到函数所在模块并回读同名对象若任务函数是嵌套定义或局部定义会抛出TypeError提示requires function tasks to be defined at module scope。同时要求hydra.main等装饰器使用functools.wraps保留__wrapped__链插件会沿该链逐层解包到真正的函数体。强制 batch_size1 与 maxtasksperchild1。这是为了按 job 隔离进程每个子进程只执行一个任务后即退出避免一个任务的副作用如全局状态、导入污染泄漏到下一个任务。对应的集成测试见 test_joblib_launcher.py用 4 个 job 运行 multiprocessing 应用断言 4 个 job 的 PID 各不相同、且各 job 内配置插值均正常解析——即并行执行没有破坏任务间的状态隔离。此外由于 Joblib 在n_jobs1时会在调用方进程内直接执行不启动 worker 池插件对 multiprocessing 后端做了特殊修正当effective_n_jobs 1时把n_jobs提升为2且pre_dispatch1确保至少有一个 worker 进程在池中承载任务见 _core.py。官方示例应用与运行效果插件仓库提供了一个可直接运行的示例应用example/my_app.pyimport logging import os import time import hydra from omegaconf import DictConfig log logging.getLogger(__name__) hydra.main(config_path., config_nameconfig) def my_app(cfg: DictConfig) - None: log.info(fProcess ID {os.getpid()} executing task {cfg.task} ...) time.sleep(1) if __name__ __main__: my_app()配套的 config.yaml 同时展示了通过配置启用插件与覆盖并发数两种写法defaults: - override hydra/launcher: joblib task: 1 hydra: launcher: # override the number of jobs for joblib n_jobs: 10执行 5 个任务的多任务启动命令python my_app.py --multirun task1,2,3,4,5运行时会先打印 Joblib.Parallel 的实际生效参数与任务总数再展示各任务在独立进程中的执行情况输出形如$ python my_app.py --multirun task1,2,3,4,5 [HYDRA] Joblib.Parallel(n_jobs-1,verbose0,timeoutNone,pre_dispatch2*n_jobs,batch_sizeauto,temp_folderNone,max_nbytesNone,mmap_moder,backendloky) is launching 5 jobs [HYDRA] Launching jobs, sweep output dir : multirun/2020-02-18/10-00-00 [__main__][INFO] - Process ID 14336 executing task 2 ... [__main__][INFO] - Process ID 14333 executing task 1 ... [__main__][INFO] - Process ID 14334 executing task 3 ... [__main__][INFO] - Process ID 14335 executing task 4 ... [__main__][INFO] - Process ID 14337 executing task 5 ...从输出可以看出5 个任务的 PID 互不相同说明确实运行在 5 个独立进程中--multirun的批量实验被真正并行化了每个任务的日志输出目录遵循 Hydra 的 sweep 目录规范multirun/时间戳/序号/各任务的my_app.log会写入各自目录集成测试 test_joblib_launcher.py 也验证了0/my_app.log、1/my_app.log的落盘。常见实战配置示例限制并发数到 4 个 workerpython my_app.py --multirun task1,2,3,4,5 hydra.launcher.n_jobs4指定 multiprocessing 后端并限制到 2 个进程python my_app.py --multirun task1,2,3,4 hydra/launcherjoblib hydra.launcher.backendmultiprocessing hydra.launcher.n_jobs2为大数组场景开启 memmap 共享内存限制触发阈值并指定临时目录python my_app.py --multirun task1,2,3,4 hydra.launcher.max_nbytes1M hydra.launcher.temp_folder/tmp/joblib_mmap限制 loky 下每个 worker 的内部线程数防止第三方库在每个进程内再开多线程导致过度订阅python my_app.py --multirun task1,2,3,4 hydra.launcher.n_jobs4 hydra.launcher.inner_max_num_threads2上述示例中n_jobs、backend、batch_size、max_nbytes、pre_dispatch、inner_max_num_threads等覆盖均在插件测试中被逐一验证见 test_joblib_launcher.py可放心用于实际项目。小结hydra-joblib-launcher是 Hydra 生态中接入并行执行最轻量的一站式方案一条pip install加一行hydra/launcherjoblib即可让--multirun任务在多核 CPU 上并行跑起来。核心要点回顾默认采用 loky 进程后端、使用全部 CPU 核心可通过n_jobs精确控制并发度全部参数由JobLibLauncherConf结构化配置承载可用--cfg hydra -p hydra.launcher随时探查仅支持进程级后端loky / multiprocessing线程类后端会被校验逻辑拒绝multiprocessing 后端自带进程隔离约束任务函数须定义在模块顶层插件当前版本要求 Hydra Core 1.4 与 Joblib 1.5.3。更进一步的场景化配置方式如在配置组中组合、覆盖与组合多个插件可参考 配置插件的标准模式以及插件仓库内的 README.md 与完整测试套件。【免费下载链接】hydraHydra is a framework for elegantly configuring complex applications项目地址: https://gitcode.com/GitHub_Trending/hyd/hydra创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表