Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
OpenDAS
nni
Commits
8c203f30
Unverified
Commit
8c203f30
authored
Oct 31, 2019
by
SparkSnail
Committed by
GitHub
Oct 31, 2019
Browse files
Merge pull request #211 from microsoft/master
merge master
parents
7c1ab114
483232c8
Changes
87
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
311 additions
and
179 deletions
+311
-179
docs/zh_CN/Tuner/MetisTuner.md
docs/zh_CN/Tuner/MetisTuner.md
+1
-1
docs/zh_CN/Tuner/PPOTuner.md
docs/zh_CN/Tuner/PPOTuner.md
+19
-0
docs/zh_CN/Tutorial/ExperimentConfig.md
docs/zh_CN/Tutorial/ExperimentConfig.md
+73
-49
docs/zh_CN/Tutorial/Nnictl.md
docs/zh_CN/Tutorial/Nnictl.md
+48
-18
docs/zh_CN/Tutorial/SearchSpaceSpec.md
docs/zh_CN/Tutorial/SearchSpaceSpec.md
+1
-1
docs/zh_CN/sdk_reference.rst
docs/zh_CN/sdk_reference.rst
+3
-0
examples/model_compress/README.md
examples/model_compress/README.md
+1
-1
examples/model_compress/README_zh_CN.md
examples/model_compress/README_zh_CN.md
+48
-0
examples/model_compress/configure_example.yaml
examples/model_compress/configure_example.yaml
+1
-1
examples/model_compress/main_tf_pruner.py
examples/model_compress/main_tf_pruner.py
+1
-1
examples/model_compress/main_tf_quantizer.py
examples/model_compress/main_tf_quantizer.py
+1
-1
examples/model_compress/main_torch_pruner.py
examples/model_compress/main_torch_pruner.py
+1
-1
examples/model_compress/main_torch_quantizer.py
examples/model_compress/main_torch_quantizer.py
+1
-1
examples/trials/nas_cifar10/README_zh_CN.md
examples/trials/nas_cifar10/README_zh_CN.md
+5
-4
src/sdk/pynni/nni/__init__.py
src/sdk/pynni/nni/__init__.py
+3
-5
src/sdk/pynni/nni/__main__.py
src/sdk/pynni/nni/__main__.py
+63
-49
src/sdk/pynni/nni/assessor.py
src/sdk/pynni/nni/assessor.py
+2
-4
src/sdk/pynni/nni/batch_tuner/batch_tuner.py
src/sdk/pynni/nni/batch_tuner/batch_tuner.py
+1
-1
src/sdk/pynni/nni/bohb_advisor/bohb_advisor.py
src/sdk/pynni/nni/bohb_advisor/bohb_advisor.py
+12
-10
src/sdk/pynni/nni/bohb_advisor/config_generator.py
src/sdk/pynni/nni/bohb_advisor/config_generator.py
+26
-31
No files found.
docs/zh_CN/Tuner/MetisTuner.md
View file @
8c203f30
...
@@ -14,6 +14,6 @@ Metis 属于基于序列的贝叶斯优化 (SMBO) 的类别,它也基于贝叶
...
@@ -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/
更多详情,参考论文:https://www.microsoft.com/en-us/research/publication/metis-robustly-tuning-tail-latencies-cloud-systems/
\ No newline at end of file
docs/zh_CN/Tuner/PPOTuner.md
0 → 100644
View file @
8c203f30
# 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
)
,结果如下:

我们也使用 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 展示了搜索空间:

上图是某个选定的架构,用来展示搜索空间。 每个方块是一层,其操作可从 6 个操作中选择。 每条虚线是直通连接,每个方块都可以有 0 或 1 条直通连接获得前面层的输出。
**注意**
,在原始的宏搜索空间中,每个方块层可选择任意条直通连接,在此实现中,仅允许 0 或 1条。
结果如下图所示(
[
配置文件
](
https://github.com/microsoft/nni/blob/master/examples/trials/nas_cifar10/config_ppo.yml
)
):

