ARTICLE DETAIL

资讯详情

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

Hydra Joblib Launcher 插件指南:用 Joblib.Parallel 为 Hydra 应用开启并行实验

Hydra Joblib Launcher 插件指南:用 Joblib.Parallel 为 Hydra 应用开启并行实验 Hydra Joblib Launcher 插件指南用 Joblib.Parallel 为 Hydra 应用开启并行实验【免费下载链接】hydraHydra is a framework for elegantly configuring complex applications项目地址: https://gitcode.com/GitHub_Trending/hyd/hydra本篇文章聚焦 Hydra 官方插件体系中的Joblib Launcherhydra-joblib-launcher它基于joblib.Parallel为 Hydra 应用提供进程级并行执行能力。阅读本文后你将掌握该插件的安装方式、两种启用方法、全部启动器配置参数的语义与默认值并能结合仓库源码理解从--multirun命令行到 Joblib 并行调度的完整调用链从而在自己的 Hydra 实验中对多任务 sweep 进行并发控制与性能调优。本文以仓库文档 website/versioned_docs/version-1.0/plugins/joblib_launcher.md 为骨架结合插件源码 plugins/hydra_joblib_launcher 展开。插件定位让多任务实验在单机多核上并行跑起来Hydra 原生提供的basic_launcher见 hydra/_internal/core_plugins/basic_launcher.py在--multirun模式下默认是串行执行每个任务的。当你的实验需要依次扫描多组参数、且每个任务相对独立时串行会白白浪费 CPU 核心。Joblib Launcher 插件正是为解决这一问题而存在它把 Hydra 的一次 multirun sweep 翻译成一次joblib.Parallel调用让多个 job 利用本机全部或部分 CPU 核心并行执行。插件仓库 README 中给出的定位很直接——Provides a Joblib.Parallel based Hydra Launcher supporting parallel execution见 plugins/hydra_joblib_launcher/README.md。它的安装依赖在 setup.py 中有明确声明hydra-core1.4.0.dev1,1.5.0.dev0与joblib1.5.3Python 版本要求3.10。安装一条命令接入在已安装 Hydra 的环境中直接通过 pip 安装即可pip install hydra-joblib-launcher --upgrade安装完成后插件会被 Hydra 的插件发现机制自动识别。这一点有测试用例直接验证在 plugins/hydra_joblib_launcher/tests/test_joblib_launcher.py 的test_discovery中测试断言JoblibLauncher出现在Plugins.instance().discover(Launcher)的发现结果里。启用方式命令行覆盖与 defaults 覆盖启用插件有两种等价方式文档给出了完整说明。方式一命令行直接指定python my_app.py --multirun hydra/launcherjoblib task1,2,3,4,5在命令行末尾追加hydra/launcherjoblib即可把启动器切换为 Joblib。方式二在配置中通过 defaults 覆盖在应用的主配置或任意一份配置里声明defaults: - hydra/launcher: joblib两种方式效果相同选择哪一种取决于你的工作流命令行方式适合临时切换defaults 方式适合把并行行为固化到项目配置中。启用后默认行为是使用全部可用 CPU 核心进行进程级并行。按文档描述可通过覆盖默认配置来限制并行数量例如在命令行追加hydra.launcher.n_jobs2或在配置文件中修改hydra.launcher.n_jobs。配置参数全解JobLibLauncherConf 的完整语义插件的配置节点JobLibLauncherConf定义在 plugins/hydra_joblib_launcher/hydra_plugins/hydra_joblib_launcher/config.py 中并通过ConfigStore.instance().store(grouphydra/launcher, namejoblib, ...)注册为 Hydra 的启动器配置。除了_target_指向启动器实现类外其余字段与joblib.Parallel的构造参数一一对应。你可以随时用下面的命令查看当前生效的完整参数python my_app.py hydra/launcherjoblib --cfg hydra -p hydra.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下表汇总了各参数的语义、默认值与取值要点注释直接取自 config.py 的源码参数默认值类型含义与说明n_jobs-1int最大并发运行的任务数-1表示使用所有 CPU 核心inner_max_num_threadsNoneOptional[int]限制每个 worker 进程中第三方库使用的线程数仅 loky 后端支持见后文backendlokyOptional[str]后端选择loky默认或multiprocessingpreferprocessesstrprocesses或threads对后端的软性提示requireNoneOptional[str]null或sharedmem设为sharedmem会强制选择基于线程的后端verbose0int大于零时打印进度消息timeoutNoneOptional[float]每个任务的超时限制单位取决于后端实现loky 后端为毫秒pre_dispatch2*n_jobsstr预分派的批次数支持all或N*n_jobs等表达式batch_sizeautostr每次分派给每个 worker 的原子任务数temp_folderNoneOptional[str]用于将大数组内存映射memmap以与 worker 共享内存的路径max_nbytesNoneOptional[str]触发自动内存映射的数组大小阈值如1Mmmap_moderstr传给 worker 的 numpy 数组的内存映射模式值得注意的是--cfg输出中的n_jobs: 10来自插件自带示例应用的配置覆盖见下文示例而源码中n_jobs的默认值是-1全部 CPU。文档同时提示以上参数的完整细节应以joblib.Parallel官方文档为准Hydra 侧只是做了透明的参数透传与少量约束校验。源码视角参数如何被校验与透传从源码可以清楚看到 Hydra 对 Joblib 参数的处理并不只是原样转发_core.py中的process_joblib_cfg见 plugins/hydra_joblib_launcher/hydra_plugins/hydra_joblib_launcher/_core.py承担了关键的校验与改写工作后端白名单SUPPORTED_BACKENDS {loky, multiprocessing}传入backendNone时回退为loky传入threading、sequential、dask等其他后端会抛出ValueError。参数规整pre_dispatch、batch_size、max_nbytes会被尝试转换为int转换失败例如all、3*n_jobs、1M这类合法字符串则保持原样。后端专用参数的互斥校验inner_max_num_threads仅允许 loky 后端使用maxtasksperchild仅允许 multiprocessing 后端使用multiprocessing 后端强制batch_size1与maxtasksperchild1以保证每个 job 的进程隔离。这些约束在测试套件 test_joblib_launcher.py 中都有对应用例test_rejects_unsupported_backend、test_null_backend_defaults_to_loky、test_multiprocessing_enforces_process_isolation以及参数化的test_rejects_backend_specific_option。JoblibLauncher类本身见 joblib_launcher.py实现了 Hydra 的Launcher接口setup()接收hydra_context、task_function与config并暂存launch()则将实际的并行调度委托给_core.launch。运行原理从 multirun 到并行执行_core.launch见 _core.py是插件的心脏其关键流程可以拆解为准备输出目录确保hydra.sweep.dir存在所有 job 的结果将写入该目录下的子目录。处理配置调用process_joblib_cfg完成参数校验与规整。构造调用图为每个 job override 构建一个delayed(execute_job)(...)调用execute_job内部会通过HydraConfig.instance().set_config()设置该 job 的独立配置再调用run_job真正执行用户任务函数并复用 Hydra 核心的JobReturn收集返回值见 _core.py。日志提示启动前打印一行类似[HYDRA] Joblib.Parallel(...) is launching 5 jobs的日志以及sweep output dir与每个 job 的 override 信息。并行执行以整理后的参数调用Parallel(**parallel_cfg)(calls)若设置了inner_max_num_threads则额外用parallel_backend(backend, ...)上下文包裹把线程上限与n_jobs传入 loky 后端。文档中给出的完整运行输出如下task1..5五个任务并行启动每个 job 运行在独立进程中Process ID各不相同$ 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 ...输出中任务完成的先后顺序不定这正是并行执行的特征。完整示例一个可复制的并行 sweep插件仓库自带可直接运行的示例应用。应用主文件 plugins/hydra_joblib_launcher/example/my_app.py 是一个最简 Hydra 应用打印当前进程 ID 与cfg.task后休眠一秒用于直观展示并行效果import 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()对应的配置文件 plugins/hydra_joblib_launcher/example/config.yaml 演示了在 defaults 中覆盖启动器、并直接覆盖n_jobs的完整写法defaults: - override hydra/launcher: joblib task: 1 hydra: launcher: # override the number of jobs for joblib n_jobs: 10然后执行python my_app.py --multirun task1,2,3,4,5n_jobs: 10意味着最多允许 10 个 job 并发这里只有 5 个任务因此五个任务会同时启动——这也与上文--cfg输出中n_jobs: 10的由来一致。该示例在测试套件中同样被覆盖test_example_apptest_joblib_launcher.py以task1,2,3,4运行示例并断言返回了 4 个 jobtest_example_app_loads_its_config验证输出中包含Joblib.Parallel字样且每个 job 的日志文件my_app.log被正确写入。后端限制与演进loky 与 multiprocessing文档对后端能力有一句明确的注意提示唯一支持的 Joblib 后端是 loky基于进程的并行即插件从设计上专注于进程级并行不提供线程级并行的执行保证。不过从当前仓库源码来看该插件的后端支持已经有所演进_core.py中的SUPPORTED_BACKENDS集合目前包含loky与multiprocessing两个进程后端并且针对 multiprocessing 后端实现了每个 job 的进程隔离强制batch_size1、maxtasksperchild1参见process_joblib_cfg与 news 文件 plugins/hydra_joblib_launcher/news/2187.feature。此外news 文件 plugins/hydra_joblib_launcher/news/3185.feature 记录了支持配置 Joblib worker 内部线程上限这一能力对应inner_max_num_threads参数。因此在实际使用时可以理解为默认走 loky进程级不指定backend时process_joblib_cfg会自动将其归一为loky若要使用multiprocessing后端则需显式设置hydra.launcher.backendmultiprocessing并注意其对任务函数形态的要求文档与测试均提示进程场景下任务函数应定义在模块顶层。相关测试如test_multiprocessing_backend_isolates_jobs_and_preserves_statetest_joblib_launcher.py验证了 4 个 job 产生 4 个不同 PID 的进程隔离行为。小结Joblib Launcher 插件是 Hydra 多核并行的轻量方案安装即用、配置直白、参数与joblib.Parallel对齐适合在单机多核场景下把 multirun sweep 从串行提速为并行。关键要点回顾安装pip install hydra-joblib-launcher --upgrade启用命令行hydra/launcherjoblib或配置中defaults: - hydra/launcher: joblib默认行为loky 后端、n_jobs-1全部 CPU、进程级并行常用调优n_jobs控制并发度timeout控制单任务超时verbose控制进度输出限制并行后端为进程级loky / multiprocessing参数校验与后端互斥约束由 _core.py 统一处理。如需深入了解各参数的底层语义建议同时查阅joblib.Parallel官方文档若想继续阅读本插件的实现细节与测试用例可从 plugins/hydra_joblib_launcher 目录入手。【免费下载链接】hydraHydra is a framework for elegantly configuring complex applications项目地址: https://gitcode.com/GitHub_Trending/hyd/hydra创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表