正如我們在前面的第 19.2 節中看到的那樣,由于超參數配置的評估代價高昂,我們可能不得不等待數小時甚至數天才能在隨機搜索返回良好的超參數配置之前。在實踐中,我們經常訪問資源池,例如同一臺機器上的多個 GPU 或具有單個 GPU 的多臺機器。這就引出了一個問題:我們如何有效地分布隨機搜索?
通常,我們區分同步和異步并行超參數優化(見圖19.3.1)。在同步設置中,我們等待所有并發運行的試驗完成,然后再開始下一批。考慮包含超參數的配置空間,例如過濾器的數量或深度神經網絡的層數。包含更多過濾器層數的超參數配置自然會花費更多時間完成,并且同一批次中的所有其他試驗都必須在同步點(圖 19.3.1 中的灰色區域)等待,然后我們才能 繼續優化過程。
在異步設置中,我們會在資源可用時立即安排新的試驗。這將以最佳方式利用我們的資源,因為我們可以避免任何同步開銷。對于隨機搜索,每個新的超參數配置都是獨立于所有其他配置選擇的,特別是沒有利用任何先前評估的觀察結果。這意味著我們可以簡單地異步并行化隨機搜索。這對于根據先前的觀察做出決定的更復雜的方法來說并不是直截了當的(參見 第 19.5 節)。雖然我們需要訪問比順序設置更多的資源,但異步隨機搜索表現出線性加速,因為達到了一定的性能K如果K試驗可以并行進行。
圖 19.3.1同步或異步分配超參數優化過程。與順序設置相比,我們可以減少整體掛鐘時間,同時保持總計算量不變。在掉隊的情況下,同步調度可能會導致工人閑置。
在本筆記本中,我們將研究異步隨機搜索,其中試驗在同一臺機器上的多個 Python 進程中執行。分布式作業調度和執行很難從頭開始實現。我們將使用Syne Tune (Salinas等人,2022 年),它為我們提供了一個簡單的異步 HPO 接口。Syne Tune 旨在與不同的執行后端一起運行,歡迎感興趣的讀者研究其簡單的 API,以了解有關分布式 HPO 的更多信息。
import logging
from d2l import torch as d2l
logging.basicConfig(level=logging.INFO)
from syne_tune import StoppingCriterion, Tuner
from syne_tune.backend.python_backend import PythonBackend
from syne_tune.config_space import loguniform, randint
from syne_tune.experiments import load_experiment
from syne_tune.optimizer.baselines import RandomSearch
INFO:root:SageMakerBackend is not imported since dependencies are missing. You can install them with
pip install 'syne-tune[extra]'
AWS dependencies are not imported since dependencies are missing. You can install them with
pip install 'syne-tune[aws]'
or (for everything)
pip install 'syne-tune[extra]'
AWS dependencies are not imported since dependencies are missing. You can install them with
pip install 'syne-tune[aws]'
or (for everything)
pip install 'syne-tune[extra]'
INFO:root:Ray Tune schedulers and searchers are not imported since dependencies are missing. You can install them with
pip install 'syne-tune[raytune]'
or (for everything)
pip install 'syne-tune[extra]'
19.3.1。目標函數
首先,我們必須定義一個新的目標函數,以便它現在通過回調將性能返回給 Syne Tune report
。
def hpo_objective_lenet_synetune(learning_rate, batch_size, max_epochs):
from syne_tune import Reporter
from d2l import torch as d2l
model = d2l.LeNet(lr=learning_rate, num_classes=10)
trainer = d2l.HPOTrainer(max_epochs=1, num_gpus=1)
data = d2l.FashionMNIST(batch_size=batch_size)
model.apply_init([next(iter(data.get_dataloader(True)))[0]], d2l.init_cnn)
report = Reporter()
for epoch in range(1, max_epochs + 1):
if epoch == 1:
# Initialize the state of Trainer
trainer.fit(model=model, data=data)
else:
trainer.fit_epoch()
validation_error = trainer.validation_error().cpu().detach().numpy()
report(epoch=epoch, validation_error=float(validation_error))
請注意,PythonBackend
Syne Tune 需要在函數定義中導入依賴項。
19.3.2。異步調度器
首先,我們定義同時評估試驗的工人數量。我們還需要通過定義總掛鐘時間的上限來指定我們想要運行隨機搜索的時間。
接下來,我們說明要優化的指標以及我們是要最小化還是最大化該指標。即,metric
需要對應傳遞給回調的參數名稱report
。
我們使用前面示例中的配置空間。在 Syne Tune 中,該字典也可用于將常量屬性傳遞給訓練腳本。我們利用此功能以通過 max_epochs
. 此外,我們指定要在 中評估的第一個配置initial_config
。
接下來,我們需要指定作業執行的后端。這里我們只考慮本地機器上的分布,其中并行作業作為子進程執行。但是,對于大規模 HPO,我們也可以在集群或云環境中運行它,其中每個試驗都會消耗一個完整的實例。
BasicScheduler
我們現在可以為異步隨機搜索創建調度程序,其行為與我們在 第 19.2 節中的類似。
INFO:syne_tune.optimizer.schedulers.fifo:max_resource_level = 10, as inferred from config_space
INFO:syne_tune.optimizer.schedulers.fifo:Master random_seed = 4033665588
Syne Tune 還具有一個Tuner
,其中主要的實驗循環和簿記是集中的,調度程序和后端之間的交互是中介的。
讓我們運行我們的分布式 HPO 實驗。根據我們的停止標準,它將運行大約 12 分鐘。
INFO:syne_tune.tuner:results of trials will be saved on /home/d2l-worker/syne-tune/python-entrypoint-2023-02-10-04-56-21-691
INFO:root:Detected 8 GPUs
INFO:root:running subprocess with command: /home/d2l-worker/miniconda3/envs/d2l-en-release-0/bin/python /home/d2l-worker/miniconda3/envs/d2l-en-release-0/lib/python3.9/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.1 --batch_size 128 --max_epochs 10 --tune_function_root /home/d2l-worker/syne-tune/python-entrypoint-2023-02-10-04-56-21-691/tune_function --tune_function_hash 53504c42ecb95363b73ac1f849a8a245 --st_checkpoint_dir /home/d2l-worker/syne-tune/python-entrypoint-2023-02-10-04-56-21-691/0/checkpoints
INFO:syne_tune.tuner:(trial 0) - scheduled config {'learning_rate': 0.1, 'batch_size': 128, 'max_epochs': 10}
INFO:root:running subprocess with command: /home/d2l-worker/miniconda3/envs/d2l-en-release-0/bin/python /home/d2l-worker/miniconda3/envs/d2l-en-release-0/lib/python3.9/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.31642002803324326 --batch_size 52 --max_epochs 10 --tune_function_root /home/d2l-worker/syne-tune/python-entrypoint-2023-02-10-04-56-21-691/tune_function --tune_function_hash 53504c42ecb95363b73ac1f849a8a245 --st_checkpoint_dir /home/d2l-worker/syne-tune/python-entrypoint-2023-02-10-04-56-21-691/1/checkpoints
INFO:syne_tune.tuner:(trial 1) - scheduled config {'learning_rate': 0.31642002803324326, 'batch_size': 52, 'max_epochs': 10}
INFO:syne_tune.tuner:Trial trial_id 0 completed.
INFO:root:running subprocess with command: /home/d2l-worker/miniconda3/envs/d2l-en-release-0/bin/python /home/d2l-worker/miniconda3/envs/d2l-en-release-0/lib/python3.9/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.045813161553582046 --batch_size 71 --max_epochs 10 --tune_function_root /home/d2l-worker/syne-tune/python-entrypoint-2023-02-10-04-56-21-691/tune_function --tune_function_hash 53504c42ecb95363b73ac1f849a8a245 --st_checkpoint_dir /home/d2l-worker/syne-tune/python-entrypoint
評論