Unverified Commit 25db55ca authored by kvartet's avatar kvartet Committed by GitHub
Browse files

Update Chinese documents (#3243)

parent 53b565e4
NNI 中使用 Hyperband
================================
1. 介绍
---------------
`Hyperband <https://arxiv.org/pdf/1603.06560.pdf>`__ 是一种流行的自动机器学习算法。 Hyperband 的基本思想是对配置分组,每组有 ``n`` 个随机生成的超参配置,每个配置使用 ``r`` 次资源(如,epoch 数量,批处理数量等)。 当 ``n`` 个配置完成后,会选择最好的 ``n/eta`` 个配置,并增加 ``r*eta`` 次使用的资源。 最后,会选择出的最好配置。
2. 实现并行
---------------------------------------
首先,此示例是基于 MsgDispatcherBase 来实现的自动机器学习算法,而不是基于 Tuner 和 Assessor。 这种实现方法下,Hyperband 集成了 Tuner 和 Assessor 两者的功能,因而将它叫做 Advisor。
其次,本实现完全利用了 Hyperband 内部的并行性。 具体来说,下一个分组不会严格的在当前分组结束后再运行。 只要有资源,就可以开始运行新的分组。 如果要使用完全并行模式,请将 ``exec_mode`` 设置为 ``parallelism(并行)``。
或者,根据原始算法将 ``exec_mode`` 设置为 ``serial(串行)``。 如果是 ``串行`` , Tuner 只会在当前分组完成后启动新的分组。
``并行`` 模式可能会导致多个未完成的分组,而 ``串行`` 模式下最多只有一个未完成的分组。 ``并行`` 模式的优点是充分利用资源,成倍减少实验时间。 下面两张图片是使用 `nas-bench-201 <../NAS/Benchmarks.rst>`__ 快速验证的结果,上面的图片是 ``并行`` 模式,下面的图片是 ``串行`` 模式。
.. image:: ../../img/hyperband_parallelism.png
:target: ../../img/hyperband_parallelism.png
:alt: parallelism mode
.. image:: ../../img/hyperband_serial.png
:target: ../../img/hyperband_serial.png
:alt: serial mode
如果你想复现这些结果,请参考示例 ``examples/trials/benchmarking/``。
3. 用法
--------
要使用 Hyperband,需要在 Experiment 的 YAML 配置文件进行如下改动。
.. code-block:: bash
advisor:
#choice: Hyperband
builtinAdvisorName: Hyperband
classArgs:
#R: Trial 的最大分组
R: 100
# eta: 丢弃的 Trial 的比例
eta: 3
#choice: 最大、最小
optimize_mode: maximize
#choice: 串行、并行
exec_mode: parallelism
注意,一旦使用了 Advisor,就不能在配置文件中添加 Tuner 和 Assessor。 使用 Hyperband 时,Trial 代码收到的超参(如键值对)中,会多一个用户定义的 ``TRIAL_BUDGET``。 **使用 ``TRIAL_BUDGET``, Trial 可以控制运行的时间。**
对于 Trial 代码中 ``report_intermediate_result(metric)`` 和 ``report_final_result(metric)``,**\ ``指标`` 应该是数值,或者用一个 dict,并保证其中有键值为 ``default`` 的项目,其值也为数值型**。 这是需要进行最大化或者最小化优化的数值,如精度或者损失度。
``R`` 和 ``eta`` 是 Hyperband 中可以改动的参数。 ``R`` 表示可以分配给 Trial 的最大资源。 这里,资源可以代表 epoch 或 批处理数量。 ``TRIAL_BUDGET`` 应该被尝试代码用来控制运行的次数。 参考示例 ``examples/trials/mnist-advisor/`` ,了解详细信息。
``eta`` 表示 ``n/eta`` 个配置中的 ``n/eta`` 个配置会留存下来,并用更多的资源来运行。
下面是 ``R=81`` 且 ``eta=3`` 时的样例:
.. list-table::
:header-rows: 1
:widths: auto
* -
- s=4
- s=3
- s=2
- s=1
- s=0
* - i
- n r
- n r
- n r
- n r
- n r
* - 0
- 81 1
- 27 3
- 9 9
- 6 27
- 5 81
* - 1
- 27 3
- 9 9
- 3 27
- 2 81
-
* - 2
- 9 9
- 3 27
- 1 81
-
-
* - 3
- 3 27
- 1 81
-
-
-
* - 4
- 1 81
-
-
-
-
``s`` 表示分组, ``n`` 表示生成的配置数量,相应的 ``r`` 表示配置使用多少资源来运行。 ``i`` 表示轮数,如分组 4 有 5 轮,分组 3 有 4 轮。
关于如何实现 Trial 代码,参考 ``examples/trials/mnist-hyperband/`` 中的说明。
4. 未来的改进
----------------------
当前实现的 Hyperband 算法可以通过改进支持的提前终止算法来提高,因为最好的 ``n/eta`` 个配置并不一定都表现很好。 不好的配置应该更早的终止。
在当前实现中,遵循了 `此论文 <https://arxiv.org/pdf/1603.06560.pdf>`__ 的设计,配置都是随机生成的。 要进一步提升,配置生成过程可以利用更高级的算法。
# TPE, Random Search, Anneal Tuners
TPE, Random Search, Anneal Tuners
========================================
## TPE
TPE
---
Tree-structured Parzen Estimator (TPE) 是一种 sequential model-based optimization(SMBO,即基于序列模型优化)的方法。 SMBO 方法根据历史指标数据来按顺序构造模型,来估算超参的性能,随后基于此模型来选择新的超参。 TPE 方法对 P(x|y) 和 P(y) 建模,其中 x 表示超参,y 表示相关的评估指标。 P(x|y) 通过变换超参的生成过程来建模,用非参数密度(non-parametric densities)代替配置的先验分布。 细节可参考 [Algorithms for Hyper-Parameter Optimization](https://papers.nips.cc/paper/4443-algorithms-for-hyper-parameter-optimization.pdf)。 ​
Tree-structured Parzen Estimator (TPE) 是一种 sequential model-based optimization(SMBO,即基于序列模型优化)的方法。 SMBO 方法根据历史指标数据来按顺序构造模型,来估算超参的性能,随后基于此模型来选择新的超参。 TPE 方法对 P(x|y) 和 P(y) 建模,其中 x 表示超参,y 表示相关的评估指标。 P(x|y) 通过变换超参的生成过程来建模,用非参数密度(non-parametric densities)代替配置的先验分布。 优化方法在论文 `Algorithms for Hyper-Parameter Optimization <https://papers.nips.cc/paper/4443-algorithms-for-hyper-parameter-optimization.pdf>`__ 中有详细描述。 ​
### TPE 的并行优化
TPE 的并行优化
^^^^^^^^^^^^^^^^^^^^^^^^^
为了利用多个计算节点,TPE 方法是异步运行的,这样能避免浪费时间等待 Trial 评估的完成。 对原始算法设计进行了顺序计算优化。 如果要大并发的使用 TPE,性能将会较差。 通过 Constant Liar 算法优化了这种情况。 关于优化的原理,参考[文档](../CommunitySharings/ParallelizingTpeSearch.md)
为了利用多个计算节点,TPE 方法是异步运行的,这样能避免浪费时间等待 Trial 评估的完成。 对原始算法设计进行了顺序计算优化。 如果要大并发的使用 TPE,性能将会较差。 通过 Constant Liar 算法优化了这种情况。 关于优化的原理,参考 `这里 <../CommunitySharings/ParallelizingTpeSearch.rst>`__
### 用法
用法
^^^^^
要使用 TPE,需要在 Experiment 的 YAML 配置文件进行如下改动:
要使用 TPE,需要在 Experiment 的 YAML 配置文件进行如下改动:
```yaml
tuner:
builtinTunerName: TPE
classArgs:
optimize_mode: maximize
parallel_optimize: True
constant_liar_type: min
```
.. code-block:: yaml
tuner:
builtinTunerName: TPE
classArgs:
optimize_mode: maximize
parallel_optimize: True
constant_liar_type: min
**classArgs 要求:**
* **optimize_mode** (*maximize 或 minimize, 可选项, 默认值为 maximize*) - 如果为 'maximize',表示 Tuner 会试着最大化指标。 如果为 'minimize',表示 Tuner 的目标是将指标最小化。
* **parallel_optimize** (*bool, 可选, 默认值为 False*) - 如果为 True,TPE 会使用 Constant Liar 算法来优化并行超参调优。 否则,TPE 不会区分序列或并发的情况。
* **constant_liar_type** (*min、max 或 mean, 可选, 默认值为 min*) - 使用的 constant liar 类型,会在 X 点根据 y 的取值来确定。对应三个值:min{Y}, max{Y}, 和 mean{Y}。
## Random Search(随机搜索)
Random Search(随机搜索)
---------------------------------------
[Random Search for Hyper-Parameter Optimization](http://www.jmlr.org/papers/volume13/bergstra12a/bergstra12a.pdf) 中介绍了随机搜索惊人的简单和效果。 建议在不知道超参数的先验分布时,使用随机搜索作为基准。
论文 `Random Search for Hyper-Parameter Optimization <http://www.jmlr.org/papers/volume13/bergstra12a/bergstra12a.pdf>`__ 中介绍了随机搜索惊人的简单和效果。 建议在不知道超参数的先验分布时,使用随机搜索作为基准。
## Anneal(退火算法)
Anneal(退火算法)
------------------------
这种简单的退火算法从先前的采样开始,会越来越靠近发现的最佳点取样。 此算法是随机搜索的简单变体,利用了反应曲面的平滑性。 退火率不是自适应的。
\ No newline at end of file
这种简单的退火算法从先前的采样开始,会越来越靠近发现的最佳点取样。 此算法是随机搜索的简单变体,利用了反应曲面的平滑性。 退火率不是自适应的。
# 如何将自定义的 Tuner 安装为内置 Tuner
参考下列步骤将自定义 Tuner: `nni/examples/tuners/customized_tuner` 安装为内置 Tuner。
## 准备安装源和安装包
有两种方法安装自定义的 Tuner:
### 方法 1: 从目录安装
步骤 1: 在 `nni/examples/tuners/customized_tuner` 目录下,运行:
`python setup.py develop`
此命令会将 `nni/examples/tuners/customized_tuner` 目录编译为 pip 安装源。
步骤 2: 运行命令
`nnictl package install ./`
### 方法 2: 从 whl 文件安装
步骤 1: 在 `nni/examples/tuners/customized_tuner` 目录下,运行:
`python setup.py bdist_wheel`
此命令会从 pip 安装源编译出 whl 文件。
步骤 2: 运行命令
`nnictl package install dist/demo_tuner-0.1-py3-none-any.whl`
## 检查安装的包
运行命令 `nnictl package list`,可以看到已安装的 demotuner:
```
+-----------------+------------+-----------+--------=-------------+------------------------------------------+
| Name | Type | Installed | Class Name | Module Name |
+-----------------+------------+-----------+----------------------+------------------------------------------+
| demotuner | tuners | Yes | DemoTuner | demo_tuner |
+-----------------+------------+-----------+----------------------+------------------------------------------+
```
## 在 Experiment 中使用安装的 Tuner
可以像使用其它内置 Tuner 一样,在 Experiment 配置文件中使用 demotuner:
```yaml
tuner:
builtinTunerName: demotuner
classArgs:
#可选项: maximize, minimize
optimize_mode: maximize
```
如何将自定义的 Tuner 安装为内置 Tuner
==================================================
参考下列步骤将自定义 Tuner: ``nni/examples/tuners/customized_tuner`` 安装为内置 Tuner。
准备安装源和安装包
-----------------------------------------------
有两种方法安装自定义的 Tuner:
方法 1: 从目录安装
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
步骤 1: 在 ``nni/examples/tuners/customized_tuner`` 目录下,运行:
``python setup.py develop``
此命令会将 ``nni/examples/tuners/customized_tuner`` 目录编译为 pip 安装源。
步骤 2: 运行命令
``nnictl package install ./``
方法 2: 从 whl 文件安装
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
步骤 1: 在 ``nni/examples/tuners/customized_tuner`` 目录下,运行:
``python setup.py bdist_wheel``
此命令会从 pip 安装源编译出 whl 文件。
步骤 2: 运行命令
``nnictl package install dist/demo_tuner-0.1-py3-none-any.whl``
检查安装的包
---------------------------
运行命令 ``nnictl package list``,可以看到已安装的 demotuner:
.. code-block:: bash
+-----------------+------------+-----------+--------=-------------+------------------------------------------+
| Name | Type | Installed | Class Name | Module Name |
+-----------------+------------+-----------+----------------------+------------------------------------------+
| demotuner | tuners | Yes | DemoTuner | demo_tuner |
+-----------------+------------+-----------+----------------------+------------------------------------------+
在 Experiment 中使用安装的 Tuner
-------------------------------------
可以像使用其它内置 Tuner 一样,在 Experiment 配置文件中使用 demotuner:
.. code-block:: yaml
tuner:
builtinTunerName: demotuner
classArgs:
#choice: maximize, minimize
optimize_mode: maximize
# Metis Tuner
Metis Tuner
==================
## Metis Tuner
Metis Tuner
-----------
[Metis](https://www.microsoft.com/en-us/research/publication/metis-robustly-tuning-tail-latencies-cloud-systems/) 相对于别的调优算法,有几个优势。 大多数调参工具仅仅预测最优配置,而 Metis 具有两个输出,最优配置的预测, 以及下一次 Trial 的建议。 不再需要随机猜测!
`Metis <https://www.microsoft.com/en-us/research/publication/metis-robustly-tuning-tail-latencies-cloud-systems/>`__ 相对于别的调优算法,有几个优势。 大多数调参工具仅仅预测最优配置,而 Metis 具有两个输出,最优配置的预测, 以及下一次 Trial 的建议。 不再需要随机猜测!
大多数工具假设训练集没有噪声数据,但 Metis 会知道是否需要对某个超参重新采样。
......@@ -10,10 +12,13 @@
Metis 属于基于序列的贝叶斯优化 (SMBO) 算法的类别,它也基于贝叶斯优化框架。 为了对超参-性能空间建模,Metis 同时使用了高斯过程(Gaussian Process)和高斯混合模型(GMM)。 由于每次 Trial 都可能有很高的时间成本,Metis 大量使用了已有模型来进行推理计算。 在每次迭代中,Metis 执行两个任务:
* 在高斯过程空间中找到全局最优点。 这一点表示了最佳配置。
* 它会标识出下一个超参的候选项。 这是通过对隐含信息的探索、挖掘和重采样来实现的。
*
在高斯过程空间中找到全局最优点。 这一点表示了最佳配置。
此 Tuner 搜索空间仅接受 `quniform``uniform``randint` 和数值的 `choice` 类型。
*
它会标识出下一个超参的候选项。 这是通过对隐含信息的探索、挖掘和重采样来实现的。
更多详情,参考[论文](https://www.microsoft.com/en-us/research/publication/metis-robustly-tuning-tail-latencies-cloud-systems/)
\ No newline at end of file
此 Tuner 搜索空间仅接受 ``quniform,uniform,randint`` 和数值的 ``choice`` 类型。
更多详情,参考 `论文 <https://www.microsoft.com/en-us/research/publication/metis-robustly-tuning-tail-latencies-cloud-systems/>`__。
# Network Morphism Tuner
## 1. 介绍
[Autokeras](https://arxiv.org/abs/1806.10282) 是使用 Network Morphism 算法的流行的自动机器学习工具。 Autokeras 的基本理念是使用贝叶斯回归来预测神经网络架构的指标。 每次都会从父网络生成几个子网络。 然后使用朴素贝叶斯回归,从网络的历史训练结果来预测它的指标值。 接下来,会选择预测结果最好的子网络加入训练队列中。 在[此代码](https://github.com/jhfjhfj1/autokeras)的启发下,我们在 NNI 中实现了 Network Morphism 算法。
要了解 Network Morphism Trial 的用法,参考 [Readme_zh_CN.md](https://github.com/Microsoft/nni/blob/master/examples/trials/network_morphism/README_zh_CN.md)
## 2. 用法
要使用 Network Morphism,需要如下配置 `config.yml` 文件:
```yaml
tuner:
#选择: NetworkMorphism
builtinTunerName: NetworkMorphism
classArgs:
#可选项: maximize, minimize
optimize_mode: maximize
#当前仅支持 cv 领域
task: cv
#修改来支持实际图像宽度
input_width: 32
#修改来支持实际图像通道
input_channel: 3
#修改来支持实际的分类数量
n_output_node: 10
```
在训练过程中,会生成一个 JSON 文件来表示网络图。 可调用 "json\_to\_graph()" 函数来将 JSON 文件转化为 Pytoch 或 Keras 模型。
```python
import nni
from nni.networkmorphism_tuner.graph import json_to_graph
def build_graph_from_json(ir_model_json):
"""从 JSON 生成 Pytorch 模型
"""
graph = json_to_graph(ir_model_json)
model = graph.produce_torch_model()
return model
# 从网络形态 Tuner 中获得下一组参数
RCV_CONFIG = nni.get_next_parameter()
# 调用函数来生成 Pytorch 或 Keras 模型
net = build_graph_from_json(RCV_CONFIG)
# 训练过程
# ....
# 将最终精度返回给 NNI
nni.report_final_result(best_acc)
```
如果需要保存并读取**最佳模型**,推荐采用以下方法。
```python
# 1. 使用 NNI API
## 可以通过 Web 界面获取最佳模型
## 或者通过 `nni-experiments/experiment_id/log/model_path/best_model.txt'
## 从模型文件中读取 json 字符串并使用 NNI API 加载
with open("best-model.json") as json_file:
json_of_model = json_file.read()
model = build_graph_from_json(json_of_model)
# 2. 使用框架的 API (与具体框架相关)
## 2.1 Keras API
## 在 Trial 代码中使用 Keras API 保存
## 最好保存 NNI 的 ID
model_id = nni.get_sequence_id()
## 将模型序列化为 JSON
model_json = model.to_json()
with open("model-{}.json".format(model_id), "w") as json_file:
json_file.write(model_json)
## 将权重序列化至 HDF5
model.save_weights("model-{}.h5".format(model_id))
## 重用模型时,使用 Keras API 读取
## 读取 JSON 文件,并创建模型
model_id = "" # 需要重用的模型 ID
with open('model-{}.json'.format(model_id), 'r') as json_file:
loaded_model_json = json_file.read()
loaded_model = model_from_json(loaded_model_json)
## 将权重加载到新模型中
loaded_model.load_weights("model-{}.h5".format(model_id))
## 2.2 PyTorch API
## 在 Trial 代码中使用 PyTorch API 保存
model_id = nni.get_sequence_id()
torch.save(model, "model-{}.pt".format(model_id))
## 重用模型时,使用 PyTorch API 读取
model_id = "" # 需要重用的模型 ID
loaded_model = torch.load("model-{}.pt".format(model_id))
```
## 3. 文件结构
Tuner 有大量的文件、函数和类。 这里简单介绍最重要的文件:
- `networkmorphism_tuner.py` 是使用 network morphism 算法的 Tuner。
- `bayesian.py` 是用来基于已经搜索到的模型来预测未知模型指标的贝叶斯算法。
- `graph.py` 是元图数据结构。 类 Graph 表示了模型的神经网络图。
- Graph 从模型中抽取神经网络。
- 图中的每个节点都是层之间的中间张量。
- 在图中,边表示层。
- 注意,多条边可能会表示同一层。
- `graph_transformer.py` 包含了一些图转换,包括变宽,变深,或在图中增加跳跃连接。
- `layers.py` 包括模型中用到的所有层。
- `layer_transformer.py` 包含了一些层转换,包括变宽,变深,或在层中增加跳跃连接。
- `nn.py` 包括生成初始网络的类。
- `metric.py` 包括了一些指标类,如 Accuracy 和 MSE。
- `utils.py` 是使用 Keras 在数据集 `cifar10` 上搜索神经网络的示例。
## 4. 网络表示的 JSON 示例
这是定义的中间表示 JSON 示例,在架构搜索过程中会从 Tuner 传到 Trial。 可调用 Trial 代码中的 "json\_to\_graph()" 函数来将 JSON 文件转化为 Pytoch 或 Keras 模型。
```json
{
"input_shape": [32, 32, 3],
"weighted": false,
"operation_history": [],
"layer_id_to_input_node_ids": {"0": [0],"1": [1],"2": [2],"3": [3],"4": [4],"5": [5],"6": [6],"7": [7],"8": [8],"9": [9],"10": [10],"11": [11],"12": [12],"13": [13],"14": [14],"15": [15],"16": [16]
},
"layer_id_to_output_node_ids": {"0": [1],"1": [2],"2": [3],"3": [4],"4": [5],"5": [6],"6": [7],"7": [8],"8": [9],"9": [10],"10": [11],"11": [12],"12": [13],"13": [14],"14": [15],"15": [16],"16": [17]
},
"adj_list": {
"0": [[1, 0]],
"1": [[2, 1]],
"2": [[3, 2]],
"3": [[4, 3]],
"4": [[5, 4]],
"5": [[6, 5]],
"6": [[7, 6]],
"7": [[8, 7]],
"8": [[9, 8]],
"9": [[10, 9]],
"10": [[11, 10]],
"11": [[12, 11]],
"12": [[13, 12]],
"13": [[14, 13]],
"14": [[15, 14]],
"15": [[16, 15]],
"16": [[17, 16]],
"17": []
},
"reverse_adj_list": {
"0": [],
"1": [[0, 0]],
"2": [[1, 1]],
"3": [[2, 2]],
"4": [[3, 3]],
"5": [[4, 4]],
"6": [[5, 5]],
"7": [[6, 6]],
"8": [[7, 7]],
"9": [[8, 8]],
"10": [[9, 9]],
"11": [[10, 10]],
"12": [[11, 11]],
"13": [[12, 12]],
"14": [[13, 13]],
"15": [[14, 14]],
"16": [[15, 15]],
"17": [[16, 16]]
},
"node_list": [
[0, [32, 32, 3]],
[1, [32, 32, 3]],
[2, [32, 32, 64]],
[3, [32, 32, 64]],
[4, [16, 16, 64]],
[5, [16, 16, 64]],
[6, [16, 16, 64]],
[7, [16, 16, 64]],
[8, [8, 8, 64]],
[9, [8, 8, 64]],
[10, [8, 8, 64]],
[11, [8, 8, 64]],
[12, [4, 4, 64]],
[13, [64]],
[14, [64]],
[15, [64]],
[16, [64]],
[17, [10]]
],
"layer_list": [
[0, ["StubReLU", 0, 1]],
[1, ["StubConv2d", 1, 2, 3, 64, 3]],
[2, ["StubBatchNormalization2d", 2, 3, 64]],
[3, ["StubPooling2d", 3, 4, 2, 2, 0]],
[4, ["StubReLU", 4, 5]],
[5, ["StubConv2d", 5, 6, 64, 64, 3]],
[6, ["StubBatchNormalization2d", 6, 7, 64]],
[7, ["StubPooling2d", 7, 8, 2, 2, 0]],
[8, ["StubReLU", 8, 9]],
[9, ["StubConv2d", 9, 10, 64, 64, 3]],
[10, ["StubBatchNormalization2d", 10, 11, 64]],
[11, ["StubPooling2d", 11, 12, 2, 2, 0]],
[12, ["StubGlobalPooling2d", 12, 13]],
[13, ["StubDropout2d", 13, 14, 0.25]],
[14, ["StubDense", 14, 15, 64, 64]],
[15, ["StubReLU", 15, 16]],
[16, ["StubDense", 16, 17, 64, 10]]
]
}
```
可将模型视为[有向无环图](https://en.wikipedia.org/wiki/Directed_acyclic_graph)。 每个模型的定义都是一个 JSON 对象:
- `input_shape` 是整数的列表,不包括批量维度。
- `weighted` 表示是否权重和偏移值应该包含在此神经网络图中。
- `operation_history` 是保存了所有网络形态操作的列表。
- `layer_id_to_input_node_ids` 是字典,将层的标识映射到输入节点标识。
- `layer_id_to_output_node_ids` 是字典,将层的标识映射到输出节点标识。
- `adj_list` 是二维列表,是图的邻接表。 第一维是张量标识。 在每条边的列表中,元素是两元组(张量标识,层标识)。
- `reverse_adj_list` 是与 adj_list 格式一样的反向邻接列表。
- `node_list` 是一个整数列表。 列表的索引是标识。
- `layer_list` 是层的列表。 列表的索引是标识。
- 对于 `StubConv(StubConv1d, StubConv2d, StubConv3d)`,后面的数字表示节点的输入 id(或 id 列表),节点输出 id,input_channel,filters,kernel_size,stride 和 padding。
- 对于 `StubDense`,后面的数字表示节点的输入 id (或 id 列表),节点输出 id,input_units 和 units。
- 对于 `StubBatchNormalization (StubBatchNormalization1d, StubBatchNormalization2d, StubBatchNormalization3d)`,后面的数字表示节点输入 id(或 id 列表),节点输出 id,和特征数量。
- 对于 `StubDropout(StubDropout1d, StubDropout2d, StubDropout3d)`,后面的数字表示节点的输入 id (或 id 列表),节点的输出 id 和 dropout 率。
- 对于 `StubPooling (StubPooling1d, StubPooling2d, StubPooling3d)`后面的数字表示节点的输入 id(或 id 列表),节点输出 id,kernel_size, stride 和 padding。
- 对于其它层,后面的数字表示节点的输入 id(或 id 列表)以及节点的输出 id。
## 5. TODO
下一步,会将 API 从固定网络生成器,改为有更多可用操作的网络生成器。 会使用 ONNX 格式来替代 JSON 作为中间表示结果。
\ No newline at end of file
Network Morphism Tuner
=============================
1. 介绍
---------------
`Autokeras <https://arxiv.org/abs/1806.10282>`__ 是使用 Network Morphism 算法的流行的自动机器学习工具。 Autokeras 的基本理念是使用贝叶斯回归来预测神经网络架构的指标。 每次都会从父网络生成几个子网络。 然后使用朴素贝叶斯回归,从网络的历史训练结果来预测它的指标值。 接下来,会选择预测结果最好的子网络加入训练队列中。 `此代码 <https://github.com/jhfjhfj1/autokeras>`__ 的启发下,我们在 NNI 中实现了 Network Morphism 算法。
要了解 Network Morphism Trial 的用法,参考 :githublink:`这里 <examples/trials/network_morphism/README.md>`
2. 用法
--------
要使用 Network Morphism,需要如下配置 ``config.yml`` 文件:
.. code-block:: yaml
tuner:
#choice: NetworkMorphism
builtinTunerName: NetworkMorphism
classArgs:
#choice: maximize, minimize
optimize_mode: maximize
# 当前,此 Tuner 仅支持视觉领域。
task: cv
# 修改以适合输入图像的宽度
input_width: 32
# 修改以适合输入图像的通道数
input_channel: 3
# 修改以适合类数
n_output_node: 10
在训练过程中,会生成一个 JSON 文件来表示网络图。 可调用 ``json\_to\_graph()`` 函数来将 JSON 文件转化为 Pytoch Keras 模型。
.. code-block:: python
import nni
from nni.networkmorphism_tuner.graph import json_to_graph
def build_graph_from_json(ir_model_json):
"""从json构建pytorch模型
"""
graph = json_to_graph(ir_model_json)
model = graph.produce_torch_model()
return model
# Trial Network Morphism Tuner 获取下一个参数
RCV_CONFIG = nni.get_next_parameter()
# 调用此函数来构建pytorch模型或keras模型
net = build_graph_from_json(RCV_CONFIG)
# 训练过程
# ....
# 将最终精度返回给 NNI
nni.report_final_result(best_acc)
如果需要保存并读取 **最佳模型** ,推荐采用以下方法。
.. code-block:: python
# 1. 使用 NNI API
# WebUI 获得最佳模型 ID
# or 'nni-experiments/experiment_id/log/model_path/best_model.txt'
# 从模型文件中读取 json 字符串,并用 NNI API 加载
with open("best-model.json") as json_file:
json_of_model = json_file.read()
model = build_graph_from_json(json_of_model)
# 2. # 使用框架 API
# 2.1 Keras API
# Trial 代码中使用 Keras API 保存模型
# 最好在 NNI 本地模式下保存 id
model_id = nni.get_sequence_id()
# 将模型序列化为 JSON
model_json = model.to_json()
with open("model-{}.json".format(model_id), "w") as json_file:
json_file.write(model_json)
# 将权重序列化为 HDF5
model.save_weights("model-{}.h5".format(model_id))
# 重用模型时,使用 Keras API 读取
# 读取 JSON 文件,并创建模型
model_id = "" # 需要重用的模型 ID
with open('model-{}.json'.format(model_id), 'r') as json_file:
loaded_model_json = json_file.read()
loaded_model = model_from_json(loaded_model_json)
# 将权重加载到新模型中
loaded_model.load_weights("model-{}.h5".format(model_id))
# 2.2 PyTorch API
# Trial 代码中使用 PyTorch API 保存
model_id = nni.get_sequence_id()
torch.save(model, "model-{}.pt".format(model_id))
# 重用模型时,使用 PyTorch API 读取
model_id = "" # id of the model you want to reuse
loaded_model = torch.load("model-{}.pt".format(model_id))
3. 文件结构
-----------------
Tuner 有大量的文件、函数和类。 这里简单介绍最重要的文件:
*
``networkmorphism_tuner.py`` 是使用 network morphism 算法的 Tuner
*
``bayesian.py`` 是用来基于已经搜索到的模型来预测未知模型指标的贝叶斯算法。
* ``graph.py`` 是元图数据结构。 Graph 表示了模型的神经网络图。
* Graph 从模型中抽取神经网络。
* 图中的每个节点都是层之间的中间张量。
* 在图中,边表示层。
* 注意,多条边可能会表示同一层。
*
``graph_transformer.py`` 包含了一些图转换,包括变宽,变深,或在图中增加跳跃连接。
*
``layers.py`` 包括模型中用到的所有层。
* ``layer_transformer.py`` 包含了一些层转换,包括变宽,变深,或在层中增加跳跃连接。
* ``nn.py`` 包括生成初始网络的类。
* ``metric.py`` 包括了一些指标类,如 Accuracy MSE
* ``utils.py`` 是使用 Keras 在数据集 ``cifar10`` 上搜索神经网络的示例。
4. 网络表示的 JSON 示例
------------------------------------------
这是样例定义的中间表示 JSON 文件,它会在架构搜索过程中从 Tuner 传到 Trial 可调用 Trial 代码中的 ``json_to_graph()`` 函数来将 JSON 文件转化为 Pytoch Keras 模型。
.. code-block:: json
{
"input_shape": [32, 32, 3],
"weighted": false,
"operation_history": [],
"layer_id_to_input_node_ids": {"0": [0],"1": [1],"2": [2],"3": [3],"4": [4],"5": [5],"6": [6],"7": [7],"8": [8],"9": [9],"10": [10],"11": [11],"12": [12],"13": [13],"14": [14],"15": [15],"16": [16]
},
"layer_id_to_output_node_ids": {"0": [1],"1": [2],"2": [3],"3": [4],"4": [5],"5": [6],"6": [7],"7": [8],"8": [9],"9": [10],"10": [11],"11": [12],"12": [13],"13": [14],"14": [15],"15": [16],"16": [17]
},
"adj_list": {
"0": [[1, 0]],
"1": [[2, 1]],
"2": [[3, 2]],
"3": [[4, 3]],
"4": [[5, 4]],
"5": [[6, 5]],
"6": [[7, 6]],
"7": [[8, 7]],
"8": [[9, 8]],
"9": [[10, 9]],
"10": [[11, 10]],
"11": [[12, 11]],
"12": [[13, 12]],
"13": [[14, 13]],
"14": [[15, 14]],
"15": [[16, 15]],
"16": [[17, 16]],
"17": []
},
"reverse_adj_list": {
"0": [],
"1": [[0, 0]],
"2": [[1, 1]],
"3": [[2, 2]],
"4": [[3, 3]],
"5": [[4, 4]],
"6": [[5, 5]],
"7": [[6, 6]],
"8": [[7, 7]],
"9": [[8, 8]],
"10": [[9, 9]],
"11": [[10, 10]],
"12": [[11, 11]],
"13": [[12, 12]],
"14": [[13, 13]],
"15": [[14, 14]],
"16": [[15, 15]],
"17": [[16, 16]]
},
"node_list": [
[0, [32, 32, 3]],
[1, [32, 32, 3]],
[2, [32, 32, 64]],
[3, [32, 32, 64]],
[4, [16, 16, 64]],
[5, [16, 16, 64]],
[6, [16, 16, 64]],
[7, [16, 16, 64]],
[8, [8, 8, 64]],
[9, [8, 8, 64]],
[10, [8, 8, 64]],
[11, [8, 8, 64]],
[12, [4, 4, 64]],
[13, [64]],
[14, [64]],
[15, [64]],
[16, [64]],
[17, [10]]
],
"layer_list": [
[0, ["StubReLU", 0, 1]],
[1, ["StubConv2d", 1, 2, 3, 64, 3]],
[2, ["StubBatchNormalization2d", 2, 3, 64]],
[3, ["StubPooling2d", 3, 4, 2, 2, 0]],
[4, ["StubReLU", 4, 5]],
[5, ["StubConv2d", 5, 6, 64, 64, 3]],
[6, ["StubBatchNormalization2d", 6, 7, 64]],
[7, ["StubPooling2d", 7, 8, 2, 2, 0]],
[8, ["StubReLU", 8, 9]],
[9, ["StubConv2d", 9, 10, 64, 64, 3]],
[10, ["StubBatchNormalization2d", 10, 11, 64]],
[11, ["StubPooling2d", 11, 12, 2, 2, 0]],
[12, ["StubGlobalPooling2d", 12, 13]],
[13, ["StubDropout2d", 13, 14, 0.25]],
[14, ["StubDense", 14, 15, 64, 64]],
[15, ["StubReLU", 15, 16]],
[16, ["StubDense", 16, 17, 64, 10]]
]
}
可将模型视为 `有向无环图 <https://zh.wikipedia.org/wiki/Directed_acyclic_graph>`__ 每个模型的定义都是一个 JSON 对象:
* ``input_shape`` 是整数的列表,不包括批量维度。
* ``weighted`` 表示是否权重和偏移值应该包含在此神经网络图中。
* ``operation_history`` 是保存了所有网络形态操作的列表。
* ``layer_id_to_input_node_ids`` 是字典,将层的标识映射到输入节点标识。
* ``layer_id_to_output_node_ids`` 是字典,将层的标识映射到输出节点标识。
* ``adj_list`` 是二维列表,是图的邻接表。 第一维是张量标识。 在每条边的列表中,元素是两元组(张量标识,层标识)。
* ``reverse_adj_list`` 是与 adj_list 格式一样的反向邻接列表。
* ``node_list`` 是一个整数列表。 列表的索引是标识。
* ``layer_list`` 是层的列表。 列表的索引是标识。
* 对于 ``StubConv(StubConv1d, StubConv2d, StubConv3d)``,后面的数字表示节点的输入 id(或 id 列表),节点输出 idinput_channelfilterskernel_sizestride padding
* 对于 ``StubDense``,后面的数字表示节点的输入 id (或 id 列表),节点输出 idinput_units units
* 对于 ``StubBatchNormalization (StubBatchNormalization1d, StubBatchNormalization2d, StubBatchNormalization3d)``,后面的数字表示节点输入 id(或 id 列表),节点输出 id,和特征数量。
* 对于 ``StubDropout(StubDropout1d, StubDropout2d, StubDropout3d)``,后面的数字表示节点的输入 id (或 id 列表),节点的输出 id dropout 率。
* 对于 ``StubPooling (StubPooling1d, StubPooling2d, StubPooling3d)`` 后面的数字表示节点的输入 id(或 id 列表),节点输出 idkernel_size, stride padding
* 对于其它层,后面的数字表示节点的输入 id(或 id 列表)以及节点的输出 id
5. TODO
-------
下一步,会将 API 从固定网络生成器,改为有更多可用操作的网络生成器。 会使用 ONNX 格式来替代 JSON 作为中间表示结果。
NNI 中的 PBTTuner
===
## PBTTuner
Population Based Training (PBT,基于种群的训练) 来自于 [Population Based Training of Neural Networks](https://arxiv.org/abs/1711.09846v1)。 它是一种简单的异步优化算法,在固定的计算资源下,它能有效的联合优化一组模型及其超参来最大化性能。 重要的是,PBT 探索的是超参设置的规划,而不是通过整个训练过程中,来试图找到某个固定的参数配置。
![](../../img/pbt.jpg)
PBTTuner 使用多个 Trial 来初始化种群 (即,`population_size`)。 上图中有四步,每个 Trial 只运行一步。 每步运行的时长由 Trial 代码控制,如一个 Epoch。 当 Trial 开始时,会加载 PBTTuner 指定的检查点,并继续运行一步,然后将检查点保存到PBTTuner 指定的目录中,并退出。 种群中的 Trial 会同步的运行这些步骤,也就是说,所有 Trial 都完成了第 `i` 步后,`(i+1)` 步才能开始。 PBT 的挖掘(Exploitation)和探索(Exploration)是两个连续的步骤。
### 提供检查点目录
为了让 Trial 读取其它 Trial 的检查点,需要提供能够被所有 Trial 访问到的目录 (即, `all_checkpoint_dir`)。 本机模式下非常容易,直接使用默认目录,或指定本机的任意目录均可。 对于其他训练平台,需要根据[训练平台文档](../TrainingService/Overview.md)来提供能共享的目录,如 NFS, Azure 存储。
### 修改 Trial 代码
在运行步骤之前,Trial 需要读取检查点,检查点目录由 PBTTuner 的超参配置来决定,即 `params['load_checkpoint_dir']`。 同样,保存检查点的目录也包含在配置中,即,`params['save_checkpoint_dir']`。 在这里,`all_checkpoint_dir``load_checkpoint_dir``save_checkpoint_dir` 的根目录,格式为 `all_checkpoint_dir/<population-id>/<step>`
```python
params = nni.get_next_parameter()
# 读取检查点的路径
load_path = os.path.join(params['load_checkpoint_dir'], 'model.pth')
# 从 `load_path` 中读取检查点
...
# 运行一步
...
# 保存检查点的路径
save_path = os.path.join(params['save_checkpoint_dir'], 'model.pth')
# 将检查点保存到 `save_path`
...
```
完整的示例代码参考[这里](https://github.com/microsoft/nni/tree/master/examples/trials/mnist-pbt-tuner-pytorch)
### Experiment 配置
以下是 PBTTuner 在 Experiment 配置文件中的示例。 **注意,如果使用了 PBTTuner,就不能使用 Assessor。**
```yaml
# config.yml
tuner:
builtinTunerName: PBTTuner
classArgs:
optimize_mode: maximize
all_checkpoint_dir: /the/path/to/store/checkpoints
population_size: 10
```
NNI 中的 PBTTuner
================================
PBTTuner
--------
Population Based Training (PBT,基于种群的训练) 来自于论文 `Population Based Training of Neural Networks <https://arxiv.org/abs/1711.09846v1>`__。 它是一种简单的异步优化算法,在固定的计算资源下,它能有效的联合优化一组模型及其超参来最大化性能。 重要的是,PBT 探索的是超参设置的规划,而不是通过整个训练过程中,来试图找到某个固定的参数配置。
.. image:: ../../img/pbt.jpg
:target: ../../img/pbt.jpg
:alt:
PBTTuner 使用多个 Trial 来初始化种群 (即,``population_size``)。 上图中有四步,每个 Trial 只运行一步。 每步运行的时长由 Trial 代码控制,如一个 Epoch。 当 Trial 开始时,会加载 PBTTuner 指定的检查点,并继续运行一步,然后将检查点保存到PBTTuner 指定的目录中,并退出。 种群中的 Trial 会同步的运行这些步骤,也就是说,所有 Trial 都完成了第 ``i`` 步后,``(i+1)`` 步才能开始。 PBT 的挖掘(Exploitation)和探索(Exploration)是两个连续的步骤。
提供检查点目录
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
为了让 Trial 读取其它 Trial 的检查点,需要提供能够被所有 Trial 访问到的目录 (即,``all_checkpoint_dir`` )。 本机模式下非常容易,直接使用默认目录,或指定本机的任意目录均可。 对于其他训练平台,需要根据 `训练平台文档 <../TrainingService/Overview.rst>`__ 来提供能共享的目录,如 NFS, Azure 存储。
修改 Trial 代码
^^^^^^^^^^^^^^^^^^^^^^
在运行步骤之前,Trial 需要读取检查点,检查点目录由 PBTTuner 的超参配置来决定,即 ``params['load_checkpoint_dir']``。 同样,保存检查点的目录也包含在配置中,即,``params['save_checkpoint_dir']``。 在这里,``all_checkpoint_dir`` 是 ``load_checkpoint_dir`` 和 ``save_checkpoint_dir``的根目录,格式为 ``all_checkpoint_dir/<population-id>/<step>``。
.. code-block:: python
params = nni.get_next_parameter()
# 读取检查点的路径
load_path = os.path.join(params['load_checkpoint_dir'], 'model.pth')
# 从 `load_path` 中读取检查点
...
# 运行一步
...
# 保存检查点的路径
save_path = os.path.join(params['save_checkpoint_dir'], 'model.pth')
# 将检查点保存到 `save_path`
...
完整的示例代码参考 :githublink:`这里 <examples/trials/mnist-pbt-tuner-pytorch>`。
Experiment 配置
^^^^^^^^^^^^^^^^^
以下是 PBTTuner 在 Experiment 配置文件中的示例。 **注意,如果使用了 PBTTuner,就不能使用 Assessor。**
.. code-block:: yaml
# config.yml
tuner:
builtinTunerName: PBTTuner
classArgs:
optimize_mode: maximize
all_checkpoint_dir: /the/path/to/store/checkpoints
population_size: 10
# NNI 中的 PPO Tuner
## PPOTuner
这是一个用于 NNI 神经网络架构搜索(NAS)接口的 Tuner。 它使用了 [ppo 算法](https://arxiv.org/abs/1707.06347)。 此实现继承了 [OpenAI 的 ppo2 实现](https://github.com/openai/baselines/tree/master/baselines/ppo2)的主要逻辑,并为 NAS 场景做了适配。
mnist-nas 示例已调优,并得到以下结果: **注意:此示例正在重构中,以支持最新的 NAS 接口,完成后会重新发布示例代码。**
![](../../img/ppo_mnist.png)
我们也使用 NAS 接口和 PPO Tuner 调优了[ ENAS 论文中为图片分类所做的宏分类](https://github.com/microsoft/nni/tree/master/examples/trials/nas_cifar10)(Trial 中 Epoch 限定为 8)。 [enas 论文](https://arxiv.org/pdf/1802.03268.pdf)中的图 7 展示了搜索空间:
![](../../img/enas_search_space.png)
上图是所选的结构。 每个方块是一层,可从 6 个操作中选择。 每条虚线是直通连接,每个方块都可以有 0 或 1 条直通连接获得前面层的输出。 **注意**,在原始的宏搜索空间中,每个方块层可选择任意条直通连接,在此实现中,仅允许 0 或 1条。
结果如下图所示([配置文件](https://github.com/microsoft/nni/blob/master/examples/trials/nas_cifar10/config_ppo.yml)):
![](../../img/ppo_cifar10.png)
\ No newline at end of file
NNI 中的 PPO Tuner
================================
PPOTuner
--------
这是一个用于 NNI 神经网络架构搜索(NAS)接口的 Tuner。 它使用了 `ppo 算法 <https://arxiv.org/abs/1707.06347>`__。 此实现继承了 `OpenAI 的 ppo2 实现 <https://github.com/openai/baselines/tree/master/baselines/ppo2>`__ 的主要逻辑,并为 NAS 场景做了适配。
mnist-nas 示例已调优,并得到以下结果:
**注意:此示例正在重构中,以支持最新的 NAS 接口,完成后会重新发布示例代码。**
.. image:: ../../img/ppo_mnist.png
:target: ../../img/ppo_mnist.png
:alt:
我们也使用 NAS 接口和 PPO Tuner 调优了 :githublink:`ENAS 论文中为图片分类所做的宏分类 <examples/trials/nas_cifar10>` (Trial 中 Epoch 限定为 8)。 `enas 论文 <https://arxiv.org/pdf/1802.03268.pdf>`__ 中的图 7 展示了搜索空间:
.. image:: ../../img/enas_search_space.png
:target: ../../img/enas_search_space.png
:alt:
上图是所选的结构。 每个方块是一层,可从 6 个操作中选择。 每条虚线是直通连接,每个方块都可以有 0 或 1 条直通连接获得前面层的输出。 **注意** ,在原始的宏搜索空间中,每个方块层可选择任意条直通连接,在此实现中,仅允许 0 或 1条。
结果如下图所示(:githublink:`配置文件 <examples/trials/nas_cifar10/config_ppo.yml>`):
.. image:: ../../img/ppo_cifar10.png
:target: ../../img/ppo_cifar10.png
:alt:
# SMAC Tuner
## SMAC
[SMAC](https://www.cs.ubc.ca/~hutter/papers/10-TR-SMAC.pdf) 基于 Sequential Model-Based Optimization (SMBO). 它利用使用过的结果好的模型(高斯随机过程模型),并将随机森林引入到 SMBO 中,来处理分类参数。 NNI 的 SMAC 通过包装 [SMAC3](https://github.com/automl/SMAC3) 来支持。
NNI 中的 SMAC 只支持部分类型的[搜索空间](../Tutorial/SearchSpaceSpec.md),包括`choice`, `randint`, `uniform`, `loguniform`, `quniform`
\ No newline at end of file
SMAC Tuner
=================
SMAC
----
`SMAC <https://www.cs.ubc.ca/~hutter/papers/10-TR-SMAC.pdf>`__ 基于 Sequential Model-Based Optimization (SMBO). 它利用使用过的结果好的模型(高斯随机过程模型),并将随机森林引入到 SMBO 中,来处理分类参数。 NNI 的 SMAC 通过包装 `SMAC3 <https://github.com/automl/SMAC3>`__ 来支持。
NNI 中的 SMAC 只支持部分类型的 `搜索空间 <../Tutorial/SearchSpaceSpec.rst>`__\ ,包括 ``choice``\ , ``randint``\ , ``uniform``\ , ``loguniform``\ , 和 ``quniform``。
# NNI Annotation
## 概述
为了获得良好的用户体验并减少对以后代码的影响,NNI 设计了通过 Annotation(标记)来使用的语法。 通过 Annotation,只需要在代码中加入一些注释字符串,就能启用 NNI,完全不影响代码原先的执行逻辑。
示例如下:
```python
'''@nni.variable(nni.choice(0.1, 0.01, 0.001), name=learning_rate)'''
learning_rate = 0.1
```
此示例中,NNI 会从 (0.1, 0.01, 0.001) 中选择一个值赋给 learning_rate 变量。 第一行就是 NNI 的 Annotation,是 Python 中的一个字符串。 接下来的一行需要是赋值语句。 NNI 会根据 Annotation 行的信息,来给这一行的变量赋上相应的值。
通过这种方式,不需要修改任何代码,代码既可以直接运行,又可以使用 NNI 来调参。
## Annotation 的类型:
NNI 中,有 4 种类型的 Annotation;
### 1. 变量
`'''@nni.variable(sampling_algo, name)'''`
`@nni.variable` 用来标记变量。
**参数**
- **sampling_algo**: 指定搜索空间的采样算法。 可将其换成 NNI 支持的其它采样函数,函数要以 `nni.` 开头。例如,`choice``uniform`,详见 [SearchSpaceSpec](SearchSpaceSpec.md)
- **name**: 将被赋值的变量名称。 注意,此参数应该与下面一行等号左边的值相同。
NNI 支持如下 10 种类型来表示搜索空间:
- `@nni.variable(nni.choice(option1,option2,...,optionN),name=variable)` 变量值是选项中的一种,这些变量可以是任意的表达式。
- `@nni.variable(nni.randint(lower, upper),name=variable)` 变量值的公式为:round(uniform(low, high))。 目前,值的类型为 float。 如果要使用整数,需要显式转换。
- `@nni.variable(nni.uniform(low, high),name=variable)` 变量值会是 low 和 high 之间均匀分布的某个值。
- `@nni.variable(nni.quniform(low, high, q),name=variable)` 变量值为 clip(round(uniform(low, high) / q) * q, low, high),clip 操作用于约束生成值的边界。
- `@nni.variable(nni.loguniform(low, high),name=variable)` 变量值是 exp(uniform(low, high)) 的点,数值以对数均匀分布。
- `@nni.variable(nni.qloguniform(low, high, q),name=variable)` 变量值为 clip(round(loguniform(low, high) / q) * q, low, high),clip 操作用于约束生成值的边界。
- `@nni.variable(nni.normal(mu, sigma),name=variable)` 变量值为正态分布的实数值,平均值为 mu,标准方差为 sigma。
- `@nni.variable(nni.qnormal(mu, sigma, q),name=variable)` 变量值分布的公式为: round(normal(mu, sigma) / q) * q
- `@nni.variable(nni.lognormal(mu, sigma),name=variable)` 变量值分布的公式为: exp(normal(mu, sigma))
- `@nni.variable(nni.qlognormal(mu, sigma, q),name=variable)` 变量值分布的公式为: round(exp(normal(mu, sigma)) / q) * q
示例如下:
```python
'''@nni.variable(nni.choice(0.1, 0.01, 0.001), name=learning_rate)'''
learning_rate = 0.1
```
### 2. 函数
`'''@nni.function_choice(*functions, name)'''`
`@nni.function_choice` 可以从几个函数中选择一个来执行。
**参数**
- **functions**: 可选择的函数。 注意,必须是包括参数的完整函数调用。 例如 `max_pool(hidden_layer, pool_size)`
- **name**: 将被替换的函数名称。
例如:
```python
"""@nni.function_choice(max_pool(hidden_layer, pool_size), avg_pool(hidden_layer, pool_size), name=max_pool)"""
h_pooling = max_pool(hidden_layer, pool_size)
```
### 3. 中间结果
`'''@nni.report_intermediate_result(metrics)'''`
`@nni.report_intermediate_result` 用来返回中间结果,这和[在 NNI 上实现 Trial](../TrialExample/Trials.md)`nni.report_intermediate_result` 的用法一样。
### 4. 最终结果
`'''@nni.report_final_result(metrics)'''`
`@nni.report_final_result` 用来返回当前 Trial 的最终结果,这和[在 NNI 上实现 Trial](../TrialExample/Trials.md) 中的 `nni.report_final_result` 用法一样。
\ No newline at end of file
NNI Annotation
==============
概述
--------
为了获得良好的用户体验并减少对以后代码的影响,NNI 设计了通过 Annotation(标记)来使用的语法。 通过 Annotation,只需要在代码中加入一些注释字符串,就能启用 NNI,完全不影响代码原先的执行逻辑。
示例如下:
.. code-block:: python
'''@nni.variable(nni.choice(0.1, 0.01, 0.001), name=learning_rate)'''
learning_rate = 0.1
此示例中,NNI 会从 (0.1, 0.01, 0.001) 中选择一个值赋给 learning_rate 变量。 第一行就是 NNI 的 Annotation,是 Python 中的一个字符串。 接下来的一行需要是赋值语句。 NNI 会根据 Annotation 行的信息,来给这一行的变量赋上相应的值。
通过这种方式,不需要修改任何代码,代码既可以直接运行,又可以使用 NNI 来调参。
Annotation 的类型:
--------------------
NNI 中,有 4 种类型的 Annotation;
1. 变量
^^^^^^^^^^^^^^^^^^^^^
``'''@nni.variable(sampling_algo, name)'''``
``@nni.variable`` is used in NNI to annotate a variable.
**参数**
* **sampling_algo**: 指定搜索空间的采样算法。 可将其换成 NNI 支持的其它采样函数,函数要以 ``nni.`` 开头。例如,``choice`` 或 ``uniform``, `SearchSpaceSpec <SearchSpaceSpec.rst>`__ 。
* **name**: 将被赋值的变量名称。 注意,此参数应该与下面一行等号左边的值相同。
NNI 支持如下 10 种类型来表示搜索空间:
* ``@nni.variable(nni.choice(option1,option2,...,optionN),name=variable)``
变量值会是列表中的 options 之一。options 的元素可以是嵌套的随机表达式。
* ``@nni.variable(nni.randint(lower, upper),name=variable)``
这表示变量值会类似于 round(uniform(low, high)) 目前,值的类型为 float。 如果要使用整数,需要显式转换。
* ``@nni.variable(nni.uniform(low, high),name=variable)``
变量是 low 和 high 之间均匀分布的值。
* ``@nni.variable(nni.quniform(low, high, q),name=variable)``
变量值为 clip(round(uniform(low, high) / q) * q, low, high),clip 操作用于约束生成值的边界。
* ``@nni.variable(nni.loguniform(low, high),name=variable)``
变量值为 exp(uniform(low, high)) 分布,范围值是对数的均匀分布。
* ``@nni.variable(nni.qloguniform(low, high, q),name=variable)``
变量值为 clip(round(loguniform(low, high) / q) * q, low, high),clip 操作用于约束生成值的边界。
* ``@nni.variable(nni.normal(mu, sigma),name=variable)``
变量值为实数,且为正态分布,均值为 mu,标准方差为 sigma。
* ``@nni.variable(nni.qnormal(mu, sigma, q),name=variable)``
这表示变量值会类似于 round(normal(mu, sigma) / q) * q
* ``@nni.variable(nni.lognormal(mu, sigma),name=variable)``
这表示变量值会类似于 exp(uniform(low, high))
* ``@nni.variable(nni.qlognormal(mu, sigma, q),name=variable)``
这表示变量值会类似于 round(exp(normal(mu, sigma)) / q) * q
示例如下:
.. code-block:: python
'''@nni.variable(nni.choice(0.1, 0.01, 0.001), name=learning_rate)'''
learning_rate = 0.1
2. 函数
^^^^^^^^^^^^^^^^^^^^^
``'''@nni.function_choice(*functions, name)'''``
``@nni.function_choice`` 可以从几个函数中选择一个来执行。
**参数**
* **functions**: 可选择的函数。 注意,必须是包括参数的完整函数调用。 例如 ``max_pool(hidden_layer, pool_size)``。
* **name**: 将被替换的函数名称。
例如:
.. code-block:: python
"""@nni.function_choice(max_pool(hidden_layer, pool_size), avg_pool(hidden_layer, pool_size), name=max_pool)"""
h_pooling = max_pool(hidden_layer, pool_size)
3. 中间结果
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
``'''@nni.report_intermediate_result(metrics)'''``
``@nni.report_intermediate_result`` 用来返回中间结果,这和 `在 NNI 中实现 Trial <../TrialExample/Trials.rst>`__ 中 ``nni.report_intermediate_result`` 的用法相同。
4. 最终结果
^^^^^^^^^^^^^^^^^^^^^^^^
``'''@nni.report_final_result(metrics)'''``
``@nni.report_final_result`` 用来返回最终结果,这和 `在 NNI 中实现 Trial <../TrialExample/Trials.rst>`__ 中 ``nni.report_final_result`` 的用法相同。
# 改进 Neural Network Intelligence (NNI)
改进 Neural Network Intelligence (NNI)
=================================================
欢迎!! 我们非常欢迎贡献者,特别是代码贡献者。
......@@ -6,56 +7,70 @@
不管怎样,如果想要更有效的贡献代码,可以阅读以下内容。 本文档包括了所有在贡献中需要注意的要点,会加快合并代码、解决问题的速度。
查看[快速入门](QuickStart.md)来初步了解。
查看 `快速入门 <QuickStart.rst>`__ 来初步了解。
下面是一些简单的贡献指南。
## 提交问题
提交问题
--------------
在提出问题时,请说明以下事项:
* 按照问题模板的内容来填写安装的细节,以便评审者检查。
* 出现问题的场景 (尽量详细,以便重现问题)。
* 错误和日志消息。
* 其它可能有用的细节信息。
## 提交新功能建议
提交新功能建议
---------------------------------
* 在适配使用场景时,总会需要一些新的功能。 可以加入新功能的讨论,也可以直接提交新功能的拉取请求。
*
在适配使用场景时,总会需要一些新的功能。 可以加入新功能的讨论,也可以直接提交新功能的拉取请求。
* 在自己的 github 账户下 fork 存储库。 在 fork 后, 对于 add, commit, push, 或 squash (如需要) 等改动都需要详细的提交消息。 然后就可以提交拉取请求了。
*
在自己的 github 账户下 fork 存储库。 在 fork 后, 对于 add, commit, push, 或 squash (如需要) 等改动都需要详细的提交消息。 然后就可以提交拉取请求了。
## 参与源代码和 Bug 修复
参与源代码和 Bug 修复
-----------------------------------------
拉取请求需要选好正确的标签,表明是 Bug 修复还是功能改进。 所有代码都需要遵循正确的命名约定和代码风格。
参考[如何配置 NNI 的开发环境](./SetupNniDeveloperEnvironment.md),来安装开发环境。
参考 `如何配置 NNI 的开发环境 <./SetupNniDeveloperEnvironment.rst>`__,来安装开发环境。
[快速入门](QuickStart.md)类似。 其它内容,参考[NNI 文档](http://nni.readthedocs.io)
`快速入门类似 <QuickStart.rst>`__, 其它内容,参考 `NNI 文档 <http://nni.readthedocs.io>`__
## 处理现有问题
处理现有问题
---------------------
查看[问题列表](https://github.com/Microsoft/nni/issues),找到需要贡献的问题。 可以找找有 'good-first-issue''help-wanted' 标签的来开始贡献。
查看 `问题列表 <https://github.com/Microsoft/nni/issues>`__,找到需要贡献的问题。 可以找找有 ``good-first-issue````help-wanted`` 标签的来开始贡献。
修改问题的注释和指派人来表明此问题已经开始跟进。 如果上述问题在一周内没有拉取请求或更新状态,这个问题会重新开放给所有人。 高优先级的 Bug 和回归问题需在一天内响应。
## 代码风格和命名约定
代码风格和命名约定
--------------------------------
* NNI 遵循 `PEP8 <https://www.python.org/dev/peps/pep-0008/>`__ 的 Python 代码命名约定。在提交拉取请求时,请尽量遵循此规范。 可通过``flake8`` 或 ``pylint`` 的提示工具来帮助遵循规范。
* NNI 还遵循 `NumPy Docstring 风格 <https://www.sphinx-doc.org/en/master/usage/extensions/example_numpy.html#example-numpy>`__ 的 Python Docstring 命名方案。 Python API 使用了 `sphinx.ext.napoleon <https://www.sphinx-doc.org/en/master/usage/extensions/napoleon.html>`__ 来生成文档。
* 有关 docstrings,参考 `numpydoc docstring 指南 <https://numpydoc.readthedocs.io/en/latest/format.html>`__ 和 `pandas docstring 指南 <https://python-sprints.github.io/pandas/guide/pandas_docstring.html>`__
* 函数的 docstring, **description**, **Parameters**, 和 **Returns Yields** 是必需的。
* 类的 docstring, **description**, **Attributes** 是必需的。
* 描述 ``dict`` 的 docstring 在超参格式描述中多处用到
* 参考 `RiboKit 文档写作准则 <https://ribokit.github.io/docs/text/>`__
文档
-------------
* NNI 遵循 [PEP8](https://www.python.org/dev/peps/pep-0008/) 的 Python 代码命名约定。在提交拉取请求时,请尽量遵循此规范。 可通过`flake8``pylint`的提示工具来帮助遵循规范。
* NNI 还遵循 [NumPy Docstring 风格](https://www.sphinx-doc.org/en/master/usage/extensions/example_numpy.html#example-numpy) 的 Python Docstring 命名方案。 Python API 使用了[sphinx.ext.napoleon](https://www.sphinx-doc.org/en/master/usage/extensions/napoleon.html)[生成文档](Contributing.md#documentation)
* 有关 docstrings,参考 [numpydoc docstring 指南](https://numpydoc.readthedocs.io/en/latest/format.html)[pandas docstring 指南](https://python-sprints.github.io/pandas/guide/pandas_docstring.html)
* 函数的 docstring, **description**, **Parameters**, 以及**Returns**/**Yields** 是必需的。
* 类的 docstring, **description**, **Attributes** 是必需的。
* 描述 `dict` 的 docstring 在超参格式描述中多处用到,参考 [RiboKit : 文档标准
* 写作标准的内部准则](https://ribokit.github.io/docs/text/)
文档使用了 :githublink:`sphinx <docs>` 来生成,
## 文档
* 在提交文档改动前,请先 **在本地生成文档**:``cd docs/zh_CN && make html``,然后,可以在 ``docs/zh_CN/_build/html`` 目录下找到所有生成的网页。 请认真分析生成日志中的 **每个 WARNING**,这非常有可能是或 **空连接** 或其它问题。
文档使用了 [sphinx](http://sphinx-doc.org/) 来生成,支持 [Markdown](https://guides.github.com/features/mastering-markdown/)[reStructuredText](http://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html) 格式。 所有文档都在 [docs/zh_CN](docs) 目录下。
*
需要链接时,尽量使用\ **相对路径**。 但如果文档是 Markdown 格式的,并且:
* 在提交文档改动前,请先**在本地生成文档**`cd docs/zh_CN && make html`,然后,可以在 `docs/zh_CN/_build/html` 目录下找到所有生成的网页。 请认真分析生成日志中的**每个 WARNING**,这非常有可能是或**空连接**或其它问题。
* 需要链接时,尽量使用**相对路径**。 但如果文档是 Markdown 格式的,并且:
* 图片需要通过嵌入的 HTML 语法来格式化,则需要使用绝对链接,如 `https://user-images.githubusercontent.com/44491713/51381727-e3d0f780-1b4f-11e9-96ab-d26b9198ba65.png`。可以通过将图片拖拽到 [Github Issue](https://github.com/Microsoft/nni/issues/new) 框中来生成这样的链接。
* 如果不能被 sphinx 重新格式化,如源代码等,则需要使用绝对链接。 如果源码连接到本代码库,使用 `https://github.com/Microsoft/nni/tree/master/` 作为根目录 (例如:[mnist.py](https://github.com/Microsoft/nni/blob/master/examples/trials/mnist-tfv1/mnist.py))。
\ No newline at end of file
* 图片需要通过嵌入的 HTML 语法来格式化,则需要使用绝对链接,如 ``https://user-images.githubusercontent.com/44491713/51381727-e3d0f780-1b4f-11e9-96ab-d26b9198ba65.png``。可以通过将图片拖拽到 `Github Issue <https://github.com/Microsoft/nni/issues/new>`__ 框中来生成这样的链接。
* 如果不能被 sphinx 重新格式化,如源代码等,则需要使用绝对链接。 如果源码连接到本代码库,使用 ``https://github.com/Microsoft/nni/tree/master/`` 作为根目录 (例如 :githublink:`mnist.py <examples/trials/mnist-tfv1/mnist.py>` )。
# Experiment(实验)配置参考
创建 Experiment 所需要的配置文件。 配置文件的路径会传入 `nnictl` 命令。 配置文件的格式为 YAML。 本文介绍了配置文件的内容,并提供了一些示例和模板。
- [Experiment(实验)配置参考](#experiment-config-reference)
- [模板](#template)
- [说明](#configuration-spec)
- [authorName](#authorname)
- [experimentName](#experimentname)
- [trialConcurrency](#trialconcurrency)
- [maxExecDuration](#maxexecduration)
- [versionCheck](#versioncheck)
- [debug](#debug)
- [maxTrialNum](#maxtrialnum)
- [trainingServicePlatform](#trainingserviceplatform)
- [searchSpacePath](#searchspacepath)
- [useAnnotation](#useannotation)
- [multiThread](#multithread)
- [nniManagerIp](#nnimanagerip)
- [logDir](#logdir)
- [logLevel](#loglevel)
- [logCollection](#logcollection)
- [tuner](#tuner)
- [builtinTunerName](#builtintunername)
- [codeDir](#codedir)
- [classFileName](#classfilename)
- [className](#classname)
- [classArgs](#classargs)
- [gpuIndices](#gpuindices)
- [includeIntermediateResults](#includeintermediateresults)
- [assessor](#assessor)
- [builtinAssessorName](#builtinassessorname)
- [codeDir](#codedir-1)
- [classFileName](#classfilename-1)
- [className](#classname-1)
- [classArgs](#classargs-1)
- [advisor](#advisor)
- [builtinAdvisorName](#builtinadvisorname)
- [codeDir](#codedir-2)
- [classFileName](#classfilename-2)
- [className](#classname-2)
- [classArgs](#classargs-2)
- [gpuIndices](#gpuindices-1)
- [trial](#trial)
- [localConfig](#localconfig)
- [gpuIndices](#gpuindices-2)
- [maxTrialNumPerGpu](#maxtrialnumpergpu)
- [useActiveGpu](#useactivegpu)
- [machineList](#machinelist)
- [ip](#ip)
- [port](#port)
- [username](#username)
- [passwd](#passwd)
- [sshKeyPath](#sshkeypath)
- [passphrase](#passphrase)
- [gpuIndices](#gpuindices-3)
- [maxTrialNumPerGpu](#maxtrialnumpergpu-1)
- [useActiveGpu](#useactivegpu-1)
- [kubeflowConfig](#kubeflowconfig)
- [operator](#operator)
- [storage](#storage)
- [nfs](#nfs)
- [keyVault](#keyvault)
- [azureStorage](#azurestorage)
- [uploadRetryCount](#uploadretrycount)
- [paiConfig](#paiconfig)
- [userName](#username)
- [password](#password)
- [token](#token)
- [host](#host)
- [reuse](#reuse)
- [示例](#examples)
- [本机模式](#local-mode)
- [远程模式](#remote-mode)
- [PAI 模式](#pai-mode)
- [Kubeflow 模式](#kubeflow-mode)
- [Kubeflow 中使用 Azure 存储](#kubeflow-with-azure-storage)
## 模板
- **简化版(不包含 Annotation(标记)和 Assessor)**
```yaml
authorName:
experimentName:
trialConcurrency:
maxExecDuration:
maxTrialNum:
# 可选项: local, remote, pai, kubeflow
trainingServicePlatform:
searchSpacePath:
# 可选项: true, false, 默认值: false
useAnnotation:
# 可选项: true, false, 默认值: false
multiThread:
tuner:
# 可选项: TPE, Random, Anneal, Evolution
builtinTunerName:
classArgs:
# 可选项: maximize, minimize
optimize_mode:
gpuIndices:
trial:
command:
codeDir:
gpuNum:
# 在本机模式下,machineList 可为空
machineList:
- ip:
port:
username:
passwd:
```
- **使用 Assessor**
```yaml
authorName:
experimentName:
trialConcurrency:
maxExecDuration:
maxTrialNum:
#可选项: local, remote, pai, kubeflow
trainingServicePlatform:
searchSpacePath:
#可选项: true, false, 默认值: false
useAnnotation:
#可选项: true, false, 默认值: false
multiThread:
tuner:
#可选项: TPE, Random, Anneal, Evolution
builtinTunerName:
classArgs:
#可选项: maximize, minimize
optimize_mode:
gpuIndices:
assessor:
#可选项: Medianstop
builtinAssessorName:
classArgs:
#可选项: maximize, minimize
optimize_mode:
gpuIndices:
trial:
command:
codeDir:
gpuIndices:
#在本地使用时,machineList 可为空
machineList:
- ip:
port:
username:
passwd:
```
- **使用 Annotation**
```yaml
authorName:
experimentName:
trialConcurrency:
maxExecDuration:
maxTrialNum:
#可选项: local, remote, pai, kubeflow
trainingServicePlatform:
#可选项: true, false, 默认值: false
useAnnotation:
#可选项: true, false, 默认值: false
multiThread:
tuner:
#可选项: TPE, Random, Anneal, Evolution
builtinTunerName:
classArgs:
#可选项: maximize, minimize
optimize_mode:
gpuIndices:
assessor:
#可选项: Medianstop
builtinAssessorName:
classArgs:
#可选项: maximize, minimize
optimize_mode:
gpuIndices:
trial:
command:
codeDir:
gpuIndices:
#在本地使用时,machineList 可为空
machineList:
- ip:
port:
username:
passwd:
```
## 说明
### authorName
必填。 字符串。
创建 Experiment 的作者的姓名。
*待定: 增加默认值。*
### experimentName
必填。 字符串。
创建的 Experiment 名称。
*待定: 增加默认值。*
### trialConcurrency
必填。 1 到 99999 之间的整数。
指定同时运行的 Trial 任务的最大数量。
如果 trialGpuNum 大于空闲的 GPU 数量,并且并发的 Trial 任务数量还没达到 **trialConcurrency**,Trial 任务会被放入队列,等待分配 GPU 资源。
### maxExecDuration
可选。 字符串。 默认值:999d。
**maxExecDuration** 指定实验的最大执行时间。 时间的单位为 {**s**, **m**, **h**, **d**},其分别表示 {*秒*, *分钟*, *小时*, *天*}。
注意:maxExecDuration 设置的是 Experiment 执行的时间,不是 Trial 的。 如果 Experiment 达到了设置的最大时间,Experiment 不会停止,但不会再启动新的 Trial 作业。
### versionCheck
可选。 布尔。 默认值:true。
NNI 会校验 remote, pai 和 Kubernetes 模式下 NNIManager 与 trialKeeper 进程的版本。 如果需要禁用版本校验,versionCheck 应设置为 false。
### debug
可选。 布尔。 默认值:false。
调试模式会将 versionCheck 设置为 False,并将 logLevel 设置为 'debug'。
### maxTrialNum
可选。 1 到 99999 之间的整数。 默认值:99999。
指定 NNI 创建的最大 Trial 任务数,包括成功和失败的任务。
### trainingServicePlatform
必填。 字符串。
指定运行 Experiment 的平台,包括 **local**, **remote**, **pai**, **kubeflow**, **frameworkcontroller**.
- **local** 在本机的 Ubuntu 上运行 Experiment。
- **remote** 将任务提交到远程的 Ubuntu 上,必须用 **machineList** 来指定远程的 SSH 连接信息。
- **pai** 提交任务到微软开源的 [OpenPAI](https://github.com/Microsoft/pai) 上。 更多 OpenPAI 配置,参考 [PAI 模式](../TrainingService/PaiMode.md)
- **kubeflow** 提交任务至 [Kubeflow](https://www.kubeflow.org/docs/about/kubeflow/)。 NNI 支持基于 Kubeflow 的 Kubenetes,以及[Azure Kubernetes](https://azure.microsoft.com/en-us/services/kubernetes-service/)。 详情参考 [Kubeflow 文档](../TrainingService/KubeflowMode.md)
- TODO:解释 FrameworkController。
### searchSpacePath
可选。 现有文件的路径。
指定搜索空间文件的路径,此文件必须在运行 nnictl 的本机。
仅在 `useAnnotation=True` 时,才不需要填写 **searchSpacePath**
### useAnnotation
可选。 布尔。 默认值:false。
使用 Annotation 分析 Trial 代码并生成搜索空间。
注意:如果 **useAnnotation** 为 true,searchSpacePath 字段会被删除。
### multiThread
可选。 布尔。 默认值:false。
为 Dispatcher 启用多线程模式。 如果启用了 multiThread,Dispatcher 将启动一个线程来处理来自 NNI 管理器的每个命令。
### nniManagerIp
可选。 字符串。 默认值:eth0 设备的 IP。
设置运行 NNI 管理器进程的计算机的 IP 地址。 此字段为可选项,如果没有设置,则会使用 eth0 的 IP 地址。
注意: 可在 NNI 管理器机器上运行 `ifconfig` 来检查 eth0 是否存在。 如果没有,建议显式设置 **nniManagerIp**
### logDir
可选。 目录的路径。 默认值:`<user home directory>/nni-experiments`
配置目录以存储 Experiment 的日志和数据。
### logLevel
可选。 字符串。 默认值:`info`
设置 Experiment 的日志级别。 可设置的日志级别包括:`trace`, `debug`, `info`, `warning`, `error`, `fatal`
### logCollection
可选。 `http``none`。 默认值:`none`
设置在remote、pai、kubeflow、frameworkcontroller 平台中收集日志的方式。 日志支持两种设置,一种是通过 `http`,让 Trial 将日志通过 POST 方法发回日志,这种方法会减慢 trialKeeper 的速度。 另一种方法是 `none`,Trial 不将日志回传回来,仅仅回传 Job 的指标。 如果日志较大,可将此参数设置为 `none`
### tuner
必填。
指定了 Experiment 的 Tuner 算法。有两种方法可设置 Tuner。 一种方法是使用 NNI SDK 提供的内置 Tuner,在这种情况下,需要设置 **builtinTunerName****classArgs**。 另一种方法,是使用用户自定义的 Tuner,需要设置 **codeDirectory****classFileName****className****classArgs***必须选择其中的一种方式。*
#### builtinTunerName
如果使用内置 Tuner,则为必需。 字符串。
指定系统 Tuner 的名称, NNI SDK 提供的各种 Tuner 的[说明](../Tuner/BuiltinTuner.md)
#### codeDir
如果使用定制 Tuner,则为必需。 相对于配置文件位置的路径。
指定 Tuner 代码的目录。
#### classFileName
如果使用定制 Tuner,则为必需。 相对于 **codeDir** 的文件路径。
指定 Tuner 文件的名称。
#### className
如果使用定制 Tuner,则为必需。 字符串。
指定 Tuner 的名称。
#### classArgs
可选。 键值对。 默认值:空。
指定 Tuner 算法的参数。 参考[此文件](../Tuner/BuiltinTuner.md)来了解内置 Tuner 的配置参数。
#### gpuIndices
可选。 字符串。 默认值:空。
指定 Tuner 进程可以使用的 GPU。 可以指定单个或多个 GPU 索引。 多个 GPU 索引用逗号 `,` 分隔。 例如,`1``0,1,3`。 如果未设置该字段,则 Tuner 将找不到 GPU(设置 `CUDA_VISIBLE_DEVICES` 成空字符串)。
#### includeIntermediateResults
可选。 布尔。 默认值:false。
如果 **includeIntermediateResults** 为 true,最后一个 Assessor 的中间结果会被发送给 Tuner 作为最终结果。
### assessor
指定 Assessor 算法以运行 Experiment。 与 Tuner 类似,有两种设置 Assessor 的方法。 一种方法是使用 NNI SDK 提供的 Assessor。 用户需要设置 **builtinAssessorName****classArgs**。 另一种方法,是使用自定义的 Assessor,需要设置 **codeDirectory****classFileName****className****classArgs***必须选择其中的一种方式。*
默认情况下,未启用任何 Assessor。
#### builtinAssessorName
如果使用内置 Assessor,则为必需。 字符串。
指定内置 Assessor 的名称,NNI SDK 提供的 Assessor 可参考[这里](../Assessor/BuiltinAssessor.md)
#### codeDir
如果使用定制 Assessor,则为必需。 相对于配置文件位置的路径。
指定 Assessor 代码的目录。
#### classFileName
如果使用定制 Assessor,则为必需。 相对于 **codeDir** 的文件路径。
指定 Assessor 文件的名称。
#### className
如果使用定制 Assessor,则为必需。 字符串。
指定 Assessor 类的名称。
#### classArgs
可选。 键值对。 默认值:空。
指定 Assessor 算法的参数。
### advisor
可选。
指定 Experiment 中的 Advisor 算法。 与 Tuner 和 Assessor 类似,有两种指定 Advisor 的方法。 一种方法是使用 SDK 提供的 Advisor ,需要设置 **builtinAdvisorName****classArgs**。 另一种方法,是使用用户自定义的 Advisor,需要设置 **codeDirectory****classFileName****className****classArgs**
启用 Advisor 后,将忽略 Tuner 和 Advisor 的设置。
#### builtinAdvisorName
指定内置 Advisor 的名称。 NNI SDK 提供了 [BOHB](../Tuner/BohbAdvisor.md)[Hyperband](../Tuner/HyperbandAdvisor.md)
#### codeDir
如果使用定制 Advisor,则为必需。 相对于配置文件位置的路径。
指定 Advisor 代码的目录。
#### classFileName
如果使用定制 Advisor,则为必需。 相对于 **codeDir** 的文件路径。
指定 Advisor 文件的名称。
#### className
如果使用定制 Advisor,则为必需。 字符串。
指定 Advisor 类的名称。
#### classArgs
可选。 键值对。 默认值:空。
指定 Advisor 的参数。
#### gpuIndices
可选。 字符串。 默认值:空。
指定可以使用的 GPU。 可以指定单个或多个 GPU 索引。 多个 GPU 索引用逗号 `,` 分隔。 例如,`1``0,1,3`。 如果未设置该字段,则 Tuner 将找不到 GPU(设置 `CUDA_VISIBLE_DEVICES` 成空字符串)。
### trial
必填。 键值对。
在 local 和 remote 模式下,需要以下键。
- **command**:必需字符串。 指定运行 Trial 的命令。
- **codeDir**:必需字符串。 指定 Trial 文件的目录。 此目录将在 remote 模式下自动上传。
- **gpuNum**:可选、整数。 指定了运行 Trial 进程的 GPU 数量。 默认值为 0。
在 PAI 模式下,需要以下键。
- **command**:必需字符串。 指定运行 Trial 的命令。
- **codeDir**:必需字符串。 指定 Trial 文件的目录。 目录中的文件将在 PAI 模式下上传。
- **gpuNum**:必需、整数。 指定了运行 Trial 进程的 GPU 数量。 默认值为 0。
- **cpuNum**:必需、整数。 指定要在 OpenPAI 容器中使用的 cpu 数。
- **memoryMB**:必需、整数。 设置要在 OpenPAI 容器中使用的内存大小,以兆字节为单位。
- **image**:必需字符串。 设置要在 OpenPAI 中使用的 Docker 映像。
- **authFile**:可选、字符串。 用于提供 Docker 注册,用于为 OpenPAI 中的映像拉取请求进行身份验证。 [参考](https://github.com/microsoft/pai/blob/2ea69b45faa018662bc164ed7733f6fdbb4c42b3/docs/faq.md#q-how-to-use-private-docker-registry-job-image-when-submitting-an-openpai-job)
- **shmMB**:可选、整数。 容器的共享内存大小。
- **portList**: `label`, `beginAt`, `portNumber` 的键值对 list。 参考[ OpenPAI Job 教程](https://github.com/microsoft/pai/blob/master/docs/job_tutorial.md)
在 Kubeflow 模式下,需要以下键。
- **codeDir** 指定了代码文件的本机路径。
- **ps**: Kubeflow 的 tensorflow-operator 的可选配置,包括:
* __replicas__: __ps__ 角色的副本数量。
* __command__: __ps__ 容器的运行脚本。
* __gpuNum__: 在 __ps__ 容器中使用的 GPU 数量。
* __cpuNum__: 在 __ps__ 容器中使用的 CPU 数量。
* __memoryMB__:容器的内存大小。
* __image__: 在 __ps__ 中使用的 Docker 映像。
- **worker** 是 Kubeflow 的 tensorflow-operator 的可选配置。
* __replicas__: __worker__ 角色的副本数量。
* __command__: __worker__ 容器的运行脚本。
* __gpuNum__: 在 __worker__ 容器中使用的 GPU 数量。
* __cpuNum__: 在 __worker__ 容器中使用的 CPU 数量。
* __memoryMB__:容器的内存大小。
* __image__: 在 __worker__ 中使用的 Docker 映像。
### localConfig
本机模式下可选。 键值对。
仅在 **trainingServicePlatform** 设为 `local` 时有效,否则,配置文件中不应该有 **localConfig** 部分。
#### gpuIndices
可选。 字符串。 默认值:none。
用于指定特定的 GPU。设置此值后,只有指定的 GPU 会被用来运行 Trial 任务。 可以指定单个或多个 GPU 索引。 多个 GPU 索引,应用逗号(`,`)分隔,如 `1``0,1,3`。 默认情况下,将使用所有可用的 GPU。
#### maxTrialNumPerGpu
可选。 整数。 默认值: 1。
用于指定 GPU 设备上的最大并发 Trial 的数量。
#### useActiveGpu
可选。 布尔。 默认值:false。
用于指定 GPU 上存在其他进程时是否使用此 GPU。 默认情况下,NNI 仅在 GPU 中没有其他活动进程时才使用 GPU。 如果 **useActiveGpu** 设置为 true,则 NNI 无论某 GPU 是否有其它进程,都将使用它。 此字段不适用于 Windows 版的 NNI。
### machineList
在 remote 模式下必需。 具有以下键的键值对的列表。
#### ip
必填。 可从当前计算机访问的 IP 地址或主机名。
远程计算机的 IP 地址或主机名。
#### port
可选。 整数。 有效端口。 默认值: 22。
用于连接计算机的 SSH 端口。
#### username
使用用户名/密码进行身份验证时是必需的。 字符串。
远程计算机的帐户。
#### passwd
使用用户名/密码进行身份验证时是必需的。 字符串。
指定帐户的密码。
#### sshKeyPath
如果使用 SSH 密钥进行身份验证,则为必需。 私钥文件的路径。
如果用户使用 SSH 密钥登录远程计算机,**sshKeyPath** 应是有效的 SSH 密钥文件路径。
*注意:如果同时设置了 passwd 和 sshKeyPath,NNI 会首先使用 passwd。*
#### passphrase
可选。 字符串。
用于保护 SSH 密钥,如果用户没有密码,可为空。
#### gpuIndices
可选。 字符串。 默认值:none。
用于指定特定的 GPU。设置此值后,只有指定的 GPU 会被用来运行 Trial 任务。 可以指定单个或多个 GPU 索引。 多个 GPU 索引,应用逗号(`,`)分隔,如 `1``0,1,3`。 默认情况下,将使用所有可用的 GPU。
#### maxTrialNumPerGpu
可选。 整数。 默认值: 1。
用于指定 GPU 设备上的最大并发 Trial 的数量。
#### useActiveGpu
可选。 布尔。 默认值:false。
用于指定 GPU 上存在其他进程时是否使用此 GPU。 默认情况下,NNI 仅在 GPU 中没有其他活动进程时才使用 GPU。 如果 **useActiveGpu** 设置为 true,则 NNI 无论某 GPU 是否有其它进程,都将使用它。 此字段不适用于 Windows 版的 NNI。
### kubeflowConfig
#### operator
必填。 字符串。 必须是 `tf-operator``pytorch-operator`
指定要使用的 Kubeflow 运算符,当前版本中 NNI 支持 `tf-operator`
#### storage
可选。 字符串。 默认值 `nfs`
指定 Kubeflow 的存储类型,包括 `nfs``azureStorage`
#### nfs
如果使用 nfs,则必需。 键值对。
- **server** 是 NFS 服务器的地址。
- **path** 是 NFS 挂载的路径。
#### keyVault
如果使用 Azure 存储,则必需。 键值对。
**keyVault** 设置为 Azure 存储帐户的私钥。 参考:https://docs.microsoft.com/en-us/azure/key-vault/key-vault-manage-with-cli2 。
- **vaultName** 是 az 命令中 `--vault-name` 的值。
- **name** 是 az 命令中 `--name` 的值。
#### azureStorage
如果使用 Azure 存储,则必需。 键值对。
设置 Azure 存储帐户以存储代码文件。
- **accountName** 是 Azure 存储账户的名称。
- **azureShare** 是 Azure 文件存储的共享参数。
#### uploadRetryCount
如果使用 Azure 存储,则必需。 1 到 99999 之间的整数。
如果上传文件至 Azure Storage 失败,NNI 会重试。此字段指定了重试的次数。
### paiConfig
#### userName
必填。 字符串。
OpenPAI 帐户的用户名。
#### password
如果使用密码身份验证,则需要。 字符串。
OpenPAI 帐户的密码。
#### token
如果使用令牌(token)身份验证,则需要。 字符串。
可以从 OpenPAI 门户检索的个人访问令牌。
#### host
必填。 字符串。
OpenPAI 的 IP 地址。
#### reuse
可选。 布尔。 默认值:`false`。 这是试用中的功能。
如果为 true,NNI 会重用 OpenPAI 作业,在其中运行尽可能多的 Trial。 这样可以节省创建新作业的时间。 用户需要确保同一作业中的每个 Trial 相互独立,例如,要避免从之前的 Trial 中读取检查点。
## 示例
### 本机模式
如果要在本机运行 Trial 任务,并使用标记来生成搜索空间,可参考下列配置:
authorName: test
experimentName: test_experiment
trialConcurrency: 3
maxExecDuration: 1h
maxTrialNum: 10
#可选项: local, remote, pai, kubeflow
trainingServicePlatform: local
#可选项: true, false
useAnnotation: true
tuner:
#可选项: TPE, Random, Anneal, Evolution
builtinTunerName: TPE
classArgs:
#可选项: maximize, minimize
optimize_mode: maximize
trial:
command: python3 mnist.py
codeDir: /nni/mnist
gpuNum: 0
增加 Assessor 配置。
authorName: test
experimentName: test_experiment
trialConcurrency: 3
maxExecDuration: 1h
maxTrialNum: 10
#可选项: local, remote, pai, kubeflow
trainingServicePlatform: local
searchSpacePath: /nni/search_space.json
#可选项: true, false
useAnnotation: false
tuner:
#可选项: TPE, Random, Anneal, Evolution
builtinTunerName: TPE
classArgs:
#可选项: maximize, minimize
optimize_mode: maximize
assessor:
#可选项: Medianstop
builtinAssessorName: Medianstop
classArgs:
#可选项: maximize, minimize
optimize_mode: maximize
trial:
command: python3 mnist.py
codeDir: /nni/mnist
gpuNum: 0
或者可以指定自定义的 Tuner 和 Assessor:
authorName: test
experimentName: test_experiment
trialConcurrency: 3
maxExecDuration: 1h
maxTrialNum: 10
#可选项: local, remote, pai, kubeflow
trainingServicePlatform: local
searchSpacePath: /nni/search_space.json
#可选项: true, false
useAnnotation: false
tuner:
codeDir: /nni/tuner
classFileName: mytuner.py
className: MyTuner
classArgs:
#可选项: maximize, minimize
optimize_mode: maximize
assessor:
codeDir: /nni/assessor
classFileName: myassessor.py
className: MyAssessor
classArgs:
#choice: maximize, minimize
optimize_mode: maximize
trial:
command: python3 mnist.py
codeDir: /nni/mnist
gpuNum: 0
### 远程模式
如果要在远程服务器上运行 Trial 任务,需要增加服务器信息:
authorName: test
experimentName: test_experiment
trialConcurrency: 3
maxExecDuration: 1h
maxTrialNum: 10
#可选项: local, remote, pai, kubeflow
trainingServicePlatform: remote
searchSpacePath: /nni/search_space.json
#可选项: true, false
useAnnotation: false
tuner:
#可选项: TPE, Random, Anneal, Evolution
builtinTunerName: TPE
classArgs:
#可选项: maximize, minimize
optimize_mode: maximize
trial:
command: python3 mnist.py
codeDir: /nni/mnist
gpuNum: 0
# 如果是本地 Experiment,machineList 可为空。
machineList:
- ip: 10.10.10.10
port: 22
username: test
passwd: test
- ip: 10.10.10.11
port: 22
username: test
passwd: test
- ip: 10.10.10.12
port: 22
username: test
sshKeyPath: /nni/sshkey
passphrase: qwert
### OpenPAI 模式
authorName: test
experimentName: nni_test1
trialConcurrency: 1
maxExecDuration:500h
maxTrialNum: 1
#可选项: local, remote, pai, kubeflow
trainingServicePlatform: pai
searchSpacePath: search_space.json
#可选项: true, false
useAnnotation: false
tuner:
#可选项: TPE, Random, Anneal, Evolution, BatchTuner
#SMAC (SMAC 需要使用 nnictl package 单独安装)
builtinTunerName: TPE
classArgs:
#可选项: maximize, minimize
optimize_mode: maximize
trial:
command: python3 main.py
codeDir: .
gpuNum: 4
cpuNum: 2
memoryMB: 10000
# 在 OpenPAI 上运行 NNI 的 Docker 映像
image: msranni/nni:latest
paiConfig:
# 登录 OpenPAI 的用户名
userName: test
# 登录 OpenPAI 的密码
passWord: test
# OpenPAI 的 RestFUL 服务器地址
host: 10.10.10.10
### Kubeflow 模式
使用 NFS 存储。
authorName: default
experimentName: example_mni
trialConcurrency: 1
maxExecDuration: 1h
maxTrialNum: 1
# 可选项: local, remote, pai, kubeflow
trainingServicePlatform: kubeflow
searchSpacePath: search_space.json
# 可选项: true, false
useAnnotation: false
tuner:
# 可选项: TPE, Random, Anneal, Evolution
builtinTunerName: TPE
classArgs:
# 可选项: maximize, minimize
optimize_mode: maximize
trial:
codeDir: .
worker:
replicas: 1
command: python3 mnist.py
gpuNum: 0
cpuNum: 1
memoryMB: 8192
image: msranni/nni:latest
kubeflowConfig:
operator: tf-operator
nfs:
server: 10.10.10.10
path: /var/nfs/general
### Kubeflow 中使用 Azure 存储
authorName: default
experimentName: example_mni
trialConcurrency: 1
maxExecDuration: 1h
maxTrialNum: 1
# 可选项: local, remote, pai, kubeflow
trainingServicePlatform: kubeflow
searchSpacePath: search_space.json
# 可选项: true, false
useAnnotation: false
#nniManagerIp: 10.10.10.10
tuner:
# 可选项: TPE, Random, Anneal, Evolution
builtinTunerName: TPE
classArgs:
# 可选项: maximize, minimize
optimize_mode: maximize
assessor:
builtinAssessorName: Medianstop
classArgs:
optimize_mode: maximize
trial:
codeDir: .
worker:
replicas: 1
command: python3 mnist.py
gpuNum: 0
cpuNum: 1
memoryMB: 4096
image: msranni/nni:latest
kubeflowConfig:
operator: tf-operator
keyVault:
vaultName: Contoso-Vault
name: AzureStorageAccountKey
azureStorage:
accountName: storage
azureShare: share01
\ No newline at end of file
Experiment(实验)配置参考
===========================
创建 Experiment 所需要的配置文件。 配置文件的路径会传入 ``nnictl`` 命令。
配置文件的格式为 YAML。
本文介绍了配置文件的内容,并提供了一些示例和模板。
* `Experiment 配置参考 <#experiment-config-reference>`__
* `模板 <#template>`__
* `说明 <#configuration-spec>`__
* `authorName <#authorname>`__
* `experimentName <#experimentname>`__
* `trialConcurrency <#trialconcurrency>`__
* `maxExecDuration <#maxexecduration>`__
* `versionCheck <#versioncheck>`__
* `debug <#debug>`__
* `maxTrialNum <#maxtrialnum>`__
* `trainingServicePlatform <#trainingserviceplatform>`__
* `searchSpacePath <#searchspacepath>`__
* `useAnnotation <#useannotation>`__
* `multiThread <#multithread>`__
* `nniManagerIp <#nnimanagerip>`__
* `logDir <#logdir>`__
* `logLevel <#loglevel>`__
* `logCollection <#logcollection>`__
* `tuner <#tuner>`__
* `builtinTunerName <#builtintunername>`__
* `codeDir <#codedir>`__
* `classFileName <#classfilename>`__
* `className <#classname>`__
* `classArgs <#classargs>`__
* `gpuIndices <#gpuindices>`__
* `includeIntermediateResults <#includeintermediateresults>`__
* `assessor <#assessor>`__
* `builtinAssessorName <#builtinassessorname>`__
* `codeDir <#codedir-1>`__
* `classFileName <#classfilename-1>`__
* `className <#classname-1>`__
* `classArgs <#classargs-1>`__
* `advisor <#advisor>`__
* `builtinAdvisorName <#builtinadvisorname>`__
* `codeDir <#codedir-2>`__
* `classFileName <#classfilename-2>`__
* `className <#classname-2>`__
* `classArgs <#classargs-2>`__
* `gpuIndices <#gpuindices-1>`__
* `trial <#trial>`__
* `localConfig <#localconfig>`__
* `gpuIndices <#gpuindices-2>`__
* `maxTrialNumPerGpu <#maxtrialnumpergpu>`__
* `useActiveGpu <#useactivegpu>`__
* `machineList <#machinelist>`__
* `ip <#ip>`__
* `port <#port>`__
* `username <#username>`__
* `passwd <#passwd>`__
* `sshKeyPath <#sshkeypath>`__
* `passphrase <#passphrase>`__
* `gpuIndices <#gpuindices-3>`__
* `maxTrialNumPerGpu <#maxtrialnumpergpu-1>`__
* `useActiveGpu <#useactivegpu-1>`__
* `preCommand <#preCommand>`__
* `kubeflowConfig <#kubeflowconfig>`__
* `operator <#operator>`__
* `storage <#storage>`__
* `nfs <#nfs>`__
* `keyVault <#keyvault>`__
* `azureStorage <#azurestorage>`__
* `uploadRetryCount <#uploadretrycount>`__
* `paiConfig <#paiconfig>`__
* `userName <#username>`__
* `password <#password>`__
* `token <#token>`__
* `host <#host>`__
* `reuse <#reuse>`__
* `示例 <#examples>`__
* `本地模式 <#local-mode>`__
* `远程模式 <#remote-mode>`__
* `PAI 模式 <#pai-mode>`__
* `Kubeflow 模式 <#kubeflow-mode>`__
* `Kubeflow 中使用 Azure 存储 <#kubeflow-with-azure-storage>`__
模板
--------
* **简化版(不包含 Annotation(标记)和 Assessor)**
.. code-block:: yaml
authorName:
experimentName:
trialConcurrency:
maxExecDuration:
maxTrialNum:
# 可选项: local, remote, pai, kubeflow
trainingServicePlatform:
searchSpacePath:
# 可选项: true, false, default: false
useAnnotation:
# 可选项: true, false, default: false
multiThread:
tuner:
# 可选项: TPE, Random, Anneal, Evolution
builtinTunerName:
classArgs:
# 可选项: maximize, minimize
optimize_mode:
gpuIndices:
trial:
command:
codeDir:
gpuNum:
# 在本机模式下,machineList 可为空
machineList:
- ip:
port:
username:
passwd:
* **使用 Assessor**
.. code-block:: yaml
authorName:
experimentName:
trialConcurrency:
maxExecDuration:
maxTrialNum:
# 可选项: local, remote, pai, kubeflow
trainingServicePlatform:
searchSpacePath:
# 可选项: true, false, default: false
useAnnotation:
# 可选项: true, false, default: false
multiThread:
tuner:
# 可选项: TPE, Random, Anneal, Evolution
builtinTunerName:
classArgs:
# 可选项: maximize, minimize
optimize_mode:
gpuIndices:
assessor:
# 可选项: Medianstop
builtinAssessorName:
classArgs:
# 可选项: maximize, minimize
optimize_mode:
trial:
command:
codeDir:
gpuNum:
# 在本机模式下,machineList 可为空
machineList:
- ip:
port:
username:
passwd:
* **使用 Annotation**
.. code-block:: yaml
authorName:
experimentName:
trialConcurrency:
maxExecDuration:
maxTrialNum:
# 可选项: local, remote, pai, kubeflow
trainingServicePlatform:
# 可选项: true, false, default: false
useAnnotation:
# 可选项: true, false, default: false
multiThread:
tuner:
# 可选项: TPE, Random, Anneal, Evolution
builtinTunerName:
classArgs:
# 可选项: maximize, minimize
optimize_mode:
gpuIndices:
assessor:
# 可选项: Medianstop
builtinAssessorName:
classArgs:
# 可选项: maximize, minimize
optimize_mode:
trial:
command:
codeDir:
gpuNum:
# 在本机模式下,machineList 可为空
machineList:
- ip:
port:
username:
passwd:
说明
------------------
authorName
^^^^^^^^^^
必填。 字符串。
创建 Experiment 的作者的姓名。
*待定: 增加默认值。*
experimentName
^^^^^^^^^^^^^^
必填。 字符串。
创建的 Experiment 名称。
*待定: 增加默认值。*
trialConcurrency
^^^^^^^^^^^^^^^^
必填。 1 到 99999 之间的整数。
指定同时运行的 Trial 任务的最大数量。
注意:如果 trialGpuNum 大于空闲的 GPU 数量,并且并发的 Trial 任务数量还没达到 **trialConcurrency**,Trial 任务会被放入队列,等待分配 GPU 资源。
maxExecDuration
^^^^^^^^^^^^^^^
可选。 字符串。 默认值:999d。
**maxExecDuration** 指定实验的最大执行时间。 时间单位为 {**s**\ ,** m**\ ,** h**\ ,** d**\ },其分别表示 {*秒*\ , *分钟*\ , *小时*\ , *天*\ }。
注意:maxExecDuration 设置的是 Experiment 执行的时间,不是 Trial 的。 如果 Experiment 达到了设置的最大时间,Experiment 不会停止,但不会再启动新的 Trial 作业。
versionCheck
^^^^^^^^^^^^
可选。 布尔。 默认值:true。
NNI 会校验 remote, pai 和 Kubernetes 模式下 NNIManager 与 trialKeeper 进程的版本。 如果需要禁用版本校验,versionCheck 应设置为 false。
debug
^^^^^
可选。 布尔。 默认值:false。
调试模式会将 versionCheck 设置为 False,并将 logLevel 设置为 'debug'。
maxTrialNum
^^^^^^^^^^^
可选。 1 到 99999 之间的整数。 默认值:99999。
指定 NNI 创建的最大 Trial 任务数,包括成功和失败的任务。
trainingServicePlatform
^^^^^^^^^^^^^^^^^^^^^^^
必填。 字符串。
指定运行 Experiment 的平台,包括 **local**\ ,** remote**\ ,** pai**\ ,** kubeflow**\ ,** frameworkcontroller**。
*
**local** 在本机的 ubuntu 上运行 Experiment。
*
**remote** 将任务提交到远程的 ubuntu 上,必须用 **machineList** 来指定远程的 SSH 连接信息。
*
**pai** 提交到微软开源的 `OpenPAI <https://github.com/Microsoft/pai>`__ 上。 更多 OpenPAI 配置,参考 `PAI 模式指南 <../TrainingService/PaiMode.rst>`__。
*
**kubeflow** 提交任务到 `kubeflow <https://www.kubeflow.org/docs/about/kubeflow/>`__\ , NNI 支持基于 kubernetes 的 kubeflow,以及 `azure kubernetes <https://azure.microsoft.com/zh-cn/services/kubernetes-service/>`__。 详情参考 `Kubeflow Docs <../TrainingService/KubeflowMode.rst>`__。
*
**adl** 提交任务到 `AdaptDL <https://www.kubeflow.org/docs/about/kubeflow/>`__\ , NNI 支持 Kubernetes 集群上的 AdaptDL。 详情参考 `AdaptDL Docs <../TrainingService/AdaptDLMode.rst>`__。
*
TODO:解释 FrameworkController。
searchSpacePath
^^^^^^^^^^^^^^^
可选。 现有文件的路径。
指定搜索空间文件的路径,此文件必须在运行 nnictl 的本机。
仅在 ``useAnnotation=True`` 时,才不需要填写 **searchSpacePath**。
useAnnotation
^^^^^^^^^^^^^
可选。 布尔。 默认值:false。
使用 Annotation 分析 Trial 代码并生成搜索空间。
注意: 如果设置了 **useAnnotation=True**,searchSpacePath 字段必须被删除。
multiThread
^^^^^^^^^^^
可选。 布尔。 默认值:false。
为 Dispatcher 启用多线程模式。 如果启用了 multiThread,Dispatcher 将启动一个线程来处理来自 NNI 管理器的每个命令。
nniManagerIp
^^^^^^^^^^^^
可选。 字符串。 默认值:eth0 设备的 IP。
设置运行 NNI 管理器进程的计算机的 IP 地址。 此字段为可选项,如果没有设置,则会使用 eth0 的 IP 地址。
注意: 可在 NNI 管理器机器上运行 ifconfig 来检查 eth0 是否存在。 如果没有,建议显式设置 **nniManagerIp**。
logDir
^^^^^^
可选。 目录的路径。 默认:``<user home directory>/nni-experiments``。
配置目录以存储 Experiment 的日志和数据。
logLevel
^^^^^^^^
可选。 字符串。 默认值: ``info``。
设置 Experiment 的日志级别。 可设置的日志级别包括:``trace``\ , ``debug``\ , ``info``\ , ``warning``\ , ``error``\ , ``fatal``。
logCollection
^^^^^^^^^^^^^
可选。 ``http`` 或者 ``none``。 默认值:``none``。
设置在remote、pai、kubeflow、frameworkcontroller 平台中收集日志的方式。 日志支持两种设置,一种是通过 ``http``,让 Trial 将日志通过 POST 方法发回日志,这种方法会减慢 trialKeeper 的速度。 另一种方法是 ``none``,Trial 不将日志回传回来,仅仅回传 Job 的指标。 如果日志较大,可将此参数设置为 ``none``。
tuner
^^^^^
必填。
指定了 Experiment 的 Tuner 算法。有两种方法可设置 Tuner。 一种方法是使用 NNI SDK 提供的内置 Tuner,在这种情况下,需要设置 **builtinTunerName** 和 **classArgs**。 另一种方法,是使用用户自定义的 Tuner,需要设置 **codeDirectory**\ ,** classFileName**\ ,** className** 和 **classArgs**。 *必须选择其中的一种方式。*
builtinTunerName
^^^^^^^^^^^^^^^^
如果使用内置 Tuner,则为必需。 字符串。
指定系统 Tuner 的名称, NNI SDK 提供的各种 Tuner 的 `说明 <../Tuner/BuiltinTuner.rst>`__。
codeDir
^^^^^^^
如果使用定制 Tuner,则为必需。 相对于配置文件位置的路径。
指定 Tuner 代码的目录。
classFileName
^^^^^^^^^^^^^
如果使用定制 Tuner,则为必需。 相对于 **codeDir** 的文件路径。
指定 Tuner 文件的名称。
className
^^^^^^^^^
如果使用定制 Tuner,则为必需。 字符串。
指定 Tuner 的名称。
classArgs
^^^^^^^^^
可选。 键值对。 默认值:空。
指定 Tuner 算法的参数。 参考 `此文件 <../Tuner/BuiltinTuner.rst>`__ 来了解内置 Tuner 的配置参数。
gpuIndices
^^^^^^^^^^
可选。 字符串。 默认值:空。
指定 Tuner 进程可以使用的 GPU。 可以指定单个或多个 GPU 索引。 多个 GPU 索引用逗号 ``,`` 分隔。 例如, ``1``\ , 或 ``0,1,3``. 如果未设置该字段,则 Tuner 将找不到 GPU(设置 ``CUDA_VISIBLE_DEVICES`` 成空字符串)。
includeIntermediateResults
^^^^^^^^^^^^^^^^^^^^^^^^^^
可选。 布尔。 默认值:false。
如果 **includeIntermediateResults** 为 true,最后一个 Assessor 的中间结果会被发送给 Tuner 作为最终结果。
assessor
^^^^^^^^
指定 Assessor 算法以运行 Experiment。 与 Tuner 类似,有两种设置 Assessor 的方法。 一种方法是使用 NNI SDK 提供的 Assessor。 必填字段:builtinAssessorName 和 classArgs。 另一种方法,是使用用户自定义的 Assessor,需要设置 **codeDirectory**\ ,** classFileName**\ ,** className** 和 **classArgs**。 *必须选择其中的一种方式。*
默认情况下,未启用任何 Assessor。
builtinAssessorName
^^^^^^^^^^^^^^^^^^^
如果使用内置 Assessor,则为必需。 字符串。
指定内置 Assessor 的名称,NNI SDK 提供的 Assessor 可参考 `这里 <../Assessor/BuiltinAssessor.rst>`__。
codeDir
^^^^^^^
如果使用定制 Assessor,则为必需。 相对于配置文件位置的路径。
指定 Assessor 代码的目录。
classFileName
^^^^^^^^^^^^^
如果使用定制 Assessor,则为必需。 相对于 **codeDir** 的文件路径。
指定 Assessor 文件的名称。
className
^^^^^^^^^
如果使用定制 Assessor,则为必需。 字符串。
指定 Assessor 类的名称。
classArgs
^^^^^^^^^
可选。 键值对。 默认值:空。
指定 Assessor 算法的参数。
Advisor
^^^^^^^
可选。
指定 Experiment 中的 Advisor 算法。 与 Tuner 和 Assessor 类似,有两种指定 Advisor 的方法。 一种方法是使用 SDK 提供的 Advisor ,需要设置 **builtinAdvisorName** 和 **classArgs**。 另一种方法,是使用用户自定义的 Advisor ,需要设置 **codeDirectory**\ ,** classFileName**\ ,** className** 和 **classArgs**。
启用 Advisor 后,将忽略 Tuner 和 Advisor 的设置。
builtinAdvisorName
^^^^^^^^^^^^^^^^^^
指定内置 Advisor 的名称。 NNI SDK 提供了 `BOHB <../Tuner/BohbAdvisor.rst>`__ 和 `Hyperband <../Tuner/HyperbandAdvisor.rst>`__ 。
codeDir
^^^^^^^
如果使用定制 Advisor,则为必需。 相对于配置文件位置的路径。
指定 Advisor 代码的目录。
classFileName
^^^^^^^^^^^^^
如果使用定制 Advisor,则为必需。 相对于 **codeDir** 的文件路径。
指定 Advisor 文件的名称。
className
^^^^^^^^^
如果使用定制 Advisor,则为必需。 字符串。
指定 Advisor 类的名称。
classArgs
^^^^^^^^^
可选。 键值对。 默认值:空。
指定 Advisor 的参数。
gpuIndices
^^^^^^^^^^
可选。 字符串。 默认值:空。
指定可以使用的 GPU。 可以指定单个或多个 GPU 索引。 多个 GPU 索引用逗号 ``,`` 分隔。 例如, ``1``\ , 或 ``0,1,3``. 如果未设置该字段,则 Tuner 将找不到 GPU(设置 ``CUDA_VISIBLE_DEVICES`` 成空字符串)。
trial
^^^^^
必填。 键值对。
在 local 和 remote 模式下,需要以下键。
*
**command**:必需字符串。 指定运行 Trial 的命令。
*
**codeDir**:必需字符串。 指定 Trial 文件的目录。 此目录将在 remote 模式下自动上传。
*
**gpuNum**:可选、整数。 指定了运行 Trial 进程的 GPU 数量。 默认值为 0。
在 PAI 模式下,需要以下键。
*
**command**:必需字符串。 指定运行 Trial 的命令。
*
**codeDir**:必需字符串。 指定 Trial 文件的目录。 目录中的文件将在 PAI 模式下上传。
*
**gpuNum**:必需、整数。 指定了运行 Trial 进程的 GPU 数量。 默认值为 0。
*
**cpuNum**:必需、整数。 指定要在 OpenPAI 容器中使用的 cpu 数。
*
**memoryMB**:必需、整数。 设置要在 OpenPAI 容器中使用的内存大小,以兆字节为单位。
*
**image**:必需字符串。 设置要在 OpenPAI 中使用的 Docker 映像。
*
**authFile**:可选、字符串。 用于提供 Docker 注册,用于为 OpenPAI 中的映像拉取请求进行身份验证。 `参考 <https://github.com/microsoft/pai/blob/2ea69b45faa018662bc164ed7733f6fdbb4c42b3/docs/faq.rst#q-how-to-use-private-docker-registry-job-image-when-submitting-an-openpai-job>`__.
*
**shmMB**:可选、整数。 容器的共享内存大小。
*
**portList**\ : ``label``\ , ``beginAt``\ , ``portNumber`` 的键值对 list。 参考 `OpenPAI 教程 <https://github.com/microsoft/pai/blob/master/docs/job_tutorial.rst>`__ 。
在 Kubeflow 模式下,需要以下键。
*
**codeDir**:指定了代码文件的本机路径。
*
**ps**:Kubeflow 的 tensorflow-operator 的可选配置,包括:
*
**replicas**:``ps`` 角色的副本数量。
*
**command**:**ps** 容器运行的脚本。
*
**gpuNum**:在 **ps** 容器中使用的 GPU 数量。
*
**cpuNum**:在 **ps** 容器中使用的 CPU 数量。
*
**memoryMB**:容器的内存大小。
*
**image**:在 **ps** 中使用的 Docker 映像。
*
**worker**:是 Kubeflow 的 tensorflow-operator 的可选配置。
*
**replicas**:**worker** 角色的副本数量。
*
**command**:**worker** 容器运行的脚本。
*
**gpuNum**:在 **worker** 容器中使用的 GPU 数量。
*
**cpuNum**:在 **worker** 容器中使用的 CPU 数量。
*
**memoryMB**:容器的内存大小。
*
**image**:在 **worker** 中使用的 Docker 映像。
localConfig
^^^^^^^^^^^
本机模式下可选。 键值对。
仅在 **trainingServicePlatform** 设为 **local** 时有效,否则,配置文件中不应该有 **localConfig** 部分。
gpuIndices
^^^^^^^^^^
可选。 字符串。 默认值:none。
用于指定特定的 GPU。设置此值后,只有指定的 GPU 会被用来运行 Trial 任务。 可以指定单个或多个 GPU 索引。 多个 GPU 索引,应用逗号(``,``)分隔,如 ``1`` 或 ``0,1,3``。 默认情况下,将使用所有可用的 GPU。
maxTrialNumPerGpu
^^^^^^^^^^^^^^^^^
可选。 整数。 默认值: 1。
用于指定 GPU 设备上的最大并发 Trial 的数量。
useActiveGpu
^^^^^^^^^^^^
可选。 布尔。 默认值:false。
用于指定 GPU 上存在其他进程时是否使用此 GPU。 默认情况下,NNI 仅在 GPU 中没有其他活动进程时才使用 GPU。 如果 **useActiveGpu** 设置为 true,则 NNI 无论某 GPU 是否有其它进程,都将使用它。 此字段不适用于 Windows 版的 NNI。
machineList
^^^^^^^^^^^
在 remote 模式下必需。 具有以下键的键值对的列表。
ip
^^
必填。 可从当前计算机访问的 IP 地址或主机名。
远程计算机的 IP 地址或主机名。
port
^^^^
可选。 整数。 有效端口。 默认值: 22。
用于连接计算机的 SSH 端口。
username
^^^^^^^^
使用用户名/密码进行身份验证时是必需的。 字符串。
远程计算机的帐户。
passwd
^^^^^^
使用用户名/密码进行身份验证时是必需的。 字符串。
指定帐户的密码。
sshKeyPath
^^^^^^^^^^
如果使用 SSH 密钥进行身份验证,则为必需。 私钥文件的路径。
如果用户使用 SSH 密钥登录远程计算机,**sshKeyPath** 应是有效的 SSH 密钥文件路径。
*注意:如果同时设置了 passwd 和 sshKeyPath,NNI 会首先使用 passwd。*
passphrase
^^^^^^^^^^
可选。 字符串。
用于保护 SSH 密钥,如果用户没有密码,可为空。
gpuIndices
^^^^^^^^^^
可选。 字符串。 默认值:none。
用于指定特定的 GPU。设置此值后,只有指定的 GPU 会被用来运行 Trial 任务。 可以指定单个或多个 GPU 索引。 多个 GPU 索引,应用逗号(``,``)分隔,如 ``1`` 或 ``0,1,3``。 默认情况下,将使用所有可用的 GPU。
maxTrialNumPerGpu
^^^^^^^^^^^^^^^^^
可选。 整数。 默认值: 1。
用于指定 GPU 设备上的最大并发 Trial 的数量。
useActiveGpu
^^^^^^^^^^^^
可选。 布尔。 默认值:false。
用于指定 GPU 上存在其他进程时是否使用此 GPU。 默认情况下,NNI 仅在 GPU 中没有其他活动进程时才使用 GPU。 如果 **useActiveGpu** 设置为 true,则 NNI 无论某 GPU 是否有其它进程,都将使用它。 此字段不适用于 Windows 版的 NNI。
preCommand
^^^^^^^^^^
可选。 字符串。
在远程机器执行其他命令之前,将执行预命令。 用户可以通过设置 **preCommand**,在远程机器上配置实验环境。 如果需要执行多个命令,请使用 ``&&`` 连接它们,例如 ``preCommand: command1 && command2&&…``。
**注意**:因为 ``preCommand`` 每次都会在其他命令之前执行,所以强烈建议不要设置 **preCommand** 来对系统进行更改,即 ``mkdir`` or ``touch``。
remoteConfig
^^^^^^^^^^^^
在 remote 模式下可选。 用户可以在 ``machineList`` 字段中设置每台机器的信息,并在该字段中设置远程模式的全局配置。
reuse
^^^^^
可选。 布尔。 默认值:``false``。 这是试用中的功能。
如果为 true,NNI 会重用远程作业,在其中运行尽可能多的 Trial。 这样可以节省创建新作业的时间。 用户需要确保同一作业中的每个 Trial 相互独立,例如,要避免从之前的 Trial 中读取检查点。
kubeflowConfig
^^^^^^^^^^^^^^
operator
^^^^^^^^
必填。 字符串。 必须是 ``tf-operator`` 或 ``pytorch-operator``。
指定要使用的 Kubeflow 运算符,当前版本中 NNI 支持 ``tf-operator``。
storage
^^^^^^^
可选。 字符串。 默认值 ``nfs``。
指定 Kubeflow 的存储类型,包括 ``nfs`` 和 ``azureStorage``。
nfs
^^^
如果使用 nfs,则必需。 键值对。
*
**server** 是 NFS 服务器的地址。
*
**path** 是 NFS 挂载的路径。
keyVault
^^^^^^^^
如果使用 Azure 存储,则必需。 键值对。
将 **keyVault** 设置为 Azure 存储帐户的私钥。 参考:https://docs.microsoft.com/zh-cn/azure/key-vault/key-vault-manage-with-cli2 。
*
**vaultName** 是 az 命令中 ``--vault-name`` 的值。
*
**name** 是 az 命令中 ``--name`` 的值。
azureStorage
^^^^^^^^^^^^
如果使用 Azure 存储,则必需。 键值对。
设置 Azure 存储帐户以存储代码文件。
*
**accountName** 是 Azure 存储账户的名称。
*
**azureShare** 是 Azure 文件存储的共享参数。
uploadRetryCount
^^^^^^^^^^^^^^^^
如果使用 Azure 存储,则必需。 1 到 99999 之间的整数。
如果上传文件至 Azure Storage 失败,NNI 会重试。此字段指定了重试的次数。
paiConfig
^^^^^^^^^
userName
^^^^^^^^
必填。 字符串。
OpenPAI 帐户的用户名。
password
^^^^^^^^
如果使用密码身份验证,则需要。 字符串。
OpenPAI 帐户的密码。
token
^^^^^
如果使用令牌(token)身份验证,则需要。 字符串。
可以从 OpenPAI 门户检索的个人访问令牌。
host
^^^^
必填。 字符串。
OpenPAI 的 IP 地址。
reuse
^^^^^
可选。 布尔。 默认值:``false``。 这是试用中的功能。
如果为 true,NNI 会重用 OpenPAI 作业,在其中运行尽可能多的 Trial。 这样可以节省创建新作业的时间。 用户需要确保同一作业中的每个 Trial 相互独立,例如,要避免从之前的 Trial 中读取检查点。
示例
--------
本机模式
^^^^^^^^^^
如果要在本机运行 Trial 任务,并使用标记来生成搜索空间,可参考下列配置:
.. code-block:: yaml
authorName: test
experimentName: test_experiment
trialConcurrency: 3
maxExecDuration: 1h
maxTrialNum: 10
# 可选项:local, remote, pai, kubeflow
trainingServicePlatform: local
# 可选项:true, false
useAnnotation: true
tuner:
# 可选项:TPE, Random, Anneal, Evolution
builtinTunerName: TPE
classArgs:
# 可选项: maximize, minimize
optimize_mode: maximize
trial:
command: python3 mnist.py
codeDir: /nni/mnist
gpuNum: 0
增加 Assessor 配置
.. code-block:: yaml
authorName: test
experimentName: test_experiment
trialConcurrency: 3
maxExecDuration: 1h
maxTrialNum: 10
# 可选项:local, remote, pai, kubeflow
trainingServicePlatform: local
searchSpacePath: /nni/search_space.json
# 可选项:true, false
useAnnotation: false
tuner:
# 可选项:TPE, Random, Anneal, Evolution
builtinTunerName: TPE
classArgs:
# 可选项: maximize, minimize
optimize_mode: maximize
assessor:
# 可选项: Medianstop
builtinAssessorName: Medianstop
classArgs:
# 可选项: maximize, minimize
optimize_mode: maximize
trial:
command: python3 mnist.py
codeDir: /nni/mnist
gpuNum: 0
或者可以指定自定义的 Tuner 和 Assessor:
.. code-block:: yaml
authorName: test
experimentName: test_experiment
trialConcurrency: 3
maxExecDuration: 1h
maxTrialNum: 10
# 可选项:local, remote, pai, kubeflow
trainingServicePlatform: local
searchSpacePath: /nni/search_space.json
# 可选项:true, false
useAnnotation: false
tuner:
codeDir: /nni/tuner
classFileName: mytuner.py
className: MyTuner
classArgs:
# 可选项: maximize, minimize
optimize_mode: maximize
assessor:
codeDir: /nni/assessor
classFileName: myassessor.py
className: MyAssessor
classArgs:
# 可选项: maximize, minimize
optimize_mode: maximize
trial:
command: python3 mnist.py
codeDir: /nni/mnist
gpuNum: 0
远程模式
^^^^^^^^^^^
如果要在远程服务器上运行 Trial 任务,需要增加服务器信息:
.. code-block:: yaml
authorName: test
experimentName: test_experiment
trialConcurrency: 3
maxExecDuration: 1h
maxTrialNum: 10
# 可选项:local, remote, pai, kubeflow
trainingServicePlatform: remote
searchSpacePath: /nni/search_space.json
# 可选项:true, false
useAnnotation: false
tuner:
# 可选项:TPE, Random, Anneal, Evolution
builtinTunerName: TPE
classArgs:
# 可选项: maximize, minimize
optimize_mode: maximize
trial:
command: python3 mnist.py
codeDir: /nni/mnist
gpuNum: 0
# 如果是本地平台的话,machineList 可以为空
machineList:
- ip: 10.10.10.10
port: 22
username: test
passwd: test
- ip: 10.10.10.11
port: 22
username: test
passwd: test
- ip: 10.10.10.12
port: 22
username: test
sshKeyPath: /nni/sshkey
passphrase: qwert
# 在远程机器执行其他命令之前,将执行预命令。
# 以下是特定 python 环境的一个示例
# 如果想同时执行多条命令,使用 "&&" 连接他们
# 预命令: source ${replace_to_absolute_path_recommended_here}/bin/activate
# 预命令: source ${replace_to_conda_path}/bin/activate ${replace_to_conda_env_name}
preCommand: export PATH=${replace_to_python_environment_path_in_your_remote_machine}:$PATH
PAI 模式
^^^^^^^^
.. code-block:: yaml
authorName: test
experimentName: nni_test1
trialConcurrency: 1
maxExecDuration:500h
maxTrialNum: 1
# 可选项:local, remote, pai, kubeflow
trainingServicePlatform: pai
searchSpacePath: search_space.json
# 可选项:true, false
useAnnotation: false
tuner:
# 可选项: TPE, Random, Anneal, Evolution, BatchTuner
# SMAC (SMAC 应该通过 nnictl 安装)
builtinTunerName: TPE
classArgs:
# 可选项: maximize, minimize
optimize_mode: maximize
trial:
command: python3 main.py
codeDir: .
gpuNum: 4
cpuNum: 2
memoryMB: 10000
# 在 OpenPAI 上运行 NNI 的 Docker 映像
image: msranni/nni:latest
paiConfig:
# 登录 OpenPAI 的用户名
userName: test
# 登录 OpenPAI 的密码
passWord: test
# OpenPAI 的 RestFUL 服务器地址
host: 10.10.10.10
Kubeflow 模式
^^^^^^^^^^^^^
使用 NFS 存储。
.. code-block:: yaml
authorName: default
experimentName: example_mni
trialConcurrency: 1
maxExecDuration: 1h
maxTrialNum: 1
# 可选项:local, remote, pai, kubeflow
trainingServicePlatform: kubeflow
searchSpacePath: search_space.json
# 可选项:true, false
useAnnotation: false
tuner:
# 可选项:TPE, Random, Anneal, Evolution
builtinTunerName: TPE
classArgs:
# 可选项: maximize, minimize
optimize_mode: maximize
trial:
codeDir: .
worker:
replicas: 1
command: python3 mnist.py
gpuNum: 0
cpuNum: 1
memoryMB: 8192
image: msranni/nni:latest
kubeflowConfig:
operator: tf-operator
nfs:
server: 10.10.10.10
path: /var/nfs/general
Kubeflow 中使用 Azure 存储
^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. code-block:: yaml
authorName: default
experimentName: example_mni
trialConcurrency: 1
maxExecDuration: 1h
maxTrialNum: 1
# 可选项:local, remote, pai, kubeflow
trainingServicePlatform: kubeflow
searchSpacePath: search_space.json
# 可选项:true, false
useAnnotation: false
# nniManagerIp: 10.10.10.10
tuner:
# 可选项:TPE, Random, Anneal, Evolution
builtinTunerName: TPE
classArgs:
# 可选项: maximize, minimize
optimize_mode: maximize
assessor:
builtinAssessorName: Medianstop
classArgs:
optimize_mode: maximize
trial:
codeDir: .
worker:
replicas: 1
command: python3 mnist.py
gpuNum: 0
cpuNum: 1
memoryMB: 4096
image: msranni/nni:latest
kubeflowConfig:
operator: tf-operator
keyVault:
vaultName: Contoso-Vault
name: AzureStorageAccountKey
azureStorage:
accountName: storage
azureShare: share01
# 常见问答
常见问答
=========
此页为常见问题
### tmp 目录没空间了
tmp 目录没空间了
^^^^^^^^^^^^^^^^^
nnictl 在执行时,使用 tmp 目录作为临时目录来复制 codeDir 下的文件。 当遇到下列错误时,先试试清空 **tmp** 目录。
nnictl 在执行时,使用 tmp 目录作为临时目录来复制 codeDir 下的文件。
当遇到下列错误时,先试试清空 **tmp** 目录。
> OSError: [Errno 28] No space left on device
..
### OpenPAI 模式下无法获得 Trial 的数据
OSError: [Errno 28] No space left on device
OpenPAI 模式下无法获得 Trial 的数据
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
在 OpenPAI 的训练模式下,NNI 管理器会在端口 51189 启动一个 RESTful 服务,来接收 OpenPAI 集群中 Trial 任务的指标数据。 如果在 OpenPAI 模式下的网页中不能看到任何指标,需要检查 51189 端口是否在防火墙规则中已打开。
### 安装时出现 Segmentation Fault (core dumped)
安装时出现 Segmentation Fault (core dumped)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. code-block:: text
make: *** [install-XXX] Segmentation fault (core dumped)
> make: *** [install-XXX] Segmentation fault (core dumped)
可依次试试以下方法:
* 更新或重新安装 Python 中的 pip: `python3 -m pip install -U pip`
* 在安装 NNI 时,添加 `--no-cache-dir` 参数:`python3 -m pip install nni --no-cache-dir`
### Job management error: getIPV4Address() failed because os.networkInterfaces().eth0 is undefined.
* 更新或重新安装 Python 中的 pip:``python3 -m pip install -U pip``
* 在安装 NNI 时,添加 ``--no-cache-dir`` 参数:``python3 -m pip install nni --no-cache-dir``
计算机没有 eth0 设备,需要在配置中设置 [nniManagerIp](ExperimentConfig.md)
Job management error: getIPV4Address() failed because os.networkInterfaces().eth0 is undefined.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
### 运行时间超过了 MaxDuration ,但没有停止
计算机没有 eth0 设备,需要在配置文件中手动设置 `nniManagerIp <ExperimentConfig.rst>`__ 。
当 Experiment 到达最长运行时间时,nniManager 不会创建新的 Trial ,但除非手动停止 Experiment,运行中的 Trial 会继续运行直到结束。
运行时间超过了 MaxDuration ,但没有停止
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
### 使用 `nnictl stop` 无法停止 Experiment
当实验到达最长运行时间时,nniManager 不会创建新的尝试,但除非手动停止实验,运行中的尝试会继续。
如果在 Experiment 运行时,升级了 nni 或删除了一些配置文件,会因为丢失配置文件而出现这类错误。 可以使用 `ps -ef | grep node` 命令来找到 Experiment 的 PID,并用 `kill -9 {pid}` 命令来停止 Experiment 进程。
使用 ``nnictl stop`` 无法停止 Experiment
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
### 无法在虚拟机的 NNI 网页中看到 `指标数据`
如果在 Experiment 运行时,升级了 nni 或删除了一些配置文件,会因为丢失配置文件而出现这类错误。 可以使用 ``ps -ef | grep node`` 命令来找到 Experiment 的 PID,并用 ``kill -9 {pid}`` 命令来停止 Experiment 进程。
无法在虚拟机的 NNI 网页中看到 ``指标数据``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
将虚拟机的网络配置为桥接模式来让虚拟机能被网络访问,并确保虚拟机的防火墙没有禁止相关端口。
### 无法打开 Web 界面的链接
无法打开 Web 界面的链接
^^^^^^^^^^^^^^^^^^^^^^^^^
无法打开 Web 界面的链接可能有以下几个原因:
* `http://127.0.0.1``http://172.17.0.1` 以及 `http://10.0.0.15` 都是 localhost。如果在服务器或远程计算机上启动 Experiment, 可将此 IP 替换为所连接的 IP 来查看 Web 界面,如 `http://[远程连接的地址]:8080`
* ``http://127.0.0.1``\ , ``http://172.17.0.1`` 以及 ``http://10.0.0.15`` 都是 localhost。如果在服务器或远程计算机上启动 Experiment, 可将此 IP 替换为所连接的 IP 来查看 Web 界面,如 ``http://[远程连接的地址]:8080``
* 如果使用服务器 IP 后还是无法看到 Web 界面,可检查此服务器上是否有防火墙或需要代理。 或使用此运行 NNI Experiment 的服务器上的浏览器来查看 Web 界面。
* 另一个可能的原因是 Experiment 启动失败了,NNI 无法读取 Experiment 的信息。 可在如下目录中查看 NNIManager 的日志: `~/nni-experiments/[your_experiment_id]` `/log/nnimanager.log`
* 另一个可能的原因是 Experiment 启动失败了,NNI 无法读取 Experiment 的信息。 可在如下目录中查看 NNIManager 的日志: ``~/nni/experiment/[your_experiment_id] /log/nnimanager.log``
### RESTful 服务器启动失败
RESTful 服务器启动失败
^^^^^^^^^^^^^^^^^^^^^^^^^^^
可能是网络配置有问题。可检查以下问题。
* 可能需要链接 `127.0.0.1``localhost`。 在 `/etc/hosts` 中增加 `127.0.0.1 localhost`
* 也可能设置了一些代理。检查环境中是否有如 `HTTP_PROXY``HTTPS_PROXY` 的变量,如果有,则需要取消。
### NNI 在 Windows 上的问题
* 可能需要链接 ``127.0.0.1`` 与 ``localhost``。 在 ``/etc/hosts`` 中增加 ``127.0.0.1 localhost``。
* 也可能设置了一些代理。检查环境中是否有如 ``HTTP_PROXY`` 或 ``HTTPS_PROXY`` 的变量,如果有,则需要取消。
NNI 在 Windows 上的问题
^^^^^^^^^^^^^^^^^^^^^^^
参考 [Windows 上 NNI](InstallationWin.md)
参考 `在 Windows 上 安装 NNI <InstallationWin.rst>`__
### 更多常见问题解答
更多常见问题解答
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[标有常见问题标签的 Issue](https://github.com/microsoft/nni/labels/FAQ)
`标有常见问题标签的 Issue <https://github.com/microsoft/nni/labels/FAQ>`__
### 帮助改进
帮助改进
^^^^^^^^^^^^^^^
在创建新问题前,请在 https://github.com/Microsoft/nni/issues 查看是否有人已经报告了相似的问题。
\ No newline at end of file
在创建新问题前,请在 https://github.com/Microsoft/nni/issues 查看是否有人已经报告了相似的问题。
# **在 NNI 中调试代码**
## 概述
NNI 中的日志分为三部分。 包括 NNI Manager, Dispatcher 以及 Trial。 这里会简单介绍这些组件。 更多信息可参考[概述](../Overview.md)
- **NNI Controller**:NNI Controller (nnictl) 是命令行工具,用来管理 Experiments(如:启动 Experiment)。
- **NNI Manager**:这是 NNI 的核心。当 Experiment 出现严重错误时,从它的日志中才能找到原因。(例如,Web 界面无法打开,或者训练平台失败)
- **Dispatcher**: Dispatcher 调用 **Tuner****Assessor** 的方法。 它的日志与 Tuner 和 Assessor 代码有关。
- **Tuner**: Tuner 是一个自动机器学习算法,会为下一个 Trial 生成新的配置。 新的 Trial 会使用这组配置来运行。
- **Assessor**:Assessor 分析 Trial 的中间结果(例如,测试数据集上定期的精度),来确定 Trial 是否应该被提前终止。
- **Trial**:Trial 的代码是用户实现的代码,每次 Trial 运行时会尝试一组新的配置(例如,一组新的超参值,或者某个神经网络结构)。
## 日志的位置
NNI 中有三种日志。 在创建 Experiment 时,可增加命令行参数 `--debug`,将日志级别设置为 debug 级别。 此外,还可以在配置文件中使用 `logLevel` 来设置日志级别。 可设置的日志级别包括:`trace`, `debug`, `info`, `warning`, `error`, `fatal`
### NNI Controller
在启动 NNI Experiment 时发生的错误,都可以在这里找到。
通过 `nnictl log stderr` 命令来查看错误信息。 参考 [NNICTL](Nnictl.md) 了解更多命令选项。
### Experiment 根目录
每个 Experiment 都有一个根目录,会显示在 Web 界面的右上角。 如果无法打开 Web 界面,可将 `~/nni-experiments/experiment_id/` 中的 `experiment_id` 替换为实际的 Experiment ID,来组合出根目录。 `experiment_id` 可以在运行 `nnictl create ...` 来创建新 Experiment 的输出中找到。
> 如有需要,可以在配置文件中修改 `logDir`,来指定存储 Experiment 的目录。(默认为 `~/nni-experiments`)。 参考[配置](ExperimentConfig.md)文档,了解更多信息。
在此目录下,还会有另一个叫做 `log` 的目录,`nnimanager.log``dispatcher.log` 都在此目录中。
### Trial 根目录
在 Web 界面中,可通过点击每个 Trial 左边的 `+` 来展开详情并看到它的日志路径。
在 Experiment 的根目录中,会有一个 `trials` 目录,这里存放了所有 Trial 的信息。 每个 Trial 都有一个用其 ID 命名的目录。 目录中会有一个 `stderr` 文件,是 Trial 的错误信息。另一个 `trial.log` 文件是 Trial 的日志。
## 不同类型的错误
NNI 中有不同的错误类型。 根据严重程度,可分为三类。 当 NNI 中发生错误时,需要按顺序检查以下三种错误。
一般情况下,打开 Web 界面,可以在 `Overview` 标签的 `Status` 上看到错误信息。 如果 Web 界面无法打开,可以通过命令行来检查。
### **NNI** 失败
这是最严重的错误。 发生这种错误时,整个 Experiment 都会失败,Trial 也不会运行。 这通常是由安装问题导致的。
先检查 `nnictl` 的错误输出文件 `stderr` (运行 nnictl log stderr),然后检查 `nnimanager` 的日志来看看是否由任何错误。
### **Dispatcher** 失败
这通常是 Tuner 失败的情况。 可检查 Dispatcher 的日志来分析出现了什么问题。 对于内置的 Tuner,常见的错误可能是无效的搜索空间(不支持的搜索空间类型,或配置文件中的 Tuner 参数的错误)。
以后一种情况为例。 某自定义的 Tuner,*\_init*\_ 函数有名为 `optimize_mode` 的参数,但配置文件中没有提供此参数。NNI 就会因为初始化 Tuner 失败而造成 Experiment 失败。 可在 Web 界面看到如下错误:
![](../../img/dispatcher_error.jpg)
可以看到这是一个 Dispatcher 的错误。 因此,检查 Dispatcher 的日志,可找到如下信息:
[2019-02-19 19:36:45] DEBUG (nni.main/MainThread) START
[2019-02-19 19:36:47] ERROR (nni.main/MainThread) __init__() missing 1 required positional arguments: 'optimize_mode'
Traceback (most recent call last):
File "/usr/lib/python3.7/site-packages/nni/__main__.py", line 202, in <module>
main()
File "/usr/lib/python3.7/site-packages/nni/__main__.py", line 164, in main
args.tuner_args)
File "/usr/lib/python3.7/site-packages/nni/__main__.py", line 81, in create_customized_class_instance
instance = class_constructor(**class_args)
TypeError: __init__() missing 1 required positional arguments: 'optimize_mode'.
### **Trial** 失败
这种情况下,NNI 可以继续运行,并创建新的 Trial。
这表示 Trial 代码中出现了失败。 这种错误与 Trial 代码相关。 需检查 Trial 的日志来修复错误。
如,其中常见的一种错误是在运行 MNIST 示例时没有安装 TensorFlow。 因为导入模块的错误(没有安装 Tensorflow,但在 Trial 代码中有 import tensorflow 的语句),每次 Trial 都会运行失败。
![](../../img/trial_error.jpg)
如图,每个 Trial 都有日志路径,可以从中找到 Trial 的日志和 stderr。
除了 Experiment 级调试之外,NNI 还提供调试单个 Trial 的功能,而无需启动整个 Experiment。 有关调试单个 Trial 代码的更多信息,请参考[独立运行模式](../TrialExample/Trials#用于调试的独立模式)
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment