Unverified Commit 0e49e659 authored by Junwei Sun's avatar Junwei Sun Committed by GitHub
Browse files

Update Chinese Translation (#2871)



* New Crowdin translations by Github Action

* remove removed files in en_US
Co-authored-by: default avatarCrowdin Bot <support+bot@crowdin.com>
parent 171400ee
NNI Compressor 中的 SlimPruner
===
## 1. Slim Pruner
SlimPruner 是一种结构化的修剪算法,通过修剪卷积层后对应的 BN 层相应的缩放因子来修剪通道。
['Learning Efficient Convolutional Networks through Network Slimming'](https://arxiv.org/pdf/1708.06519.pdf) 中提出,作者 Zhuang Liu, Jianguo Li, Zhiqiang Shen, Gao Huang, Shoumeng Yan 以及 Changshui Zhang。
![](../../img/slim_pruner.png)
> Slim Pruner **会遮盖卷据层通道之后 BN 层对应的缩放因子**,训练时在缩放因子上的 L1 正规化应在批量正规化 (BN) 层之后来做。BN 层的缩放因子在修剪时,是**全局排序的**,因此稀疏模型能自动找到给定的稀疏度。
## 2. 用法
PyTorch 代码
```
from nni.compression.torch import SlimPruner
config_list = [{ 'sparsity': 0.8, 'op_types': ['BatchNorm2d'] }]
pruner = SlimPruner(model, config_list)
pruner.compress()
```
#### Filter Pruner 的用户配置
- **sparsity:**,指定压缩的稀疏度。
- **op_types:** 在 Slim Pruner 中仅支持 BatchNorm2d。
## 3. 实验
我们实现了 ['Learning Efficient Convolutional Networks through Network Slimming'](https://arxiv.org/pdf/1708.06519.pdf) 中的一项实验。根据论文,对 CIFAR-10 上的 **VGGNet** 剪除了 $70\%$ 的通道,即约 $88.5\%$ 的参数。 我们的实验结果如下:
| 模型 | 错误率(论文/我们的) | 参数量 | 剪除率 |
| ------------- | ----------- | ------ | ----- |
| VGGNet | 6.34/6.40 | 20.04M | |
| Pruned-VGGNet | 6.20/6.26 | 2.03M | 88.5% |
实验代码在 [examples/model_compress](https://github.com/microsoft/nni/tree/master/examples/model_compress/)
NN I 上的 L1FilterPruner
===
## 介绍
L1FilterPruner 是在卷积层中用来修剪过滤器的通用剪枝算法。
['PRUNING FILTERS FOR EFFICIENT CONVNETS'](https://arxiv.org/abs/1608.08710) 中提出,作者 Hao Li, Asim Kadav, Igor Durdanovic, Hanan Samet 以及 Hans Peter Graf。
![](../../img/l1filter_pruner.png)
> L1Filter Pruner 修剪**卷积层**中的过滤器
>
> 从第 i 个卷积层修剪 m 个过滤器的过程如下:
>
> 1. 对于每个过滤器 ![](http://latex.codecogs.com/gif.latex?F_{i,j}),计算其绝对内核权重之和![](http://latex.codecogs.com/gif.latex?s_j=\sum_{l=1}^{n_i}\sum|K_l|)
> 2. 将过滤器按 ![](http://latex.codecogs.com/gif.latex?s_j) 排序。
> 3. 修剪 ![](http://latex.codecogs.com/gif.latex?m) 具有最小求和值及其相应特征图的筛选器。 在 下一个卷积层中,被剪除的特征图所对应的内核也被移除。
> 4. 为第 ![](http://latex.codecogs.com/gif.latex?i) 和 ![](http://latex.codecogs.com/gif.latex?i+1) 层创建新的内核举证,并保留剩余的内核 权重,并复制到新模型中。
## 实验
我们通过 **L1FilterPruner** 实现了 ['PRUNING FILTERS FOR EFFICIENT CONVNETS'](https://arxiv.org/abs/1608.08710) 中的一项实验, 即论文中,在 CIFAR-10 数据集上修剪 **VGG-16****VGG-16-pruned-A**,其中大约剪除了 $64\%$ 的参数。 我们的实验结果如下:
| 模型 | 错误率(论文/我们的) | 参数量 | 剪除率 |
| --------------- | ----------- | -------- | ----- |
| VGG-16 | 6.75/6.49 | 1.5x10^7 | |
| VGG-16-pruned-A | 6.60/6.47 | 5.4x10^6 | 64.0% |
实验代码在 [examples/model_compress](https://github.com/microsoft/nni/tree/master/examples/model_compress/)
## GradientFeatureSelector ## GradientFeatureSelector
GradinetFeatureSelector 的算法来源于 ["Feature Gradients: Scalable Feature Selection via Discrete Relaxation"](https://arxiv.org/pdf/1908.10382.pdf) GradientFeatureSelector 的算法来源于 ["Feature Gradients: Scalable Feature Selection via Discrete Relaxation"](https://arxiv.org/pdf/1908.10382.pdf)
GradientFeatureSelector,基于梯度搜索算法的特征选择。 GradientFeatureSelector,基于梯度搜索算法的特征选择。
......
# NAS 基准测试(测试版) # NAS 基准测试
```eval_rst ```eval_rst
.. toctree:: .. toctree::
...@@ -7,40 +7,28 @@ ...@@ -7,40 +7,28 @@
用法示例 <BenchmarksExample> 用法示例 <BenchmarksExample>
``` ```
## 先决条件 ## 介绍
* 准备目录来保存基准测试的数据库。 默认情况下,目录为 `${HOME}/.nni/nasbenchmark`。 可将其设置为任何位置,并在 import nni 前,通过 `NASBENCHMARK_DIR` 指定。
* 通过 `pip install peewee` 命令安装 `peewee`,NNI 用其连接数据库。
## 准备数据
为了避免存储和法规问题,NNI 不提供数据库。 强烈建议通过 Docker 来运行生成的脚本,减少安装依赖项的时间。 步骤: 为了提高 NAS 算法的可复现性并降低对计算资源的需求,研究者们提出了一系列 NAS 基准测试如[NAS-Bench-101](https://arxiv.org/abs/1902.09635), [NAS-Bench-201](https://arxiv.org/abs/2001.00326), [NDS](https://arxiv.org/abs/1905.13214)等等。 NNI 为用户提供了查询接口来获取这些基准测试。 只需要几行代码,研究者就可以通过使用这些基准测试容易且公平地评估他们的 NAS 算法。
**步骤 1.** 克隆 NNI 存储库。 将 `${NNI_VERSION}` 替换为发布的版本或分支名称,例如:`v1.6` ## 先决条件
```bash * 准备目录来保存基准测试的数据库。 默认情况下,目录为 `${HOME}/.nni/nasbenchmark`。 可以将其放在任意位置, 并在导入 NNI 之前指定 `NASBENCHMARK_DIR` 通过 `export NASBENCHMARK_DIR=/path/to/your/nasbenchmark`.
git clone -b ${NNI_VERSION} https://github.com/microsoft/nni * 通过 `pip3 install peewee` 命令安装 `peewee`,NNI 用其连接数据库。
```
**步骤 2.** 运行 Docker。 ## 准备数据
对于 NAS-Bench-101, 为了避免存储和法规问题,NNI 不提供数据库。 步骤:
```bash 1. 将 NNI 克隆到机器上并进入 `examples/nas/benchmarks` 目录。
docker run -v ${HOME}/.nni/nasbenchmark:/outputs -v /path/to/your/nni:/nni tensorflow/tensorflow:1.15.2-py3 /bin/bash /nni/examples/nas/benchmarks/nasbench101.sh
``` ```
git clone -b ${NNI_VERSION} https://github.com/microsoft/nni
对于 NAS-Bench-201, cd nni/examples/nas/benchmarks
```bash
docker run -v ${HOME}/.nni/nasbenchmark:/outputs -v /path/to/your/nni:/nni ufoym/deepo:pytorch-cpu /bin/bash /nni/examples/nas/benchmarks/nasbench201.sh
``` ```
`${NNI_VERSION}` 替换为发布的版本或分支名称,例如:`v1.8`
对于 NDS, 2. 通过 `pip3 install -r xxx.requirements.txt` 安装依赖。 `xxx` 可以为 `nasbench101`, `nasbench201``nds`.
3. 通过 `./xxx.sh`生成数据库。 存储数据库的目录可以通过环境变量 `NASBENCHMARK_DIR` 设置,默认为 `~/.nni/nasbenchmark`。 注意 NAS-Bench-201 数据库将从 google drive 被下载。
```bash
docker run -v ${HOME}/.nni/nasbenchmark:/outputs -v /path/to/your/nni:/nni python:3.7 /bin/bash /nni/examples/nas/benchmarks/nds.sh
```
确保至少有 10GB 的可用磁盘空间,运行过程可能需要几个小时。 确保至少有 10GB 的可用磁盘空间,运行过程可能需要几个小时。
......
{ {
"nbformat": 4,
"nbformat_minor": 2,
"metadata": {
"language_info": {
"name": "python",
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"version": "3.6.10-final"
},
"orig_nbformat": 2,
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"npconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": 3,
"kernelspec": {
"name": "python361064bitnnilatestcondabff8d66a619a4d26af34fe0fe687c7b0",
"display_name": "Python 3.6.10 64-bit ('nnilatest': conda)"
}
},
"cells": [ "cells": [
{ {
"cell_type": "markdown", "cell_type": "markdown",
...@@ -53,15 +30,26 @@ ...@@ -53,15 +30,26 @@
"## NAS-Bench-101" "## NAS-Bench-101"
] ]
}, },
{
"cell_type": "markdown",
"metadata": {},
"source": [
"使用以下网络结构作为示例:\n",
"\n",
"![nas-101](../../img/nas-bench-101-example.png)"
]
},
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 2, "execution_count": 2,
"metadata": {}, "metadata": {
"tags": []
},
"outputs": [ "outputs": [
{ {
"output_type": "stream", "output_type": "stream",
"name": "stdout", "name": "stdout",
"text": "{'config': {'arch': {'input1': [0],\n 'input2': [1],\n 'input3': [2],\n 'input4': [0],\n 'input5': [0, 3, 4],\n 'input6': [2, 5],\n 'op1': 'conv3x3-bn-relu',\n 'op2': 'maxpool3x3',\n 'op3': 'conv3x3-bn-relu',\n 'op4': 'conv3x3-bn-relu',\n 'op5': 'conv1x1-bn-relu'},\n 'hash': '00005c142e6f48ac74fdcf73e3439874',\n 'id': 4,\n 'num_epochs': 108,\n 'num_vertices': 7},\n 'id': 10,\n 'parameters': 8.55553,\n 'test_acc': 92.11738705635071,\n 'train_acc': 100.0,\n 'training_time': 106147.67578125,\n 'valid_acc': 92.41786599159241}\n{'config': {'arch': {'input1': [0],\n 'input2': [1],\n 'input3': [2],\n 'input4': [0],\n 'input5': [0, 3, 4],\n 'input6': [2, 5],\n 'op1': 'conv3x3-bn-relu',\n 'op2': 'maxpool3x3',\n 'op3': 'conv3x3-bn-relu',\n 'op4': 'conv3x3-bn-relu',\n 'op5': 'conv1x1-bn-relu'},\n 'hash': '00005c142e6f48ac74fdcf73e3439874',\n 'id': 4,\n 'num_epochs': 108,\n 'num_vertices': 7},\n 'id': 11,\n 'parameters': 8.55553,\n 'test_acc': 91.90705418586731,\n 'train_acc': 100.0,\n 'training_time': 106095.05859375,\n 'valid_acc': 92.45793223381042}\n{'config': {'arch': {'input1': [0],\n 'input2': [1],\n 'input3': [2],\n 'input4': [0],\n 'input5': [0, 3, 4],\n 'input6': [2, 5],\n 'op1': 'conv3x3-bn-relu',\n 'op2': 'maxpool3x3',\n 'op3': 'conv3x3-bn-relu',\n 'op4': 'conv3x3-bn-relu',\n 'op5': 'conv1x1-bn-relu'},\n 'hash': '00005c142e6f48ac74fdcf73e3439874',\n 'id': 4,\n 'num_epochs': 108,\n 'num_vertices': 7},\n 'id': 12,\n 'parameters': 8.55553,\n 'test_acc': 92.15745329856873,\n 'train_acc': 100.0,\n 'training_time': 106138.55712890625,\n 'valid_acc': 93.04887652397156}\n" "text": "{'config': {'arch': {'input1': [0],\n 'input2': [1],\n 'input3': [2],\n 'input4': [0],\n 'input5': [0, 3, 4],\n 'input6': [2, 5],\n 'op1': 'conv3x3-bn-relu',\n 'op2': 'maxpool3x3',\n 'op3': 'conv3x3-bn-relu',\n 'op4': 'conv3x3-bn-relu',\n 'op5': 'conv1x1-bn-relu'},\n 'hash': '00005c142e6f48ac74fdcf73e3439874',\n 'id': 4,\n 'num_epochs': 108,\n 'num_vertices': 7},\n 'id': 10,\n 'intermediates': [{'current_epoch': 54,\n 'id': 19,\n 'test_acc': 77.40384340286255,\n 'train_acc': 82.82251358032227,\n 'training_time': 883.4580078125,\n 'valid_acc': 77.76442170143127},\n {'current_epoch': 108,\n 'id': 20,\n 'test_acc': 92.11738705635071,\n 'train_acc': 100.0,\n 'training_time': 1769.1279296875,\n 'valid_acc': 92.41786599159241}],\n 'parameters': 8.55553,\n 'test_acc': 92.11738705635071,\n 'train_acc': 100.0,\n 'training_time': 106147.67578125,\n 'valid_acc': 92.41786599159241}\n{'config': {'arch': {'input1': [0],\n 'input2': [1],\n 'input3': [2],\n 'input4': [0],\n 'input5': [0, 3, 4],\n 'input6': [2, 5],\n 'op1': 'conv3x3-bn-relu',\n 'op2': 'maxpool3x3',\n 'op3': 'conv3x3-bn-relu',\n 'op4': 'conv3x3-bn-relu',\n 'op5': 'conv1x1-bn-relu'},\n 'hash': '00005c142e6f48ac74fdcf73e3439874',\n 'id': 4,\n 'num_epochs': 108,\n 'num_vertices': 7},\n 'id': 11,\n 'intermediates': [{'current_epoch': 54,\n 'id': 21,\n 'test_acc': 82.04126358032227,\n 'train_acc': 87.96073794364929,\n 'training_time': 883.6810302734375,\n 'valid_acc': 82.91265964508057},\n {'current_epoch': 108,\n 'id': 22,\n 'test_acc': 91.90705418586731,\n 'train_acc': 100.0,\n 'training_time': 1768.2509765625,\n 'valid_acc': 92.45793223381042}],\n 'parameters': 8.55553,\n 'test_acc': 91.90705418586731,\n 'train_acc': 100.0,\n 'training_time': 106095.05859375,\n 'valid_acc': 92.45793223381042}\n{'config': {'arch': {'input1': [0],\n 'input2': [1],\n 'input3': [2],\n 'input4': [0],\n 'input5': [0, 3, 4],\n 'input6': [2, 5],\n 'op1': 'conv3x3-bn-relu',\n 'op2': 'maxpool3x3',\n 'op3': 'conv3x3-bn-relu',\n 'op4': 'conv3x3-bn-relu',\n 'op5': 'conv1x1-bn-relu'},\n 'hash': '00005c142e6f48ac74fdcf73e3439874',\n 'id': 4,\n 'num_epochs': 108,\n 'num_vertices': 7},\n 'id': 12,\n 'intermediates': [{'current_epoch': 54,\n 'id': 23,\n 'test_acc': 80.58894276618958,\n 'train_acc': 86.34815812110901,\n 'training_time': 883.4569702148438,\n 'valid_acc': 81.1598539352417},\n {'current_epoch': 108,\n 'id': 24,\n 'test_acc': 92.15745329856873,\n 'train_acc': 100.0,\n 'training_time': 1768.9759521484375,\n 'valid_acc': 93.04887652397156}],\n 'parameters': 8.55553,\n 'test_acc': 92.15745329856873,\n 'train_acc': 100.0,\n 'training_time': 106138.55712890625,\n 'valid_acc': 93.04887652397156}\n"
} }
], ],
"source": [ "source": [
...@@ -78,10 +66,17 @@ ...@@ -78,10 +66,17 @@
" 'input5': [0, 3, 4],\n", " 'input5': [0, 3, 4],\n",
" 'input6': [2, 5]\n", " 'input6': [2, 5]\n",
"}\n", "}\n",
"for t in query_nb101_trial_stats(arch, 108):\n", "for t in query_nb101_trial_stats(arch, 108, include_intermediates=True):\n",
" pprint.pprint(t)" " pprint.pprint(t)"
] ]
}, },
{
"cell_type": "markdown",
"metadata": {},
"source": [
"一个 NAS-Bench-101 的网络结构可以被训练多次。 生成器返回的每一个元素是一个字典,包含了该 Trial 设置(网络结构+超参数)中其中一个训练结果,如训练集/验证集/测试集准确率,训练时间,Epoch数等等。 NAS-Bench-201 和 NDS 的结果遵循了相似的格式。"
]
},
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
...@@ -89,10 +84,21 @@ ...@@ -89,10 +84,21 @@
"## NAS-Bench-201" "## NAS-Bench-201"
] ]
}, },
{
"cell_type": "markdown",
"metadata": {},
"source": [
"使用以下网络结构作为示例:\n",
"\n",
"![nas-201](../../img/nas-bench-201-example.png)"
]
},
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 3, "execution_count": 3,
"metadata": {}, "metadata": {
"tags": []
},
"outputs": [ "outputs": [
{ {
"output_type": "stream", "output_type": "stream",
...@@ -117,13 +123,51 @@ ...@@ -117,13 +123,51 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"## NDS" "中间结果也可得到。"
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 4, "execution_count": 4,
"metadata": {
"tags": []
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": "{'id': 4, 'arch': {'0_1': 'avg_pool_3x3', '0_2': 'conv_1x1', '0_3': 'conv_1x1', '1_2': 'skip_connect', '1_3': 'skip_connect', '2_3': 'skip_connect'}, 'num_epochs': 12, 'num_channels': 16, 'num_cells': 5, 'dataset': 'imagenet16-120'}\nIntermediates: 12\n{'id': 8, 'arch': {'0_1': 'avg_pool_3x3', '0_2': 'conv_1x1', '0_3': 'conv_1x1', '1_2': 'skip_connect', '1_3': 'skip_connect', '2_3': 'skip_connect'}, 'num_epochs': 200, 'num_channels': 16, 'num_cells': 5, 'dataset': 'imagenet16-120'}\nIntermediates: 200\n{'id': 8, 'arch': {'0_1': 'avg_pool_3x3', '0_2': 'conv_1x1', '0_3': 'conv_1x1', '1_2': 'skip_connect', '1_3': 'skip_connect', '2_3': 'skip_connect'}, 'num_epochs': 200, 'num_channels': 16, 'num_cells': 5, 'dataset': 'imagenet16-120'}\nIntermediates: 200\n{'id': 8, 'arch': {'0_1': 'avg_pool_3x3', '0_2': 'conv_1x1', '0_3': 'conv_1x1', '1_2': 'skip_connect', '1_3': 'skip_connect', '2_3': 'skip_connect'}, 'num_epochs': 200, 'num_channels': 16, 'num_cells': 5, 'dataset': 'imagenet16-120'}\nIntermediates: 200\n"
}
],
"source": [
"for t in query_nb201_trial_stats(arch, None, 'imagenet16-120', include_intermediates=True):\n",
" print(t['config'])\n",
" print('Intermediates:', len(t['intermediates']))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## NDS"
]
},
{
"cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [
"使用以下网络结构作为示例:<br>\n",
"![nds](../../img/nas-bench-nds-example.png)\n",
"\n",
"这里, `bot_muls`, `ds`, `num_gs`, `ss` 和 `ws` 分别代表 \"bottleneck multipliers\", \"depths\", \"number of groups\", \"strides\" and \"widths\"。"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"tags": []
},
"outputs": [ "outputs": [
{ {
"output_type": "stream", "output_type": "stream",
...@@ -146,8 +190,35 @@ ...@@ -146,8 +190,35 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 5, "execution_count": 6,
"metadata": {}, "metadata": {
"tags": []
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": "[{'current_epoch': 1,\n 'id': 4494501,\n 'test_acc': 41.76,\n 'train_acc': 30.421000000000006,\n 'train_loss': 1.793},\n {'current_epoch': 2,\n 'id': 4494502,\n 'test_acc': 54.66,\n 'train_acc': 47.24,\n 'train_loss': 1.415},\n {'current_epoch': 3,\n 'id': 4494503,\n 'test_acc': 59.97,\n 'train_acc': 56.983,\n 'train_loss': 1.179},\n {'current_epoch': 4,\n 'id': 4494504,\n 'test_acc': 62.91,\n 'train_acc': 61.955,\n 'train_loss': 1.048},\n {'current_epoch': 5,\n 'id': 4494505,\n 'test_acc': 66.16,\n 'train_acc': 64.493,\n 'train_loss': 0.983},\n {'current_epoch': 6,\n 'id': 4494506,\n 'test_acc': 66.5,\n 'train_acc': 66.274,\n 'train_loss': 0.937},\n {'current_epoch': 7,\n 'id': 4494507,\n 'test_acc': 67.55,\n 'train_acc': 67.426,\n 'train_loss': 0.907},\n {'current_epoch': 8,\n 'id': 4494508,\n 'test_acc': 69.45,\n 'train_acc': 68.45400000000001,\n 'train_loss': 0.878},\n {'current_epoch': 9,\n 'id': 4494509,\n 'test_acc': 70.14,\n 'train_acc': 69.295,\n 'train_loss': 0.857},\n {'current_epoch': 10,\n 'id': 4494510,\n 'test_acc': 69.47,\n 'train_acc': 70.304,\n 'train_loss': 0.832}]\n"
}
],
"source": [
"model_spec = {\n",
" 'bot_muls': [0.0, 0.25, 0.25, 0.25],\n",
" 'ds': [1, 16, 1, 4],\n",
" 'num_gs': [1, 2, 1, 2],\n",
" 'ss': [1, 1, 2, 2],\n",
" 'ws': [16, 64, 128, 16]\n",
"}\n",
"for t in query_nds_trial_stats('residual_bottleneck', None, None, model_spec, None, 'cifar10', include_intermediates=True):\n",
" pprint.pprint(t['intermediates'][:10])"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"tags": []
},
"outputs": [ "outputs": [
{ {
"output_type": "stream", "output_type": "stream",
...@@ -163,8 +234,10 @@ ...@@ -163,8 +234,10 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 6, "execution_count": 8,
"metadata": {}, "metadata": {
"tags": []
},
"outputs": [ "outputs": [
{ {
"output_type": "stream", "output_type": "stream",
...@@ -179,8 +252,10 @@ ...@@ -179,8 +252,10 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 7, "execution_count": 9,
"metadata": {}, "metadata": {
"tags": []
},
"outputs": [ "outputs": [
{ {
"output_type": "stream", "output_type": "stream",
...@@ -244,8 +319,10 @@ ...@@ -244,8 +319,10 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 8, "execution_count": 10,
"metadata": {}, "metadata": {
"tags": []
},
"outputs": [ "outputs": [
{ {
"output_type": "stream", "output_type": "stream",
...@@ -260,18 +337,43 @@ ...@@ -260,18 +337,43 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 9, "execution_count": 11,
"metadata": {}, "metadata": {
"tags": []
},
"outputs": [ "outputs": [
{ {
"output_type": "stream", "output_type": "stream",
"name": "stdout", "name": "stdout",
"text": "Elapsed time: 1.9107539653778076 seconds\n" "text": "Elapsed time: 2.2023813724517822 seconds\n"
} }
], ],
"source": [ "source": [
"print('Elapsed time: ', time.time() - ti, 'seconds')" "print('Elapsed time: ', time.time() - ti, 'seconds')"
] ]
} }
] ],
"metadata": {
"language_info": {
"name": "python",
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"version": "3.6.10-final"
},
"orig_nbformat": 2,
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"npconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": 3,
"kernelspec": {
"name": "python361064bitnnilatestcondabff8d66a619a4d26af34fe0fe687c7b0",
"display_name": "Python 3.6.10 64-bit ('nnilatest': conda)"
}
},
"nbformat": 4,
"nbformat_minor": 2
} }
\ No newline at end of file
...@@ -54,6 +54,17 @@ One-shot 算法**不需要 nnictl,可单独运行**。 NNI 支持 PyTorch 和 ...@@ -54,6 +54,17 @@ One-shot 算法**不需要 nnictl,可单独运行**。 NNI 支持 PyTorch 和
One-Shot NAS 可以通过可视化工具来查看。 点击[这里](./Visualization.md),了解详情。 One-Shot NAS 可以通过可视化工具来查看。 点击[这里](./Visualization.md),了解详情。
## 搜索空间集合
NNI 提供了一些预定义的、可被重用的搜索空间。 通过堆叠这些抽取出的单元,用户可以快速复现 NAS 模型。
搜索空间集合包含了以下 NAS 单元:
* [DartsCell](./SearchSpaceZoo.md#DartsCell)
* [ENAS micro](./SearchSpaceZoo.md#ENASMicroLayer)
* [ENAS macro](./SearchSpaceZoo.md#ENASMacroLayer)
## 使用 NNI API 来编写搜索空间 ## 使用 NNI API 来编写搜索空间
在两种场景下需要用于设计和搜索模型的编程接口。 在两种场景下需要用于设计和搜索模型的编程接口。
......
# NAS 快速入门
NNI 提供的 NAS 功能有两个关键组件:用于表示搜索空间的 API 和 NAS 的训练方法。 前者为用户提供了表示性能好的模块的方法(即,通过搜索空间指定的候选模型)。 后者能让用户可以轻松的在自己的模型上使用最新的 NAS 训练方法。
这里,通过简单的示例,来一步步演示如何使用 NNI NAS API 调优自己的模型架构。 示例的完整代码可在[这里](https://github.com/microsoft/nni/tree/master/examples/nas/naive)找到。
## 使用 NAS API 编写模型
可通过两个 NAS API `LayerChoice``InputChoice` 来定义神经网络模型,而不需要编写具体的模型。 例如,如果认为在第一卷积层有两种操作可能会有效,可通过 `LayerChoice` 来为代码中的 `self.conv1` 赋值。 同样,第二个卷积层 `self.conv2` 也可以从中选择一个。 此处,指定了 4 个候选的神经网络。 `self.skipconnect` 使用 `InputChoice` 来指定两个选项,即是否添加跳跃的连接。
```python
import torch.nn as nn
from nni.nas.pytorch.mutables import LayerChoice, InputChoice
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv1 = LayerChoice([nn.Conv2d(3, 6, 3, padding=1), nn.Conv2d(3, 6, 5, padding=2)])
self.pool = nn.MaxPool2d(2, 2)
self.conv2 = LayerChoice([nn.Conv2d(6, 16, 3, padding=1), nn.Conv2d(6, 16, 5, padding=2)])
self.conv3 = nn.Conv2d(16, 16, 1)
self.skipconnect = InputChoice(n_candidates=1)
self.bn = nn.BatchNorm2d(16)
self.gap = nn.AdaptiveAvgPool2d(4)
self.fc1 = nn.Linear(16 * 4 * 4, 120)
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10)
```
有关 `LayerChoice``InputChoice` 的详细描述可参考[ NAS 指南](NasGuide.md)
## 选择 NAS Trainer
实例化模型后,需要通过 NAS Trainer 来训练模型。 不同的 Trainer 会使用不同的方法来从指定的神经网络模块中搜索出最好的。 NNI 提供了几种流行的 NAS 训练方法,如 DARTS,ENAS。 以下以 `DartsTrainer` 为例。 在 Trainer 实例化后,调用`trainer.train()` 开始搜索。
```python
trainer = DartsTrainer(net,
loss=criterion,
metrics=accuracy,
optimizer=optimizer,
num_epochs=2,
dataset_train=dataset_train,
dataset_valid=dataset_valid,
batch_size=64,
log_frequency=10)
trainer.train()
```
## 导出最佳模型
搜索(即`trainer.train()`)完成后,需要拿到最好的模型,只需要调用 `trainer.export("final_arch.json")` 来将找到的神经网络架构导出到文件。
## NAS 可视化
正在研究 NAS 的可视化,并将很快发布此功能。
## 重新训练导出的最佳模型
重新训练找到(导出)的网络架构非常容易。 第一步,实例化上面定义的模型。 第二步,在模型上调用 `apply_fixed_architecture`。 然后,此模型会作为找到的(导出的)模型。 之后,可以使用传统方法来训练此模型。
```python
model = Net()
apply_fixed_architecture(model, "final_arch.json")
```
...@@ -74,7 +74,7 @@ nnictl ss_gen -t "python tester.py" ...@@ -74,7 +74,7 @@ nnictl ss_gen -t "python tester.py"
nnictl create --config config_search.yml nnictl create --config config_search.yml
``` ```
从每个 Epoch 导出的最终架构可在 Tuner 工作目录下的 `checkpoints` 中找到,默认值为 `$HOME/nni/experiments/your_experiment_id/log` 从每个 Epoch 导出的最终架构可在 Tuner 工作目录下的 `checkpoints` 中找到,默认值为 `$HOME/nni-experiments/your_experiment_id/log`
### 步骤 3. 从头开始训练 ### 步骤 3. 从头开始训练
......
# 搜索空间集合
## DartsCell
DartsCell 是从[这里](https://github.com/microsoft/nni/tree/master/examples/nas/darts)[CNN 模型](./DARTS.md)中提取出来的。 一个 DartsCell 是一个包含 N 个节点的序列的有向无环图 ,其中每个节点代表一个潜在特征的表示(例如卷积网络中的特征图)。 从节点1到节点2的有向边表示一些将节点1转换为节点2的操作。这些操作获取节点1的值并将转换的结果储存在节点2上。 节点之间的[操作](#darts-predefined-operations)是预定义的且不可更改。 一条边表示从预定义的操作中选择的一项,并将该操作将应用于边的起始节点。 一个 cell 包括两个输入节点,一个输出节点和其他 `n_node` 个节点。 输入节点定义为前两个 cell 的输出。 Cell 的输出是通过对所有中间节点进行归约运算(例如连接)而获得的。 为了使搜索空间连续,在所有可能的操作上通过softmax对特定操作选择进行松弛。 通过调整每个节点上softmax的权重,选择概率最高的操作作为最终结构的一部分。 可以通过堆叠多个cell组成一个CNN模型,从而构建一个搜索空间。 值得注意的是,在DARTS论文中,模型中的所有cell都具有相同的结构。
Darts的搜索空间如下图所示。 请注意,在NNI的实现中将最后一个中间节点与输出节点进行了合并。
![](../../img/NAS_Darts_cell.svg)
预定义的操作在[参考](#predefined-operations-darts)中列出。
```eval_rst
.. autoclass:: nni.nas.pytorch.search_space_zoo.DartsCell
:members:
```
### 示例代码
[示例代码](https://github.com/microsoft/nni/tree/master/examples/nas/search_space_zoo/darts_example.py)
```bash
git clone https://github.com/Microsoft/nni.git
cd nni/examples/nas/search_space_zoo
# search the best structure
python3 darts_example.py
```
<a name="predefined-operations-darts"></a>
### 参考
所有Darts支持的操作如下。
* 最大池化 / 平均池化
* 最大池化:调用`torch.nn.MaxPool2d`。 这个操作对所有输入的通道进行最大池化。 操作的参数固定,`kernel_size=3``padding=1`。 在池化操作后通过BatchNorm2d得到最终结果。
* 平均池化:调用`torch.nn.AvgPool2d`。 这个操作对所有输入的通道进行平均池化。 操作的参数固定,`kernel_size=3``padding=1`。 在池化操作后通过BatchNorm2d得到最终结果。
参数为`kernel_size=3`和`padding=1` 的最大池化操作和平均池化操作后均有BatchNorm2d操作。
```eval_rst
.. autoclass:: nni.nas.pytorch.search_space_zoo.darts_ops.PoolBN
```
* 跳过连接
两个节点之间没有任何操作。 调用` torch.nn.Identity `将其获取的内容转发到输出。
* 零操作
两个节点之间没有连接。
* DilConv3x3 / DilConv5x5
<a name="DilConv"></a>深度可分离卷积。 3x3深度可分离卷积是由 `C_in` 组的3x3深度卷积和1x1的卷积串联组成。 这个操作减少了参数的数量。 输入首先通过RelLU,然后通过DilConv,最后是batchNorm2d。 **请注意这个操作不是扩散卷积,但是我们按照NAS论文中的约定命名为DilConv。**3x3深度可分离卷积的参数是 `kernel_size=3`, `padding=1` 。5x5深度可分离卷积的参数是 `kernel_size=5`, `padding=4`。
```eval_rst
.. autoclass:: nni.nas.pytorch.search_space_zoo.darts_ops.DilConv
```
* SepConv3x3 / SepConv5x5
由两个参数为`kernel_size=3`, `padding=1`或`kernel_size=5`, `padding=2` 的深度可分离卷积串联组成。
```eval_rst
.. autoclass:: nni.nas.pytorch.search_space_zoo.darts_ops.SepConv
```
## ENASMicroLayer
这个层是由[这里](https://github.com/microsoft/nni/tree/master/examples/nas/enas)的模型提取出来的。 一个模型包含共享结构的多个块。 一个块由一些常规层和约简层组成,`ENASMicroLayer`是这两型层的统一实现。 这两类层之间的唯一区别是约简层的所有操作`stride=2`
ENAS Micro的一个cell是含有N个节点的有向无环图。其中节点表示张量,边表示N个节点间的信息流。 一个cell包含两个输入节点和一个输出节点。 接下来节点选择前两个之前的节点作为输入,并从[预定义的的操作集](#predefined-operations-enas)中选择两个操作,分别应用到输入上,然后将它们相加为该节点的输出。 例如,节点4选择节点1和节点3作为输入,然后分别对输入应用` MaxPool `` AvgPool `,然后将它们相加作为节点4的输出。 未用作任何其他节点输入的节点将被视为该层的输出。 如果有多个输出节点,则模型将计算这些节点的平均值作为当前层的输出。
ENAS Micro的搜索空间如下图所示。
![](../../img/NAS_ENAS_micro.svg)
预定义的操作在[参考](#predefined-operations-enas)中列出。
```eval_rst
.. autoclass:: nni.nas.pytorch.search_space_zoo.ENASMicroLayer
:members:
```
归约层由两个卷积操作和之后的BatchNorm组成,每个卷积操作都将输出` C_out//2`个通道并将它们在通道方向上串联作为输出。 卷积的参数是`kernel_size=1``stride=2`,并且它们对输入进行交替采样以降低分辨率而不会丢失信息。 该层封装在`ENASMicroLayer`中。
### 示例代码
[示例代码](https://github.com/microsoft/nni/tree/master/examples/nas/search_space_zoo/enas_micro_example.py)
```bash
git clone https://github.com/Microsoft/nni.git
cd nni/examples/nas/search_space_zoo
# search the best cell structure
python3 enas_micro_example.py
```
<a name="predefined-operations-enas"></a>
### 参考
所有ENAS Micro支持的操作如下。
* 最大池化 / 平均池化
* 最大池化:调用`torch.nn.MaxPool2d`。 这个操作对所有输入的通道进行最大池化,之后进行BatchNorm2d。 池化操作的参数为`kernel_size=3`,,`stride=1``padding=1`
* 平均池化:调用`torch.nn.AvgPool2d`。 这个操作对所有输入的通道进行最大池化,之后进行BatchNorm2d。 池化操作的参数为`kernel_size=3`,,`stride=1``padding=1`
```eval_rst
.. autoclass:: nni.nas.pytorch.search_space_zoo.enas_ops.Pool
```
* SepConv
* SepConvBN3x3:首先进行ReLU,之后进行[DilConv](#DilConv),最后是BatchNorm2d。 卷积操作的参数为`kernel_size=3`,,`stride=1``padding=1`
* SepConvBN5x5:进行与之前相同的操作,但是它具有不同的内核大小和填充,分别设置为5和2。
```eval_rst
.. autoclass:: nni.nas.pytorch.search_space_zoo.enas_ops.SepConvBN
```
* 跳过连接
调用`torch.nn.Identity`直接连接到一个cell。
## ENASMacroLayer
在宏搜索中,控制器为每个层做出两个决定:i)对上一层的结果执行的[操作](#macro-operations),ii)通过跳过连接,连接到之前的那个层。 ENAS使用控制器来设计整个模型结构而不是模型的某一部分。 操作的输出将与跳过连接的所选层的张量连接在一起。 NNI提供了宏搜索中使用的[预定义的操作](#macro-operations),在[参考](#macro-operations)中列出。
ENAS Macro的搜索空间如下图所示。
![](../../img/NAS_ENAS_macro.svg)
```eval_rst
.. autoclass:: nni.nas.pytorch.search_space_zoo.ENASMacroLayer
:members:
```
为了描述整个搜索空间,NNI提供了一个模型,该模型是通过堆叠ENASMacroLayer构成的。
```eval_rst
.. autoclass:: nni.nas.pytorch.search_space_zoo.ENASMacroGeneralModel
:members:
```
### 示例代码
[示例代码](https://github.com/microsoft/nni/tree/master/examples/nas/search_space_zoo/enas_macro_example.py)
```bash
git clone https://github.com/Microsoft/nni.git
cd nni/examples/nas/search_space_zoo
# search the best cell structure
python3 enas_macro_example.py
```
<a name="macro-operations"></a>
### 参考
所有ENAS Macro支持的操作如下。
* ConvBranch
首先将所有输入传递到StdConv,该操作由1x1Conv,BatchNorm2d和ReLU组成。 然后进行下列的操作之一。 最终结果通过后处理,包括BatchNorm2d和ReLU。
* Separable Conv3x3:如果`separable=True`,则cell将使用[ SepConv](#DilConv)而不是常规的卷积操作。 卷积操作的参数为`kernel_size=3`,`stride=1` ,`padding=1`。
* Separable Conv5x5:卷积操作的参数为`kernel_size=5`,,`stride=1` ,`padding=2`。
* Normal Conv3x3:如果`separable=False`,cell将使用参数为` kernel_size=3`,`stride=1`,` padding=1`的一般卷积。
* Separable Conv5x5:卷积操作的参数为`kernel_size=5`,,`stride=1` ,`padding=2`。
```eval_rst
.. autoclass:: nni.nas.pytorch.search_space_zoo.enas_ops.ConvBranch
```
* PoolBranch
首先将所有输入传递到StdConv,该操作由1x1Conv,BatchNorm2d和ReLU组成。 然后对中间结果进行池化操作和BatchNorm。
* 平均池化:调用`torch.nn.AvgPool2d`。 这个操作对所有输入的通道进行平均池化。 池化操作的参数为`kernel_size=3`,,`stride=1` ,`padding=1`。
* 最大池化:调用`torch.nn.MaxPool2d`。 这个操作对所有输入的通道进行最大池化。 池化操作的参数为`kernel_size=3`,,`stride=1` ,`padding=1`。
```eval_rst
.. autoclass:: nni.nas.pytorch.search_space_zoo.enas_ops.PoolBranch
```
<!-- push -->
...@@ -10,7 +10,7 @@ NNI (Neural Network Intelligence) 是一个工具包,可有效的帮助用户 ...@@ -10,7 +10,7 @@ NNI (Neural Network Intelligence) 是一个工具包,可有效的帮助用户
下图显示了 NNI 的体系结构。 下图显示了 NNI 的体系结构。
<p align="center"> <p align="center">
<img src="https://user-images.githubusercontent.com/23273522/51816536-ed055580-2301-11e9-8ad8-605a79ee1b9a.png" alt="绘图" width="700"/> <img src="https://user-images.githubusercontent.com/16907603/92089316-94147200-ee00-11ea-9944-bf3c4544257f.png" alt="绘图" width="700"/>
</p> </p>
## 主要概念 ## 主要概念
......
This diff is collapsed.
# 框架和库的支持 # 框架和库的支持
通过内置的 Python API,NNI 天然支持所有 Python (` 版本 >= 3.5`) 语言的 AI 框架,可使用所有超参调优和神经网络搜索算法。 NNI 还为常见场景提供了一些示例和教程,使上手更容易。 通过内置的 Python API,NNI 天然支持所有 Python (` 版本 >= 3.6`) 语言的 AI 框架,可使用所有超参调优和神经网络搜索算法。 NNI 还为常见场景提供了一些示例和教程,使上手更容易。
## 支持的 AI 框架 ## 支持的 AI 框架
......
...@@ -5,14 +5,23 @@ NNI 支持在 [AML](https://azure.microsoft.com/zh-cn/services/machine-learning/ ...@@ -5,14 +5,23 @@ NNI 支持在 [AML](https://azure.microsoft.com/zh-cn/services/machine-learning/
## 设置环境 ## 设置环境
步骤 1. 参考[指南](../Tutorial/QuickStart.md)安装 NNI。 步骤 1. 参考[指南](../Tutorial/QuickStart.md)安装 NNI。
步骤 2. 按照[文档](https://docs.microsoft.com/zh-cn/azure/machine-learning/how-to-manage-workspace-cli),创建 AML 账户 步骤 2. 通过此 [链接](https://azure.microsoft.com/en-us/free/services/machine-learning/) 创建 Azure 账户/订阅。 如果已有 Azure 账户/订阅,跳过此步骤
步骤 3. 获取账户信息。 ![](../../img/aml_account.png) 步骤 3. 在机器上安装 Azure CLI,参照[](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest)安装指南。
步骤 4. 安装 AML 包环境。 步骤 4. 从CLI验证您的Azure订阅。 要进行交互式身份验证,请打开命令行或终端并使用以下命令:
``` ```
python3 -m pip install azureml --user az login
python3 -m pip install azureml-sdk --user ```
步骤 5. 使用 Web 浏览器登录Azure帐户,并创建机器学习资源。 需要选择资源组并指定工作空间的名称。 之后下载 `config.json`,该文件将会在后面用到。 ![](../../img/aml_workspace.png)
步骤 6. 创建 AML 集群作为计算集群。 ![](../../img/aml_cluster.png)
步骤 7. 打开命令行并安装 AML 环境。
```
python3 -m pip install azureml
python3 -m pip install azureml-sdk
``` ```
## 运行 Experiment ## 运行 Experiment
...@@ -38,28 +47,44 @@ tuner: ...@@ -38,28 +47,44 @@ tuner:
trial: trial:
command: python3 mnist.py command: python3 mnist.py
codeDir: . codeDir: .
computeTarget: ${replace_to_your_computeTarget}
image: msranni/nni image: msranni/nni
gpuNum: 1
amlConfig: amlConfig:
subscriptionId: ${replace_to_your_subscriptionId} subscriptionId: ${replace_to_your_subscriptionId}
resourceGroup: ${replace_to_your_resourceGroup} resourceGroup: ${replace_to_your_resourceGroup}
workspaceName: ${replace_to_your_workspaceName} workspaceName: ${replace_to_your_workspaceName}
computeTarget: ${replace_to_your_computeTarget}
``` ```
注意:如果用 aml 模式运行,需要在 YAML 文件中设置 `trainingServicePlatform: aml` 注意:如果用 aml 模式运行,需要在 YAML 文件中设置 `trainingServicePlatform: aml`
[本机模式](LocalMode.md)的 Trial 配置相比,aml 模式下的键值还有: [本机模式](LocalMode.md)的 Trial 配置相比,aml 模式下的键值还有:
* computeTarget
* 必填。 要在 AML 工作区中使用的计算机集群名称。
* image * image
* 必填。 作业中使用的 Docker 映像名称。 * 必填。 作业中使用的 Docker 映像名称。 此示例中的镜像 `msranni/nni` 只支持 GPU 计算集群。
amlConfig: amlConfig:
* subscriptionId * subscriptionId
* Azure 订阅的 Id * 必填,Azure 订阅的 Id
* resourceGroup * resourceGroup
* 账户的资源组 * 必填,Azure 订阅的资源组
* workspaceName * workspaceName
* 账户的工作区名称 * 必填,Azure 订阅的工作空间
* computeTarget
* 必填,要在 AML 工作区中使用的计算机集群名称。 见步骤6。
* maxTrialNumPerGpu
* 可选,用于指定 GPU 设备上的最大并发 Trial 的数量。
* useActiveGpu
* 可选,用于指定 GPU 上存在其他进程时是否使用此 GPU。 默认情况下,NNI 仅在 GPU 中没有其他活动进程时才使用 GPU。
amlConfig 需要的信息可以从步骤 5 下载的 `config.json` 找到。
运行以下命令来启动示例示例 Experiment:
```
git clone -b ${NNI_VERSION} https://github.com/microsoft/nni
cd nni/examples/trials/mnist-tfv1
# 修改 config.aml ...
nnictl create --config config_aml.yml
```
`${NNI_VERSION}` 替换为发布的版本或分支名称,例如:`v1.8`
...@@ -57,7 +57,6 @@ assessor: ...@@ -57,7 +57,6 @@ assessor:
builtinAssessorName: Medianstop builtinAssessorName: Medianstop
classArgs: classArgs:
optimize_mode: maximize optimize_mode: maximize
gpuNum: 0
trial: trial:
codeDir: ~/nni/examples/trials/mnist-tfv1 codeDir: ~/nni/examples/trials/mnist-tfv1
taskRoles: taskRoles:
......
...@@ -101,7 +101,6 @@ assessor: ...@@ -101,7 +101,6 @@ assessor:
builtinAssessorName: Medianstop builtinAssessorName: Medianstop
classArgs: classArgs:
optimize_mode: maximize optimize_mode: maximize
gpuNum: 0
trial: trial:
codeDir: . codeDir: .
worker: worker:
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
NNI 训练平台让用户专注于 AutoML 任务,不需要关心 Trial 实际运行的计算基础架构平台。 当从一个集群迁移到另一个集群时 (如,从本机迁移到 Kubeflow),用户只需要调整几项配置,能很容易的扩展计算资源。 NNI 训练平台让用户专注于 AutoML 任务,不需要关心 Trial 实际运行的计算基础架构平台。 当从一个集群迁移到另一个集群时 (如,从本机迁移到 Kubeflow),用户只需要调整几项配置,能很容易的扩展计算资源。
NNI 提供的训练平台包括:[本机](./LocalMode.md), [远程计算机](./RemoteMachineMode.md), 以及集群类的 [OpenPAI](./PaiMode.md)[Kubeflow](./KubeflowMode.md) [FrameworkController](./FrameworkControllerMode.md)。 这些都是*内置的训练平台* NNI 提供的训练平台包括:[本机](./LocalMode.md), [远程计算机](./RemoteMachineMode.md), 以及集群类的 [OpenPAI](./PaiMode.md), [Kubeflow](./KubeflowMode.md), [FrameworkController](./FrameworkControllerMode.md), [DLTS](./DLTSMode.md)[AML](./AMLMode.md).。 这些都是*内置的训练平台*
如果需要在计算资源上使用 NNI,可以根据相关接口,轻松构建对其它训练平台的支持。 参考 "[如何实现训练平台](./HowToImplementTrainingService)" 了解详情。 如果需要在计算资源上使用 NNI,可以根据相关接口,轻松构建对其它训练平台的支持。 参考 "[如何实现训练平台](./HowToImplementTrainingService)" 了解详情。
...@@ -12,20 +12,21 @@ NNI 提供的训练平台包括:[本机](./LocalMode.md), [远程计算机](./ ...@@ -12,20 +12,21 @@ NNI 提供的训练平台包括:[本机](./LocalMode.md), [远程计算机](./
在 Experiment 的 YAML 配置文件中选择并配置好训练平台。 参考相应训练平台的文档来了解如何配置。 同时,[Experiment 文档](../Tutorial/ExperimentConfig)提供了更多详细信息。 在 Experiment 的 YAML 配置文件中选择并配置好训练平台。 参考相应训练平台的文档来了解如何配置。 同时,[Experiment 文档](../Tutorial/ExperimentConfig)提供了更多详细信息。
然后,需要准备代码目录,将路径填入配置文件的 `codeDir` 字段。 注意,非本机模式下,代码目录会在 Experiment 运行前上传到远程或集群中。 因此,NNI 将文件数量限制到 2000,总大小限制为 300 MB。 如果代码目录中文件太多,可添加 `.nniignore` 文件来排除一部分文件,其用法与 `.gitignore` 类似。 具体用法可参考 [git 文档](https://git-scm.com/docs/gitignore#_pattern_format) 然后,需要准备代码目录,将路径填入配置文件的 `codeDir` 字段。 注意,非本机模式下,代码目录会在 Experiment 运行前上传到远程或集群中。 因此,NNI 将文件数量限制到 2000,总大小限制为 300 MB。 如果代码目录中文件太多,可添加 `.nniignore` 文件来排除一部分文件,其用法与 `.gitignore` 类似。 关于如何编写该文件,详见 [此示例](https://github.com/Microsoft/nni/tree/master/examples/trials/mnist-tfv1/.nniignore) 以及 [git 文档](https://git-scm.com/docs/gitignore#_pattern_format).
如果用户需要在 Experiment 使用大文件(如,大规模的数据集),并且不想使用本机模式,可以:1) 在 Trial command 字段中添加命令,每次 Trial 运行前下载数据;或 2) 使用工作节点可访问的共享存储。 通常情况下,训练平台都会有共享存储。 参考每个训练平台的文档,了解详情。 如果用户需要在 Experiment 使用大文件(如,大规模的数据集),并且不想使用本机模式,可以:1) 在 Trial command 字段中添加命令,每次 Trial 运行前下载数据;或 2) 使用工作节点可访问的共享存储。 通常情况下,训练平台都会有共享存储。 参考每个训练平台的文档,了解详情。
## 内置训练平台 ## 内置训练平台
| 训练平台 | 简介 | | 训练平台 | 简介 |
| --------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [__本机__](./LocalMode.html) | NNI 支持在本机运行实验,称为 local 模式。 local 模式表示 NNI 会在运行 NNI Manager 进程计算机上运行 Trial 任务,支持 GPU 调度功能。 | | [__本机__](./LocalMode.md) | NNI 支持在本机运行实验,称为 local 模式。 local 模式表示 NNI 会在运行 NNI Manager 进程计算机上运行 Trial 任务,支持 GPU 调度功能。 |
| [__远程计算机__](./RemoteMachineMode.html) | NNI 支持通过 SSH 通道在多台计算机上运行 Experiment,称为 remote 模式。 NNI 需要这些计算机的访问权限,并假定已配置好了深度学习训练环境。 NNI 将在远程计算机上中提交 Trial 任务,并根据 GPU 资源调度 Trial 任务。 | | [__远程计算机__](./RemoteMachineMode.md) | NNI 支持通过 SSH 通道在多台计算机上运行 Experiment,称为 remote 模式。 NNI 需要这些计算机的访问权限,并假定已配置好了深度学习训练环境。 NNI 将在远程计算机上中提交 Trial 任务,并根据 GPU 资源调度 Trial 任务。 |
| [__OpenPAI__](./PaiMode.html) | NNI 支持在 [OpenPAI](https://github.com/Microsoft/pai) 上运行 Experiment,即 pai 模式。 在使用 NNI 的 pai 模式前, 需要有 [OpenPAI](https://github.com/Microsoft/pai) 群集的账户。 如果没有 OpenPAI,参考[这里](https://github.com/Microsoft/pai#how-to-deploy)来进行部署。 在 pai 模式中,会在 Docker 创建的容器中运行 Trial 程序。 | | [__OpenPAI__](./PaiMode.md) | NNI 支持在 [OpenPAI](https://github.com/Microsoft/pai) 上运行 Experiment,即 pai 模式。 在使用 NNI 的 pai 模式前, 需要有 [OpenPAI](https://github.com/Microsoft/pai) 群集的账户。 如果没有 OpenPAI,参考[这里](https://github.com/Microsoft/pai#how-to-deploy)来进行部署。 在 pai 模式中,会在 Docker 创建的容器中运行 Trial 程序。 |
| [__Kubeflow__](./KubeflowMode.html) | NNI 支持在 [Kubeflow](https://github.com/kubeflow/kubeflow)上运行,称为 kubeflow 模式。 在开始使用 NNI 的 Kubeflow 模式前,需要有一个 Kubernetes 集群,可以是私有部署的,或者是 [Azure Kubernetes Service(AKS)](https://azure.microsoft.com/zh-cn/services/kubernetes-service/),并需要一台配置好 [kubeconfig](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/) 的 Ubuntu 计算机连接到此 Kubernetes 集群。 如果不熟悉 Kubernetes,可先浏览[这里](https://kubernetes.io/docs/tutorials/kubernetes-basics/)。 在 kubeflow 模式下,每个 Trial 程序会在 Kubernetes 集群中作为一个 Kubeflow 作业来运行。 | | [__Kubeflow__](./KubeflowMode.md) | NNI 支持在 [Kubeflow](https://github.com/kubeflow/kubeflow)上运行,称为 kubeflow 模式。 在开始使用 NNI 的 Kubeflow 模式前,需要有一个 Kubernetes 集群,可以是私有部署的,或者是 [Azure Kubernetes Service(AKS)](https://azure.microsoft.com/zh-cn/services/kubernetes-service/),并需要一台配置好 [kubeconfig](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/) 的 Ubuntu 计算机连接到此 Kubernetes 集群。 如果不熟悉 Kubernetes,可先浏览[这里](https://kubernetes.io/docs/tutorials/kubernetes-basics/)。 在 kubeflow 模式下,每个 Trial 程序会在 Kubernetes 集群中作为一个 Kubeflow 作业来运行。 |
| [__FrameworkController__](./FrameworkControllerMode.html) | NNI 支持使用 [FrameworkController](https://github.com/Microsoft/frameworkcontroller),来运行 Experiment,称之为 frameworkcontroller 模式。 FrameworkController 构建于 Kubernetes 上,用于编排各种应用。这样,可以不用为某个深度学习框架安装 Kubeflow 的 tf-operator 或 pytorch-operator 等。 而直接用 FrameworkController 作为 NNI Experiment 的训练平台。 | | [__FrameworkController__](./FrameworkControllerMode.md) | NNI 支持使用 [FrameworkController](https://github.com/Microsoft/frameworkcontroller),来运行 Experiment,称之为 frameworkcontroller 模式。 FrameworkController 构建于 Kubernetes 上,用于编排各种应用。这样,可以不用为某个深度学习框架安装 Kubeflow 的 tf-operator 或 pytorch-operator 等。 而直接用 FrameworkController 作为 NNI Experiment 的训练平台。 |
| [__DLTS__](./DLTSMode.html) | NNI 支持在 [DLTS](https://github.com/microsoft/DLWorkspace.git) 上运行 Experiment,这是一个由微软开源的工具包。 | | [__DLTS__](./DLTSMode.md) | NNI 支持在 [DLTS](https://github.com/microsoft/DLWorkspace.git) 上运行 Experiment,这是一个由微软开源的工具包。 |
| [__AML__](./AMLMode.md) | NNI 支持在 [AML](https://azure.microsoft.com/zh-cn/services/machine-learning/) 上运行 Experiment,称为 aml 模式。 |
## 训练平台做了什么? ## 训练平台做了什么?
......
...@@ -72,8 +72,8 @@ trial: ...@@ -72,8 +72,8 @@ trial:
memoryMB: 8196 memoryMB: 8196
image: msranni/nni:latest image: msranni/nni:latest
virtualCluster: default virtualCluster: default
nniManagerNFSMountPath: /home/user/mnt nniManagerNFSMountPath: /local/mnt
containerNFSMountPath: /mnt/data/user containerNFSMountPath: /mnt/confignfs-data
paiStorageConfigName: confignfs-data paiStorageConfigName: confignfs-data
# 配置要访问的 OpenPAI 集群 # 配置要访问的 OpenPAI 集群
paiConfig: paiConfig:
...@@ -84,7 +84,7 @@ paiConfig: ...@@ -84,7 +84,7 @@ paiConfig:
reuse: true reuse: true
``` ```
注意:如果用 pai 模式运行,需要在 YAML 文件中设置 `trainingServicePlatform: pai` 注意:如果用 pai 模式运行,需要在 YAML 文件中设置 `trainingServicePlatform: pai` 配置文件中的 host 字段是 OpenPAI 作业提交页面的地址,例如:`10.10.5.1`,NNI 中默认协议是 `http`,如果 OpenPAI 集群启用了 https,则需要使用 `https://10.10.5.1` 的格式。
### Trial 配置 ### Trial 配置
......
# 训练平台
NNI 为 Trial 任务实现了训练平台。 NNI 支持[本机](./LocalMode.md), [远程](./RemoteMachineMode.md), [OpenPAI](./PaiMode.md), [Kubeflow](./KubeflowMode.md)[FrameworkController](./FrameworkControllerMode.md) 这些内置的训练平台。
NNI 不仅提供了这些内置的训练平台,还提供了轻松连接自己训练平台的方法。
## 内置训练平台
| 训练平台 | 简介 |
| ------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [**本机**](./LocalMode.md) | NNI 支持在本机运行实验,称为 local 模式。 local 模式表示 NNI 会在运行 NNI Manager 进程计算机上运行 Trial 任务,支持 GPU 调度功能。 |
| [**远程计算机**](./RemoteMachineMode.md) | NNI 支持通过 SSH 通道在多台计算机上运行 Experiment,称为 remote 模式。 NNI 需要这些计算机的访问权限,并假定已配置好了深度学习训练环境。 NNI 将在远程计算机上中提交 Trial 任务,并根据 GPU 资源调度 Trial 任务。 |
| [**OpenPAI**](./PaiMode.md) | NNI 支持在 [OpenPAI](https://github.com/Microsoft/pai) (简称 pai)上运行 Experiment,即 pai 模式。 在使用 NNI 的 pai 模式前, 需要有 [OpenPAI](https://github.com/Microsoft/pai) 群集及其账户。 如果没有 OpenPAI,参考[这里](https://github.com/Microsoft/pai#how-to-deploy)来进行部署。 在 pai 模式中,会在 Docker 创建的容器中运行 Trial 程序。 |
| [**Kubeflow**](./KubeflowMode.md) | NNI 支持在 [Kubeflow](https://github.com/kubeflow/kubeflow)上运行,称为 kubeflow 模式。 在开始使用 NNI 的 Kubeflow 模式前,需要有一个 Kubernetes 集群,可以是私有部署的,或者是 [Azure Kubernetes Service(AKS)](https://azure.microsoft.com/zh-cn/services/kubernetes-service/),并需要一台配置好 [kubeconfig](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/) 的 Ubuntu 计算机连接到此 Kubernetes 集群。 如果不熟悉 Kubernetes,可先浏览[这里](https://kubernetes.io/docs/tutorials/kubernetes-basics/)。 在 kubeflow 模式下,每个 Trial 程序会在 Kubernetes 集群中作为一个 Kubeflow 作业来运行。 |
| [**FrameworkController**](./FrameworkControllerMode.md) | NNI 支持使用 [FrameworkController](https://github.com/Microsoft/frameworkcontroller),来运行 Experiment,称之为 frameworkcontroller 模式。 FrameworkController 构建于 Kubernetes 上,用于编排各种应用。这样,可以不用为某个深度学习框架安装 Kubeflow 的 tf-operator 或 pytorch-operator 等。 而直接用 FrameworkController 作为 NNI Experiment 的训练平台。 |
## 实现训练平台
TrainingService 在设计上为了便于实现,将平台相关的公共属性抽象成类。用户只需要继承这个抽象类,并根据平台特点实现子类,便能够实现 TrainingService。
TrainingService 的声明如下:
```javascript
abstract class TrainingService {
public abstract listTrialJobs(): Promise<TrialJobDetail[]>;
public abstract getTrialJob(trialJobId: string): Promise<TrialJobDetail>;
public abstract addTrialJobMetricListener(listener: (metric: TrialJobMetric) => void): void;
public abstract removeTrialJobMetricListener(listener: (metric: TrialJobMetric) => void): void;
public abstract submitTrialJob(form: JobApplicationForm): Promise<TrialJobDetail>;
public abstract updateTrialJob(trialJobId: string, form: JobApplicationForm): Promise<TrialJobDetail>;
public abstract get isMultiPhaseJobSupported(): boolean;
public abstract cancelTrialJob(trialJobId: string, isEarlyStopped?: boolean): Promise<void>;
public abstract setClusterMetadata(key: string, value: string): Promise<void>;
public abstract getClusterMetadata(key: string): Promise<string>;
public abstract cleanUp(): Promise<void>;
public abstract run(): Promise<void>;
}
```
TrainingService 的父类有一些抽象函数,用户需要继承父类并实现所有这些抽象函数。
有关如何实现 TrainingService 的更多信息,[参考这里](https://github.com/microsoft/nni/blob/master/docs/zh_CN/TrainingService/HowToImplementTrainingService.md)
\ No newline at end of file
...@@ -4,8 +4,11 @@ ...@@ -4,8 +4,11 @@
深度神经网络(DNN)的大量应用,催生了对从云服务器到嵌入式设备等不同硬件平台上的训练和推理的需求。 此外,还有深度神经网络上的计算图优化问题,如张量算子融合会引入新的张量算子。 然而,人工通过特定硬件库来优化张量算子,不能很好的支持新硬件平台和新算子,存在一定的局限性。因此,在大规模部署和深度学习技术的实际场景中,不同平台上的自动化的张量算子优化变得非常重要。 深度神经网络(DNN)的大量应用,催生了对从云服务器到嵌入式设备等不同硬件平台上的训练和推理的需求。 此外,还有深度神经网络上的计算图优化问题,如张量算子融合会引入新的张量算子。 然而,人工通过特定硬件库来优化张量算子,不能很好的支持新硬件平台和新算子,存在一定的局限性。因此,在大规模部署和深度学习技术的实际场景中,不同平台上的自动化的张量算子优化变得非常重要。
张量算子优化的本质,是一个组合优化问题。 目标函数是张量算子在某个硬件平台上的性能,通过调整超参(如,如何切片矩阵,展开循环)实现该平台上的最佳性能。 此示例展示了如何使用 NNI 来自动调优张量算子。 其提供了 OpEvo, G-BFS 和 N-A2C 三种调优算法。 参考论文 [OpEvo: An Evolutionary Method for Tensor Operator Optimization](https://arxiv.org/abs/2006.05664) 来了解算法 张量算子优化的本质,是一个组合优化问题。 目标函数是张量算子在某个硬件平台上的性能,通过调整超参(如,如何切片矩阵,展开循环)实现该平台上的最佳性能。 与许多典型的此类问题(如旅行推销员问题)不同,张量算子优化的目标函数是黑盒,采样成本较高。 必须用特定的配置编译设备代码,并在真实的硬件上运行,以获得相应的性能指标。 因此,理想的张量算子优化方法应该在尽可能少的样本下找到最佳的配置
代价昂贵的目标函数使得用传统的组合优化方法,如模拟退火和进化算法求解张量算子优化问题几乎不可能。 尽管这些算法本质上支持组合搜索空间,但它们并未考虑采样效率,因此通常需要成千上万甚至更多的样本,这在生产环境中调整张量算子时是不可接受的。 另一方面,事实证明,基于序列模型的优化(SMBO)方法可有效地优化具有连续搜索空间的黑盒函数。 然而,在使用组合搜索空间进行优化时,SMBO 方法的采样效率不及连续搜索方法,这是因为缺少关于目标函数的先验假设,例如连续搜索空间的连续性和可微性。 例如,如果可以假设具有连续搜索空间的目标函数是无限可微的,则可以使用具有径向基函数(RBF)核的高斯过程对目标函数进行建模。 这样,一个样本不仅提供了一个点上的单一值,而且还提供了目标函数在其邻域上的局部性质,甚至是全局性质,从而获得了较高的采样效率。 相比之下,用于组合优化的SMBO方法由于缺乏适当的先验假设和可以利用它们的替代模型而导致采样效率低下。
最近提出的 OpEvo 就是为了解决这个具有挑战性的问题。 它通过引入基于 q-随机游走分布的拓扑感知突变操作来利用搜索空间上的拓扑结构,有效地探索了张量算子的搜索空间。 在本例中,可以使用OpEvo调优从两个流行的神经网络(BERT和AlexNet)中选择的三种代表性张量算子。 还提供了三个比较基线:AutoTVM,G-BFS和N-A2C。 参考论文 [OpEvo: An Evolutionary Method for Tensor Operator Optimization](https://arxiv.org/abs/2006.05664) 来了解算法。
## 配置环境 ## 配置环境
...@@ -26,53 +29,79 @@ make rocm-env ...@@ -26,53 +29,79 @@ make rocm-env
# (N, K) x (K, M) 表示形状为 (N, K) 的矩阵乘以形状为 (K, M) 的矩阵 # (N, K) x (K, M) 表示形状为 (N, K) 的矩阵乘以形状为 (K, M) 的矩阵
# (512, 1024) x (1024, 1024) # (512, 1024) x (1024, 1024)
# 用 opevo 调优 # 用 OpenEvo 调优
nnictl create --config experiments/mm/N512K1024M1024/config_opevo.yml nnictl create --config experiments/mm/N512K1024M1024/config_opevo.yml
# 用 g-bfs 调优 # 用 G-BFS 调优
nnictl create --config experiments/mm/N512K1024M1024/config_gbfs.yml nnictl create --config experiments/mm/N512K1024M1024/config_gbfs.yml
# 用 n-a2c 调优 # 用 N-A2C 调优
nnictl create --config experiments/mm/N512K1024M1024/config_na2c.yml nnictl create --config experiments/mm/N512K1024M1024/config_na2c.yml
# 用 AutoTVM 调优
OP=matmul STEP=512 N=512 M=1024 K=1024 P=NN ./run.s
# (512, 1024) x (1024, 4096) # (512, 1024) x (1024, 4096)
# 用 opevo 调优 # 用 OpenEvo 调优
nnictl create --config experiments/mm/N512K1024M4096/config_opevo.yml nnictl create --config experiments/mm/N512K1024M4096/config_opevo.yml
# 用 g-bfs 调优 # 用 G-BFS 调优
nnictl create --config experiments/mm/N512K1024M4096/config_gbfs.yml nnictl create --config experiments/mm/N512K1024M4096/config_gbfs.yml
# 用 n-a2c 调优 # 用 N-A2C调优
nnictl create --config experiments/mm/N512K1024M4096/config_na2c.yml nnictl create --config experiments/mm/N512K1024M4096/config_na2c.yml
# 用 AutoTVM 调优
OP=matmul STEP=512 N=512 M=1024 K=4096 P=NN ./run.sh
# (512, 4096) x (4096, 1024) # (512, 4096) x (4096, 1024)
# 用 opevo 调优 # 用 OpenEvo 调优
nnictl create --config experiments/mm/N512K1024M4096/config_opevo.yml nnictl create --config experiments/mm/N512K4096M1024/config_opevo.yml
# 用 g-bfs 调优 # 用 G-BFS 调优
nnictl create --config experiments/mm/N512K1024M4096/config_gbfs.yml nnictl create --config experiments/mm/N512K4096M1024/config_gbfs.yml
# 用 n-a2c 调优 # 用 N-A2C调优
nnictl create --config experiments/mm/N512K1024M4096/config_na2c.yml nnictl create --config experiments/mm/N512K4096M1024/config_na2c.yml
# 用 AutoTVM 调优
OP=matmul STEP=512 N=512 M=4096 K=1024 P=NN ./run.sh
``` ```
`/root` 中运行以下命令来调优批处理矩阵乘法: `/root` 中运行以下命令来调优批处理矩阵乘法:
```bash ```bash
# 批处理大小为 960,形状为 (128, 128) 的矩阵,乘以批处理大小为 960,形状为 (128, 64) 的矩阵 # 批处理大小为 960,形状为 (128, 128) 的矩阵,乘以批处理大小为 960,形状为 (128, 64) 的矩阵
# 用 OpEvo 调优
nnictl create --config experiments/bmm/B960N128K128M64PNN/config_opevo.yml nnictl create --config experiments/bmm/B960N128K128M64PNN/config_opevo.yml
# 用 AutoTVM 调优
OP=batch_matmul STEP=512 B=960 N=128 K=128 M=64 P=NN ./run.sh
# 批处理大小为 960,形状为 (128, 128) 的矩阵,先转置,然后乘以批处理大小为 960,形状为 (128, 64) 的矩阵 # 批处理大小为 960,形状为 (128, 128) 的矩阵,先转置,然后乘以批处理大小为 960,形状为 (128, 64) 的矩阵
# 用 OpEvo 调优
nnictl create --config experiments/bmm/B960N128K128M64PTN/config_opevo.yml nnictl create --config experiments/bmm/B960N128K128M64PTN/config_opevo.yml
# 用 AutoTVM 调优
OP=batch_matmul STEP=512 B=960 N=128 K=128 M=64 P=TN ./run.sh
# 批处理大小为 960,形状为 (128, 128) 的矩阵,先转置,然后右乘批处理大小为 960,形状为 (128, 64) 的矩阵 # 批处理大小为 960,形状为 (128, 128) 的矩阵,先转置,然后右乘批处理大小为 960,形状为 (128, 64) 的矩阵
# 用 OpEvo 调优
nnictl create --config experiments/bmm/B960N128K64M128PNT/config_opevo.yml nnictl create --config experiments/bmm/B960N128K64M128PNT/config_opevo.yml
# 用 AutoTVM 调优
OP=batch_matmul STEP=512 B=960 N=128 K=64 M=128 P=NT ./run.sh
``` ```
`/root` 中运行以下命令来调优二维卷积: `/root` 中运行以下命令来调优二维卷积:
```bash ```bash
# 图片张量形状为 $(512, 3, 227, 227)$ 与形状为 $(64, 3, 11, 11)$ 的核进行卷积,stride 为 4、padding 为 0 # 形状为(512,3,227,227)的图像张量与形状为(64,3,11,11)的内核张量以步幅 4 和填充 0 卷积
# 用 OpEvo 调优
nnictl create --config experiments/conv/N512C3HW227F64K11ST4PD0/config_opevo.yml nnictl create --config experiments/conv/N512C3HW227F64K11ST4PD0/config_opevo.yml
# 图片张量形状为 $(512, 64, 27, 27)$ 与形状为 $(192, 64, 5, 5)$ 的核进行卷积,stride 为 1、padding 为 2 # 用 AutoTVM 调优
OP=convfwd_direct STEP=512 N=512 C=3 H=227 W=227 F=64 K=11 ST=4 PD=0 ./run.sh
# 形状为(512,64,27,27)的图像张量和形状为(192,64,5,5)的内核张量以步幅 1 和填充 2 卷积
# 用 OpEvo 调优
nnictl create --config experiments/conv/N512C64HW27F192K5ST1PD2/config_opevo.yml nnictl create --config experiments/conv/N512C64HW27F192K5ST1PD2/config_opevo.yml
# 用 AutoTVM 调优
OP=convfwd_direct STEP=512 N=512 C=64 H=27 W=27 F=192 K=5 ST=1 PD=2 ./run.sh
``` ```
注意,G-BFS 和 N-A2C 算法不能用于调优批处理矩阵乘法和二维卷积,因为这些算子的搜索空间中有不支持的参数。 请注意,G-BFS 和 N-A2C 这两种方法是专为优化行和列为2的幂的矩阵相乘的平铺(tiling)策略而设计的,所以他们不能够兼容其他类型的搜索空间,因此不能够用来优化批量矩阵乘和2维卷积这两种张量算子。 这里,AutoTVM是由作者在 TVM 项目中实现的,因此调优结果打印在屏幕上,而不是报告给 NNI 管理器。 容器的端口 8080 绑定到主机的同一端口,因此可以通过 `host_ip_addr:8080` 访问NNI Web 界面,并监视调优过程,如下面的屏幕截图所示。
<img src="../../../examples/trials/systems/opevo/screenshot.png" />
## 引用 OpEvo ## 引用 OpEvo
如果在研究中使用了 OpEvo,请考虑如下引用论文: 如果认为 OpEvo 有帮助,请考虑如下引用论文:
``` ```
@misc{gao2020opevo, @misc{gao2020opevo,
title={OpEvo: An Evolutionary Method for Tensor Operator Optimization}, title={OpEvo: An Evolutionary Method for Tensor Operator Optimization},
......
...@@ -162,19 +162,19 @@ nni.get_sequence_id#返回 0 ...@@ -162,19 +162,19 @@ nni.get_sequence_id#返回 0
#!/bin/bash #!/bin/bash
cd /tmp/user_name/nni/annotation/tmpzj0h72x6 #This is the actual directory cd /tmp/user_name/nni/annotation/tmpzj0h72x6 #This is the actual directory
export NNI_PLATFORM=local export NNI_PLATFORM=local
export NNI_SYS_DIR=/home/user_name/nni/experiments/$experiment_id$/trials/$trial_id$ export NNI_SYS_DIR=/home/user_name/nni-experiments/$experiment_id$/trials/$trial_id$
export NNI_TRIAL_JOB_ID=nrbb2 export NNI_TRIAL_JOB_ID=nrbb2
export NNI_OUTPUT_DIR=/home/user_name/nni/experiments/$eperiment_id$/trials/$trial_id$ export NNI_OUTPUT_DIR=/home/user_name/nni-experiments/$eperiment_id$/trials/$trial_id$
export NNI_TRIAL_SEQ_ID=1 export NNI_TRIAL_SEQ_ID=1
export MULTI_PHASE=false export MULTI_PHASE=false
export CUDA_VISIBLE_DEVICES= export CUDA_VISIBLE_DEVICES=
eval python3 mnist.py 2>/home/user_name/nni/experiments/$experiment_id$/trials/$trial_id$/stderr eval python3 mnist.py 2>/home/user_name/nni-experiments/$experiment_id$/trials/$trial_id$/stderr
echo $? `date +%s%3N` >/home/user_name/nni/experiments/$experiment_id$/trials/$trial_id$/.nni/state echo $? `date +%s%3N` >/home/user_name/nni-experiments/$experiment_id$/trials/$trial_id$/.nni/state
``` ```
### 其它模式 ### 其它模式
当 Trial 运行在 OpenPAI 这样的远程服务器上时,`NNI_OUTPUT_DIR` 仅会指向 Trial 的输出目录,而 `run.sh` 不会在此目录中。 `trial.log` 文件会被复制回本机的 Trial 目录中。目录的默认位置在 `~/nni/experiments/$experiment_id$/trials/$trial_id$/` 当 Trial 运行在 OpenPAI 这样的远程服务器上时,`NNI_OUTPUT_DIR` 仅会指向 Trial 的输出目录,而 `run.sh` 不会在此目录中。 `trial.log` 文件会被复制回本机的 Trial 目录中。目录的默认位置在 `~/nni-experiments/$experiment_id$/trials/$trial_id$/`
详细信息,可参考[调试指南](../Tutorial/HowToDebug.md) 详细信息,可参考[调试指南](../Tutorial/HowToDebug.md)
......
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