Hydra Ray Launcher 插件实战指南:在本地集群与 AWS EC2 上并行执行 Sweep 任务
Hydra Ray Launcher 插件实战指南在本地集群与 AWS EC2 上并行执行 Sweep 任务【免费下载链接】hydraHydra is a framework for elegantly configuring complex applications项目地址: https://gitcode.com/GitHub_Trending/hyd/hydraHydra Ray Launcher 插件为 Hydra 提供了两个开箱即用的启动器Launcherray_aws与ray分别用于将 multirun 任务远程提交到 AWS EC2 上的 Ray 集群以及在本地机器或既有 Ray 集群上并行执行任务。阅读完本文你将掌握插件的安装方式、两种启动器的完整配置模型、集群生命周期与日志的管理手段以及如何借助sync_up/sync_down在远程与本地之间同步代码和产物从而把 Hydra 的配置驱动实验能力无缝延伸到 Ray 生态。插件概览两个 Launcher一套配置哲学ray_awslauncher 构建在 Ray 的 Autoscaler SDKray.autoscaler.sdk之上负责在 AWS 上创建、更新并最终拆除 EC2 集群把任务调度到该远程集群执行raylauncher 则直接通过ray.init()连接本地机器或既有的 Ray 集群不需要任何云资源。两个 launcher 都遵循 Hydra 的插件配置规范安装插件后Hydra 会自动在hydra/launcher配置组下注册ray与ray_aws两个选项。从源码看这一注册动作发生在 _config.py通过ConfigStore将RayLauncherConf与RayAWSLauncherConf两个结构化配置节点分别存入hydra/launcher组config_store.store( grouphydra/launcher, nameray, nodeRayLauncherConf, providerray_launcher, ) config_store.store( grouphydra/launcher, nameray_aws, nodeRayAWSLauncherConf, providerray_launcher, )这两个配置节点的入口分别指向 ray_launcher.py 中的RayLauncher和 ray_aws_launcher.py 中的RayAWSLauncher。二者都继承自 Hydra 的Launcher基类定义于 launcher.py并实现setup()与launch()两个核心方法——这也意味着你可以用标准的--multirun方式触发它们。安装插件以独立 Python 包形式发布安装命令$ pip install hydra-ray-launcher --upgrade安装完成后无需任何额外注册即可在命令行中通过hydra/launcherray_aws或hydra/launcherray启用对应启动器。使用方法启用方式有两种命令行参数覆盖或在配置文件 defaults 中 override。命令行方式$ python my_app.py --multirun hydra/launcherray_aws配置文件方式defaults: - override hydra/launcher: ray_aws其中--multirun是触发 sweep 的关键Hydra 只有在 multirun 模式下才会真正调度多个任务。关于插件的标准配置方式可参考 configuring_plugins 一文。ray_awsLauncher在 AWS EC2 上运行任务前置条件ray_aws构建在 Ray Autoscaler SDK 之上使用前需要满足两个条件配置好 AWS 凭据~/.aws/credentials与~/.aws/config可参考 AWS CLI 的配置文件说明你的 AWS 凭据必须具备 EC2 与 IAM 的相关权限——Autoscaler SDK 需要调用 EC2 创建/查询实例、IAM 管理密钥对等接口权限不足会导致集群创建失败。配置模型与默认值Autoscaler SDK 期望一份 EC2 集群配置Hydra 将其完整 schema 化到了 _config.py 中全部字段均有合理的默认值因此你可以在不写任何集群配置的情况下直接跑通示例。执行下面的命令可以查看ray_awslauncher 的完整生效配置$ python my_app.py hydra/launcherray_aws --cfg hydra -p hydra.launcher该命令输出的配置如下节选自插件源码中 _config.py 的默认值# package hydra.launcher _target_: hydra_plugins.hydra_ray_launcher.ray_aws_launcher.RayAWSLauncher env_setup: pip_packages: omegaconf: ${ray_pkg_version:omegaconf} hydra_core: ${ray_pkg_version:hydra} ray: ${ray_pkg_version:ray} cloudpickle: ${ray_pkg_version:cloudpickle} pickle5: 0.0.11 hydra_ray_launcher: 1.2.0.dev1 commands: - conda create -n hydra_${python_version:micro} python${python_version:micro} -y - echo export PATH$HOME/anaconda3/envs/hydra_${python_version:micro}/bin:$PATH ~/.bashrc ray: init: address: null remote: {} cluster: cluster_name: default min_workers: 0 upscaling_speed: 1.0 max_workers: 1 initial_workers: 0 autoscaling_mode: default target_utilization_fraction: 0.8 idle_timeout_minutes: 5 docker: image: container_name: pull_before_run: true run_options: [] provider: type: aws region: us-west-2 availability_zone: us-west-2a,us-west-2b cache_stopped_nodes: false key_pair: key_name: hydra-${oc.env:USER,user} auth: ssh_user: ubuntu available_node_types: ray.head.default: resources: {} node_config: InstanceType: m5.large ImageId: ami-0a2363a9cff180a64 ray.worker.default: min_workers: 0 max_workers: 2 resources: {} node_config: InstanceType: m5.large ImageId: ami-0a2363a9cff180a64 InstanceMarketOptions: MarketType: spot head_node_type: ray.head.default file_mounts: {} initialization_commands: [] cluster_synced_files: [] setup_commands: [] head_setup_commands: [] worker_setup_commands: [] head_start_ray_commands: - ray stop - ulimit -n 65536;ray start --head --port6379 --object-manager-port8076 --autoscaling-config~/ray_bootstrap_config.yaml worker_start_ray_commands: - ray stop - ulimit -n 65536; ray start --address$RAY_HEAD_IP:6379 --object-manager-port8076 run_env: auto stop_cluster: true sync_up: source_dir: null target_dir: null include: [] exclude: [] sync_down: source_dir: null target_dir: null include: [] exclude: [] logging: log_style: auto color_mode: auto verbosity: 0 create_update_cluster: no_restart: false restart_only: false no_config_cache: false teardown_cluster: workers_only: false keep_min_workers: false配置分五大块各有明确职责env_setup集群上环境的准备动作。pip_packages会通过ray_pkg_version解析器在 _config.py 中注册自动对齐本地各依赖的版本再结合commands中创建 conda 环境、写~/.bashrc的命令保证远程环境与本地一致。从 _core_aws.py 的launch()实现看这些命令会被拼装为pip install packageversion后合并进cluster.setup_commands随集群创建一并执行ray.cluster完整的 Ray Autoscaler 集群配置与 Ray 官方ray-schema.json一一对应sync_up / sync_down基于 rsync 的代码与产物双向同步logging / create_update_cluster / teardown_cluster分别控制 Ray 日志、集群创建/更新与拆除行为。集群自动扩缩容关键参数ray.cluster中与扩缩容直接相关的字段值得逐一说明对应 _config.py 中的RayClusterConf参数默认值含义cluster_namedefault集群的唯一标识min_workers0除 head 节点外最少启动的 worker 数≥ 0max_workers1最多启动的 worker 数优先级高于min_workersinitial_workers0集群首次创建时启动的 worker 数upscaling_speed1.0扩缩容速度系数数值越大扩容越快target_utilization_fraction0.8扩到目标资源利用率必须小于 1.0 才会触发扩容idle_timeout_minutes5节点空闲超过该分钟数即被移除autoscaling_modedefaultdefault或aggressivehead_node_typeray.head.default指定 head 节点类型provider.typeaws云提供商类型available_node_types定义了允许的节点类型及其资源、实例规格。默认配置中 head 节点使用按需的m5.largeworker 节点同样为m5.large但采用 spot 实例InstanceMarketOptions.MarketType: spot以降低成本。file_mounts、cluster_synced_files、initialization_commands、setup_commands等字段与 Ray Autoscaler 的语义完全一致可用于分发数据文件、执行初始化脚本。一个最小的运行示例仓库中的 examples/simple 目录提供了可直接运行的示例应用其配置文件 config.yaml 只是 override 了 launcherdefaults: - override hydra/launcher: ray_aws task: 1应用本体 my_app.py 是一个标准的 Hydra 应用读取cfg.task后打印日志并休眠 1 秒。运行命令与输出如下$ python my_app.py --multirun task1,2,3 [HYDRA] Ray Launcher is launching 3 jobs, [HYDRA] #0 : task1 [HYDRA] #1 : task2 [HYDRA] #2 : task3 [HYDRA] Pickle for jobs: /var/folders/n_/9qzct77j68j6n9lh0lw3vjqcn96zxl/T/tmpqqg4v4i7/job_spec.pkl Cluster: default ... INFO services.py:1172 -- View the Ray dashboard at http://localhost:8265 (pid3374) [__main__][INFO] - Executing task 1 (pid3374) [__main__][INFO] - Executing task 2 (pid3374) [__main__][INFO] - Executing task 3 ... [HYDRA] Stopping cluster now. (stop_clustertrue) [HYDRA] Deleted the cluster (provider.cache_stopped_nodesfalse) Destroying cluster. Confirm [y/N]: y [automatic, due to --yes] ... No nodes remaining.从输出可以看到完整的执行链路任务规格被序列化为job_spec.pkl上传到远端集群创建后各任务在 worker 上并行执行可通过 Ray dashboard 观察任务全部完成后插件默认自动拆除集群。这一流程对应的底层实现位于 _core_aws.py所有 sweep 配置、任务函数与 Hydra 的 singleton 状态会被cloudpickle打包进job_spec.pkl交由远端 _remote_invoke.py 反序列化后逐任务执行。多模块应用的代码与产物同步sync_up / sync_down如果应用依赖多个模块单文件上传便不够了此时需要配置hydra.launcher.sync_up将依赖模块同步到远程集群任务结束后如需将远程产物取回本地则配置hydra.launcher.sync_down。该功能构建在rsync之上include与exclude的语义与 rsync 完全一致二者可以组合实现“只上传/下载需要的文件”的白名单效果。仓库中的 examples/upload_download 演示了这一能力。训练脚本 train.py 从model.my_model导入MyModel多模块依赖并在cfg.checkpoint_path目录下保存 checkpoint 文件。其 launcher 配置 custom_ray_aws.yaml 如下defaults: - ray_aws sync_up: # source_dir 可以是相对路径相对于运行命令的目录也支持绝对路径 source_dir: . # target_dir 保持 null文件会被同步到远端临时目录 # 任务结束后临时目录自动清理。 # 推荐同步代码/产物时保持 null这样无需在远端配置 $PYTHONPATH include: [model, *.py] # 无需上传配置文件 exclude: [*] sync_down: include: [*.pt, */] # 无需下载配置文件 exclude: [*]这里的关键技巧sync_up.target_dir留空时代码被同步到远端临时目录该目录随任务结束自动清理临时目录会自动加入PYTHONPATH因此你无需手动配置远端环境变量。sync_down则把远程checkpoint目录下的.ptcheckpoint 文件下载回本地。运行效果$ python train.py --multirun random_seed1,2,3 [HYDRA] Ray Launcher is launching 3 jobs, [HYDRA] #0 : random_seed1 [HYDRA] #1 : random_seed2 [HYDRA] #2 : random_seed3 [HYDRA] Pickle for jobs: /var/folders/n_/9qzct77j68j6n9lh0lw3vjqcn96zxl/T/tmptdkye9of/job_spec.pkl Cluster: default ... INFO services.py:1172 -- View the Ray dashboard at http://localhost:8265 (pid1772) [__main__][INFO] - Start training... (pid1772) [INFO] - Init my model (pid1772) [INFO] - Created dir for checkpoints. dircheckpoint (pid1772) [__main__][INFO] - Start training... (pid1772) [INFO] - Init my model (pid1772) [INFO] - Created dir for checkpoints. dircheckpoint (pid1772) [__main__][INFO] - Start training... (pid1772) [INFO] - Init my model (pid1772) [INFO] - Created dir for checkpoints. dircheckpoint Loaded cached provider configuration ... [HYDRA] Output: receiving file list ... done 16-32-25/ 16-32-25/0/ 16-32-25/0/checkpoint/ 16-32-25/0/checkpoint/checkpoint_1.pt 16-32-25/1/ 16-32-25/1/checkpoint/ 16-32-25/1/checkpoint/checkpoint_2.pt 16-32-25/2/ 16-32-25/2/checkpoint/ 16-32-25/2/checkpoint/checkpoint_3.pt ... [HYDRA] Stopping cluster now. (stop_clustertrue) [HYDRA] Deleted the cluster (provider.cache_stopped_nodesfalse) Destroying cluster. Confirm [y/N]: y [automatic, due to --yes] ... No nodes remaining.从实现上看_core_aws.py 会在任务执行前通过sdk.rsync把source_dir可相对可绝对_get_abs_code_dir会把相对路径拼接为绝对路径按include/exclude规则同步到远端临时目录任务结束后再按 L175-L202 的逻辑把远端输出目录默认是 sweep 输出目录同步回本地sweep.dir。rsync 对应的 CLI 等价形式为rsync {source} {target} --include{include} --exclude{exclude}source/target谁在本地、谁在远端取决于sync_up本地→远端还是sync_down远端→本地。集群生命周期管理插件提供三组 flag 精细控制集群从创建到拆除的完整生命周期默认行为与覆盖方式见 _core_aws.py 中stop_cluster分支的实现。默认设置无需在命令行指定任务在远端执行完毕后删除集群hydra.launcher.stop_clustertrue hydra.launcher.ray.cluster.provider.cache_stopped_nodesfalse hydra.launcher.teardown_cluster.workers_onlyfalse hydra.launcher.teardown_cluster.keep_min_workersfalse任务结束后保持集群运行便于复用作下一次实验但会产生持续费用hydra.launcher.stop_clusterfalseEC2 实例的关机/终止行为由hydra.launcher.ray.cluster.provider.cache_stopped_nodes与hydra.launcher.teardown_cluster.workers_only组合决定cache_stopped_nodesworkers_only行为falsefalse所有节点被终止falsetrue保留 head 节点运行仅终止 worker 节点truefalse保留 head 与 worker 节点并全部停机truetrue保留 head 与 worker 节点仅停止 worker 节点保留hydra.launcher.ray.cluster.min_workers个 worker 节点、删除其余 worker 节点hydra.launcher.teardown_cluster.keep_min_workerstrue集群创建/更新行为控制插件还允许你控制ray up过程中跑 setup、重启 Ray、用缓存这三个环节的取舍对应 Ray SDK 的create_or_update_cluster参数见 _config.py 中的RayCreateOrUpdateClusterConf默认配置执行 setup 命令、重启 Ray并使用配置缓存如可用hydra.launcher.create_update_cluster.no_restartfalse hydra.launcher.create_update_cluster.restart_onlyfalse hydra.launcher.create_update_cluster.no_config_cachefalse更新集群配置时跳过重启 Ray 服务避免中断运行中的任务可用来动态调整 autoscaler 配置hydra.launcher.create_update_cluster.no_restarttrue跳过 setup 命令、只重启 Ray不可与no_restart同时使用hydra.launcher.create_update_cluster.restart_onlytrue禁用配置缓存、强制从云提供商处完整重新解析环境设置hydra.launcher.create_update_cluster.no_config_cachetrueRay 日志配置ray_aws通过hydra.launcher.logging控制 Ray SDK 的configure_logging行为对应 _config.py 中的RayLoggingConf最终在 _core_aws.py 中调用sdk.configure_logging(**logging_config)默认配置使用最低 verbosity自动检测是否启用 pretty-print 与彩色输出hydra.launcher.logging.log_styleauto hydra.launcher.logging.color_modeauto hydra.launcher.logging.verbosity0关闭 pretty-printrecord风格输出不带格式化hydra.launcher.logging.log_stylerecord关闭彩色输出hydra.launcher.logging.color_modefalse提高 Ray 日志详细程度hydra.launcher.logging.verbosity3log_style的可选值auto/pretty/record定义于 _config.py其中auto在 stdin 不是 TTY 时会自动退化为非 pretty 输出color_mode的可选值true/false/auto见 L56-L63verbosity从 0minimal到 3very_very_verbose共四级见 L66-L74。rayLauncher在本地机器或既有集群上运行任务raylauncher 不需要任何云资源适用于本地开发调试、或把任务提交到已经运行的 Ray 集群。它的配置模型更轻量仅包含ray.init与ray.remote两个字段见 _config.pydataclass class RayConf: init: Dict[str, Any] field(default_factorylambda: {address: None}) remote: Dict[str, Any] field(default_factorydict)默认情况下ray.init(addressNone)会在本地启动一个新的 Ray 集群。运行方式与ray_aws完全一致$ python my_app.py --multirun hydra/launcherray [HYDRA] Ray Launcher is launching 1 jobs, sweep output dir: multirun/2020-11-10/15-16-28 [HYDRA] Initializing ray with config: {} INFO services.py:1164 -- View the Ray dashboard at http://127.0.0.1:8266 [HYDRA] #0 : (pid97801) [__main__][INFO] - Executing task 1从 _core.py 的实现可以看到ray_cfg.init会被解析后传入start_ray随后每个 sweep 任务通过launch_job_on_ray包装成ray.remote调用并收集结果。如果本地已存在运行的 Ray 集群可以通过hydra.launcher.ray.init.address指定地址连接它$ python my_app.py --multirun hydra/launcherray hydra.launcher.ray.init.addresslocalhost:6379 [HYDRA] Ray Launcher is launching 1 jobs, sweep output dir: multirun/2020-11-10/15-13-32 [HYDRA] Initializing ray with config: {num_cpus: None, num_gpus: None, address: localhost:6379} INFO worker.py:633 -- Connecting to existing Ray cluster at address: 10.30.99.17:6379 [HYDRA] #0 : (pid93358) [__main__][INFO] - Executing task 1注意输出中Initializing ray with config展示的num_cpus/num_gpus字段——它们同样可以通过hydra.launcher.ray.init传递。配置ray.init()与ray.remote()raylauncher 构建在 Ray 的ray.init()与ray.remote()两个 API 之上。通过覆盖hydra.launcher.ray.init与hydra.launcher.ray.remote你可以精确控制 Ray 运行时的行为$ python my_app.py --multirun hydra/launcherray \ hydra.launcher.ray.init.addresslocalhost:6379 \ hydra.launcher.ray.init.num_cpus4 \ hydra.launcher.ray.init.num_gpus0 \ hydra.launcher.ray.remote.memory1024000000其中init下的字段如address、num_cpus、num_gpus、memory等与ray.init()的参数一一对应remote下的字段则对应ray.remote装饰器的资源配置参数。如果你需要为不同任务定制差异化资源可以为每个任务单独设置ray.remote的num_cpus/num_gpus等值。测试验证与运行限制插件自带测试 test_ray_launcher.py用于验证raylauncher 在本地集群上的行为而 ray_aws_launcher_tests_disabled.py 从文件名即可看出AWS 相关测试默认是禁用的——因为创建/拆除真实 EC2 集群会产生云费用且依赖真实 AWS 凭据。这提示我们ray_aws的功能验证需要真实的 AWS 环境本地开发阶段建议优先使用raylauncher 打通任务逻辑。小结Hydra Ray Launcher 插件把配置即实验的理念带入了 Ray 生态raylauncher 让本地/既有集群上的 multirun 变成一行命令ray_awslauncher 则把同样的一行命令延伸到 AWS EC2 上的弹性集群并借助 schema 化的配置模型把 Autoscaler 的复杂参数、集群生命周期、代码与产物同步全部纳入 Hydra 的覆盖语法之下。无论你是想在本地快速并行跑参数扫描还是需要按需在云端拉起带 spot worker 的集群跑大规模实验都可以从本文给出的默认配置出发用 override 逐步定制出自己的 Ray 训练流水线。【免费下载链接】hydraHydra is a framework for elegantly configuring complex applications项目地址: https://gitcode.com/GitHub_Trending/hyd/hydra创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考