\ No newline at end of file
docs/zh_CN/Tutorial/ExperimentConfig.md
View file @
8c203f30
...
@@ -2,12 +2,10 @@
...
@@ -2,12 +2,10 @@
创建 Experiment 所需要的配置文件。 配置文件的路径会传入
`nnictl`
命令。 配置文件的格式为 YAML。 本文介绍了配置文件的内容,并提供了一些示例和模板。
创建 Experiment 所需要的配置文件。 配置文件的路径会传入
`nnictl`
命令。 配置文件的格式为 YAML。 本文介绍了配置文件的内容,并提供了一些示例和模板。
-
[
Experiment(实验)配置参考
](
#Experiment-config-reference
)
-
[
Experiment(实验)配置参考
](
#experiment-config-reference
)
-
[
模板
](
#Template
)
-
[
模板
](
#template
)
-
[
说明
](
#Configuration-spec
)
-
[
说明
](
#configuration-spec
)
-
[
样例
](
#Examples
)
-
[
样例
](
#examples
)
<a
name=
"Template"
></a>
## 模板
## 模板
...
@@ -19,27 +17,27 @@ experimentName:
...
@@ -19,27 +17,27 @@ experimentName:
trialConcurrency
:
trialConcurrency
:
maxExecDuration
:
maxExecDuration
:
maxTrialNum
:
maxTrialNum
:
#可选项: local, remote, pai, kubeflow
#
可选项: local, remote, pai, kubeflow
trainingServicePlatform
:
trainingServicePlatform
:
searchSpacePath
:
searchSpacePath
:
#可选项: true, false, 默认值: false
#
可选项: true, false, 默认值: false
useAnnotation
:
useAnnotation
:
#可选项: true, false, 默认值: false
#
可选项: true, false, 默认值: false
multiPhase
:
multiPhase
:
#可选项: true, false, 默认值: false
#
可选项: true, false, 默认值: false
multiThread
:
multiThread
:
tuner
:
tuner
:
#可选项: TPE, Random, Anneal, Evolution
#
可选项: TPE, Random, Anneal, Evolution
builtinTunerName
:
builtinTunerName
:
classArgs
:
classArgs
:
#可选项: maximize, minimize
#
可选项: maximize, minimize
optimize_mode
:
optimize_mode
:
gpu
Num
:
gpu
Indices
:
trial
:
trial
:
command
:
command
:
codeDir
:
codeDir
:
gpuNum
:
gpuNum
:
#在本
地使用时
,machineList 可为空
#
在本
机模式下
,machineList 可为空
machineList
:
machineList
:
-
ip
:
-
ip
:
port
:
port
:
...
@@ -70,18 +68,18 @@ tuner:
...
@@ -70,18 +68,18 @@ tuner:
classArgs
:
classArgs
:
#可选项: maximize, minimize
#可选项: maximize, minimize
optimize_mode
:
optimize_mode
:
gpu
Num
:
gpu
Indices
:
assessor
:
assessor
:
#可选项: Medianstop
#可选项: Medianstop
builtinAssessorName
:
builtinAssessorName
:
classArgs
:
classArgs
:
#可选项: maximize, minimize
#可选项: maximize, minimize
optimize_mode
:
optimize_mode
:
gpu
Num
:
gpu
Indices
:
trial
:
trial
:
command
:
command
:
codeDir
:
codeDir
:
gpu
Num
:
gpu
Indices
:
#在本地使用时,machineList 可为空
#在本地使用时,machineList 可为空
machineList
:
machineList
:
-
ip
:
-
ip
:
...
@@ -112,18 +110,18 @@ tuner:
...
@@ -112,18 +110,18 @@ tuner:
classArgs
:
classArgs
:
#可选项: maximize, minimize
#可选项: maximize, minimize
optimize_mode
:
optimize_mode
:
gpu
Num
:
gpu
Indices
:
assessor
:
assessor
:
#可选项: Medianstop
#可选项: Medianstop
builtinAssessorName
:
builtinAssessorName
:
classArgs
:
classArgs
:
#可选项: maximize, minimize
#可选项: maximize, minimize
optimize_mode
:
optimize_mode
:
gpu
Num
:
gpu
Indices
:
trial
:
trial
:
command
:
command
:
codeDir
:
codeDir
:
gpu
Num
:
gpu
Indices
:
#在本地使用时,machineList 可为空
#在本地使用时,machineList 可为空
machineList
:
machineList
:
-
ip
:
-
ip
:
...
@@ -132,8 +130,6 @@ machineList:
...
@@ -132,8 +130,6 @@ machineList:
passwd
:
passwd
:
```
```
<a
name=
"Configuration"
></a>
## 说明
## 说明
-
**authorName**
-
**authorName**
...
@@ -264,11 +260,11 @@ machineList:
...
@@ -264,11 +260,11 @@ machineList:
-
**builtinTunerName**
-
**builtinTunerName**
**builtinTunerName**
指定
了
系统 Tuner 的名
字
,NNI SDK 提供了多
种
Tuner,
如:{
**TPE**
,
**Random**
,
**Anneal**
,
**Evolution**
,
**BatchTuner**
,
**GridSearch**
}
。
**builtinTunerName**
指定系统 Tuner 的名
称
,NNI SDK 提供了多
个内置
Tuner,
详情参考
[
这里
](
../Tuner/BuiltinTuner.md
)
。
-
**classArgs**
-
**classArgs**
**classArgs**
指定了 Tuner 算法的参数。
如果
**builtinTunerName**
是{
**TPE**
,
**Random**
,
**Anneal**
,
**Evolution**
},用户需要设置
**optimize_mode**
。
**classArgs**
指定了 Tuner 算法的参数。
参考
[
此文件
](
../Tuner/BuiltinTuner.md
)
来了解内置 Tuner 的配置参数
。
-
**codeDir**
,
**classFileName**
,
**className**
和
**classArgs**
-
**codeDir**
,
**classFileName**
,
**className**
和
**classArgs**
...
@@ -288,17 +284,17 @@ machineList:
...
@@ -288,17 +284,17 @@ machineList:
**classArgs**
指定了 Tuner 算法的参数。
**classArgs**
指定了 Tuner 算法的参数。
-
**gpu
Num
**
-
**gpu
Indices
**
__gpuNum__ 指定了运行 Tuner 进程的 GPU 数量。 此字段的值必须是正整数。 如果此字段没有设置,NNI不会在脚本中添加
`CUDA_VISIBLE_DEVICES`
(也就是说,不会通过
`CUDA_VISIBLE_DEVICES`
来控制 GPU 在 Trial 中是否可见),也不会管理 GPU 资源。
__gpuIndices__ 指定了 Tuner 进程可使用的 GPU。 可以指定单个或多个 GPU 索引,多个索引间使用逗号(,)隔开,例如:
`1`
或
`0,1,3`
。 如果没设置此字段,脚本中的
`CUDA_VISIBLE_DEVICES`
会为空 '',即 Tuner 中找不到 GPU。
注意: 只能使用一种方法来指定 Tuner,例如:设置 {tunerName, optimizationMode} 或 {tunerCommand, tunerCwd},不能同时设置两者。
-
**includeIntermediateResults**
-
**includeIntermediateResults**
如果 __includeIntermediateResults__ 为 true,最后一个 Assessor 的中间结果会被发送给 Tuner 作为最终结果。 __includeIntermediateResults__ 的默认值为 false。
如果 __includeIntermediateResults__ 为 true,最后一个 Assessor 的中间结果会被发送给 Tuner 作为最终结果。 __includeIntermediateResults__ 的默认值为 false。
注意:用户只能用一种方法来指定 Tuner,指定
`builtinTunerName`
和
`classArgs`
,或指定
`codeDir`
,
`classFileName`
,
`className`
以及
`classArgs`
。
-
**Assessor**
-
**Assessor**
...
@@ -310,7 +306,7 @@ machineList:
...
@@ -310,7 +306,7 @@ machineList:
-
**builtinAssessorName**
-
**builtinAssessorName**
**builtinAssessorName**
指定了
系统
Assessor 的名称,
NNI 内置的 Assessor
有 {
**Medianstop**
,等等}
。
**builtinAssessorName**
指定了
内置
Assessor 的名称,NNI
SDK 提供了多个
内置的 Assessor
,详情参考
[
这里
](
../Assessor/BuiltinAssessor.md
)
。
-
**classArgs**
-
**classArgs**
...
@@ -334,11 +330,48 @@ machineList:
...
@@ -334,11 +330,48 @@ machineList:
**classArgs**
指定了 Assessor 算法的参数。
**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)**
-
**trial (local, remote)**
...
@@ -568,8 +601,6 @@ machineList:
...
@@ -568,8 +601,6 @@ machineList:
**host**
是 OpenPAI 的主机地址。
**host**
是 OpenPAI 的主机地址。
<a
name=
"Examples"
></a>
## 样例
## 样例
-
**本机模式**
-
**本机模式**
...
@@ -592,7 +623,6 @@ machineList:
...
@@ -592,7 +623,6 @@ machineList:
classArgs
:
classArgs
:
#可选项: maximize, minimize
#可选项: maximize, minimize
optimize_mode
:
maximize
optimize_mode
:
maximize
gpuNum
:
0
trial
:
trial
:
command
:
python3 mnist.py
command
:
python3 mnist.py
codeDir
:
/nni/mnist
codeDir
:
/nni/mnist
...
@@ -618,14 +648,12 @@ machineList:
...
@@ -618,14 +648,12 @@ machineList:
classArgs
:
classArgs
:
#可选项: maximize, minimize
#可选项: maximize, minimize
optimize_mode
:
maximize
optimize_mode
:
maximize
gpuNum
:
0
assessor
:
assessor
:
#可选项: Medianstop
#可选项: Medianstop
builtinAssessorName
:
Medianstop
builtinAssessorName
:
Medianstop
classArgs
:
classArgs
:
#可选项: maximize, minimize
#可选项: maximize, minimize
optimize_mode
:
maximize
optimize_mode
:
maximize
gpuNum
:
0
trial
:
trial
:
command
:
python3 mnist.py
command
:
python3 mnist.py
codeDir
:
/nni/mnist
codeDir
:
/nni/mnist
...
@@ -652,7 +680,6 @@ machineList:
...
@@ -652,7 +680,6 @@ machineList:
classArgs
:
classArgs
:
#可选项: maximize, minimize
#可选项: maximize, minimize
optimize_mode
:
maximize
optimize_mode
:
maximize
gpuNum
:
0
assessor
:
assessor
:
codeDir
:
/nni/assessor
codeDir
:
/nni/assessor
classFileName
:
myassessor.py
classFileName
:
myassessor.py
...
@@ -660,7 +687,6 @@ machineList:
...
@@ -660,7 +687,6 @@ machineList:
classArgs
:
classArgs
:
#choice: maximize, minimize
#choice: maximize, minimize
optimize_mode
:
maximize
optimize_mode
:
maximize
gpuNum
:
0
trial
:
trial
:
command
:
python3 mnist.py
command
:
python3 mnist.py
codeDir
:
/nni/mnist
codeDir
:
/nni/mnist
...
@@ -688,7 +714,6 @@ machineList:
...
@@ -688,7 +714,6 @@ machineList:
classArgs
:
classArgs
:
#可选项: maximize, minimize
#可选项: maximize, minimize
optimize_mode
:
maximize
optimize_mode
:
maximize
gpuNum
:
0
trial
:
trial
:
command
:
python3 mnist.py
command
:
python3 mnist.py
codeDir
:
/nni/mnist
codeDir
:
/nni/mnist
...
@@ -762,16 +787,16 @@ machineList:
...
@@ -762,16 +787,16 @@ machineList:
trialConcurrency
:
1
trialConcurrency
:
1
maxExecDuration
:
1h
maxExecDuration
:
1h
maxTrialNum
:
1
maxTrialNum
:
1
#可选项: local, remote, pai, kubeflow
#
可选项: local, remote, pai, kubeflow
trainingServicePlatform
:
kubeflow
trainingServicePlatform
:
kubeflow
searchSpacePath
:
search_space.json
searchSpacePath
:
search_space.json
#可选项: true, false
#
可选项: true, false
useAnnotation
:
false
useAnnotation
:
false
tuner
:
tuner
:
#可选项: TPE, Random, Anneal, Evolution
#
可选项: TPE, Random, Anneal, Evolution
builtinTunerName
:
TPE
builtinTunerName
:
TPE
classArgs
:
classArgs
:
#可选项: maximize, minimize
#
可选项: maximize, minimize
optimize_mode
:
maximize
optimize_mode
:
maximize
trial
:
trial
:
codeDir
:
.
codeDir
:
.
...
@@ -797,23 +822,22 @@ machineList:
...
@@ -797,23 +822,22 @@ machineList:
trialConcurrency
:
1
trialConcurrency
:
1
maxExecDuration
:
1h
maxExecDuration
:
1h
maxTrialNum
:
1
maxTrialNum
:
1
#可选项: local, remote, pai, kubeflow
#
可选项: local, remote, pai, kubeflow
trainingServicePlatform
:
kubeflow
trainingServicePlatform
:
kubeflow
searchSpacePath
:
search_space.json
searchSpacePath
:
search_space.json
#可选项: true, false
#
可选项: true, false
useAnnotation
:
false
useAnnotation
:
false
#nniManagerIp: 10.10.10.10
#nniManagerIp: 10.10.10.10
tuner
:
tuner
:
#可选项: TPE, Random, Anneal, Evolution
#
可选项: TPE, Random, Anneal, Evolution
builtinTunerName
:
TPE
builtinTunerName
:
TPE
classArgs
:
classArgs
:
#可选项: maximize, minimize
#
可选项: maximize, minimize
optimize_mode
:
maximize
optimize_mode
:
maximize
assessor
:
assessor
:
builtinAssessorName
:
Medianstop
builtinAssessorName
:
Medianstop
classArgs
:
classArgs
:
optimize_mode
:
maximize
optimize_mode
:
maximize
gpuNum
:
0
trial
:
trial
:
codeDir
:
.
codeDir
:
.
worker
:
worker
:
...
...
docs/zh_CN/Tutorial/Nnictl.md
View file @
8c203f30
...
@@ -10,6 +10,7 @@ nnictl 支持的命令:
...
@@ -10,6 +10,7 @@ nnictl 支持的命令:
*
[
nnictl create
](
#create
)
*
[
nnictl create
](
#create
)
*
[
nnictl resume
](
#resume
)
*
[
nnictl resume
](
#resume
)
*
[
nnictl view
](
#view
)
*
[
nnictl stop
](
#stop
)
*
[
nnictl stop
](
#stop
)
*
[
nnictl update
](
#update
)
*
[
nnictl update
](
#update
)
*
[
nnictl trial
](
#trial
)
*
[
nnictl trial
](
#trial
)
...
@@ -104,6 +105,35 @@ nnictl 支持的命令:
...
@@ -104,6 +105,35 @@ nnictl 支持的命令:
nnictl resume
[
experiment_id]
--port
8088
nnictl resume
[
experiment_id]
--port
8088
```
```
<a
name=
"view"
></a>

