Skip to content
This repository has been archived by the owner on Sep 18, 2024. It is now read-only.

Commit

Permalink
Merge pull request #214 from microsoft/master
Browse files Browse the repository at this point in the history
merge master
  • Loading branch information
SparkSnail authored Nov 14, 2019
2 parents c037a7c + 187494a commit 7620e7c
Show file tree
Hide file tree
Showing 56 changed files with 2,000 additions and 918 deletions.
2 changes: 1 addition & 1 deletion README_zh_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -359,4 +359,4 @@ You can use these commands to get more information about the experiment

## **许可协议**

代码库遵循 [MIT 许可协议](LICENSE)
代码库遵循 [MIT 许可协议](LICENSE)
8 changes: 0 additions & 8 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -126,18 +126,10 @@ jobs:
cd test
powershell.exe -file unittest.ps1
displayName: 'unit test'
- script: |
cd test
python naive_test.py
displayName: 'Naive test'
- script: |
cd test
python tuner_test.py
displayName: 'Built-in tuners / assessors tests'
- script: |
cd test
python metrics_test.py
displayName: 'Trial job metrics test'
- script: |
cd test
PATH=$HOME/.local/bin:$PATH python3 cli_test.py
Expand Down
10 changes: 10 additions & 0 deletions docs/en_US/CommunitySharings/TuningSystems.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Automatically tune systems with NNI

As computer systems and networking get increasingly complicated, optimizing them manually with explicit rules and heuristics becomes harder than ever before, sometimes impossible. Below are two examples of tuning systems with NNI. Anyone can easily tune their own systems by following them.

* [Tuning RocksDB with NNI](../TrialExample/RocksdbExamples.md)
* [Tuning parameters of SPTAG (Space Partition Tree And Graph) with NNI](SptagAutoTune.md)

