Vega已更新到1.2版本,所以本教程以1.2版本爲準進行介紹。
Vega框架鏈接:https://github.com/huawei-noah/vega
Vega論文:VEGA: Towards an End-to-End Configurable AutoML Pipeline[1]
Vega QQ討論羣: 833345709
Vega是基於Pipeline的設計思路,這和我們實驗室寫的AutoML綜述思路不謀而合,感興趣的也可以看看我們的論文:AutoML: A Survey of the State-of-the-art[2]
整體代碼架構
之前的華爲諾亞實驗室AutoML框架-Vega:(1) 介紹 已經介紹了相比於其他的AutoML框架, Vega框架的優點和特性。本文將從代碼結構的角度來介紹Vega,幫助大家對Vega有一個全局的瞭解,主要起到一個幫助索引查找的作用。
普通開發者用戶需要特別關注上圖圈出的4個目錄:
docs
: 該目錄下包含豐富的中英文文檔說明,不同算法的設置和用法可以通過查閱文檔就能輕鬆解決examples
:該目錄下包含所有內置的開箱即用的算法,你可以進入該目錄來選擇運行指定的算法,後面會介紹運行方法vega
:很顯然,這是Vega的核心部件。zeus
:這是一個涵蓋數據集、訓練、評估等階段的全Pipeline通用組件,將Pytorch、TensorFlow和MindSpore三個框架做了整合,用戶在寫好代碼之後可以一鍵切換不同框架。因此如果你想測試不同框架的性能,Zeus一定能助你一臂之力。
看到這你可能會想爲什麼要叫 Vega呢? Vega名字官方的解釋[3]如下:
“ Zhinü (織女, the weaver girl, symbolizing the star Vega) is a fairy in ancient Chinese myths and legends. She's responsible for providing the fairy's clothes and clouds. We hope that Vega will provide AI research and application infrastructure like a weaver girl.
織女是中國古代神話傳說中的仙女,織女類比織女星。她負責提供仙女的衣服和雲彩。我們希望織女星能像織女一樣提供人工智能研究和應用基礎設施。
”
那Zeus也很好理解了,因爲Zeus是古希臘神話中的衆神之王,這裏Zeus將三個流行深度學習框架做了深度整合,提供了基礎的深度學習訓練Pipeline。
Docs提供了什麼?
Docs目錄下提供了中英雙語版本的文檔方便用戶查閱,這裏以中文文檔進行介紹。
由上圖可以看到docs
目錄主要分成四個部分:
user
: 該目錄下的內容主要介紹了Vega初學者需要注意的問題,介紹了Vega中引入的新的概念README.md
: 對user
目錄的總結說明config_reference.md
: Vega的所有任務都是由yaml文件配置的,該文件主要介紹瞭如何在yaml文件中配置不同組件(數據集、算法等)。deployment.md
:介紹如何部署集羣evaluate_service.md
: 介紹如何部署服務器的評估服務examples.md
: 介紹內置算法的在不同階段的輸入(如配置文件和預訓練模型)和輸出(如保存日誌和checkpoints)faq.md
:常見問題和解決辦法install.md
:Vega安裝教程
developer
:該目錄下的內容主要介紹開發者應當如何實現自定義的功能,如自定義數據集、模型、NAS算法等。developer_guide.md
:介紹了Vega的搜索空間、搜索算法和參數配置等基本概念和使用方法datasets.md
: 介紹如何自定義數據集fine_grained_search_space
: 介紹Vega框架的細粒度搜索空間概念和自定義方式new_algorithm.md
:介紹如何自定義算法
algorithms
: 該目錄下包含了所有Vega框架下內置的算法介紹。tasks
:該目錄對幾個常見的CV任務進行介紹不同場景下的使用。
Zeus代碼架構
前面已經提到過了,Zeus是一個提供基礎組件的框架,所有組件採樣註冊機制,因此我們可以通過修改yaml文件設置即可調用不同的組件(如數據集、模型等)。
Zeus的代碼結構如上圖所示,每個模塊的作用其實可以看名字也能大概知道,下面對各個模塊做一個簡單的介紹,後續的教程會做進一步的分析。
common
該目錄下主要提供了各種參數配置組件和註冊工廠。
config.py
: 新建了Config
類,該類繼承自dict
,能夠靈活處理yaml
、json
、py
等不同格式的配置文件,同樣也可以直接傳入一個字典。其代碼大致示例如下:
1 class Config(dict): 2 def __init__(self, *args, **kwargs): 3 """Init config class with multiple config files or dictionary.""" 4 super(Config, self).__init__() 5 for arg in args: 6 if isinstance(arg, str): # 可以傳入多個配置文件的路徑 7 if arg.endswith('.yaml') or arg.endswith('.yml'): 8 ... 9 elif arg.endswith('.py'): 10 ... 11 elif arg.endswith(".json"): 12 ... 13 if kwargs: # 也可以傳入一個字典進行處理 14 ...
config_serializable.py
: 該文件提供了ConfigSerializable
類,該類的作用是提供將類序列化爲Config
的作用,比如我們定義如下類
class MyDatasetConf(ConfigSerializable): data_dir = './data/cifar10' batch_size = 32 ...
之後我們可以只需要執行如下命令即可把MyDatasetConf
這個類轉化成Config
類。
MyDatasetConf.to_json()
user_config.py
:該文件中定義了一個UserConfig
類,該類是單例模式,可以簡單理解成是一個全局信息,因此在整個pipeline過程中都由這個類管理所有配置信息。general.py
: 該文件定義了通用的配置信息,如 日誌信息、集羣配置、任務ID、Backend (可以是Pytorch、TensorFlow或者Mindspore)等。file_ops.py
主要是對常用的文件操作做了封裝,提供了更加便捷的操作task_ops.py
主要管理每次task的ID、日誌路徑、checkpoint路徑等信息class_factory.py
:該文件內定義了兩個非常重要的類,即ClassType
和ClassFactory
,Vega的註冊機制就是靠這兩個類來管理和實現的。ClassType
:該類預先定義好了可以註冊的組件類別,部分代碼示例如下:
class ClassType(object): """Const class saved defined class type.""" DATASET = 'dataset' # 數據集 NETWORK = "network" # 模型 TRAINER = 'trainer' # 訓練器 METRIC = 'trainer.metric' # 指標(如accuracy) OPTIMIZER = 'trainer.optimizer' # 優化器 LR_SCHEDULER = 'trainer.lr_scheduler' # 學習率scheduler LOSS = 'trainer.loss' # 損失函數 EVALUATOR = 'evaluator' # 評估器基類,會自動根據設置調用下面不同類別的評估器 GPU_EVALUATOR = 'evaluator.gpu_evaluator' # GPU評估器,即在GPU上對模型等設置進行評估 HAVA_D_EVALUATOR = 'evaluator.hava_d_evaluator' # 華爲自研達芬奇芯片評估器 DAVINCI_MOBILE_EVALUATOR = 'evaluator.davinci_mobile_evaluator' # 達芬奇移動端評估器 SEARCH_ALGORITHM = 'search_algorithm' # 搜索算法 PIPE_STEP = 'pipe_step' # GENERAL = 'general' # 通用參數配置 TRANSFORM = 'dataset.transforms' # 數據增強 CALLBACK = 'trainer.callback' # Callback (後面教程會介紹) CONFIG = 'CONFIG' # CODEC = 'search_algorithm.codec' # 編碼解碼 (比如進化算法會把模型編碼成01序列,之後也需要解碼) QUOTA = 'quota' # 配額(比如搜索會對時間和flops有要求,可以起到過濾篩選的作用)
ClassFactory
可以通過裝飾器的方式來註冊你想要複用的模塊。如下面的代碼示例,你自定義了一個數據集MyDataset
和模型MyModel
,你只需要在上面加上一行ClassFactory.register(<class type>)
即可完成註冊。
@ClassFactory.register(ClassType.NETWORK) class MyModel(...): ... @ClassFactory.register(ClassType.DATASET) class MyDataset(...): ...
註冊之後,你只需要在yaml
文件中將模型和數據集的名字改成MyModel
和MyDataset
,之後會根據名字自動調用對應的類。
modules、 networks、model_zoo
這三個模塊提供的都是模型結構,看名字可能會覺得有點搞不清楚,區別在於
modules
提供的是一些基礎模塊,Conv2D、MaxPool2d、ResBlock、StemBlock等等networks
提供的通常是一個Zeus內置的完整的網絡結構,比如MobileNetV3
、FasterRCNN
等model_zoo
主要有兩個作用- 將
torchvision
的模型進行了註冊,也就是說你可以很方便地調用torchvision.models
內置的模型,方法是在你想調用的模型名字前面加上torchvision_
前綴即可。假如你想調用ResNet18
,你只需要在yaml
文件裏把模型名稱改爲torchvision_resnet18
。 - 提供了
ModelZoo
類,你可以通過調用該類的ModelZoo.get_model
(model_desc
,pretrained_model_file
)方法來得到指定模型, 其中model_desc
是模型的描述字典信息,比如{'type':'torchvision_resnet18', 'num_classes':10}
,這樣會自動生成一個ResNet18
類,其輸出類別是10;pretrained_model_file
是預訓練模型權重的路徑。
trainer
trainer
模塊下主要有如下兩部分組件:
- 一個是
callbacks
,目前Zeus內置了豐富的Callback,如lr_scheduler
,model_checkpoint
,progress_logger
(負責管理打印日誌信息),model_statistics
(計算模型參數量,FLOPS ,latency)等。這些Callback也支持註冊機制,因此你可以靈活選擇你需要的Callback。
- 另一個是
modules
,如下圖示主要包含了losses
,lr_scheduler
,optimizer
等。
Zeus分別爲Pytorch、TensorFlow、MindSpore三個框架實現了trainer組件,他們都繼承自trainer_base.py
裏的TrainerBase
類,該類實現了通用的參數初始化設置等操作。
trainer_api.py
則是將三個框架的trainer做了整合,會自動根據設置的Backend選擇合適的trainer,代碼示例如下:
# trainer_api.py @ClassFactory.register(ClassType.TRAINER) class Trainer(TrainerBase): """Trainer class.""" def __new__(cls, model=None, id=None, hps=None, load_ckpt_flag=False, model_desc=None, lazy_build=True, **kwargs): """Create Trainer clss.""" if zeus.is_torch_backend(): from zeus.trainer_torch import TrainerTorch trainer_cls = TrainerTorch elif zeus.is_tf_backend(): from zeus.trainer_tf import TrainerTf trainer_cls = TrainerTf else: from zeus.trainer_ms import TrainerMs trainer_cls = TrainerMs return trainer_cls(model=model, id=id, hps=hps, load_ckpt_flag=load_ckpt_flag, model_desc=model_desc, lazy_build=lazy_build, **kwargs)
Vega
下圖是vega目錄下的整體代碼架構,可以看到很簡單隻有3個部分組成,下面開始介紹Vega的代碼架構設計邏輯。
tools
- 提供了一系列的運行腳本,如
run_pipeline.py
,full_train.py
,benchmark.py
,inference.py
等 - 提供依賴包安裝腳本,
install_pkgs.py
core
下圖是core目錄下的代碼結構
Pipeline
Vega是基於Pipeline的設計思路,這和我們實驗室寫的AutoML綜述思路不謀而合。下圖是我們的綜述論文中Pipeline示意圖,Vega的實現方法則是把每個階段視爲一個PipeStep
,通過講這些階段串聯起來就可以很方便且靈活跑完所有階段,而不再需要每個階段跑完後,再手動運行下一個階段代碼。
具體而言,整個pipeline由Vega的Pipeline
類管理執行,另外Vega中的PipeStep
類有三個子類:BenchmarkPipeStep
, NasPipeStep
和FullyTrainPipeStep
,這些定義在vega/core/pipeline
中。
爲了方便理解,我把Pipeline
代碼做了簡化如下進行介紹
class Pipeline: def run(self): for step_name in PipelineConfig.steps: # 遍歷['nas', 'fully_train'] step_cfg = UserConfig().data.get(step_name) # 拿到對應step的參數設置 ... PipeStep().do() # 運行對應Step
可以看到會有一個for
循環來遍歷PipelineConfig.steps
內存儲的所有step名稱,這個是由yaml
文件中的pipeline
定義的(如下圖示)。
每次遍歷會讀取出對應名稱的step參數,比如首先會把名稱爲nas
的參數讀取出來,其實你也可以設置爲其他名字,這個名字主要是爲了方便人理解,主要用於判斷step類型的是上圖中藍色框的部分,因爲不同類型的step會有不同的運行方法。
拿到參數後會運行PipeStep().do()
,這裏面的PipeStep()
會通過設計好的__new__
函數調用對應的step,例如NasPipeStep
,之後會運行NasPipeStep
內設置的do
函數開始運行,這些細節會在後面的教程中做詳細介紹。
search_algs和search_space
search_algs
和search_space
目錄分別定義了搜索算法和搜索空間的基類,爲避免文章累贅,這部分內容也會在後面的教程中做詳細介紹。
backend_register.py
前面已經介紹過了Zeus將三個通用深度學習框架做了整合,vega下的backend_register.py
作用就是設置指定的Backend和設備(如GPU、NPU等)。
在運行代碼前必須設置好Backend,否則會報錯。因爲只有這樣才能,才能知道應該調用哪個框架的模型結構。
run.py
這是Vega框架的運行入口,代碼如下所示。可以看到在對參數進行驗證處理後就會通過_run_pipeline()
函數開始運行指定的Pipeline。
# vega/run.py def run(cfg_path): """Run vega automl. :param cfg_path: config path. """ if sys.version_info < (3, 6): sys.exit('Sorry, Python < 3.6 is not supported.') _init_env(cfg_path) _backup_cfg(cfg_path) _adjust_config() _run_pipeline()
微信公衆號:AutoML機器學習
MARSGGBO♥原創
如有意合作或學術討論歡迎私戳聯繫~
郵箱:[email protected]
2020-11-21 10:44:27
參考資料
[1] VEGA: Towards an End-to-End Configurable AutoML Pipeline: https://arxiv.org/abs/2011.01507
[2] AutoML: A Survey of the State-of-the-art: https://arxiv.org/abs/1908.00709
[3] Vega名字官方的解釋: https://github.com/huawei-noah/vega/issues/74