天天看點

華為諾亞AutoML架構-Vega:(2) 代碼結構

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:(2) 代碼結構

整體代碼架構

之前的華為諾亞實驗室AutoML架構-Vega:(1) 介紹 已經介紹了相比于其他的AutoML架構, Vega架構的優點和特性。本文将從代碼結構的角度來介紹Vega,幫助大家對Vega有一個全局的了解,主要起到一個幫助索引查找的作用。

華為諾亞AutoML架構-Vega:(2) 代碼結構

普通開發者使用者需要特别關注上圖圈出的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目錄下提供了中英雙語版本的文檔友善使用者查閱,這裡以中文文檔進行介紹。

華為諾亞AutoML架構-Vega:(2) 代碼結構

由上圖可以看到

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檔案設定即可調用不同的元件(如資料集、模型等)。

華為諾亞AutoML架構-Vega:(2) 代碼結構

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。
華為諾亞AutoML架構-Vega:(2) 代碼結構
  • 另一個是

    modules

    ,如下圖示主要包含了

    losses

    lr_scheduler

    optimizer

    等。
華為諾亞AutoML架構-Vega:(2) 代碼結構

Zeus分别為Pytorch、TensorFlow、MindSpore三個架構實作了trainer元件,他們都繼承自

trainer_base.py

裡的

TrainerBase

類,該類實作了通用的參數初始化設定等操作。

華為諾亞AutoML架構-Vega:(2) 代碼結構

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的代碼架構設計邏輯。

華為諾亞AutoML架構-Vega:(2) 代碼結構

tools

  • 提供了一系列的運作腳本,如

    run_pipeline.py

    full_train.py

    benchmark.py

    inference.py

  • 提供依賴包安裝腳本,

    install_pkgs.py

core

下圖是core目錄下的代碼結構

華為諾亞AutoML架構-Vega:(2) 代碼結構

Pipeline

Vega是基于Pipeline的設計思路,這和我們實驗室寫的AutoML綜述思路不謀而合。下圖是我們的綜述論文中Pipeline示意圖,Vega的實作方法則是把每個階段視為一個

PipeStep

,通過講這些階段串聯起來就可以很友善且靈活跑完所有階段,而不再需要每個階段跑完後,再手動運作下一個階段代碼。

華為諾亞AutoML架構-Vega:(2) 代碼結構

具體而言,整個pipeline由Vega的

Pipeline

類管理執行,另外Vega中的

PipeStep

類有三個子類:

BenchmarkPipeStep

NasPipeStep

FullyTrainPipeStep

,這些定義在

vega/core/pipeline

中。

華為諾亞AutoML架構-Vega:(2) 代碼結構

為了友善了解,我把

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

定義的(如下圖示)。

華為諾亞AutoML架構-Vega:(2) 代碼結構

每次周遊會讀取出對應名稱的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

繼續閱讀