Please see [this paper](https://dl.acm.org/citation.cfm?id=3352031) for more details:

Mike Liang, Chieh-Jan, et al. "The Case for Learning-and-System Co-design." ACM SIGOPS Operating Systems Review 53.1 (2019): 68-74.
52 changes: 46 additions & 6 deletions docs/en_US/Compressor/Overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,12 +180,54 @@ class YourQuantizer(nni.compression.tensorflow.Quantizer):

def quantize_weight(self, weight, config, **kwargs):
"""
weight is the target weight tensor
config is the selected dict object in config_list for this layer
kwargs contains op, op_types, and op_name
design your quantizer and return new weight
quantize should overload this method to quantize weight tensors.
This method is effectively hooked to :meth:`forward` of the model.
Parameters
----------
weight : Tensor
weight that needs to be quantized
config : dict
the configuration for weight quantization
"""

# Put your code to generate `new_weight` here

return new_weight

def quantize_output(self, output, config, **kwargs):
"""
quantize should overload this method to quantize output.
This method is effectively hooked to `:meth:`forward` of the model.
Parameters
----------
output : Tensor
output that needs to be quantized
config : dict
the configuration for output quantization
"""

# Put your code to generate `new_output` here

return new_output

def quantize_input(self, *inputs, config, **kwargs):
"""
quantize should overload this method to quantize input.
This method is effectively hooked to :meth:`forward` of the model.
Parameters
----------
inputs : Tensor
inputs that needs to be quantized
config : dict
the configuration for inputs quantization
"""

# Put your code to generate `new_input` here

return new_input

# note for pytorch version, there is no sess in input arguments
def update_epoch(self, epoch_num, sess):
Expand All @@ -200,8 +242,6 @@ class YourQuantizer(nni.compression.tensorflow.Quantizer):
pass
```

__[TODO]__ Will add another member function `quantize_layer_output`, as some quantization algorithms also quantize layers' output.

### Usage of user customized compression algorithm

__[TODO]__ ...
16 changes: 12 additions & 4 deletions docs/en_US/TrialExample/GbdtExample.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,15 @@ Given the features and label in train data, we train a GBDT regression model and

## 3. How to run in nni

### 3.1 Prepare your trial code

### 3.1 Install all the requirments

```
pip install lightgbm
pip install pandas
```

### 3.2 Prepare your trial code

You need to prepare a basic code as following:

Expand Down Expand Up @@ -86,7 +94,7 @@ if __name__ == '__main__':
run(lgb_train, lgb_eval, PARAMS, X_test, y_test)
```

### 3.2 Prepare your search space.
### 3.3 Prepare your search space.
If you like to tune `num_leaves`, `learning_rate`, `bagging_fraction` and `bagging_freq`, you could write a [search_space.json](https://github.com/Microsoft/nni/blob/master/examples/trials/auto-gbdt/search_space.json) as follow:

```json
Expand All @@ -100,7 +108,7 @@ If you like to tune `num_leaves`, `learning_rate`, `bagging_fraction` and `baggi

More support variable type you could reference [here](../Tutorial/SearchSpaceSpec.md).

### 3.3 Add SDK of nni into your code.
### 3.4 Add SDK of nni into your code.

```diff
+import nni
Expand Down Expand Up @@ -146,7 +154,7 @@ if __name__ == '__main__':
run(lgb_train, lgb_eval, PARAMS, X_test, y_test)
```

### 3.4 Write a config file and run it.
### 3.5 Write a config file and run it.

In the config file, you could set some settings including:

Expand Down
5 changes: 4 additions & 1 deletion docs/en_US/Tutorial/Contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ A person looking to contribute can take up an issue by claiming it as a comment/
## Code Styles & Naming Conventions
* We follow [PEP8](https://www.python.org/dev/peps/pep-0008/) for Python code and naming conventions, do try to adhere to the same when making a pull request or making a change. One can also take the help of linters such as `flake8` or `pylint`
* We also follow [NumPy Docstring Style](https://www.sphinx-doc.org/en/master/usage/extensions/example_numpy.html#example-numpy) for Python Docstring Conventions. During the [documentation building](Contributing.md#documentation), we use [sphinx.ext.napoleon](https://www.sphinx-doc.org/en/master/usage/extensions/napoleon.html) to generate Python API documentation from Docstring.
* For docstrings, please refer to [numpydoc docstring guide](https://numpydoc.readthedocs.io/en/latest/format.html) and [pandas docstring guide](https://python-sprints.github.io/pandas/guide/pandas_docstring.html)
* For function docstring, **description**, **Parameters**, and **Returns**/**Yields** are mandatory.
* For class docstring, **description**, **Attributes** are mandatory.

## Documentation
Our documentation is built with [sphinx](http://sphinx-doc.org/), supporting [Markdown](https://guides.github.com/features/mastering-markdown/) and [reStructuredText](http://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html) format. All our documentations are placed under [docs/en_US](https://github.com/Microsoft/nni/tree/master/docs).
Expand All @@ -48,4 +51,4 @@ Our documentation is built with [sphinx](http://sphinx-doc.org/), supporting [Ma

* For links, please consider using __relative paths__ first. However, if the documentation is written in Markdown format, and:
* It's an image link which needs to be formatted with embedded html grammar, please use global URL like `https://user-images.githubusercontent.com/44491713/51381727-e3d0f780-1b4f-11e9-96ab-d26b9198ba65.png`, which can be automatically generated by dragging picture onto [Github Issue](https://github.com/Microsoft/nni/issues/new) Box.
* It cannot be re-formatted by sphinx, such as source code, please use its global URL. For source code that links to our github repo, please use URLs rooted at `https://github.com/Microsoft/nni/tree/master/` ([mnist.py](https://github.com/Microsoft/nni/blob/master/examples/trials/mnist/mnist.py) for example).
* It cannot be re-formatted by sphinx, such as source code, please use its global URL. For source code that links to our github repo, please use URLs rooted at `https://github.com/Microsoft/nni/tree/master/` ([mnist.py](https://github.com/Microsoft/nni/blob/master/examples/trials/mnist/mnist.py) for example).
13 changes: 11 additions & 2 deletions docs/en_US/sdk_reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ Tuner
.. autoclass:: nni.evolution_tuner.evolution_tuner.EvolutionTuner
:members:

.. autoclass:: nni.smac_tuner.smac_tuner.SMACTuner
.. autoclass:: nni.smac_tuner.SMACTuner
:members:

.. autoclass:: nni.gridsearch_tuner.gridsearch_tuner.GridSearchTuner
.. autoclass:: nni.gridsearch_tuner.GridSearchTuner
:members:

.. autoclass:: nni.networkmorphism_tuner.networkmorphism_tuner.NetworkMorphismTuner
Expand All @@ -36,6 +36,15 @@ Tuner
.. autoclass:: nni.metis_tuner.metis_tuner.MetisTuner
:members:

.. autoclass:: nni.ppo_tuner.PPOTuner
:members:

.. autoclass:: nni.batch_tuner.batch_tuner.BatchTuner
:members:

.. autoclass:: nni.gp_tuner.gp_tuner.GPTuner
:members:

Assessor
------------------------
.. autoclass:: nni.assessor.Assessor
Expand Down
2 changes: 1 addition & 1 deletion src/nni_manager/common/experimentStartupInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class ExperimentStartupInfo {
this.initialized = true;

if (logDir !== undefined && logDir.length > 0) {
this.logDir = path.join(logDir, getExperimentId());
this.logDir = path.join(path.normalize(logDir), getExperimentId());
} else {
this.logDir = path.join(os.homedir(), 'nni', 'experiments', getExperimentId());
}
Expand Down
28 changes: 14 additions & 14 deletions src/nni_manager/training_service/common/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,11 @@ export async function validateCodeDir(codeDir: string) : Promise<number> {
*/
export async function execMkdir(directory: string, share: boolean = false): Promise<void> {
if (process.platform === 'win32') {
await cpp.exec(`powershell.exe New-Item -Path ${directory} -ItemType "directory" -Force`);
await cpp.exec(`powershell.exe New-Item -Path "${directory}" -ItemType "directory" -Force`);
} else if (share) {
await cpp.exec(`(umask 0; mkdir -p ${directory})`);
await cpp.exec(`(umask 0; mkdir -p '${directory}')`);
} else {
await cpp.exec(`mkdir -p ${directory}`);
await cpp.exec(`mkdir -p '${directory}'`);
}

return Promise.resolve();
Expand All @@ -87,9 +87,9 @@ export async function execMkdir(directory: string, share: boolean = false): Prom
*/
export async function execCopydir(source: string, destination: string): Promise<void> {
if (process.platform === 'win32') {
await cpp.exec(`powershell.exe Copy-Item ${source} -Destination ${destination} -Recurse`);
await cpp.exec(`powershell.exe Copy-Item "${source}" -Destination "${destination}" -Recurse`);
} else {
await cpp.exec(`cp -r ${source} ${destination}`);
await cpp.exec(`cp -r '${source}' '${destination}'`);
}

return Promise.resolve();
Expand All @@ -101,9 +101,9 @@ export async function execCopydir(source: string, destination: string): Promise<
*/
export async function execNewFile(filename: string): Promise<void> {
if (process.platform === 'win32') {
await cpp.exec(`powershell.exe New-Item -Path ${filename} -ItemType "file" -Force`);
await cpp.exec(`powershell.exe New-Item -Path "${filename}" -ItemType "file" -Force`);
} else {
await cpp.exec(`touch ${filename}`);
await cpp.exec(`touch '${filename}'`);
}

return Promise.resolve();
Expand All @@ -115,9 +115,9 @@ export async function execNewFile(filename: string): Promise<void> {
*/
export function runScript(filePath: string): cp.ChildProcess {
if (process.platform === 'win32') {
return cp.exec(`powershell.exe -ExecutionPolicy Bypass -file ${filePath}`);
return cp.exec(`powershell.exe -ExecutionPolicy Bypass -file "${filePath}"`);
} else {
return cp.exec(`bash ${filePath}`);
return cp.exec(`bash '${filePath}'`);
}
}

Expand All @@ -128,9 +128,9 @@ export function runScript(filePath: string): cp.ChildProcess {
export async function execTail(filePath: string): Promise<cpp.childProcessPromise.Result> {
let cmdresult: cpp.childProcessPromise.Result;
if (process.platform === 'win32') {
cmdresult = await cpp.exec(`powershell.exe Get-Content ${filePath} -Tail 1`);
cmdresult = await cpp.exec(`powershell.exe Get-Content "${filePath}" -Tail 1`);
} else {
cmdresult = await cpp.exec(`tail -n 1 ${filePath}`);
cmdresult = await cpp.exec(`tail -n 1 '${filePath}'`);
}

return Promise.resolve(cmdresult);
Expand All @@ -142,9 +142,9 @@ export async function execTail(filePath: string): Promise<cpp.childProcessPromis
*/
export async function execRemove(directory: string): Promise<void> {
if (process.platform === 'win32') {
await cpp.exec(`powershell.exe Remove-Item ${directory} -Recurse -Force`);
await cpp.exec(`powershell.exe Remove-Item "${directory}" -Recurse -Force`);
} else {
await cpp.exec(`rm -rf ${directory}`);
await cpp.exec(`rm -rf '${directory}'`);
}

return Promise.resolve();
Expand Down Expand Up @@ -173,7 +173,7 @@ export function setEnvironmentVariable(variable: { key: string; value: string })
if (process.platform === 'win32') {
return `$env:${variable.key}="${variable.value}"`;
} else {
return `export ${variable.key}=${variable.value}`;
return `export ${variable.key}='${variable.value}'`;
}
}

Expand Down
12 changes: 6 additions & 6 deletions src/nni_manager/training_service/local/localTrainingService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -490,18 +490,18 @@ class LocalTrainingService implements TrainingService {
const script: string[] = [];
if (process.platform === 'win32') {
script.push(
`cmd.exe /c ${localTrialConfig.command} 2>${path.join(workingDirectory, 'stderr')}`,
`cmd.exe /c ${localTrialConfig.command} 2>"${path.join(workingDirectory, 'stderr')}"`,
`$NOW_DATE = [int64](([datetime]::UtcNow)-(get-date "1/1/1970")).TotalSeconds`,
`$NOW_DATE = "$NOW_DATE" + (Get-Date -Format fff).ToString()`,
`Write $LASTEXITCODE " " $NOW_DATE | Out-File ${path.join(workingDirectory, '.nni', 'state')} -NoNewline -encoding utf8`);
`Write $LASTEXITCODE " " $NOW_DATE | Out-File "${path.join(workingDirectory, '.nni', 'state')}" -NoNewline -encoding utf8`);
} else {
script.push(`eval ${localTrialConfig.command} 2>${path.join(workingDirectory, 'stderr')}`);
script.push(`eval ${localTrialConfig.command} 2>"${path.join(workingDirectory, 'stderr')}"`);
if (process.platform === 'darwin') {
// https://superuser.com/questions/599072/how-to-get-bash-execution-time-in-milliseconds-under-mac-os-x
// Considering the worst case, write 999 to avoid negative duration
script.push(`echo $? \`date +%s999\` >${path.join(workingDirectory, '.nni', 'state')}`);
script.push(`echo $? \`date +%s999\` >'${path.join(workingDirectory, '.nni', 'state')}'`);
} else {
script.push(`echo $? \`date +%s%3N\` >${path.join(workingDirectory, '.nni', 'state')}`);
script.push(`echo $? \`date +%s%3N\` >'${path.join(workingDirectory, '.nni', 'state')}'`);
}
}

Expand All @@ -522,7 +522,7 @@ class LocalTrainingService implements TrainingService {
if (process.platform !== 'win32') {
runScriptContent.push('#!/bin/bash');
}
runScriptContent.push(`cd ${this.localTrialConfig.codeDir}`);
runScriptContent.push(`cd '${this.localTrialConfig.codeDir}'`);
for (const variable of variables) {
runScriptContent.push(setEnvironmentVariable(variable));
}
Expand Down
Loading

0 comments on commit 7620e7c

Please sign in to comment.