FacebookHydra 基本介紹 - 輕鬆地管理 Config - 筆記長也

FacebookHydra 基本介紹 - 輕鬆地管理 Config

2021-11-18 21:11:00   其他

Hydra

hydra 是 facebook 的開源框架,用於簡化 python 應用程式的設定文件管理,可以透過命令列介面來設定修改不同的設定值以及使用不同的設定文件組合檔案,因應需要頻繁更動設定值的情況,例如 AI 模型參數的調整。

安裝

使用 pip 來安裝到專案裡面

pip install hydra-core --upgrade

指定 Config 文件

hydraDemo.py

from omegaconf import DictConfig, OmegaConf
import hydra

@hydra.main(config_path="config", config_name="config")
def my_app(cfg: DictConfig) -> None:
    print(OmegaConf.to_yaml(cfg))
    print(cfg.db)
    print(connecdb(cfg.db.driver, cfg.db.user, cfg.db.password))
    
def connecdb(driver, user, password):
    return "Connected Sucsefull!! Driver:" + driver + ", user:" + user

if __name__ == "__main__":
    my_app()

config/config.yaml

db:
  driver: mysql
  user: omry
  password: secret

這裡使用 @hydra.main 裝飾器來指定 config

python hydraDemo.py

執行之後可以順利印出結果

db:
  driver: mysql
  user: omry
  password: secret

{'driver': 'mysql', 'user': 'omry', 'password': 'secret'}
Connected Sucsefull!! Driver:mysql, user:omry

從命令列修改 config 的數值

可以透過命令列來修改或增加 config 的數值

python hydraDemo.py db.user=fff

如果要增加數值,可以使用 ++

python hydraDemo.py ++db.timeout=30

分組建立 Config 文件

先在 config 下建立一個 db 資料夾,並新增 mysql.yaml 以及 postgresql.yaml 兩個 config

config/db/mysql.yaml

driver: mysql
user: omry
password: secret

config/db/postgresql.yaml

driver: postgresql
user: postgres_user
password: drowssap
timeout: 10

使用分組 Config 文件

hydraDemo.py

from omegaconf import DictConfig, OmegaConf
import hydra

@hydra.main(config_path="config")
def my_app(cfg: DictConfig) -> None:
    print(OmegaConf.to_yaml(cfg))
    print(cfg.db)
    print(connecdb(cfg.db.driver, cfg.db.user, cfg.db.password))  

def connecdb(driver, user, password):
    return "Connected Sucsefull!! Driver:" + driver + ", user:" + user

if __name__ == "__main__":
    my_app()

可以發現與上面指定文件的例子比較,就是只指定 config 的 path

python hydraDemo.py            
{}

如果直接執行而不帶參數,預設不帶入任何 config

python hydraDemo.py +db=postgresql

db:
  driver: postgresql
  user: postgres_user
  password: drowssap
  timeout: 10

{'driver': 'postgresql', 'user': 'postgres_user', 'password': 'drowssap', 'timeout': 10}

透過指令將 db 的 config 加入

指定預設分組 Config

如果某個分組比較常被使用,可以直接給定預設值,就不用每次在命令列輸入指定的分組了。

修改一下 config/config.yaml,如果要指定多個預設的 config ,可以直接往下加就好

defaults:
  - db: mysql

然後將 hydraDemo.py 的 @hydra.main 裝飾器修改一下

 @hydra.main(config_path="config", config_name="config")

重新將 config.yaml 指定上去,之後不帶參數執行

python hydraDemo.py                
db:
  driver: mysql
  user: omry
  password: secret

{'driver': 'mysql', 'user': 'omry', 'password': 'secret'}

會發現使用了 config.yaml 設定的預設值

Multirun 組合執行

在某些情況下,可能需要將不同的 config 組合來執行,例如訓練 AI 模型的時候需要使用不同的參數設定來比對不同的結果。

首先,修改一下 hydraDemo.py ,加入 log 輸出

from omegaconf import DictConfig, OmegaConf
import hydra
import logging

@hydra.main(config_path="config", config_name="config")
def my_app(cfg: DictConfig) -> None:
    print(OmegaConf.to_yaml(cfg))
    print(cfg.db)
    logging.info(connecdb(cfg.db.driver, cfg.db.user, cfg.db.password))
    print(connecdb(cfg.db.driver, cfg.db.user, cfg.db.password))  

def connecdb(driver, user, password):
    return "Connected Sucsefull!! Driver:" + driver + ", user:" + user

if __name__ == "__main__":
    my_app()

然後再以命令列執行

python hydraDemo.py --multirun db.user=ua,ub db.password=pa,pb

會得到這樣的輸出結果

[2021-11-18 21:59:29,919][HYDRA] Launching 4 jobs locally
[2021-11-18 21:59:29,919][HYDRA] 	#0 : db.user=ua db.password=pa
db:
  driver: mysql
  user: ua
  password: pa

{'driver': 'mysql', 'user': 'ua', 'password': 'pa'}
[2021-11-18 21:59:30,061][root][INFO] - Connected Sucsefull!! Driver:mysql, user:ua
Connected Sucsefull!! Driver:mysql, user:ua
[2021-11-18 21:59:30,062][HYDRA] 	#1 : db.user=ua db.password=pb
db:
  driver: mysql
  user: ua
  password: pb

{'driver': 'mysql', 'user': 'ua', 'password': 'pb'}
[2021-11-18 21:59:30,208][root][INFO] - Connected Sucsefull!! Driver:mysql, user:ua
Connected Sucsefull!! Driver:mysql, user:ua
[2021-11-18 21:59:30,209][HYDRA] 	#2 : db.user=ub db.password=pa
db:
  driver: mysql
  user: ub
  password: pa

{'driver': 'mysql', 'user': 'ub', 'password': 'pa'}
[2021-11-18 21:59:30,347][root][INFO] - Connected Sucsefull!! Driver:mysql, user:ub
Connected Sucsefull!! Driver:mysql, user:ub
[2021-11-18 21:59:30,348][HYDRA] 	#3 : db.user=ub db.password=pb
db:
  driver: mysql
  user: ub
  password: pb

{'driver': 'mysql', 'user': 'ub', 'password': 'pb'}
[2021-11-18 21:59:30,486][root][INFO] - Connected Sucsefull!! Driver:mysql, user:ub
Connected Sucsefull!! Driver:mysql, user:ub

輸出結果來看,hydra 會交叉執行各種參數,此外也會將不同執行階段的 log 存在 multirun 的資料夾下面。

結論

本篇文章簡單介紹了 hydra 幾個基本的用法,這樣透過命令列的方式來設定 config 可以省去頻繁修改程式碼,而且可以自動保存每一次的 log 輸出。

關於作者


長也

資管菸酒生,嘗試成為網頁全端工程師(laravel / React),技能樹成長中,閒暇之餘就寫一些筆記。 喔對了,也愛追一些劇,例如火神跟遺物整理師,推推。最愛的樂團應該是告五人吧(?)