`nnictl view`
*
说明
使用此命令查看已停止的 Experiment。
*
用法
```
bash
nnictl view
[
OPTIONS]
```
*
选项
| 参数及缩写 | 是否必需 | 默认值 | 说明 |
| ---------- | ----- | --- | -------------------------------- |
| id | True | | 要查看的 Experiment 标识 |
| --port, -p | False | | 要查看的 Experiment 使用的 RESTful 服务端口 |
*
示例
> 在指定的端口 8088 上查看 Experiment
```
bash
nnictl view
[
experiment_id]
--port
8088
```
<a
name=
"stop"
></a>
<a
name=
"stop"
></a>

`nnictl stop`

`nnictl stop`
...
@@ -125,7 +155,7 @@ nnictl 支持的命令:
...
@@ -125,7 +155,7 @@ nnictl 支持的命令:
| --port, -p | False | | 要停止的 Experiment 使用的 RESTful 服务端口 |
| --port, -p | False | | 要停止的 Experiment 使用的 RESTful 服务端口 |
| --all, -a | False | | 停止所有 Experiment |
| --all, -a | False | | 停止所有 Experiment |
*
详细信息及
样
例
*
详细信息及
示
例
1.
如果没有指定 id,并且当前有运行的 Experiment,则会停止该 Experiment,否则会输出错误信息。
1.
如果没有指定 id,并且当前有运行的 Experiment,则会停止该 Experiment,否则会输出错误信息。
...
@@ -183,7 +213,7 @@ nnictl 支持的命令:
...
@@ -183,7 +213,7 @@ nnictl 支持的命令:
| id | False | | 需要设置的 Experiment 的 id |
| id | False | | 需要设置的 Experiment 的 id |
| --filename, -f | True | | 新的搜索空间文件名 |
| --filename, -f | True | | 新的搜索空间文件名 |
*
样
例
*
示
例
`使用 'examples/trials/mnist/search_space.json' 来更新 Experiment 的搜索空间`
`使用 'examples/trials/mnist/search_space.json' 来更新 Experiment 的搜索空间`
...
@@ -207,7 +237,7 @@ nnictl 支持的命令:
...
@@ -207,7 +237,7 @@ nnictl 支持的命令:
| 参数及缩写 | 是否必需 | 默认值 | 说明 |
| 参数及缩写 | 是否必需 | 默认值 | 说明 |
| ----------- | ----- | --- | --------------------- |
| ----------- | ----- | --- | --------------------- |
| id | False | | 需要设置的 Experiment 的
id
|
| id | False | | 需要设置的 Experiment 的
ID
|
| --value, -v | True | | 允许同时运行的 Trial 的数量 |
| --value, -v | True | | 允许同时运行的 Trial 的数量 |
*
样例
*
样例
...
@@ -232,12 +262,12 @@ nnictl 支持的命令:
...
@@ -232,12 +262,12 @@ nnictl 支持的命令:
*
选项
*
选项
| 参数及缩写 | 是否必需 | 默认值 | 说明 |
| 参数及缩写 | 是否必需 | 默认值 | 说明
|
| ----------- | ----- | --- | ----------------------------------------------------------------------- |
| ----------- | ----- | --- | -----------------------------------------------------------------------
-
|
| id | False | | 需要设置的 Experiment 的
id
|
| id | False | | 需要设置的 Experiment 的
ID
|
| --value, -v | True | | Experiment 持续时间如没有单位,则为秒。 后缀可以为 's' 即秒 (默认值), 'm' 即分钟, 'h' 即小时或 'd' 即天。 |
| --value, -v | True | | Experiment 持续时间
,
如没有单位,则为秒。 后缀可以为 's' 即秒 (默认值), 'm' 即分钟, 'h' 即小时或 'd' 即天。 |
*
样
例
*
示
例
> 修改 Experiment 的执行时间
> 修改 Experiment 的执行时间
...
@@ -264,7 +294,7 @@ nnictl 支持的命令:
...
@@ -264,7 +294,7 @@ nnictl 支持的命令:
| id | False | | 需要设置的 Experiment 的 id |
| id | False | | 需要设置的 Experiment 的 id |
| --value, -v | True | | 需要设置的 maxtrialnum 的数量 |
| --value, -v | True | | 需要设置的 maxtrialnum 的数量 |
*
样
例
*
示
例
> 更新 Experiment 的 Trial 数量
> 更新 Experiment 的 Trial 数量
...
@@ -312,7 +342,7 @@ nnictl 支持的命令:
...
@@ -312,7 +342,7 @@ nnictl 支持的命令:
| id | False | | Trial 的 Experiment ID |
| id | False | | Trial 的 Experiment ID |
| --trial_id, -T | True | | 需要终止的 Trial 的 ID。 |
| --trial_id, -T | True | | 需要终止的 Trial 的 ID。 |
*
样
例
*
示
例
> 结束 Trial 任务
> 结束 Trial 任务
...
@@ -378,7 +408,7 @@ nnictl 支持的命令:
...
@@ -378,7 +408,7 @@ nnictl 支持的命令:
| 参数及缩写 | 是否必需 | 默认值 | 说明 |
| 参数及缩写 | 是否必需 | 默认值 | 说明 |
| ----- | ----- | --- | --------------------- |
| ----- | ----- | --- | --------------------- |
| id | False | | 需要设置的 Experiment 的
id
|
| id | False | | 需要设置的 Experiment 的
ID
|
*
**nnictl experiment list**
*
**nnictl experiment list**
...
@@ -439,7 +469,7 @@ nnictl 支持的命令:
...
@@ -439,7 +469,7 @@ nnictl 支持的命令:
| --filename, -f | True | | 文件的输出路径 |
| --filename, -f | True | | 文件的输出路径 |
| --type | True | | 输出文件类型,仅支持 "csv" 和 "json" |
| --type | True | | 输出文件类型,仅支持 "csv" 和 "json" |
*
样
例
*
示
例
> 将 Experiment 中所有 Trial 数据导出为 JSON 格式
> 将 Experiment 中所有 Trial 数据导出为 JSON 格式
...
@@ -478,7 +508,7 @@ nnictl 支持的命令:
...
@@ -478,7 +508,7 @@ nnictl 支持的命令:
]
]
```
```
最顶层列表的每个元素都是一个
样
例。 对于内置的 Tuner 和 Advisor,每个样本至少需要两个主键:
`parameter`
和
`value`
。
`parameter`
必须与 Experiment 的搜索空间相匹配,
`parameter`
中的所有的主键(或超参)都必须与搜索空间中的主键相匹配。 否则, Tuner 或 Advisor 可能会有无法预期的行为。
`Value`
应当遵循与
`nni.report_final_result`
的输入值一样的规则,即要么时一个数字,或者是包含
`default`
主键的 dict。 对于自定义的 Tuner 或 Advisor,根据实现的不同,此文件可以是任意的 JSON 内容(例如,
`import_data`
)。
最顶层列表的每个元素都是一个
示
例。 对于内置的 Tuner 和 Advisor,每个样本至少需要两个主键:
`parameter`
和
`value`
。
`parameter`
必须与 Experiment 的搜索空间相匹配,
`parameter`
中的所有的主键(或超参)都必须与搜索空间中的主键相匹配。 否则, Tuner 或 Advisor 可能会有无法预期的行为。
`Value`
应当遵循与
`nni.report_final_result`
的输入值一样的规则,即要么时一个数字,或者是包含
`default`
主键的 dict。 对于自定义的 Tuner 或 Advisor,根据实现的不同,此文件可以是任意的 JSON 内容(例如,
`import_data`
)。
也可以用
[
nnictl experiment export
](
#export
)
命令导出 Experiment 已经运行过的 Trial 超参和结果。
也可以用
[
nnictl experiment export
](
#export
)
命令导出 Experiment 已经运行过的 Trial 超参和结果。
...
@@ -489,7 +519,7 @@ nnictl 支持的命令:
...
@@ -489,7 +519,7 @@ nnictl 支持的命令:
内置 Advisor
:
BOHB
内置 Advisor
:
BOHB
```
```
*如果要将数据导入到 BOHB Advisor,建议像 NNI 一样,增加 "TRIAL_BUDGET" 参数,否则,BOHB 会使用 max_budget 作为 "TRIAL_BUDGET"。
样
例如下:*
*如果要将数据导入到 BOHB Advisor,建议像 NNI 一样,增加 "TRIAL_BUDGET" 参数,否则,BOHB 会使用 max_budget 作为 "TRIAL_BUDGET"。
示
例如下:*
```
json
```
json
[
[
...
@@ -497,7 +527,7 @@ nnictl 支持的命令:
...
@@ -497,7 +527,7 @@ nnictl 支持的命令:
]
]
```
```
*
样
例
*
示
例
> 将数据导入运行中的 Experiment
> 将数据导入运行中的 Experiment
...
@@ -563,7 +593,7 @@ nnictl 支持的命令:
...
@@ -563,7 +593,7 @@ nnictl 支持的命令:
| 参数及缩写 | 是否必需 | 默认值 | 说明 |
| 参数及缩写 | 是否必需 | 默认值 | 说明 |
| ---------- | ----- | --- | --------------------- |
| ---------- | ----- | --- | --------------------- |
| id | False | | 需要设置的 Experiment 的
ID
|
| id | False | | 需要设置的 Experiment 的
id
|
| --head, -h | False | | 显示 stdout 开始的若干行 |
| --head, -h | False | | 显示 stdout 开始的若干行 |
| --tail, -t | False | | 显示 stdout 结尾的若干行 |
| --tail, -t | False | | 显示 stdout 结尾的若干行 |
| --path, -p | False | | 显示 stdout 文件的路径 |
| --path, -p | False | | 显示 stdout 文件的路径 |
...
@@ -592,7 +622,7 @@ nnictl 支持的命令:
...
@@ -592,7 +622,7 @@ nnictl 支持的命令:
| 参数及缩写 | 是否必需 | 默认值 | 说明 |
| 参数及缩写 | 是否必需 | 默认值 | 说明 |
| ---------- | ----- | --- | --------------------- |
| ---------- | ----- | --- | --------------------- |
| id | False | | 需要设置的 Experiment 的
ID
|
| id | False | | 需要设置的 Experiment 的
id
|
| --head, -h | False | | 显示 stderr 开始的若干行 |
| --head, -h | False | | 显示 stderr 开始的若干行 |
| --tail, -t | False | | 显示 stderr 结尾的若干行 |
| --tail, -t | False | | 显示 stderr 结尾的若干行 |
| --path, -p | False | | 显示 stderr 文件的路径 |
| --path, -p | False | | 显示 stderr 文件的路径 |
...
@@ -641,7 +671,7 @@ nnictl 支持的命令:
...
@@ -641,7 +671,7 @@ nnictl 支持的命令:
| 参数及缩写 | 是否必需 | 默认值 | 说明 |
| 参数及缩写 | 是否必需 | 默认值 | 说明 |
| -------------- | ----- | ---- | --------------------- |
| -------------- | ----- | ---- | --------------------- |
| id | False | | 需要设置的 Experiment 的 id |
| id | False | | 需要设置的 Experiment 的 id |
| --trial_id, -T | False | | Trial 的
id
|
| --trial_id, -T | False | | Trial 的
ID
|
| --port | False | 6006 | Tensorboard 进程的端口 |
| --port | False | 6006 | Tensorboard 进程的端口 |
*
详细说明
*
详细说明
...
...
docs/zh_CN/Tutorial/SearchSpaceSpec.md
View file @
8c203f30
...
@@ -101,7 +101,7 @@
...
@@ -101,7 +101,7 @@
已知的局限:
已知的局限:
*
注意
Metis Tuner
当前仅支持在
`choice`
中
使用数值。
*
GP Tuner 和
Metis Tuner
的搜索空间只支持
**数值**
,(
`choice`
类型在其它 Tuner 中可以
使用
非
数值
,如:字符串等)。 GP Tuner 和 Metis Tuner 都使用了高斯过程的回归(Gaussian Process Regressor, GPR)。 GPR 基于计算不同点距离的和函数来进行预测,其无法计算非数值值的距离
。
*
请注意,对于嵌套搜索空间:
*
请注意,对于嵌套搜索空间:
...
...
docs/zh_CN/sdk_reference.rst
View file @
8c203f30
...
@@ -50,6 +50,9 @@ Assessor(评估器)
...
@@ -50,6 +50,9 @@ Assessor(评估器)
Advisor
Advisor
------------------------
------------------------
.. autoclass:: nni.msg_dispatcher_base.MsgDispatcherBase
:members:
.. autoclass:: nni.hyperband_advisor.hyperband_advisor.Hyperband
.. autoclass:: nni.hyperband_advisor.hyperband_advisor.Hyperband
:members:
:members:
...
...
examples/model_compress/README.md
View file @
8c203f30
...
@@ -20,7 +20,7 @@ configure_list = [{
...
@@ -20,7 +20,7 @@ configure_list = [{
'start_epoch'
:
0
,
'start_epoch'
:
0
,
'end_epoch'
:
10
,
'end_epoch'
:
10
,
'frequency'
:
1
,
'frequency'
:
1
,
'op_type'
:
'default'
'op_type
s
'
:
[
'default'
]
}]
}]
pruner
=
AGP_Pruner
(
configure_list
)
pruner
=
AGP_Pruner
(
configure_list
)
```
```
...
...
examples/model_compress/README_zh_CN.md
0 → 100644
View file @
8c203f30
# 运行模型压缩示例
以 PyTorch 剪枝为例:
```
bash
python main_torch_pruner.py
```
此示例使用了 AGP Pruner。 初始化 Pruner 需要通过以下两种方式来提供配置。
-
读取
`configure_example.yaml`
,这样代码会更整洁,但配置会比较复杂。
-
直接在代码中配置
此例在代码中配置了模型压缩:
```
python
configure_list
=
[{
'initial_sparsity'
:
0
,
'final_sparsity'
:
0.8
,
'start_epoch'
:
0
,
'end_epoch'
:
10
,
'frequency'
:
1
,
'op_types'
:
[
'default'
]
}]
pruner
=
AGP_Pruner
(
configure_list
)
```
当调用
`pruner(model)`
时,模型会被嵌入掩码操作。 例如,某层以权重作为输入,可在权重和层操作之间插入一个操作,此操作以权重为输入,并将其应用掩码后输出。 因此,计算过程中,只要通过此操作,就会应用掩码。 还可以
**不做任何改动**
,来对模型进行微调。
```
python
for
epoch
in
range
(
10
):
# update_epoch 来让 Pruner 知道 Epoch 的数量,从而能够在训练过程中调整掩码。
pruner
.
update_epoch
(
epoch
)
print
(
'# Epoch {} #'
.
format
(
epoch
))
train
(
model
,
device
,
train_loader
,
optimizer
)
test
(
model
,
device
,
test_loader
)
```
微调完成后,被修剪过的权重可通过以下代码获得:
```
masks = pruner.mask_list
layer_name = xxx
mask = masks[layer_name]
```
examples/model_compress/configure_example.yaml
View file @
8c203f30
...
@@ -6,4 +6,4 @@ AGPruner:
...
@@ -6,4 +6,4 @@ AGPruner:
frequency
:
1
frequency
:
1
initial_sparsity
:
0.05
initial_sparsity
:
0.05
final_sparsity
:
0.8
final_sparsity
:
0.8
op_type
:
'
default'
op_type
s
:
[
'
default'
]
examples/model_compress/main_tf_pruner.py
View file @
8c203f30
...
@@ -91,7 +91,7 @@ def main():
...
@@ -91,7 +91,7 @@ def main():
'start_epoch'
:
0
,
'start_epoch'
:
0
,
'end_epoch'
:
10
,
'end_epoch'
:
10
,
'frequency'
:
1
,
'frequency'
:
1
,
'op_type'
:
'default'
'op_type
s
'
:
[
'default'
]
}]
}]
pruner
=
AGP_Pruner
(
configure_list
)
pruner
=
AGP_Pruner
(
configure_list
)
# if you want to load from yaml file
# if you want to load from yaml file
...
...
examples/model_compress/main_tf_quantizer.py
View file @
8c203f30
...
@@ -82,7 +82,7 @@ def main():
...
@@ -82,7 +82,7 @@ def main():
'''you can change this to DoReFaQuantizer to implement it
'''you can change this to DoReFaQuantizer to implement it
DoReFaQuantizer(configure_list).compress(tf.get_default_graph())
DoReFaQuantizer(configure_list).compress(tf.get_default_graph())
'''
'''
configure_list
=
[{
'q_bits'
:
8
,
'op_type'
:
'default'
}]
configure_list
=
[{
'q_bits'
:
8
,
'op_type
s
'
:
[
'default'
]
}]
quantizer
=
QAT_Quantizer
(
configure_list
)
quantizer
=
QAT_Quantizer
(
configure_list
)
quantizer
(
tf
.
get_default_graph
())
quantizer
(
tf
.
get_default_graph
())
# you can also use compress(model) or compress_default_graph()
# you can also use compress(model) or compress_default_graph()
...
...
examples/model_compress/main_torch_pruner.py
View file @
8c203f30
...
@@ -76,7 +76,7 @@ def main():
...
@@ -76,7 +76,7 @@ def main():
'start_epoch'
:
0
,
'start_epoch'
:
0
,
'end_epoch'
:
10
,
'end_epoch'
:
10
,
'frequency'
:
1
,
'frequency'
:
1
,
'op_type'
:
'default'
'op_type
s
'
:
[
'default'
]
}]
}]
pruner
=
AGP_Pruner
(
configure_list
)
pruner
=
AGP_Pruner
(
configure_list
)
...
...
examples/model_compress/main_torch_quantizer.py
View file @
8c203f30
...
@@ -68,7 +68,7 @@ def main():
...
@@ -68,7 +68,7 @@ def main():
'''you can change this to DoReFaQuantizer to implement it
'''you can change this to DoReFaQuantizer to implement it
DoReFaQuantizer(configure_list).compress(model)
DoReFaQuantizer(configure_list).compress(model)
'''
'''
configure_list
=
[{
'q_bits'
:
8
,
'op_type'
:
'default'
}]
configure_list
=
[{
'q_bits'
:
8
,
'op_type
s
'
:
[
'default'
]
}]
quantizer
=
QAT_Quantizer
(
configure_list
)
quantizer
=
QAT_Quantizer
(
configure_list
)
quantizer
(
model
)
quantizer
(
model
)
# you can also use compress(model) method
# you can also use compress(model) method
...
...
examples/trials/nas_cifar10/README_zh_CN.md
View file @
8c203f30
**在 NNI 中运行神经网络架构搜索**
# 在 NNI 中运行神经网络架构搜索
===
参考
[
NNI-NAS-Example
](
https://github.com/Crysple/NNI-NAS-Example
)
,来使用贡献者提供的 NAS 接口。
参考
[
NNI-NAS-Example
](
https://github.com/Crysple/NNI-NAS-Example
)
,来使用贡献者提供的 NAS 接口。
谢谢可爱的贡献者!
此目录中包含了 Trial 代码,并提供了示例的配置文件来展示如何使用 PPO Tuner 来调优此 Trial 代码。
欢迎越来越多的人加入我们!
运行下列代码来准备数据集
`cd data && . download.sh`
.
\ No newline at end of file
感谢可爱的志愿者,欢迎更多的人加入我们!
\ No newline at end of file
src/sdk/pynni/nni/__init__.py
View file @
8c203f30
...
@@ -19,16 +19,14 @@
...
@@ -19,16 +19,14 @@
# ==================================================================================================
# ==================================================================================================
# pylint: disable=wildcard-import
from
.trial
import
*
from
.trial
import
*
from
.smartparam
import
*
from
.smartparam
import
*
from
.nas_utils
import
training_update
from
.nas_utils
import
training_update
class
NoMoreTrialError
(
Exception
):
class
NoMoreTrialError
(
Exception
):
def
__init__
(
self
,
ErrorInfo
):
def
__init__
(
self
,
ErrorInfo
):
super
().
__init__
(
self
)
super
().
__init__
(
self
)
self
.
errorinfo
=
ErrorInfo
self
.
errorinfo
=
ErrorInfo
def
__str__
(
self
):
def
__str__
(
self
):
return
self
.
errorinfo
return
self
.
errorinfo
\ No newline at end of file
src/sdk/pynni/nni/__main__.py
View file @
8c203f30
...
@@ -27,9 +27,10 @@ import logging
...
@@ -27,9 +27,10 @@ import logging
import
json
import
json
import
importlib
import
importlib
from
.common
import
enable_multi_thread
,
enable_multi_phase
from
.constants
import
ModuleName
,
ClassName
,
ClassArgs
,
AdvisorModuleName
,
AdvisorClassName
from
.constants
import
ModuleName
,
ClassName
,
ClassArgs
,
AdvisorModuleName
,
AdvisorClassName
from
nni.common
import
enable_multi_thread
,
enable_multi_phase
from
.msg_dispatcher
import
MsgDispatcher
from
nni.msg_dispatcher
import
MsgDispatcher
logger
=
logging
.
getLogger
(
'nni.main'
)
logger
=
logging
.
getLogger
(
'nni.main'
)
logger
.
debug
(
'START'
)
logger
.
debug
(
'START'
)
...
@@ -44,7 +45,7 @@ def augment_classargs(input_class_args, classname):
...
@@ -44,7 +45,7 @@ def augment_classargs(input_class_args, classname):
input_class_args
[
key
]
=
value
input_class_args
[
key
]
=
value
return
input_class_args
return
input_class_args
def
create_builtin_class_instance
(
classname
,
jsonstr_args
,
is_advisor
=
False
):
def
create_builtin_class_instance
(
classname
,
jsonstr_args
,
is_advisor
=
False
):
if
is_advisor
:
if
is_advisor
:
if
classname
not
in
AdvisorModuleName
or
\
if
classname
not
in
AdvisorModuleName
or
\
importlib
.
util
.
find_spec
(
AdvisorModuleName
[
classname
])
is
None
:
importlib
.
util
.
find_spec
(
AdvisorModuleName
[
classname
])
is
None
:
...
@@ -130,55 +131,15 @@ def main():
...
@@ -130,55 +131,15 @@ def main():
if
args
.
advisor_class_name
:
if
args
.
advisor_class_name
:
# advisor is enabled and starts to run
# advisor is enabled and starts to run
if
args
.
advisor_class_name
in
AdvisorModuleName
:
_run_advisor
(
args
)
dispatcher
=
create_builtin_class_instance
(
args
.
advisor_class_name
,
args
.
advisor_args
,
True
)
else
:
dispatcher
=
create_customized_class_instance
(
args
.
advisor_directory
,
args
.
advisor_class_filename
,
args
.
advisor_class_name
,
args
.
advisor_args
)
if
dispatcher
is
None
:
raise
AssertionError
(
'Failed to create Advisor instance'
)
try
:
dispatcher
.
run
()
except
Exception
as
exception
:
logger
.
exception
(
exception
)
raise
else
:
else
:
# tuner (and assessor) is enabled and starts to run
# tuner (and assessor) is enabled and starts to run
tuner
=
None
tuner
=
_create_tuner
(
args
)
assessor
=
None
if
args
.
tuner_class_name
in
ModuleName
:
tuner
=
create_builtin_class_instance
(
args
.
tuner_class_name
,
args
.
tuner_args
)
else
:
tuner
=
create_customized_class_instance
(
args
.
tuner_directory
,
args
.
tuner_class_filename
,
args
.
tuner_class_name
,
args
.
tuner_args
)
if
tuner
is
None
:
raise
AssertionError
(
'Failed to create Tuner instance'
)
if
args
.
assessor_class_name
:
if
args
.
assessor_class_name
:
if
args
.
assessor_class_name
in
ModuleName
:
assessor
=
_create_assessor
(
args
)
assessor
=
create_builtin_class_instance
(
else
:
args
.
assessor_class_name
,
assessor
=
None
args
.
assessor_args
)
else
:
assessor
=
create_customized_class_instance
(
args
.
assessor_directory
,
args
.
assessor_class_filename
,
args
.
assessor_class_name
,
args
.
assessor_args
)
if
assessor
is
None
:
raise
AssertionError
(
'Failed to create Assessor instance'
)
dispatcher
=
MsgDispatcher
(
tuner
,
assessor
)
dispatcher
=
MsgDispatcher
(
tuner
,
assessor
)
try
:
try
:
...
@@ -193,6 +154,59 @@ def main():
...
@@ -193,6 +154,59 @@ def main():
assessor
.
_on_error
()
assessor
.
_on_error
()
raise
raise
def
_run_advisor
(
args
):
if
args
.
advisor_class_name
in
AdvisorModuleName
:
dispatcher
=
create_builtin_class_instance
(
args
.
advisor_class_name
,
args
.
advisor_args
,
True
)
else
:
dispatcher
=
create_customized_class_instance
(
args
.
advisor_directory
,
args
.
advisor_class_filename
,
args
.
advisor_class_name
,
args
.
advisor_args
)
if
dispatcher
is
None
:
raise
AssertionError
(
'Failed to create Advisor instance'
)
try
:
dispatcher
.
run
()
except
Exception
as
exception
:
logger
.
exception
(
exception
)
raise
def
_create_tuner
(
args
):
if
args
.
tuner_class_name
in
ModuleName
:
tuner
=
create_builtin_class_instance
(
args
.
tuner_class_name
,
args
.
tuner_args
)
else
:
tuner
=
create_customized_class_instance
(
args
.
tuner_directory
,
args
.
tuner_class_filename
,
args
.
tuner_class_name
,
args
.
tuner_args
)
if
tuner
is
None
:
raise
AssertionError
(
'Failed to create Tuner instance'
)
return
tuner
def
_create_assessor
(
args
):
if
args
.
assessor_class_name
in
ModuleName
:
assessor
=
create_builtin_class_instance
(
args
.
assessor_class_name
,
args
.
assessor_args
)
else
:
assessor
=
create_customized_class_instance
(
args
.
assessor_directory
,
args
.
assessor_class_filename
,
args
.
assessor_class_name
,
args
.
assessor_args
)
if
assessor
is
None
:
raise
AssertionError
(
'Failed to create Assessor instance'
)
return
assessor
if
__name__
==
'__main__'
:
if
__name__
==
'__main__'
:
try
:
try
:
main
()
main
()
...
...
src/sdk/pynni/nni/assessor.py
View file @
8c203f30
...
@@ -31,7 +31,6 @@ class AssessResult(Enum):
...
@@ -31,7 +31,6 @@ class AssessResult(Enum):
Bad
=
False
Bad
=
False
class
Assessor
(
Recoverable
):
class
Assessor
(
Recoverable
):
# pylint: disable=no-self-use,unused-argument
def
assess_trial
(
self
,
trial_job_id
,
trial_history
):
def
assess_trial
(
self
,
trial_job_id
,
trial_history
):
"""Determines whether a trial should be killed. Must override.
"""Determines whether a trial should be killed. Must override.
...
@@ -46,21 +45,20 @@ class Assessor(Recoverable):
...
@@ -46,21 +45,20 @@ class Assessor(Recoverable):
trial_job_id: identifier of the trial (str).
trial_job_id: identifier of the trial (str).
success: True if the trial successfully completed; False if failed or terminated.
success: True if the trial successfully completed; False if failed or terminated.
"""
"""
pass
def
load_checkpoint
(
self
):
def
load_checkpoint
(
self
):
"""Load the checkpoint of assessr.
"""Load the checkpoint of assessr.
path: checkpoint directory for assessor
path: checkpoint directory for assessor
"""
"""
checkpoin_path
=
self
.
get_checkpoint_path
()
checkpoin_path
=
self
.
get_checkpoint_path
()
_logger
.
info
(
'Load checkpoint ignored by assessor, checkpoint path: %s'
%
checkpoin_path
)
_logger
.
info
(
'Load checkpoint ignored by assessor, checkpoint path: %s'
,
checkpoin_path
)
def
save_checkpoint
(
self
):
def
save_checkpoint
(
self
):
"""Save the checkpoint of assessor.
"""Save the checkpoint of assessor.
path: checkpoint directory for assessor
path: checkpoint directory for assessor
"""
"""
checkpoin_path
=
self
.
get_checkpoint_path
()
checkpoin_path
=
self
.
get_checkpoint_path
()
_logger
.
info
(
'Save checkpoint ignored by assessor, checkpoint path: %s'
%
checkpoin_path
)
_logger
.
info
(
'Save checkpoint ignored by assessor, checkpoint path: %s'
,
checkpoin_path
)
def
_on_exit
(
self
):
def
_on_exit
(
self
):
pass
pass
...
...
src/sdk/pynni/nni/batch_tuner/batch_tuner.py
View file @
8c203f30
...
@@ -100,7 +100,7 @@ class BatchTuner(Tuner):
...
@@ -100,7 +100,7 @@ class BatchTuner(Tuner):
data:
data:
a list of dictionarys, each of which has at least two keys, 'parameter' and 'value'
a list of dictionarys, each of which has at least two keys, 'parameter' and 'value'
"""
"""
if
len
(
self
.
values
)
==
0
:
if
not
self
.
values
:
logger
.
info
(
"Search space has not been initialized, skip this data import"
)
logger
.
info
(
"Search space has not been initialized, skip this data import"
)
return
return
...
...
src/sdk/pynni/nni/bohb_advisor/bohb_advisor.py
View file @
8c203f30
...
@@ -51,7 +51,7 @@ def create_parameter_id():
...
@@ -51,7 +51,7 @@ def create_parameter_id():
int
int
parameter id
parameter id
"""
"""
global
_next_parameter_id
# pylint: disable=global-statement
global
_next_parameter_id
_next_parameter_id
+=
1
_next_parameter_id
+=
1
return
_next_parameter_id
-
1
return
_next_parameter_id
-
1
...
@@ -80,7 +80,7 @@ def create_bracket_parameter_id(brackets_id, brackets_curr_decay, increased_id=-
...
@@ -80,7 +80,7 @@ def create_bracket_parameter_id(brackets_id, brackets_curr_decay, increased_id=-
return
params_id
return
params_id
class
Bracket
(
object
)
:
class
Bracket
:
"""
"""
A bracket in BOHB, all the information of a bracket is managed by
A bracket in BOHB, all the information of a bracket is managed by
an instance of this class.
an instance of this class.
...
@@ -98,7 +98,7 @@ class Bracket(object):
...
@@ -98,7 +98,7 @@ class Bracket(object):
max_budget : float
max_budget : float
The largest budget to consider. Needs to be larger than min_budget!
The largest budget to consider. Needs to be larger than min_budget!
The budgets will be geometrically distributed
The budgets will be geometrically distributed
:math:`a^2 + b^2 = c^2 \sim \eta^k` for :math:`k\in [0, 1, ... , num\_subsets - 1]`.
:math:`a^2 + b^2 = c^2
\
\
sim
\
\
eta^k` for :math:`k
\
\
in [0, 1, ... , num
\
\
_subsets - 1]`.
optimize_mode: str
optimize_mode: str
optimize mode, 'maximize' or 'minimize'
optimize mode, 'maximize' or 'minimize'
"""
"""
...
@@ -169,7 +169,7 @@ class Bracket(object):
...
@@ -169,7 +169,7 @@ class Bracket(object):
If we have generated new trials after this trial end, we will return a new trial parameters.
If we have generated new trials after this trial end, we will return a new trial parameters.
Otherwise, we will return None.
Otherwise, we will return None.
"""
"""
global
_KEY
# pylint: disable=global-statement
global
_KEY
self
.
num_finished_configs
[
i
]
+=
1
self
.
num_finished_configs
[
i
]
+=
1
logger
.
debug
(
'bracket id: %d, round: %d %d, finished: %d, all: %d'
,
logger
.
debug
(
'bracket id: %d, round: %d %d, finished: %d, all: %d'
,
self
.
s
,
self
.
i
,
i
,
self
.
num_finished_configs
[
i
],
self
.
num_configs_to_run
[
i
])
self
.
s
,
self
.
i
,
i
,
self
.
num_finished_configs
[
i
],
self
.
num_configs_to_run
[
i
])
...
@@ -377,8 +377,10 @@ class BOHB(MsgDispatcherBase):
...
@@ -377,8 +377,10 @@ class BOHB(MsgDispatcherBase):
if
self
.
curr_s
<
0
:
if
self
.
curr_s
<
0
:
logger
.
info
(
"s < 0, Finish this round of Hyperband in BOHB. Generate new round"
)
logger
.
info
(
"s < 0, Finish this round of Hyperband in BOHB. Generate new round"
)
self
.
curr_s
=
self
.
s_max
self
.
curr_s
=
self
.
s_max
self
.
brackets
[
self
.
curr_s
]
=
Bracket
(
s
=
self
.
curr_s
,
s_max
=
self
.
s_max
,
eta
=
self
.
eta
,
self
.
brackets
[
self
.
curr_s
]
=
Bracket
(
max_budget
=
self
.
max_budget
,
optimize_mode
=
self
.
optimize_mode
)
s
=
self
.
curr_s
,
s_max
=
self
.
s_max
,
eta
=
self
.
eta
,
max_budget
=
self
.
max_budget
,
optimize_mode
=
self
.
optimize_mode
)
next_n
,
next_r
=
self
.
brackets
[
self
.
curr_s
].
get_n_r
()
next_n
,
next_r
=
self
.
brackets
[
self
.
curr_s
].
get_n_r
()
logger
.
debug
(
logger
.
debug
(
'new SuccessiveHalving iteration, next_n=%d, next_r=%d'
,
next_n
,
next_r
)
'new SuccessiveHalving iteration, next_n=%d, next_r=%d'
,
next_n
,
next_r
)
...
@@ -599,7 +601,7 @@ class BOHB(MsgDispatcherBase):
...
@@ -599,7 +601,7 @@ class BOHB(MsgDispatcherBase):
logger
.
debug
(
'bracket id = %s, metrics value = %s, type = %s'
,
s
,
value
,
data
[
'type'
])
logger
.
debug
(
'bracket id = %s, metrics value = %s, type = %s'
,
s
,
value
,
data
[
'type'
])
s
=
int
(
s
)
s
=
int
(
s
)
# add <trial_job_id, parameter_id> to self.job_id_para_id_map here,
# add <trial_job_id, parameter_id> to self.job_id_para_id_map here,
# because when the first parameter_id is created, trial_job_id is not known yet.
# because when the first parameter_id is created, trial_job_id is not known yet.
if
data
[
'trial_job_id'
]
in
self
.
job_id_para_id_map
:
if
data
[
'trial_job_id'
]
in
self
.
job_id_para_id_map
:
assert
self
.
job_id_para_id_map
[
data
[
'trial_job_id'
]]
==
data
[
'parameter_id'
]
assert
self
.
job_id_para_id_map
[
data
[
'trial_job_id'
]]
==
data
[
'parameter_id'
]
...
@@ -643,14 +645,14 @@ class BOHB(MsgDispatcherBase):
...
@@ -643,14 +645,14 @@ class BOHB(MsgDispatcherBase):
"""
"""
_completed_num
=
0
_completed_num
=
0
for
trial_info
in
data
:
for
trial_info
in
data
:
logger
.
info
(
"Importing data, current processing progress %s / %s"
%
(
_completed_num
,
len
(
data
))
)
logger
.
info
(
"Importing data, current processing progress %s / %s"
,
_completed_num
,
len
(
data
))
_completed_num
+=
1
_completed_num
+=
1
assert
"parameter"
in
trial_info
assert
"parameter"
in
trial_info
_params
=
trial_info
[
"parameter"
]
_params
=
trial_info
[
"parameter"
]
assert
"value"
in
trial_info
assert
"value"
in
trial_info
_value
=
trial_info
[
'value'
]
_value
=
trial_info
[
'value'
]
if
not
_value
:
if
not
_value
:
logger
.
info
(
"Useless trial data, value is %s, skip this trial data."
%
_value
)
logger
.
info
(
"Useless trial data, value is %s, skip this trial data."
,
_value
)
continue
continue
budget_exist_flag
=
False
budget_exist_flag
=
False
barely_params
=
dict
()
barely_params
=
dict
()
...
@@ -662,7 +664,7 @@ class BOHB(MsgDispatcherBase):
...
@@ -662,7 +664,7 @@ class BOHB(MsgDispatcherBase):
barely_params
[
keys
]
=
_params
[
keys
]
barely_params
[
keys
]
=
_params
[
keys
]
if
not
budget_exist_flag
:
if
not
budget_exist_flag
:
_budget
=
self
.
max_budget
_budget
=
self
.
max_budget
logger
.
info
(
"Set
\"
TRIAL_BUDGET
\"
value to %s (max budget)"
%
self
.
max_budget
)
logger
.
info
(
"Set
\"
TRIAL_BUDGET
\"
value to %s (max budget)"
,
self
.
max_budget
)
if
self
.
optimize_mode
is
OptimizeMode
.
Maximize
:
if
self
.
optimize_mode
is
OptimizeMode
.
Maximize
:
reward
=
-
_value
reward
=
-
_value
else
:
else
:
...
...
src/sdk/pynni/nni/bohb_advisor/config_generator.py
View file @
8c203f30
...
@@ -28,7 +28,6 @@
...
@@ -28,7 +28,6 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import
logging
import
logging
import
traceback
import
ConfigSpace
import
ConfigSpace
import
ConfigSpace.hyperparameters
import
ConfigSpace.hyperparameters
...
@@ -39,7 +38,7 @@ import statsmodels.api as sm
...
@@ -39,7 +38,7 @@ import statsmodels.api as sm
logger
=
logging
.
getLogger
(
'BOHB_Advisor'
)
logger
=
logging
.
getLogger
(
'BOHB_Advisor'
)
class
CG_BOHB
(
object
)
:
class
CG_BOHB
:
def
__init__
(
self
,
configspace
,
min_points_in_model
=
None
,
def
__init__
(
self
,
configspace
,
min_points_in_model
=
None
,
top_n_percent
=
15
,
num_samples
=
64
,
random_fraction
=
1
/
3
,
top_n_percent
=
15
,
num_samples
=
64
,
random_fraction
=
1
/
3
,
bandwidth_factor
=
3
,
min_bandwidth
=
1e-3
):
bandwidth_factor
=
3
,
min_bandwidth
=
1e-3
):
...
@@ -77,8 +76,8 @@ class CG_BOHB(object):
...
@@ -77,8 +76,8 @@ class CG_BOHB(object):
self
.
min_points_in_model
=
len
(
self
.
configspace
.
get_hyperparameters
())
+
1
self
.
min_points_in_model
=
len
(
self
.
configspace
.
get_hyperparameters
())
+
1
if
self
.
min_points_in_model
<
len
(
self
.
configspace
.
get_hyperparameters
())
+
1
:
if
self
.
min_points_in_model
<
len
(
self
.
configspace
.
get_hyperparameters
())
+
1
:
logger
.
warning
(
'Invalid min_points_in_model value. Setting it to %i'
%
(
len
(
self
.
configspace
.
get_hyperparameters
())
+
1
)
)
logger
.
warning
(
'Invalid min_points_in_model value. Setting it to %i'
,
len
(
self
.
configspace
.
get_hyperparameters
())
+
1
)
self
.
min_points_in_model
=
len
(
self
.
configspace
.
get_hyperparameters
())
+
1
self
.
min_points_in_model
=
len
(
self
.
configspace
.
get_hyperparameters
())
+
1
self
.
num_samples
=
num_samples
self
.
num_samples
=
num_samples
self
.
random_fraction
=
random_fraction
self
.
random_fraction
=
random_fraction
...
@@ -107,9 +106,9 @@ class CG_BOHB(object):
...
@@ -107,9 +106,9 @@ class CG_BOHB(object):
self
.
kde_models
=
dict
()
self
.
kde_models
=
dict
()
def
largest_budget_with_model
(
self
):
def
largest_budget_with_model
(
self
):
if
len
(
self
.
kde_models
)
==
0
:
if
not
self
.
kde_models
:
return
(
-
float
(
'inf'
)
)
return
-
float
(
'inf'
)
return
(
max
(
self
.
kde_models
.
keys
())
)
return
max
(
self
.
kde_models
.
keys
())
def
sample_from_largest_budget
(
self
,
info_dict
):
def
sample_from_largest_budget
(
self
,
info_dict
):
"""We opted for a single multidimensional KDE compared to the
"""We opted for a single multidimensional KDE compared to the
...
@@ -162,11 +161,11 @@ class CG_BOHB(object):
...
@@ -162,11 +161,11 @@ class CG_BOHB(object):
val
=
minimize_me
(
vector
)
val
=
minimize_me
(
vector
)
if
not
np
.
isfinite
(
val
):
if
not
np
.
isfinite
(
val
):
logger
.
warning
(
'sampled vector: %s has EI value %s'
%
(
vector
,
val
)
)
logger
.
warning
(
'sampled vector: %s has EI value %s'
,
vector
,
val
)
logger
.
warning
(
"data in the KDEs:
\n
%s
\n
%s"
%
(
kde_good
.
data
,
kde_bad
.
data
)
)
logger
.
warning
(
"data in the KDEs:
\n
%s
\n
%s"
,
kde_good
.
data
,
kde_bad
.
data
)
logger
.
warning
(
"bandwidth of the KDEs:
\n
%s
\n
%s"
%
(
kde_good
.
bw
,
kde_bad
.
bw
)
)
logger
.
warning
(
"bandwidth of the KDEs:
\n
%s
\n
%s"
,
kde_good
.
bw
,
kde_bad
.
bw
)
logger
.
warning
(
"l(x) = %s"
%
(
l
(
vector
))
)
logger
.
warning
(
"l(x) = %s"
,
l
(
vector
))
logger
.
warning
(
"g(x) = %s"
%
(
g
(
vector
))
)
logger
.
warning
(
"g(x) = %s"
,
g
(
vector
))
# right now, this happens because a KDE does not contain all values for a categorical parameter
# right now, this happens because a KDE does not contain all values for a categorical parameter
# this cannot be fixed with the statsmodels KDE, so for now, we are just going to evaluate this one
# this cannot be fixed with the statsmodels KDE, so for now, we are just going to evaluate this one
...
@@ -181,19 +180,15 @@ class CG_BOHB(object):
...
@@ -181,19 +180,15 @@ class CG_BOHB(object):
best_vector
=
vector
best_vector
=
vector
if
best_vector
is
None
:
if
best_vector
is
None
:
logger
.
debug
(
"Sampling based optimization with %i samples failed -> using random configuration"
%
self
.
num_samples
)
logger
.
debug
(
"Sampling based optimization with %i samples failed -> using random configuration"
,
self
.
num_samples
)
sample
=
self
.
configspace
.
sample_configuration
().
get_dictionary
()
sample
=
self
.
configspace
.
sample_configuration
().
get_dictionary
()
info_dict
[
'model_based_pick'
]
=
False
info_dict
[
'model_based_pick'
]
=
False
else
:
else
:
logger
.
debug
(
'best_vector: {}, {}, {}, {}'
.
format
(
best_vector
,
best
,
l
(
best_vector
),
g
(
best_vector
)))
logger
.
debug
(
'best_vector: %s, %s, %s, %s'
,
best_vector
,
best
,
l
(
best_vector
),
g
(
best_vector
))
for
i
,
hp_value
in
enumerate
(
best_vector
):
for
i
,
_
in
enumerate
(
best_vector
):
if
isinstance
(
hp
=
self
.
configspace
.
get_hyperparameter
(
self
.
configspace
.
get_hyperparameter_by_idx
(
i
))
self
.
configspace
.
get_hyperparameter
(
if
isinstance
(
hp
,
ConfigSpace
.
hyperparameters
.
CategoricalHyperparameter
):
self
.
configspace
.
get_hyperparameter_by_idx
(
i
)
),
ConfigSpace
.
hyperparameters
.
CategoricalHyperparameter
):
best_vector
[
i
]
=
int
(
np
.
rint
(
best_vector
[
i
]))
best_vector
[
i
]
=
int
(
np
.
rint
(
best_vector
[
i
]))
sample
=
ConfigSpace
.
Configuration
(
self
.
configspace
,
vector
=
best_vector
).
get_dictionary
()
sample
=
ConfigSpace
.
Configuration
(
self
.
configspace
,
vector
=
best_vector
).
get_dictionary
()
...
@@ -224,12 +219,12 @@ class CG_BOHB(object):
...
@@ -224,12 +219,12 @@ class CG_BOHB(object):
# If no model is available, sample from prior
# If no model is available, sample from prior
# also mix in a fraction of random configs
# also mix in a fraction of random configs
if
len
(
self
.
kde_models
.
keys
()
)
==
0
or
np
.
random
.
rand
()
<
self
.
random_fraction
:
if
not
self
.
kde_models
.
keys
()
or
np
.
random
.
rand
()
<
self
.
random_fraction
:
sample
=
self
.
configspace
.
sample_configuration
()
sample
=
self
.
configspace
.
sample_configuration
()
info_dict
[
'model_based_pick'
]
=
False
info_dict
[
'model_based_pick'
]
=
False
if
sample
is
None
:
if
sample
is
None
:
sample
,
info_dict
=
self
.
sample_from_largest_budget
(
info_dict
)
sample
,
info_dict
=
self
.
sample_from_largest_budget
(
info_dict
)
sample
=
ConfigSpace
.
util
.
deactivate_inactive_hyperparameters
(
sample
=
ConfigSpace
.
util
.
deactivate_inactive_hyperparameters
(
configuration_space
=
self
.
configspace
,
configuration_space
=
self
.
configspace
,
...
@@ -245,10 +240,10 @@ class CG_BOHB(object):
...
@@ -245,10 +240,10 @@ class CG_BOHB(object):
for
i
in
range
(
array
.
shape
[
0
]):
for
i
in
range
(
array
.
shape
[
0
]):
datum
=
np
.
copy
(
array
[
i
])
datum
=
np
.
copy
(
array
[
i
])
nan_indices
=
np
.
argwhere
(
np
.
isnan
(
datum
)).
flatten
()
nan_indices
=
np
.
argwhere
(
np
.
isnan
(
datum
)).
flatten
()
while
(
np
.
any
(
nan_indices
)
)
:
while
np
.
any
(
nan_indices
):
nan_idx
=
nan_indices
[
0
]
nan_idx
=
nan_indices
[
0
]
valid_indices
=
np
.
argwhere
(
np
.
isfinite
(
array
[:,
nan_idx
])).
flatten
()
valid_indices
=
np
.
argwhere
(
np
.
isfinite
(
array
[:,
nan_idx
])).
flatten
()
if
len
(
valid_indices
)
>
0
:
if
valid_indices
:
# pick one of them at random and overwrite all NaN values
# pick one of them at random and overwrite all NaN values
row_idx
=
np
.
random
.
choice
(
valid_indices
)
row_idx
=
np
.
random
.
choice
(
valid_indices
)
datum
[
nan_indices
]
=
array
[
row_idx
,
nan_indices
]
datum
[
nan_indices
]
=
array
[
row_idx
,
nan_indices
]
...
@@ -260,8 +255,8 @@ class CG_BOHB(object):
...
@@ -260,8 +255,8 @@ class CG_BOHB(object):
else
:
else
:
datum
[
nan_idx
]
=
np
.
random
.
randint
(
t
)
datum
[
nan_idx
]
=
np
.
random
.
randint
(
t
)
nan_indices
=
np
.
argwhere
(
np
.
isnan
(
datum
)).
flatten
()
nan_indices
=
np
.
argwhere
(
np
.
isnan
(
datum
)).
flatten
()
return_array
[
i
,:]
=
datum
return_array
[
i
,
:]
=
datum
return
(
return_array
)
return
return_array
def
new_result
(
self
,
loss
,
budget
,
parameters
,
update_model
=
True
):
def
new_result
(
self
,
loss
,
budget
,
parameters
,
update_model
=
True
):
"""
"""
...
@@ -305,7 +300,7 @@ class CG_BOHB(object):
...
@@ -305,7 +300,7 @@ class CG_BOHB(object):
# a) if not enough points are available
# a) if not enough points are available
if
len
(
self
.
configs
[
budget
])
<=
self
.
min_points_in_model
-
1
:
if
len
(
self
.
configs
[
budget
])
<=
self
.
min_points_in_model
-
1
:
logger
.
debug
(
"Only %i run(s) for budget %f available, need more than %s
\
logger
.
debug
(
"Only %i run(s) for budget %f available, need more than %s
\
-> can't build model!"
%
(
len
(
self
.
configs
[
budget
]),
budget
,
self
.
min_points_in_model
+
1
)
)
-> can't build model!"
,
len
(
self
.
configs
[
budget
]),
budget
,
self
.
min_points_in_model
+
1
)
return
return
# b) during warnm starting when we feed previous results in and only update once
# b) during warnm starting when we feed previous results in and only update once
if
not
update_model
:
if
not
update_model
:
...
@@ -345,5 +340,5 @@ class CG_BOHB(object):
...
@@ -345,5 +340,5 @@ class CG_BOHB(object):
}
}
# update probs for the categorical parameters for later sampling
# update probs for the categorical parameters for later sampling
logger
.
debug
(
'done building a new model for budget %f based on %i/%i split
\n
Best loss for this budget:%f
\n
'
logger
.
debug
(
'done building a new model for budget %f based on %i/%i split
\n
Best loss for this budget:%f
\n
'
,
%
(
budget
,
n_good
,
n_bad
,
np
.
min
(
train_losses
))
)
budget
,
n_good
,
n_bad
,
np
.
min
(
train_losses
))
Prev
1
2
3
4
5
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment