Unverified Commit 483232c8 authored by Chi Song's avatar Chi Song Committed by GitHub
Browse files

Chinese translation (#1554)

parent 76086583
......@@ -10,7 +10,7 @@
NNI (Neural Network Intelligence) 是自动机器学习(AutoML)的工具包。 它通过多种调优的算法来搜索最好的神经网络结构和(或)超参,并支持单机、本地多机、云等不同的运行环境。
### **NNI [v1.0](https://github.com/Microsoft/nni/blob/master/docs/zh_CN/Release_v1.0.md) 已发布! &nbsp;[<img width="48" src="docs/img/release_icon.png" />](#nni-released-reminder)**
### **NNI v1.1 已发布! &nbsp;[<img width="48" src="docs/img/release_icon.png" />](#nni-released-reminder)**
<p align="center">
<a href="#nni-has-been-released"><img src="docs/img/overview.svg" /></a>
......@@ -199,7 +199,7 @@ Linux 和 macOS
*`python >= 3.5` 的环境中运行命令: `git``wget`,确保安装了这两个组件。
```bash
git clone -b v1.0 https://github.com/Microsoft/nni.git
git clone -b v1.1 https://github.com/Microsoft/nni.git
cd nni
source install.sh
```
......@@ -209,7 +209,7 @@ Windows
*`python >=3.5` 的环境中运行命令: `git``PowerShell`,确保安装了这两个组件。
```bash
git clone -b v1.0 https://github.com/Microsoft/nni.git
git clone -b v1.1 https://github.com/Microsoft/nni.git
cd nni
powershell -ExecutionPolicy Bypass -file install.ps1
```
......@@ -220,12 +220,12 @@ Windows 上参考 [Windows 上使用 NNI](docs/zh_CN/Tutorial/NniOnWindows.md)
**验证安装**
以下示例 Experiment 依赖于 TensorFlow 。 在运行前确保安装了 **TensorFlow**
以下示例 Experiment 依赖于 TensorFlow 。 在运行前确保安装了 **TensorFlow 1.x**。 注意,**目前不支持 TensorFlow 2.0**
* 通过克隆源代码下载示例。
```bash
git clone -b v1.0 https://github.com/Microsoft/nni.git
git clone -b v1.1 https://github.com/Microsoft/nni.git
```
Linux 和 macOS
......
......@@ -16,26 +16,26 @@ __1. Update trial code__
It is pretty simple to use multi-phase in trial code, an example is shown below:
```python
```python
# ...
for i in range(5):
# get parameter from tuner
tuner_param = nni.get_next_parameter()
# nni.get_next_parameter returns None if there is no more hyper parameters can be generated by tuner.
if tuner_param is None:
break
# consume the params
# ...
for i in range(5):
# get parameter from tuner
tuner_param = nni.get_next_parameter()
# nni.get_next_parameter returns None if there is no more hyper parameters can be generated by tuner.
if tuner_param is None:
break
# consume the params
# ...
# report final result somewhere for the parameter retrieved above
nni.report_final_result()
# ...
# report final result somewhere for the parameter retrieved above
nni.report_final_result()
# ...
```
# ...
```
In multi-phase experiments, at each time the API ```nni.get_next_parameter()``` is called, it returns a new hyper parameter generated by tuner, then the trail code consume this new hyper parameter and report final result of this hyper parameter. `nni.get_next_parameter()` and `nni.report_final_result()` should be called sequentially: __call the former one, then call the later one; and repeat this pattern__. If `nni.get_next_parameter()` is called multiple times consecutively, and then `nni.report_final_result()` is called once, the result is associated to the last configuration, which is retrieved from the last get_next_parameter call. So there is no result associated to previous get_next_parameter calls, and it may cause some multi-phase algorithm broken.
In multi-phase experiments, at each time the API `nni.get_next_parameter()` is called, it returns a new hyper parameter generated by tuner, then the trail code consume this new hyper parameter and report final result of this hyper parameter. `nni.get_next_parameter()` and `nni.report_final_result()` should be called sequentially: __call the former one, then call the later one; and repeat this pattern__. If `nni.get_next_parameter()` is called multiple times consecutively, and then `nni.report_final_result()` is called once, the result is associated to the last configuration, which is retrieved from the last get_next_parameter call. So there is no result associated to previous get_next_parameter calls, and it may cause some multi-phase algorithm broken.
Note that, ```nni.get_next_parameter``` returns None if there is no more hyper parameters can be generated by tuner.
Note that, `nni.get_next_parameter` returns None if there is no more hyper parameters can be generated by tuner.
__2. Experiment configuration__
......@@ -43,7 +43,7 @@ To enable multi-phase, you should also add `multiPhase: true` in your experiment
Multi-phase experiment configuration example:
```
```yaml
authorName: default
experimentName: multiphase experiment
trialConcurrency: 2
......@@ -66,13 +66,15 @@ trial:
### Write a tuner that leverages multi-phase:
Before writing a multi-phase tuner, we highly suggest you to go through [Customize Tuner](https://nni.readthedocs.io/en/latest/Tuner/CustomizeTuner.html). Same as writing a normal tuner, your tuner needs to inherit from `Tuner` class. When you enable multi-phase through configuration (set `multiPhase` to true), your tuner will get an additional parameter `trial_job_id` via tuner's following methods:
```
```text
generate_parameters
generate_multiple_parameters
receive_trial_result
receive_customized_trial_result
trial_end
```
With this information, the tuner could know which trial is requesting a configuration, and which trial is reporting results. This information provides enough flexibility for your tuner to deal with different trials and different phases. For example, you may want to use the trial_job_id parameter of generate_parameters method to generate hyperparameters for a specific trial job.
### Tuners support multi-phase experiments:
......
......@@ -5,6 +5,7 @@ We are glad to announce the alpha release for model compression toolkit on top o
NNI provides an easy-to-use toolkit to help user design and use compression algorithms. It supports Tensorflow and PyTorch with unified interface. For users to compress their models, they only need to add several lines in their code. There are some popular model compression algorithms built-in in NNI. Users could further use NNI's auto tuning power to find the best compressed model, which is detailed in [Auto Model Compression](./AutoCompression.md). On the other hand, users could easily customize their new compression algorithms using NNI's interface, refer to the tutorial [here](#customize-new-compression-algorithms).
## Supported algorithms
We have provided two naive compression algorithms and three popular ones for users, including two pruning algorithms and three quantization algorithms:
|Name|Brief Introduction of Algorithm|
......@@ -20,6 +21,7 @@ We have provided two naive compression algorithms and three popular ones for use
We use a simple example to show how to modify your trial code in order to apply the compression algorithms. Let's say you want to prune all weight to 80% sparsity with Level Pruner, you can add the following three lines into your code before training your model ([here](https://github.com/microsoft/nni/tree/master/examples/model_compress) is complete code).
Tensorflow code
```python
from nni.compression.tensorflow import LevelPruner
config_list = [{ 'sparsity': 0.8, 'op_types': ['default'] }]
......@@ -28,6 +30,7 @@ pruner(tf.get_default_graph())
```
PyTorch code
```python
from nni.compression.torch import LevelPruner
config_list = [{ 'sparsity': 0.8, 'op_types': ['default'] }]
......@@ -54,6 +57,7 @@ There are also other keys in the `dict`, but they are specific for every compres
The `dict`s in the `list` are applied one by one, that is, the configurations in latter `dict` will overwrite the configurations in former ones on the operations that are within the scope of both of them.
A simple example of configuration is shown below:
```python
[
{
......@@ -70,17 +74,21 @@ A simple example of configuration is shown below:
}
]
```
It means following the algorithm's default setting for compressed operations with sparsity 0.8, but for `op_name1` and `op_name2` use sparsity 0.6, and please do not compress `op_name3`.
### Other APIs
Some compression algorithms use epochs to control the progress of compression (e.g. [AGP](./Pruner.md#agp-pruner)), and some algorithms need to do something after every minibatch. Therefore, we provide another two APIs for users to invoke. One is `update_epoch`, you can use it as follows:
Tensorflow code
Tensorflow code
```python
pruner.update_epoch(epoch, sess)
```
PyTorch code
```python
pruner.update_epoch(epoch)
```
......@@ -130,7 +138,7 @@ class YourPruner(nni.compression.tensorflow.Pruner):
pass
```
For the simpliest algorithm, you only need to override `calc_mask`. It receives each layer's weight and selected configuration, as well as op information. You generate the mask for this weight in this function and return. Then NNI applies the mask for you.
For the simplest algorithm, you only need to override `calc_mask`. It receives each layer's weight and selected configuration, as well as op information. You generate the mask for this weight in this function and return. Then NNI applies the mask for you.
Some algorithms generate mask based on training progress, i.e., epoch number. We provide `update_epoch` for the pruner to be aware of the training progress.
......@@ -145,7 +153,7 @@ The interface for customizing quantization algorithm is similar to that of pruni
# For writing a Quantizer in PyTorch, you can simply replace
# nni.compression.tensorflow.Quantizer with
# nni.compression.torch.Quantizer
class YourPruner(nni.compression.tensorflow.Quantizer):
class YourQuantizer(nni.compression.tensorflow.Quantizer):
def __init__(self, config_list):
# suggest you to use the NNI defined spec for config
super().__init__(config_list)
......@@ -171,13 +179,6 @@ class YourPruner(nni.compression.tensorflow.Quantizer):
# can do some processing based on the model or weights binded
# in the func bind_model
pass
# you can also design your method
def your_method(self, your_input):
#your code
def bind_model(self, model):
#preprocess model
```
__[TODO]__ Will add another member function `quantize_layer_output`, as some quantization algorithms also quantize layers' output.
......
......@@ -74,5 +74,5 @@ quantizer(model)
You can view example for more information
#### User configuration for QAT Quantizer
#### User configuration for DoReFa Quantizer
* **q_bits:** This is to specify the q_bits operations to be quantized to
......@@ -20,7 +20,7 @@ Currently we support the following algorithms:
|[__Metis Tuner__](#MetisTuner)|Metis offers the following benefits when it comes to tuning parameters: While most tools only predict the optimal configuration, Metis gives you two outputs: (a) current prediction of optimal configuration, and (b) suggestion for the next trial. No more guesswork. While most tools assume training datasets do not have noisy data, Metis actually tells you if you need to re-sample a particular hyper-parameter. [Reference Paper](https://www.microsoft.com/en-us/research/publication/metis-robustly-tuning-tail-latencies-cloud-systems/)|
|[__BOHB__](#BOHB)|BOHB is a follow-up work of Hyperband. It targets the weakness of Hyperband that new configurations are generated randomly without leveraging finished trials. For the name BOHB, HB means Hyperband, BO means Bayesian Optimization. BOHB leverages finished trials by building multiple TPE models, a proportion of new configurations are generated through these models. [Reference Paper](https://arxiv.org/abs/1807.01774)|
|[__GP Tuner__](#GPTuner)|Gaussian Process Tuner is a sequential model-based optimization (SMBO) approach with Gaussian Process as the surrogate. [Reference Paper](https://papers.nips.cc/paper/4443-algorithms-for-hyper-parameter-optimization.pdf), [Github Repo](https://github.com/fmfn/BayesianOptimization)|
|[__PPO Tuner__](#PPOTuner)|PPO Tuner is an Reinforcement Learning tuner based on PPO algorithm. [Reference Paper](https://arxiv.org/abs/1707.06347)|
|[__PPO Tuner__](#PPOTuner)|PPO Tuner is a Reinforcement Learning tuner based on PPO algorithm. [Reference Paper](https://arxiv.org/abs/1707.06347)|
## Usage of Built-in Tuners
......@@ -309,6 +309,7 @@ tuner:
> Built-in Tuner Name: **MetisTuner**
Note that the only acceptable types of search space are `quniform`, `uniform` and `randint` and numerical `choice`. Only numerical values are supported since the values will be used to evaluate the 'distance' between different points.
**Suggested scenario**
Similar to TPE and SMAC, Metis is a black-box tuner. If your system takes a long time to finish each trial, Metis is more favorable than other approaches such as random search. Furthermore, Metis provides guidance on the subsequent trial. Here is an [example](https://github.com/Microsoft/nni/tree/master/examples/trials/auto-gbdt/search_space_metis.json) about the use of Metis. User only need to send the final result like `accuracy` to tuner, by calling the NNI SDK. [Detailed Description](./MetisTuner.md)
......@@ -426,14 +427,14 @@ Note that the only acceptable type of search space is `mutable_layer`. `optional
**Suggested scenario**
PPOTuner is a Reinforcement Learning tuner based on PPO algorithm. When you are using NNI NAS interface in your trial code to do neural architecture search, PPOTuner is recommended. It has relatively high data efficiency but is suggested when you have large amount of computation resource. You could try it on very simple task, such as the [mnist-nas](https://github.com/microsoft/nni/tree/master/examples/trials/mnist-nas) example. [Detailed Description](./PPOTuner.md)
PPOTuner is a Reinforcement Learning tuner based on PPO algorithm. When you are using NNI NAS interface in your trial code to do neural architecture search, PPOTuner can be used. In general, Reinforcement Learning algorithm need more computing resource, though PPO algorithm is more efficient than others relatively. So it's recommended to use this tuner when there are large amount of computing resource. You could try it on very simple task, such as the [mnist-nas](https://github.com/microsoft/nni/tree/master/examples/trials/mnist-nas) example. [See details](./PPOTuner.md)
**Requirement of classArgs**
* **optimize_mode** (*'maximize' or 'minimize'*) - If 'maximize', the tuner will target to maximize metrics. If 'minimize', the tuner will target to minimize metrics.
* **trials_per_update** (*int, optional, default = 20*) - The number of trials to be used for one update. This number is recommended to be larger than `trialConcurrency` and `trialConcurrency` be a aliquot devisor of `trials_per_update`. Note that trials_per_update should be divisible by minibatch_size.
* **trials_per_update** (*int, optional, default = 20*) - The number of trials to be used for one update. It must be divisible by minibatch_size. `trials_per_update` is recommended to be an exact multiple of `trialConcurrency` for better concurrency of trials.
* **epochs_per_update** (*int, optional, default = 4*) - The number of epochs for one update.
* **minibatch_size** (*int, optional, default = 4*) - Mini-batch size (i.e., number of trials for a mini-batch) for the update. Note that, trials_per_update should be divisible by minibatch_size.
* **minibatch_size** (*int, optional, default = 4*) - Mini-batch size (i.e., number of trials for a mini-batch) for the update. Note that, trials_per_update must be divisible by minibatch_size.
* **ent_coef** (*float, optional, default = 0.0*) - Policy entropy coefficient in the optimization objective.
* **lr** (*float, optional, default = 3e-4*) - Learning rate of the model (lstm network), constant.
* **vf_coef** (*float, optional, default = 0.5*) - Value function loss coefficient in the optimization objective.
......@@ -450,4 +451,4 @@ tuner:
builtinTunerName: PPOTuner
classArgs:
optimize_mode: maximize
```
\ No newline at end of file
```
......@@ -4,12 +4,11 @@ A config file is needed when creating an experiment. The path of the config file
The config file is in YAML format.
This document describes the rules to write the config file, and provides some examples and templates.
- [Experiment config reference](#Experiment-config-reference)
- [Template](#Template)
- [Configuration spec](#Configuration-spec)
- [Examples](#Examples)
- [Experiment config reference](#experiment-config-reference)
- [Template](#template)
- [Configuration spec](#configuration-spec)
- [Examples](#examples)
<a name="Template"></a>
## Template
* __light weight(without Annotation and Assessor)__
......@@ -131,7 +130,6 @@ machineList:
passwd:
```
<a name="Configuration"></a>
## Configuration spec
* __authorName__
......@@ -333,7 +331,7 @@ machineList:
* __gpuIndices__
__gpuIndices__ specifies the gpus that can be used by the tuner process. Single or multiple GPU indices can be specified, multiple GPU indices are seperated by comma(,), such as `1` or `0,1,3`. If the field is not set, `CUDA_VISIBLE_DEVICES` will be '' in script, that is, no GPU is visible to tuner.
__gpuIndices__ specifies the gpus that can be used by the advisor process. Single or multiple GPU indices can be specified, multiple GPU indices are seperated by comma(,), such as `1` or `0,1,3`. If the field is not set, `CUDA_VISIBLE_DEVICES` will be '' in script, that is, no GPU is visible to tuner.
Note: users could only use one way to specify advisor, either specifying `builtinAdvisorName` and `classArgs`, or specifying `codeDir`, `classFileName`, `className` and `classArgs`.
......@@ -563,7 +561,6 @@ machineList:
__host__ is the host of pai.
<a name="Examples"></a>
## Examples
* __local mode__
......
......@@ -79,7 +79,7 @@ sudo mount -t nfs 10.10.10.10:/tmp/nni/shared /mnt/nfs/nni
实际使用时,IP `10.10.10.10` 需要替换为 NFS 服务器的真实地址。
## Trial 依赖控制的异步调度模式
## Trial 依赖控制的异步 Dispatcher 模式
多机间启用权重的 Trial,一般是通过**先写后读**的方式来保持一致性。 子节点在父节点的 Trial 完成训练前,不应该读取父节点模型。 要解决这个问题,要通过 `multiThread: true` 来启用**异步调度模式**。在 `config.yml` 中,每次收到 `NEW_TRIAL` 请求,分派一个新的 Trial 时,Tuner 线程可以决定是否阻塞当前线程。 例如:
......
......@@ -8,30 +8,34 @@
上述情况都可以通过多阶段执行的功能来支持。 为了支持这些情况,一个 Trial 任务需要能从 Tuner 请求多个配置。 Tuner 需要知道两次配置请求是否来自同一个 Trial 任务。 同时,多阶段中的 Trial 任务需要多次返回最终结果。
注意, `nni.get_next_parameter()``nni.report_final_result()` 需要被依次调用:**先调用前者,然后调用后者,并按此顺序重复调用**。 如果 `nni.get_next_parameter()` 被连续多次调用,然后再调用 `nni.report_final_result()`,这会造成最终结果只会与 get_next_parameter 所返回的最后一个配置相关联。 因此,前面的 get_next_parameter 调用都没有关联的结果,这可能会造成一些多阶段算法出问题。
## 创建多阶段的 Experiment
### 实现使用多阶段的 Trial 代码:
**1. 更新 Trial 代码**
Trial 代码中使用多阶段非常容易,样例如下:
Trial 代码中使用多阶段非常容易,示例如下:
```python
# ...
for i in range(5):
# 从 Tuner 中获得参数
tuner_param = nni.get_next_parameter()
# 如果没有更多超参可生成,nni.get_next_parameter 会返回 None。
if tuner_param is None:
break
```python
# 使用参数
# ...
for i in range(5):
# 从 Tuner 中获得参数
tuner_param = nni.get_next_parameter()
# 使用参数
# ...
# 为上面获取的参数返回最终结果
# 返回最终结果
nni.report_final_result()
# ...
# ...
```
# ...
```
在多阶段 Experiment 中,每次 API `nni.get_next_parameter()` 被调用时,会返回 Tuner 新生成的超参,然后 Trial 代码会使用新的超参,并返回其最终结果。 `nni.get_next_parameter()``nni.report_final_result()` 需要依次被调用:**先调用前者,然后调用后者,并按此顺序重复调用**。 如果 `nni.get_next_parameter()` 被连续多次调用,然后再调用 `nni.report_final_result()`,这会造成最终结果只会与 get_next_parameter 所返回的最后一个配置相关联。 因此,前面的 get_next_parameter 调用都没有关联的结果,这可能会造成一些多阶段算法出问题。
注意,如果 `nni.get_next_parameter` 返回 None,表示 Tuner 没有生成更多的超参。
**2. Experiment 配置**
......@@ -39,35 +43,37 @@ Trial 代码中使用多阶段非常容易,样例如下:
多阶段 Experiment 配置示例:
authorName: default
experimentName: multiphase experiment
trialConcurrency: 2
maxExecDuration: 1h
maxTrialNum: 8
trainingServicePlatform: local
searchSpacePath: search_space.json
multiPhase: true
useAnnotation: false
tuner:
builtinTunerName: TPE
classArgs:
optimize_mode: maximize
trial:
command: python3 mytrial.py
codeDir: .
gpuNum: 0
```yaml
authorName: default
experimentName: multiphase experiment
trialConcurrency: 2
maxExecDuration: 1h
maxTrialNum: 8
trainingServicePlatform: local
searchSpacePath: search_space.json
multiPhase: true
useAnnotation: false
tuner:
builtinTunerName: TPE
classArgs:
optimize_mode: maximize
trial:
command: python3 mytrial.py
codeDir: .
gpuNum: 0
```
### 实现使用多阶段的 Tuner:
强烈建议首先阅读[自定义 Tuner](https://nni.readthedocs.io/zh/latest/Tuner/CustomizeTuner.html),再开始实现多阶段 Tuner。 与普通 Tuner 一样,需要从 `Tuner` 类继承。 当通过配置启用多阶段时(将 `multiPhase` 设为 true),Tuner 会通过下列方法得到一个新的参数 `trial_job_id`
generate_parameters
generate_multiple_parameters
receive_trial_result
receive_customized_trial_result
trial_end
```text
generate_parameters
generate_multiple_parameters
receive_trial_result
receive_customized_trial_result
trial_end
```
有了这个信息, Tuner 能够知道哪个 Trial 在请求配置信息, 返回的结果是哪个 Trial 的。 通过此信息,Tuner 能够灵活的为不同的 Trial 及其阶段实现功能。 例如,可在 generate_parameters 方法中使用 trial_job_id 来为特定的 Trial 任务生成超参。
......
# NNI 上的自动模型压缩
使用 NNI 的压缩和 Tuner 能轻松实现自动模型压缩
## 首先,使用 NNI 压缩模型
可使用 NNI 轻松压缩模型。 以剪枝为例,可通过 LevelPruner 对预训练模型剪枝:
```python
from nni.compression.torch import LevelPruner
config_list = [{ 'sparsity': 0.8, 'op_types': ['default'] }]
pruner = LevelPruner(config_list)
pruner(model)
```
op_type 为 'default' 表示模块类型定义在了 [default_layers.py](https://github.com/microsoft/nni/blob/master/src/sdk/pynni/nni/compression/torch/default_layers.py)
因此 `{ 'sparsity': 0.8, 'op_types': ['default'] }` 表示 **所有指定 op_types 的层都会被压缩到 0.8 的稀疏度**。 当调用 `pruner(model)` 时,模型会通过掩码进行压缩。随后还可以微调模型,此时**被剪除的权重不会被更新**
## 然后,进行自动化
前面的示例手工选择了 LevelPruner,并对所有层使用了相同的稀疏度,显然这不是最佳方法,因为不同层会有不同的冗余度。 每层的稀疏度都应该仔细调整,以便减少模型性能的下降,可通过 NNI Tuner 来完成。
首先需要设计搜索空间,这里使用了嵌套的搜索空间,其中包含了选择的剪枝函数以及需要优化稀疏度的层。
```json
{
"prune_method": {
"_type": "choice",
"_value": [
{
"_name": "agp",
"conv0_sparsity": {
"_type": "uniform",
"_value": [
0.1,
0.9
]
},
"conv1_sparsity": {
"_type": "uniform",
"_value": [
0.1,
0.9
]
},
},
{
"_name": "level",
"conv0_sparsity": {
"_type": "uniform",
"_value": [
0.1,
0.9
]
},
"conv1_sparsity": {
"_type": "uniform",
"_value": [
0.01,
0.9
]
},
}
]
}
}
```
然后需要修改几行代码。
```python
import nni
from nni.compression.torch import *
params = nni.get_parameters()
conv0_sparsity = params['prune_method']['conv0_sparsity']
conv1_sparsity = params['prune_method']['conv1_sparsity']
# 如果对总稀疏度有要求,这些原始稀疏度就需要调整。
config_list_level = [{ 'sparsity': conv0_sparsity, 'op_name': 'conv0' },
{ 'sparsity': conv1_sparsity, 'op_name': 'conv1' }]
config_list_agp = [{'initial_sparsity': 0, 'final_sparsity': conv0_sparsity,
'start_epoch': 0, 'end_epoch': 3,
'frequency': 1,'op_name': 'conv0' },
{'initial_sparsity': 0, 'final_sparsity': conv1_sparsity,
'start_epoch': 0, 'end_epoch': 3,
'frequency': 1,'op_name': 'conv1' },]
PRUNERS = {'level':LevelPruner(config_list_level)'agp':AGP_Pruner(config_list_agp)}
pruner = PRUNERS(params['prune_method']['_name'])
pruner(model)
... # fine tuning
acc = evaluate(model) # evaluation
nni.report_final_results(acc)
```
最后,定义任务,并使用任务来自动修剪层稀疏度。
```yaml
authorName: default
experimentName: Auto_Compression
trialConcurrency: 2
maxExecDuration: 100h
maxTrialNum: 500
# 可选项: local, remote, pai
trainingServicePlatform: local
# 可选项: true, false
useAnnotation: False
searchSpacePath: search_space.json
tuner:
# 可选项: TPE, Random, Anneal...
builtinTunerName: TPE
classArgs:
# 可选项: maximize, minimize
optimize_mode: maximize
trial:
command: bash run_prune.sh
codeDir: .
gpuNum: 1
```
# Compressor
我们很高兴的宣布,基于 NNI 的模型压缩工具发布了 Alpha 版本。该版本仍处于试验阶段,根据用户反馈会进行改进。 诚挚邀请您使用、反馈,或更多贡献。
NNI 提供了易于使用的工具包来帮助用户设计并使用压缩算法。 其使用了统一的接口来支持 TensorFlow 和 PyTorch。 只需要添加几行代码即可压缩模型。 NNI 中也内置了一些流程的模型压缩算法。 用户还可以通过 NNI 强大的自动调参功能来找到最好的压缩后的模型,详见[自动模型压缩](./AutoCompression.md)。 另外,用户还能使用 NNI 的接口,轻松定制新的压缩算法,详见[教程](#customize-new-compression-algorithms)
## 支持的算法
NNI 提供了两种朴素压缩算法以及三种流行的压缩算法,包括两种剪枝算法以及三种量化算法:
| 名称 | 算法简介 |
| --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Level Pruner](./Pruner.md#level-pruner) | 根据权重的绝对值,来按比例修剪权重。 |
| [AGP Pruner](./Pruner.md#agp-pruner) | 自动的逐步剪枝(是否剪枝的判断:基于对模型剪枝的效果)[参考论文](https://arxiv.org/abs/1710.01878) |
| [Naive Quantizer](./Quantizer.md#naive-quantizer) | 默认将权重量化为 8 位 |
| [QAT Quantizer](./Quantizer.md#qat-quantizer) | 为 Efficient Integer-Arithmetic-Only Inference 量化并训练神经网络。 [参考论文](http://openaccess.thecvf.com/content_cvpr_2018/papers/Jacob_Quantization_and_Training_CVPR_2018_paper.pdf) |
| [DoReFa Quantizer](./Quantizer.md#dorefa-quantizer) | DoReFa-Net: 通过低位宽的梯度算法来训练低位宽的卷积神经网络。 [参考论文](https://arxiv.org/abs/1606.06160) |
## 内置压缩算法的用法
通过简单的示例来展示如何修改 Trial 代码来使用压缩算法。 比如,需要通过 Level Pruner 来将权重剪枝 80%,首先在代码中训练模型前,添加以下内容([完整代码](https://github.com/microsoft/nni/tree/master/examples/model_compress))。
TensorFlow 代码
```python
from nni.compression.tensorflow import LevelPruner
config_list = [{ 'sparsity': 0.8, 'op_types': ['default'] }]
pruner = LevelPruner(config_list)
pruner(tf.get_default_graph())
```
PyTorch 代码
```python
from nni.compression.torch import LevelPruner
config_list = [{ 'sparsity': 0.8, 'op_types': ['default'] }]
pruner = LevelPruner(config_list)
pruner(model)
```
可使用 `nni.compression` 中的其它压缩算法。 此算法分别在 `nni.compression.torch``nni.compression.tensorflow` 中实现,支持 PyTorch 和 TensorFlow。 参考 [Pruner](./Pruner.md)[Quantizer](./Quantizer.md) 进一步了解支持的算法。
函数调用 `pruner(model)` 接收用户定义的模型(在 Tensorflow 中,通过 `tf.get_default_graph()` 来获得模型,而 PyTorch 中 model 是定义的模型类),并修改模型来插入 mask。 然后运行模型时,这些 mask 即会生效。 mask 可在运行时通过算法来调整。
实例化压缩算法时,会传入 `config_list`。 配置说明如下。
### 压缩算法中的用户配置
压缩模型时,用户可能希望指定稀疏率,为不同类型的操作指定不同的比例,排除某些类型的操作,或仅压缩某类操作。 配置规范可用于表达此类需求。 可将其视为一个 Python 的 `list` 对象,其中每个元素都是一个 `dict` 对象。 在每个 `dict` 中,有一些 NNI 压缩算法支持的键值:
* __op_types__:指定要压缩的操作类型。 'default' 表示使用算法的默认设置。
* __op_names__:指定需要压缩的操作的名称。 如果没有设置此字段,操作符不会通过名称筛选。
* __exclude__:默认为 False。 如果此字段为 True,表示要通过类型和名称,将一些操作从压缩中排除。
`dict` 还有一些其它键值,由特定的压缩算法所使用。 例如:
`list` 中的 `dict` 会依次被应用,也就是说,如果一个操作出现在两个配置里,后面的 `dict` 会覆盖前面的配置。
配置的简单示例如下:
```python
[
{
'sparsity': 0.8,
'op_types': ['default']
},
{
'sparsity': 0.6,
'op_names': ['op_name1', 'op_name2']
},
{
'exclude': True,
'op_names': ['op_name3']
}
]
```
其表示压缩操作的默认稀疏度为 0.8,但`op_name1``op_name2` 会使用 0.6,且不压缩 `op_name3`
### 其它 API
一些压缩算法使用 Epoch 来控制压缩进度(如[AGP](./Pruner.md#agp-pruner)),一些算法需要在每个批处理步骤后执行一些逻辑。 因此提供了另外两个 API。 一个是 `update_epoch`,可参考下例使用:
TensorFlow 代码
```python
pruner.update_epoch(epoch, sess)
```
PyTorch 代码
```python
pruner.update_epoch(epoch)
```
另一个是 `step`,可在每个批处理后调用 `pruner.step()`。 注意,并不是所有的算法都需要这两个 API,对于不需要它们的算法,调用它们不会有影响。
__[TODO]__ 最后一个 API 可供用户导出压缩后的模型。 当完成训练后使用此 API,可得到压缩后的模型。 同时也可导出另一个文件用来存储 mask 的数值。
## 定制新的压缩算法
为了简化压缩算法的编写,NNI 设计了简单且灵活的接口。 对于 Pruner 和 Quantizer 分别有相应的接口。
### 剪枝算法
要实现新的剪枝算法,根据使用的框架,添加继承于 `nni.compression.tensorflow.Pruner``nni.compression.torch.Pruner` 的类。 然后,根据算法逻辑来重写成员函数。
```python
# TensorFlow 中定制 Pruner。
# 如果要在 PyTorch 中定制 Pruner,可将
# nni.compression.tensorflow.Pruner 替换为
# nni.compression.torch.Pruner
class YourPruner(nni.compression.tensorflow.Pruner):
def __init__(self, config_list):
# 建议使用 NNI 定义的规范来进行配置
super().__init__(config_list)
def bind_model(self, model):
# 此函数可通过成员变量,来保存模型和其权重,
# 从而能在训练过程中获取这些信息。
pass
def calc_mask(self, weight, config, **kwargs):
# weight 是目标的权重张量
# config 是在 config_list 中为此层选定的 dict 对象
# kwargs 包括 op, op_types, 和 op_name
# 实现定制的 mask 并返回
return your_mask
# 注意, PyTorch 不需要 sess 参数
def update_epoch(self, epoch_num, sess):
pass
# 注意, PyTorch 不需要 sess 参数
def step(self, sess):
# 根据在 bind_model 函数中引用的模型或权重进行一些处理
pass
```
对于最简单的算法,只需要重写 `calc_mask` 函数。 它可接收每层的权重,并选择对应的配置和操作的信息。 可在此函数中为此权重生成 mask 并返回。 NNI 会应用此 mask。
一些算法根据训练进度来生成 mask,如 Epoch 数量。 Pruner 可使用 `update_epoch` 来了解训练进度。
一些算法可能需要全局的信息来生成 mask,例如模型的所有权重(用于生成统计信息),模型优化器的信息。 可使用 `bind_model` 来支持此类需求。 `bind_model` 接受完整模型作为参数,因而其记录了所有信息(例如,权重的引用)。 然后 `step` 可以根据算法来处理或更新信息。 可参考[内置算法的源码](https://github.com/microsoft/nni/tree/master/src/sdk/pynni/nni/compressors)作为示例。
### 量化算法
定制量化算法的接口与剪枝算法类似。 唯一的不同是使用 `quantize_weight` 替换了 `calc_mask``quantize_weight` 直接返回量化后的权重,而不是 mask。这是因为对于量化算法,量化后的权重不能通过应用 mask 来获得。
```python
# TensorFlow 中定制 Quantizer。
# 如果要在 PyTorch 中定制 Quantizer,可将
# nni.compression.tensorflow.Quantizer 替换为
# nni.compression.torch.Quantizer
class YourQuantizer(nni.compression.tensorflow.Quantizer):
def __init__(self, config_list):
# 建议使用 NNI 定义的规范来进行配置
super().__init__(config_list)
def bind_model(self, model):
# 此函数可通过成员变量,来保存模型和其权重,
# 从而能在训练过程中获取这些信息。
pass
def quantize_weight(self, weight, config, **kwargs):
# weight 是目标的权重张量
# config 是在 config_list 中为此层选定的 dict 对象
# kwargs 包括 op, op_types, 和 op_name
# 实现定制的 Quantizer 并返回新的权重
return new_weight
# 注意, PyTorch 不需要 sess 参数
def update_epoch(self, epoch_num, sess):
pass
# 注意, PyTorch 不需要 sess 参数
def step(self, sess):
# 根据在 bind_model 函数中引用的模型或权重进行一些处理
pass
```
__[TODO]__ 添加成员函数 `quantize_layer_output`,用于支持量化层输出的量化算法。
### 使用用户自定义的压缩算法
__[TODO]__ ...
NNI Compressor 中的 Pruner
===
## Level Pruner
这是个基本的 Pruner:可设置目标稀疏度(以分数表示,0.6 表示会剪除 60%)。
首先按照绝对值对指定层的权重排序。 然后按照所需的稀疏度,将值最小的权重屏蔽为 0。
### 用法
TensorFlow 代码
```
from nni.compression.tensorflow import LevelPruner
config_list = [{ 'sparsity': 0.8, 'op_types': ['default'] }]
pruner = LevelPruner(config_list)
pruner(model_graph)
```
PyTorch 代码
```
from nni.compression.torch import LevelPruner
config_list = [{ 'sparsity': 0.8, 'op_types': ['default'] }]
pruner = LevelPruner(config_list)
pruner(model)
```
#### Level Pruner 的用户配置
* **sparsity:**,指定压缩的稀疏度。
***
## AGP Pruner
[To prune, or not to prune: exploring the efficacy of pruning for model compression](https://arxiv.org/abs/1710.01878)中,作者 Michael Zhu 和 Suyog Gupta 提出了一种逐渐修建权重的算法。
> 我们引入了一种新的自动梯度剪枝算法。这种算法从初始的稀疏度值 si(一般为 0)开始,通过 n 步的剪枝操作,增加到最终所需的稀疏度 sf。从训练步骤 t0 开始,以 ∆t 为剪枝频率: ![](../../img/agp_pruner.png) 在神经网络训练时‘逐步增加网络稀疏度时,每训练 ∆t 步更新一次权重剪枝的二进制掩码。同时也允许训练步骤恢复因为剪枝而造成的精度损失。 根据我们的经验,∆t 设为 100 到 1000 个训练步骤之间时,对于模型最终精度的影响可忽略不计。 一旦模型达到了稀疏度目标 sf,权重掩码将不再更新。 公式背后的稀疏函数直觉。
### 用法
通过下列代码,可以在 10 个 Epoch 中将权重稀疏度从 0% 剪枝到 80%。
首先,导入 Pruner 来为模型添加遮盖。
TensorFlow 代码
```python
from nni.compression.tensorflow import AGP_Pruner
config_list = [{
'initial_sparsity': 0,
'final_sparsity': 0.8,
'start_epoch': 0,
'end_epoch': 10,
'frequency': 1,
'op_types': 'default'
}]
pruner = AGP_Pruner(config_list)
pruner(tf.get_default_graph())
```
PyTorch 代码
```python
from nni.compression.torch import AGP_Pruner
config_list = [{
'initial_sparsity': 0,
'final_sparsity': 0.8,
'start_epoch': 0,
'end_epoch': 10,
'frequency': 1,
'op_types': 'default'
}]
pruner = AGP_Pruner(config_list)
pruner(model)
```
其次,在训练代码中每完成一个 Epoch,更新一下 Epoch 数值。
TensorFlow 代码
```python
pruner.update_epoch(epoch, sess)
```
PyTorch 代码
```python
pruner.update_epoch(epoch)
```
查看示例进一步了解
#### AGP Pruner 的用户配置
* **initial_sparsity:** 指定了 Compressor 开始压缩的稀疏度。
* **final_sparsity:** 指定了 Compressor 压缩结束时的稀疏度。
* **start_epoch:** 指定了 Compressor 开始压缩时的 Epoch 数值,默认为 0。
* **end_epoch:** 指定了 Compressor 结束压缩时的 Epoch 数值。
* **frequency:** 指定了 Compressor 每过多少个 Epoch 进行一次剪枝,默认 frequency=1。
***
NNI Compressor 中的 Quantizer
===
## Naive Quantizer
Naive Quantizer 将 Quantizer 权重默认设置为 8 位,可用它来测试量化算法。
### 用法
Tensorflow
```python
nni.compressors.tensorflow.NaiveQuantizer()(model_graph)
```
PyTorch
```python
nni.compressors.torch.NaiveQuantizer()(model)
```
***
## QAT Quantizer
[Quantization and Training of Neural Networks for Efficient Integer-Arithmetic-Only Inference](http://openaccess.thecvf.com/content_cvpr_2018/papers/Jacob_Quantization_and_Training_CVPR_2018_paper.pdf) 中,作者 Benoit Jacob 和 Skirmantas Kligys 提出了一种算法在训练中量化模型。
> 我们提出了一种方法,在训练的前向过程中模拟量化效果。 此方法不影响反向传播,所有权重和偏差都使用了浮点数保存,因此能很容易的进行量化。 然后,前向传播通过实现浮点算法的舍入操作,来在推理引擎中模拟量化的推理。 * 权重在与输入卷积操作前进行量化。 如果在层中使用了批量归一化(参考 [17]),批量归一化参数会被在量化前被“折叠”到权重中。 * 激活操作在推理时会被量化,例如,在激活函数被应用到卷积或全连接层输出之后,或在增加旁路连接,或连接多个层的输出之后(如:ResNet)。 Activations are quantized at points where they would be during inference, e.g. after the activation function is applied to a convolutional or fully connected layer’s output, or after a bypass connection adds or concatenates the outputs of several layers together such as in ResNets.
### 用法
可在训练代码前将模型量化为 8 位。
TensorFlow 代码
```python
from nni.compressors.tensorflow import QAT_Quantizer
config_list = [{ 'q_bits': 8, 'op_types': ['default'] }]
quantizer = QAT_Quantizer(config_list)
quantizer(tf.get_default_graph())
```
PyTorch 代码
```python
from nni.compressors.torch import QAT_Quantizer
config_list = [{ 'q_bits': 8, 'op_types': ['default'] }]
quantizer = QAT_Quantizer(config_list)
quantizer(model)
```
查看示例进一步了解
#### QAT Quantizer 的用户配置
* **q_bits:** 指定需要被量化的位数。
***
## DoReFa Quantizer
[DoReFa-Net: Training Low Bitwidth Convolutional Neural Networks with Low Bitwidth Gradients](https://arxiv.org/abs/1606.06160) 中,作者 Shuchang Zhou 和 Yuxin Wu 提出了 DoReFa 算法在训练时量化权重,激活函数和梯度。
### 用法
要实现 DoReFa Quantizer,在训练代码前加入以下代码。
TensorFlow 代码
```python
from nni.compressors.tensorflow import DoReFaQuantizer
config_list = [{ 'q_bits': 8, 'op_types': 'default' }]
quantizer = DoReFaQuantizer(config_list)
quantizer(tf.get_default_graph())
```
PyTorch 代码
```python
from nni.compressors.torch import DoReFaQuantizer
config_list = [{ 'q_bits': 8, 'op_types': 'default' }]
quantizer = DoReFaQuantizer(config_list)
quantizer(model)
```
查看示例进一步了解
#### QAT Quantizer 的用户配置
* **q_bits:** 指定需要被量化的位数。
# 使用 NNI 调优 RocksDB
# NNI 调优 RocksDB
## 概述
[RocksDB](https://github.com/facebook/rocksdb)一种很受欢迎的高性能嵌入式键值数据库,被许多公司,如 Facebook, Yahoo! 和 LinkedIn 等,广泛应用于各种网络规模的产品中。它是 Facebook [LevelDB](https://github.com/google/leveldb) 的基础上,通过充分利用多核心中央处理器和快速存储(如固态硬盘)的特点,针对IO密集型应用优化而成的
[RocksDB](https://github.com/facebook/rocksdb)流行的高性能嵌入式的生产级别的键值数据库,它在 Facebook,Yahoo!和 LinkedIn 等各种规模的网站上使用。 这是 Facebook [LevelDB](https://github.com/google/leveldb) 分支,为多 CPU,快速存储(如 SSD)的输入输出进行了优化
RocksDB 的性能高度依赖于运行参数的调优。然而,由于其底层技术极为复杂,需要调整的参数过多,有时很难找到合适的运行参数。NNI 可帮助数据库运维工程师解决这个问题。NNI 支持多种自动调参算法,并支持运行于本地、远程和云端的各种负载
RocksDB 的性能表现非常依赖于调优操作。 但由于其底层技术复杂,可配置参数非常多,很难获得较好的配置。 NNI 可帮助解决此问题。 NNI 支持多种调优算法来为 RocksDB 搜索最好的配置,并支持本机、远程服务器和云服务等多种环境
本例展示了如何使用 NNI 搜索 RocksDB 在 `fillrandom` 基准测试中的最佳运行参数,`fillrandom` 基准测试是 RocksDB 官方提供的基准测试工具 `db_bench` 所支持的一种基准测试,因此在运行本例之前请确保您已经安装了 NNI,并且 `db_bench` 在您的 `PATH` 路径中。关于如何安装和准备 NNI 环境,请参考[这里](../Tuner/BuiltinTuner.md),关于如何编译 RocksDB 以及 `db_bench`,请参考[这里](https://github.com/facebook/rocksdb/blob/master/INSTALL.md)
例展示了如何使用 NNI,通过评测工具 `db_bench` 来找到 `fillrandom` 基准的最佳配置,此工具是 RocksDB 官方提供的评测工具。 在运行示例前,需要检查 NNI 已安装,
我们还提供了一个简单的脚本 [`db_bench_installation.sh`](../../../examples/trials/systems/rocksdb-fillrandom/db_bench_installation.sh),用来在 Ubuntu 系统上编译和安装 `db_bench` 和相关依赖。在其他系统中的安装也可以参考该脚本实现。
db_bench</code> 已经加入到了 `PATH` 中。 参考[这里](../Tutorial/QuickStart.md),了解如何安装并准备 NNI 环境,参考[这里](https://github.com/facebook/rocksdb/blob/master/INSTALL.md)来编译 RocksDB 以及 `db_bench`</p>
*代码目录: [`example/trials/systems/rocksdb-fillrandom`](../../../examples/trials/systems/rocksdb-fillrandom)*
此简单脚本 [`db_bench_installation.sh`](../../../examples/trials/systems/rocksdb-fillrandom/db_bench_installation.sh) 可帮助编译并在 Ubuntu 上安装 `db_bench` 及其依赖包。 可遵循相同的过程在其它系统中安装 RocksDB。
*代码目录:[`example/trials/systems/rocksdb-fillrandom`](../../../examples/trials/systems/rocksdb-fillrandom)*
## Experiment 设置
在 NNI 上配置调优的 Experiment 主要有三个步骤。 使用 `json` 文件定义搜索空间,编写评测代码,将配置传入 NNI 管理器来启动 Experiment。
## 实验配置
使用 NNI 进行调优系统主要有三个步骤,分别是,使用一个 `json` 文件定义搜索空间;准备一个基准测试程序;和一个用来启动 NNI 实验的配置文件。
### 搜索空间
简便起见,本例基于 Rocks_DB 每秒的写入操作数(Operations Per Second, OPS),在随机写入 16M 个键长为 20 字节值长为 100 字节的键值对的情况下,对三个系统运行参数,`write_buffer_size``min_write_buffer_num``level0_file_num_compaction_trigger`,进行了调优。`write_buffer_size` 控制了单个 memtable 的大小。在写入过程中,当 memtable 的大小超过了 `write_buffer_size` 指定的数值,该 memtable 将会被标记为不可变,并创建一个新的 memtable。`min_write_buffer_num` 是在写入(flush)磁盘之前需要合并(merge)的 memtable 的最小数量。一旦 level 0 中的文件数量超过了 `level0_file_num_compaction_trigger` 所指定的数,level 0 向 level 1 的压缩(compaction)将会被触发。
为简单起见,此示例仅调优三个参数,`write_buffer_size`, `min_write_buffer_num` 以及 `level0_file_num_compaction_trigger`,场景为测试随机写入 16M 数据的每秒写操作数(OPS),其 Key 为 20 字节,值为 100 字节。 `write_buffer_size` 设置单个内存表的大小。 一旦内存表超过此大小,会被标记为不可变,并创建新内存表。 `min_write_buffer_num` 是要合并写入存储的最小内存表数量。 一旦 Level 0 的文件数量达到了 `level0_file_num_compaction_trigger`,就会触发 Level 0 到 Level 1 的压缩。
此示例中,下列 `search_space.json` 文件指定了搜索空间。 搜索空间的详细说明参考[这里](../Tutorial/SearchSpaceSpec.md)
搜索空间由如下所示的文件 `search_space.json` 指定。更多关于搜索空间的解释请参考[这里](../Tutorial/SearchSpaceSpec.md)
```json
{
......@@ -39,59 +47,69 @@ RocksDB 的性能高度依赖于运行参数的调优。然而,由于其底层
}
```
*代码目录: [`example/trials/systems/rocksdb-fillrandom/search_space.json`](../../../examples/trials/systems/rocksdb-fillrandom/search_space.json)*
### 基准测试
*代码目录:[`example/trials/systems/rocksdb-fillrandom/search_space.json`](../../../examples/trials/systems/rocksdb-fillrandom/search_space.json)*
基准测试程序需要从 NNI manager 接收一个运行参数,并在运行基准测试以后向 NNI manager 汇报基准测试结果。NNI 提供了下面两个 APIs 来完成这些任务。更多关于 NNI trials 的信息请参考[这里](Trials.md)
### 评测代码
评测代码从 NNI 管理器接收配置,并返回相应的基准测试结果。 下列 NNI API 用于相应的操作。 此示例中,每秒写操作数(OPS)作为了性能指标。 参考[这里](Trials.md),了解详情。
* 使用 `nni.get_next_parameter()` 来获取下一个系统配置。
* 使用 `nni.report_final_result(metric)` 来返回测试结果。
*代码目录:[`example/trials/systems/rocksdb-fillrandom/main.py`](../../../examples/trials/systems/rocksdb-fillrandom/main.py)*
* 使用 `nni.get_next_parameter()` 从 NNI manager 得到需要测试的系统运行参数。
* 使用 `nni.report_final_result(metric)` 向 NNI manager 汇报基准测试的结果。
*代码目录: [`example/trials/systems/rocksdb-fillrandom/main.py`](../../../examples/trials/systems/rocksdb-fillrandom/main.py)*
### 配置文件
NNI 实验可以通过配置文件来启动。通常而言,NNI 配置文件是一个 `yaml` 文件,通常包含实验设置(`trialConcurrency``maxExecDuration``maxTrialNum``trial gpuNum`),运行平台设置`trainingServicePlatform`),路径设置`searchSpacePath``trial codeDir`)和 调参器设置(`tuner``tuner optimize_mode`)。更多关于 NNI 配置文件的信息请参考[这里](../Tutorial/QuickStart.md)
用于启动 NNI Experiment 的配置文件。 NNI 配置文件是 `YAML` 格式,通常包括了 Experiment 设置 (`trialConcurrency`, `maxExecDuration`, `maxTrialNum`, `trial gpuNum`,),平台设置 (`trainingServicePlatform`,), 路径设置 (`searchSpacePath`, `trial codeDir`,) 以及 Tuner 设置 (`tuner`, `tuner optimize_mode`,)。 参考[这里](../Tutorial/QuickStart.md)了解详情
下面是使用 SMAC 算法调优 RocksDB 配置文件的例子
是使用 SMAC 算法调优 RocksDB 的示例
*代码目录: [`example/trials/systems/rocksdb-fillrandom/config_smac.yml`](../../../examples/trials/systems/rocksdb-fillrandom/config_smac.yml)*
*代码目录[`example/trials/systems/rocksdb-fillrandom/config_smac.yml`](../../../examples/trials/systems/rocksdb-fillrandom/config_smac.yml)*
下面是使用 TPE 算法调优 RocksDB 配置文件的例子
是使用 TPE 算法调优 RocksDB 的示例
*代码目录: [`example/trials/systems/rocksdb-fillrandom/config_tpe.yml`](../../../examples/trials/systems/rocksdb-fillrandom/config_tpe.yml)*
其他的调参器可以使用同样的方式应用,更多关于调参器的信息请参考[这里](../Tuner/BuiltinTuner.md)
其它 Tuner 算法可以通过相同的方式来使用。 参考[这里](../Tuner/BuiltinTuner.md)了解详情。
最后,进入示例目录,并通过下列命令启动 Experiment:
最后,我们可以进入本例的文件夹内,用下面的命令启动实验:
```bash
# tuning RocksDB with SMAC tuner
# 使用 SMAC Tuner 调优 RocksDB
nnictl create --config ./config_smac.yml
# tuning RocksDB with TPE tuner
# 使用 TPE Tuner 调优 RocksDB
nnictl create --config ./config_tpe.yml
```
## 实验结果
我们在同一台机器上运行了这两个实验,相关信息如下:
## Experiment 结果
在同一台计算机上运行这两个示例的详细信息:
* 16 * Intel(R) Xeon(R) CPU E5-2650 v2 @ 2.60GHz
* 465 GB of rotational hard drive with ext4 file system
* 128 GB of RAM
* Kernel version: 4.15.0-58-generic
* NNI version: v1.0-37-g1bd24577
* RocksDB version: 6.4
* 465 GB 磁盘,安装 ext4 操作系统
* 128 GB 内存
* 内核版本: 4.15.0-58-generic
* NNI 版本: v1.0-37-g1bd24577
* RocksDB 版本: 6.4
* RocksDB DEBUG_LEVEL: 0
具体的实验结果如下图所示。横轴是基准测试的顺序,纵轴是基准测试得到的结果,在本例中是每秒钟写操作的次数。蓝色的圆点代表用 SMAC 调优 RocksDB 得到的基准测试结果,而橘黄色的圆点表示用 TPE 调优得到的基准测试结果。
详细的实验结果如下图所示。 水平轴是 Trial 的顺序。 垂直轴是指标,此例中为写入的 OPS。 蓝点表示使用的是 SMAC Tuner,橙色表示使用的是 TPE Tuner。
![image](../../../examples/trials/systems/rocksdb-fillrandom/plot.png)
面的表格列出了使用两种调参器得到的最好的基准测试结果及相应的参数。毫不意外,使用这两种调参器在 `fillrandom` 基准测试中搜索得到了相同的最优参数
表列出了两个 Tuner 获得的最佳 Trial 以及相应的参数和指标。 不出所料,两个 Tuner 都为 `fillrandom` 测试找到了一样的最佳配置
| Tuner | Best trial | Best OPS | write_buffer_size | min_write_buffer_number_to_merge | level0_file_num_compaction_trigger |
| :---: | :--------: | :------: | :---------------: | :------------------------------: | :--------------------------------: |
| SMAC | 255 | 779289 | 2097152 | 7.0 | 7.0 |
| TPE | 169 | 761456 | 2097152 | 7.0 | 7.0 |
| Tuner | 最佳 Trial | 最佳 OPS | write_buffer_size | min_write_buffer_number_to_merge | level0_file_num_compaction_trigger |
|:-----:|:--------:|:------:|:-------------------:|:------------------------------------:|:--------------------------------------:|
| SMAC | 255 | 779289 | 2097152 | 7.0 | 7.0 |
| TPE | 169 | 761456 | 2097152 | 7.0 | 7.0 |
......@@ -169,4 +169,4 @@ echo $? `date +%s%3N` >/home/user_name/nni/experiments/$experiment_id$/trials/$t
* [如何在 NNI 调优 SciKit-learn 的参数](SklearnExamples.md)
* [在阅读理解上使用自动模型架构搜索。](SquadEvolutionExamples.md)
* [如何在 NNI 上调优 GBDT](GbdtExample.md)
* [如何在 NNI 上调优 RocksDB](RocksdbExamples.md)
\ No newline at end of file
* [在 NNI 上调优 RocksDB](RocksdbExamples.md)
\ No newline at end of file
......@@ -20,6 +20,7 @@ NNI 提供了先进的调优算法,使用上也很简单。 下面是内置 Tu
| [**Metis Tuner**](#MetisTuner) | 大多数调参工具仅仅预测最优配置,而 Metis 的优势在于有两个输出:(a) 最优配置的当前预测结果, 以及 (b) 下一次 Trial 的建议。 它不进行随机取样。 大多数工具假设训练集没有噪声数据,但 Metis 会知道是否需要对某个超参重新采样。 [参考论文](https://www.microsoft.com/en-us/research/publication/metis-robustly-tuning-tail-latencies-cloud-systems/) |
| [**BOHB**](#BOHB) | BOHB 是 Hyperband 算法的后续工作。 Hyperband 在生成新的配置时,没有利用已有的 Trial 结果,而本算法利用了 Trial 结果。 BOHB 中,HB 表示 Hyperband,BO 表示贝叶斯优化(Byesian Optimization)。 BOHB 会建立多个 TPE 模型,从而利用已完成的 Trial 生成新的配置。 [参考论文](https://arxiv.org/abs/1807.01774) |
| [**GP Tuner**](#GPTuner) | Gaussian Process(高斯过程) Tuner 是序列化的基于模型优化(SMBO)的方法,并使用了高斯过程来替代。 [参考论文](https://papers.nips.cc/paper/4443-algorithms-for-hyper-parameter-optimization.pdf)[Github 库](https://github.com/fmfn/BayesianOptimization) |
| [**PPO Tuner**](#PPOTuner) | PPO Tuner 是基于 PPO 算法的强化学习 Tuner。 [参考论文](https://arxiv.org/abs/1707.06347) |
## 用法
......@@ -305,7 +306,7 @@ tuner:
> 名称:**MetisTuner**
注意,搜索空间仅支持 `choice`, `quniform`, `uniform``randint`
此 Tuner 搜索空间仅接受 `quniform``uniform``randint` 和数值的 `choice` 类型。 因为数值会被用来评估点之间的距离,所以只支持数值
**建议场景**
......@@ -343,7 +344,7 @@ nnictl package install --name=BOHB
**建议场景**
与 Hyperband 类似,当计算资源有限但搜索空间相对较大时,建议使用此方法。 中间结果能够很好的反映最终结果的情况下,此算法会非常有效。 在这种情况下, 由于贝叶斯优化使用, 它可能会收敛到更好的配置。 [详细说明](./BohbAdvisor.md)
与 Hyperband 类似,当计算资源有限但搜索空间相对较大时,建议使用此方法。 中间结果能够很好的反映最终结果的情况下,此算法会非常有效。 在这种情况下,使用贝叶斯优化可能会收敛到更好的配置。 [详细说明](./BohbAdvisor.md)
**参数**
......@@ -378,7 +379,7 @@ advisor:
> 名称:**GPTuner**
注意,搜索空间接受的类型包括 `choice`, `randint`, `uniform`, `quniform`, `loguniform`, `qloguniform`
注意,搜索空间接受的类型包括 `randint`, `uniform`, `quniform`, `loguniform`, `qloguniform`,以及数值的 `choice`。 因为数值会被用来评估点之间的距离,所以只支持数值
**建议场景**
......@@ -412,4 +413,40 @@ tuner:
cold_start_num: 10
selection_num_warm_up: 100000
selection_num_starting_points: 250
```
<a name="PPOTuner"></a>
![](https://placehold.it/15/1589F0/000000?text=+) `PPO Tuner`
> 内置 Tuner 名称:**PPOTuner**
搜索空间类型仅支持 `mutable_layer``optional_input_size` 只能是 0, 1, 或 [0, 1]。
**建议场景**
PPO Tuner 是基于 PPO 算法的强化学习 Tuner。 当在 Trial 代码中使用 NNI 的 NAS 接口进行神经网络架构搜索时,推荐使用 PPO Tuner。 一般来说,尽管PPO算法比其它强化学习算法效率更高,但强化学习算法需要更多的计算资源。 因此,建议在有大量计算资源时,再使用此 Tuner。 可以在简单的任务上尝试,如 [mnist-nas](https://github.com/microsoft/nni/tree/master/examples/trials/mnist-nas) 示例。 [查看详细信息](./PPOTuner.md)
**参数**
* **optimize_mode** (*'maximize' 或 'minimize'*) - 如果为 'maximize',表示 Tuner 的目标是将指标最大化。 如果为 'minimize',表示 Tuner 的目标是将指标最小化。
* **trials_per_update** (*int, 可选, 默认为 20*) - 每次更新的 Trial 数量。 此数字必须可被 minibatch_size 整除。 推荐将 `trials_per_update` 设为 `trialConcurrency` 的倍数,以提高 Trial 的并发效率。
* **epochs_per_update** (*int, 可选, 默认为 4*) - 每次更新的 Epoch 数量。
* **minibatch_size** (*int, 可选, 默认为 4*) - mini-batch 大小 (即每个 mini-batch 的 Trial 数量)。 注意,trials_per_update 必须可被 minibatch_size 整除。
* **ent_coef** (*float, 可选, 默认为 0.0*) - 优化目标中的 Policy entropy coefficient。
* **lr** (*float, 可选, 默认为 3e-4*) - 模型的学习率(LSTM 网络),为常数。
* **vf_coef** (*float, 可选, 默认为 0.5*) - Value function loss coefficient in the optimization objective.
* **max_grad_norm** (*float, 可选, 默认为 0.5*) - Gradient norm clipping coefficient.
* **gamma** (*float, 可选, 默认为 0.99*) - Discounting factor.
* **lam** (*float, 可选, 默认为 0.95*) - Advantage estimation discounting factor (论文中的 lambda).
* **cliprange** (*float, 可选, 默认为 0.2*) - PPO 算法的 cliprange, 为常数。
**示例**
```yaml
# config.yml
tuner:
builtinTunerName: PPOTuner
classArgs:
optimize_mode: maximize
```
\ No newline at end of file
# **指南** - 自定义 Advisor
*Advisor 用于同时需要 Tuner 和 Assessor 方法的自动机器学习算法。 Advisor 与 Tuner 类似,它接收 Trial 的参数请求、最终结果,并生成 Trial 的参数。 另外,它也能像 Assessor 一样接收中间结果、Trial 的最终状态,并可以发送终止 Trial 的命令。 注意,在使用 Advisor 时,不能同时使用 Tuner 和 Assessor。*
*警告:API 可能会在将来的版本中更改。*
如果要自定义 Advisor,需要:
1. 从 MsgDispatcherBase 类继承并创建新的 Advisor 类
2. 实现所有除了 `handle_request` 外的,以 `handle_` 前缀开始的方法
3. 在 Experiment 的 YAML 文件中配置好自定义的 Advisor
Advisor 用于同时需要 Tuner 和 Assessor 方法的自动机器学习算法。 Advisor 与 Tuner 类似,它接收 Trial 的参数请求、最终结果,并生成 Trial 的参数。 另外,它也能像 Assessor 一样接收中间结果、Trial 的最终状态,并可以发送终止 Trial 的命令。 注意,在使用 Advisor 时,不能同时使用 Tuner 和 Assessor。
样例如下
如果要自定义 Advisor,需要
**1) 从 MsgDispatcherBase 类继承并创建新的 Advisor 类**
**1. 定义从 MsgDispatcherBase 类继承的 Advisor。** 如:
```python
from nni.msg_dispatcher_base import MsgDispatcherBase
......@@ -20,13 +16,11 @@ class CustomizedAdvisor(MsgDispatcherBase):
...
```
**2) 实现所有除了 `handle_request` 外的,以 `handle_` 前缀开始的方法**
参考 Hyperband 的实现 ([src/sdk/pynni/nni/hyperband_advisor/hyperband_advisor.py](https://github.com/Microsoft/nni/tree/master/src/sdk/pynni/nni/hyperband_advisor/hyperband_advisor.py)) 来学习如何实现这些方法。
**2. 实现所有除了 `handle_request` 外的,以 `handle_` 前缀开始的方法**[此文档](https://nni.readthedocs.io/en/latest/sdk_reference.html#nni.msg_dispatcher_base.MsgDispatcherBase)可帮助理解 `MsgDispatcherBase`
**3) 在 Experiment 的 YAML 文件中配置好自定义的 Advisor**
**3. 在 Experiment 的 YAML 文件中配置好自定义的 Advisor**
与 Tuner 和 Assessor 类似。 NNI 需要定位到自定义的 Advisor 类,并实例化它,因此需要指定自定义 Advisor 类的文件位置,并将参数值传给 \_\_init__ 构造函数。
与 Tuner 和 Assessor 类似。 NNI 需要定位到自定义的 Advisor 类,并实例化它,因此需要指定自定义 Advisor 类的文件位置,并将参数值传给 `__init__` 构造函数。
```yaml
advisor:
......@@ -37,4 +31,8 @@ advisor:
# 都需要声明在 classArgs 字段中,如:
classArgs:
arg1: value1
```
\ No newline at end of file
```
## 示例
[参考示例](../../../examples/tuners/mnist_keras_customized_advisor)
\ No newline at end of file
......@@ -6,4 +6,6 @@
GP Tuner 被设计为通过最大化或最小化步数来找到最接近最优结果的参数组合。 GP Tuner 使用了代理优化问题(找到采集函数的最大值)。虽然这仍然是个难题,但成本更低(从计算的角度来看),并且有通用的工具。 因此,贝叶斯优化适合于采样函数的成本非常高时来使用。
注意,搜索空间接受的类型包括 `randint`, `uniform`, `quniform`, `loguniform`, `qloguniform`,以及数值的 `choice`
优化方法在 [Algorithms for Hyper-Parameter Optimization](https://papers.nips.cc/paper/4443-algorithms-for-hyper-parameter-optimization.pdf) 的第三章有详细描述。
\ No newline at end of file
......@@ -14,6 +14,6 @@ Metis 属于基于序列的贝叶斯优化 (SMBO) 的类别,它也基于贝叶
它会标识出下一个超参的候选项。 这是通过对隐含信息的探索、挖掘和重采样来实现的。
注意,搜索空间仅支持 `choice`, `quniform`, `uniform``randint`
此 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
# NNI 中的 PPO Tuner
## PPOTuner
这是通常用于 NAS 接口的 NNI Tuner,使用了 [PPO 算法](https://arxiv.org/abs/1707.06347)。 此实现继承了[这里](https://github.com/openai/baselines/tree/master/baselines/ppo2)的主要逻辑,(即 OpenAI 的 PPO2),并为 NAS 场景做了适配。
它能成功调优 [mnist-nas 示例](https://github.com/microsoft/nni/tree/master/examples/trials/mnist-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
......@@ -2,12 +2,10 @@
创建 Experiment 所需要的配置文件。 配置文件的路径会传入 `nnictl` 命令。 配置文件的格式为 YAML。 本文介绍了配置文件的内容,并提供了一些示例和模板。
- [Experiment(实验)配置参考](#Experiment-config-reference)
- [模板](#Template)
- [说明](#Configuration-spec)
- [样例](#Examples)
<a name="Template"></a>
- [Experiment(实验)配置参考](#experiment-config-reference)
- [模板](#template)
- [说明](#configuration-spec)
- [样例](#examples)
## 模板
......@@ -19,27 +17,27 @@ experimentName:
trialConcurrency:
maxExecDuration:
maxTrialNum:
#可选项: local, remote, pai, kubeflow
# 可选项: local, remote, pai, kubeflow
trainingServicePlatform:
searchSpacePath:
#可选项: true, false, 默认值: false
# 可选项: true, false, 默认值: false
useAnnotation:
#可选项: true, false, 默认值: false
# 可选项: true, false, 默认值: false
multiPhase:
#可选项: true, false, 默认值: false
# 可选项: true, false, 默认值: false
multiThread:
tuner:
#可选项: TPE, Random, Anneal, Evolution
# 可选项: TPE, Random, Anneal, Evolution
builtinTunerName:
classArgs:
#可选项: maximize, minimize
# 可选项: maximize, minimize
optimize_mode:
gpuNum:
gpuIndices:
trial:
command:
codeDir:
gpuNum:
#在本地使用时,machineList 可为空
# 在本机模式下,machineList 可为空
machineList:
- ip:
port:
......@@ -70,18 +68,18 @@ tuner:
classArgs:
#可选项: maximize, minimize
optimize_mode:
gpuNum:
gpuIndices:
assessor:
#可选项: Medianstop
builtinAssessorName:
classArgs:
#可选项: maximize, minimize
optimize_mode:
gpuNum:
gpuIndices:
trial:
command:
codeDir:
gpuNum:
gpuIndices:
#在本地使用时,machineList 可为空
machineList:
- ip:
......@@ -112,18 +110,18 @@ tuner:
classArgs:
#可选项: maximize, minimize
optimize_mode:
gpuNum:
gpuIndices:
assessor:
#可选项: Medianstop
builtinAssessorName:
classArgs:
#可选项: maximize, minimize
optimize_mode:
gpuNum:
gpuIndices:
trial:
command:
codeDir:
gpuNum:
gpuIndices:
#在本地使用时,machineList 可为空
machineList:
- ip:
......@@ -132,8 +130,6 @@ machineList:
passwd:
```
<a name="Configuration"></a>
## 说明
- **authorName**
......@@ -264,11 +260,11 @@ machineList:
- **builtinTunerName**
**builtinTunerName** 指定系统 Tuner 的名,NNI SDK 提供了多 Tuner,如:{**TPE**, **Random**, **Anneal**, **Evolution**, **BatchTuner**, **GridSearch**}
**builtinTunerName** 指定系统 Tuner 的名,NNI SDK 提供了多个内置 Tuner,详情参考[这里](../Tuner/BuiltinTuner.md)
- **classArgs**
**classArgs** 指定了 Tuner 算法的参数。 如果 **builtinTunerName** 是{**TPE**, **Random**, **Anneal**, **Evolution**},用户需要设置 **optimize_mode**
**classArgs** 指定了 Tuner 算法的参数。 参考[此文件](../Tuner/BuiltinTuner.md)来了解内置 Tuner 的配置参数
- **codeDir**, **classFileName**, **className****classArgs**
......@@ -288,17 +284,17 @@ machineList:
**classArgs** 指定了 Tuner 算法的参数。
- **gpuNum**
- **gpuIndices**
__gpuNum__ 指定了运行 Tuner 进程的 GPU 数量。 此字段的值必须是正整数。 如果此字段没有设置,NNI不会在脚本中添加 `CUDA_VISIBLE_DEVICES` (也就是说,不会通过 `CUDA_VISIBLE_DEVICES` 来控制 GPU 在 Trial 中是否可见),也不会管理 GPU 资源。
注意: 只能使用一种方法来指定 Tuner,例如:设置 {tunerName, optimizationMode} 或 {tunerCommand, tunerCwd},不能同时设置两者。
__gpuIndices__ 指定了 Tuner 进程可使用的 GPU。 可以指定单个或多个 GPU 索引,多个索引间使用逗号(,)隔开,例如:`1``0,1,3`。 如果没设置此字段,脚本中的 `CUDA_VISIBLE_DEVICES` 会为空 '',即 Tuner 中找不到 GPU。
- **includeIntermediateResults**
如果 __includeIntermediateResults__ 为 true,最后一个 Assessor 的中间结果会被发送给 Tuner 作为最终结果。 __includeIntermediateResults__ 的默认值为 false。
注意:用户只能用一种方法来指定 Tuner,指定 `builtinTunerName``classArgs`,或指定 `codeDir``classFileName``className` 以及 `classArgs`
- **Assessor**
......@@ -310,7 +306,7 @@ machineList:
- **builtinAssessorName**
**builtinAssessorName** 指定了系统 Assessor 的名称, NNI 内置的 Assessor 有 {**Medianstop**,等等}
**builtinAssessorName** 指定了内置 Assessor 的名称,NNI SDK 提供了多个内置的 Assessor,详情参考[这里](../Assessor/BuiltinAssessor.md)
- **classArgs**
......@@ -334,11 +330,48 @@ machineList:
**classArgs** 指定了 Assessor 算法的参数。
- **gpuNum**
注意:用户只能用一种方法来指定 Assessor,指定 `builtinAssessorName``classArgs`,或指定 `codeDir``classFileName``className` 以及 `classArgs`。 如果不需要使用 Assessor,此字段可为空。
- **Advisor**
- 说明
**Advisor** 指定了 Experiment 的 Advisor 算法。有两种方法可设置 Advisor。 一种方法是使用 SDK 提供的 Advisor ,需要设置 **builtinAdvisorName****classArgs**。 另一种方法,是使用用户自定义的 Advisor,需要设置 **codeDirectory****classFileName****className****classArgs**
- **builtinAdvisorName****classArgs**
- **builtinAdvisorName**
**builtinAdvisorName** 指定了内置 Advisor 的名称,NNI SDK 提供了多个[内置的 Advisor](../Tuner/BuiltinTuner.md)
- **classArgs**
**classArgs** 指定了 Advisor 算法的参数。 参考[此文件](../Tuner/BuiltinTuner.md)来了解内置 Advisor 的配置参数。
- **codeDir**, **classFileName**, **className****classArgs**
- **codeDir**
**codeDir** 指定 Advisor 代码的目录。
- **classFileName**
**classFileName** 指定 Advisor 文件名。
**gpuNum** 指定了运行 Assessor 进程的 GPU 数量。 此字段的值必须是正整数。
- **className**
**className** 指定 Advisor 类名。
注意: 只能使用一种方法来指定 Assessor,例如:设置 {assessorName, optimizationMode} 或 {assessorCommand, assessorCwd},不能同时设置。如果不需要使用 Assessor,可将其置为空。
- **classArgs**
**classArgs** 指定了 Advisor 算法的参数。
- **gpuIndices**
__gpuIndices__ 指定了 Advisor 进程可使用的 GPU。 可以指定单个或多个 GPU 索引,多个索引间使用逗号(,)隔开,例如:`1``0,1,3`。 如果没设置此字段,脚本中的 `CUDA_VISIBLE_DEVICES` 会为空 '',即 Tuner 中找不到 GPU。
注意:用户只能用一种方法来指定 Advisor ,指定 `builtinAdvisorName``classArgs`,或指定 `codeDir``classFileName``className` 以及 `classArgs`
- **trial (local, remote)**
......@@ -568,8 +601,6 @@ machineList:
**host** 是 OpenPAI 的主机地址。
<a name="Examples"></a>
## 样例
- **本机模式**
......@@ -592,7 +623,6 @@ machineList:
classArgs:
#可选项: maximize, minimize
optimize_mode: maximize
gpuNum: 0
trial:
command: python3 mnist.py
codeDir: /nni/mnist
......@@ -618,14 +648,12 @@ machineList:
classArgs:
#可选项: maximize, minimize
optimize_mode: maximize
gpuNum: 0
assessor:
#可选项: Medianstop
builtinAssessorName: Medianstop
classArgs:
#可选项: maximize, minimize
optimize_mode: maximize
gpuNum: 0
trial:
command: python3 mnist.py
codeDir: /nni/mnist
......@@ -652,7 +680,6 @@ machineList:
classArgs:
#可选项: maximize, minimize
optimize_mode: maximize
gpuNum: 0
assessor:
codeDir: /nni/assessor
classFileName: myassessor.py
......@@ -660,7 +687,6 @@ machineList:
classArgs:
#choice: maximize, minimize
optimize_mode: maximize
gpuNum: 0
trial:
command: python3 mnist.py
codeDir: /nni/mnist
......@@ -688,7 +714,6 @@ machineList:
classArgs:
#可选项: maximize, minimize
optimize_mode: maximize
gpuNum: 0
trial:
command: python3 mnist.py
codeDir: /nni/mnist
......@@ -762,16 +787,16 @@ machineList:
trialConcurrency: 1
maxExecDuration: 1h
maxTrialNum: 1
#可选项: local, remote, pai, kubeflow
# 可选项: local, remote, pai, kubeflow
trainingServicePlatform: kubeflow
searchSpacePath: search_space.json
#可选项: true, false
# 可选项: true, false
useAnnotation: false
tuner:
#可选项: TPE, Random, Anneal, Evolution
# 可选项: TPE, Random, Anneal, Evolution
builtinTunerName: TPE
classArgs:
#可选项: maximize, minimize
# 可选项: maximize, minimize
optimize_mode: maximize
trial:
codeDir: .
......@@ -797,23 +822,22 @@ machineList:
trialConcurrency: 1
maxExecDuration: 1h
maxTrialNum: 1
#可选项: local, remote, pai, kubeflow
# 可选项: local, remote, pai, kubeflow
trainingServicePlatform: kubeflow
searchSpacePath: search_space.json
#可选项: true, false
# 可选项: true, false
useAnnotation: false
#nniManagerIp: 10.10.10.10
tuner:
#可选项: TPE, Random, Anneal, Evolution
# 可选项: TPE, Random, Anneal, Evolution
builtinTunerName: TPE
classArgs:
#可选项: maximize, minimize
# 可选项: maximize, minimize
optimize_mode: maximize
assessor:
builtinAssessorName: Medianstop
classArgs:
optimize_mode: maximize
gpuNum: 0
trial:
codeDir: .
worker:
......
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