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

Merge v1.4.1 back to master #2144

Merged
merged 7 commits into from
Mar 12, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion deployment/deployment-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ jobs:
export IMG_NAME=$(dev_docker_img)
export IMG_TAG=`git describe --tags --abbrev=0`.`date -u +%y%m%d%H%M`
echo 'updating docker file for testpyi...'
sed -ie 's/RUN python3 -m pip --no-cache-dir install nni/RUN python3 -m pip install --user --no-cache-dir --index-url https:\/\/test.pypi.org\/simple --extra-index-url https:\/\/pypi.org\/simple nni/' Dockerfile
sed -ie 's/RUN python3 -m pip --no-cache-dir install nni/RUN python3 -m pip install --no-cache-dir --index-url https:\/\/test.pypi.org\/simple --extra-index-url https:\/\/pypi.org\/simple nni/' Dockerfile
else
docker login -u $(docker_hub_user) -p $(docker_hub_pwd)
export IMG_NAME=msranni/nni
Expand Down
7 changes: 7 additions & 0 deletions examples/trials/mnist-pytorch/mnist.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@
import torch.optim as optim
from torchvision import datasets, transforms

# Temporary patch this example until the MNIST dataset download issue get resolved
# https://github.com/pytorch/vision/issues/1938
import urllib

opener = urllib.request.build_opener()
opener.addheaders = [('User-agent', 'Mozilla/5.0')]
urllib.request.install_opener(opener)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we still need this fix?


logger = logging.getLogger('mnist_AutoML')

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import logging
import datetime
from nni.assessor import Assessor, AssessResult
from nni.utils import extract_scalar_history
from .model_factory import CurveModel

logger = logging.getLogger('curvefitting_Assessor')
Expand Down Expand Up @@ -91,10 +92,11 @@ def assess_trial(self, trial_job_id, trial_history):
Exception
unrecognize exception in curvefitting_assessor
"""
self.trial_history = trial_history
scalar_trial_history = extract_scalar_history(trial_history)
self.trial_history = scalar_trial_history
if not self.set_best_performance:
return AssessResult.Good
curr_step = len(trial_history)
curr_step = len(scalar_trial_history)
if curr_step < self.start_step:
return AssessResult.Good

Expand All @@ -106,7 +108,7 @@ def assess_trial(self, trial_job_id, trial_history):
start_time = datetime.datetime.now()
# Predict the final result
curvemodel = CurveModel(self.target_pos)
predict_y = curvemodel.predict(trial_history)
predict_y = curvemodel.predict(scalar_trial_history)
logger.info('Prediction done. Trial job id = %s. Predict value = %s', trial_job_id, predict_y)
if predict_y is None:
logger.info('wait for more information to predict precisely')
Expand Down
17 changes: 5 additions & 12 deletions src/sdk/pynni/nni/medianstop_assessor/medianstop_assessor.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import logging
from nni.assessor import Assessor, AssessResult
from nni.utils import extract_scalar_history

logger = logging.getLogger('medianstop_Assessor')

Expand Down Expand Up @@ -91,20 +92,12 @@ def assess_trial(self, trial_job_id, trial_history):
if curr_step < self._start_step:
return AssessResult.Good

try:
num_trial_history = [float(ele) for ele in trial_history]
except (TypeError, ValueError) as error:
logger.warning('incorrect data type or value:')
logger.exception(error)
except Exception as error:
logger.warning('unrecognized exception in medianstop_assessor:')
logger.exception(error)

self._update_data(trial_job_id, num_trial_history)
scalar_trial_history = extract_scalar_history(trial_history)
self._update_data(trial_job_id, scalar_trial_history)
if self._high_better:
best_history = max(trial_history)
best_history = max(scalar_trial_history)
else:
best_history = min(trial_history)
best_history = min(scalar_trial_history)

avg_array = []
for id_ in self._completed_avg_history:
Expand Down
1 change: 1 addition & 0 deletions src/sdk/pynni/nni/msg_dispatcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,4 +234,5 @@ def _earlystop_notify_tuner(self, data):
if multi_thread_enabled():
self._handle_final_metric_data(data)
else:
data['value'] = to_json(data['value'])
self.enqueue_command(CommandType.ReportMetricData, data)
31 changes: 30 additions & 1 deletion src/sdk/pynni/nni/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,13 @@ def extract_scalar_reward(value, scalar_key='default'):
"""
Extract scalar reward from trial result.

Parameters
----------
value : int, float, dict
the reported final metric data
scalar_key : str
the key name that indicates the numeric number

Raises
------
RuntimeError
Expand All @@ -78,6 +85,26 @@ def extract_scalar_reward(value, scalar_key='default'):
return reward


def extract_scalar_history(trial_history, scalar_key='default'):
"""
Extract scalar value from a list of intermediate results.

Parameters
----------
trial_history : list
accumulated intermediate results of a trial
scalar_key : str
the key name that indicates the numeric number

Raises
------
RuntimeError
Incorrect final result: the final result should be float/int,
or a dict which has a key named "default" whose value is float/int.
"""
return [extract_scalar_reward(ele, scalar_key) for ele in trial_history]


def convert_dict2tuple(value):
"""
convert dict type to tuple to solve unhashable problem.
Expand All @@ -90,7 +117,9 @@ def convert_dict2tuple(value):


def init_dispatcher_logger():
""" Initialize dispatcher logging configuration"""
"""
Initialize dispatcher logging configuration
"""
logger_file_path = 'dispatcher.log'
if dispatcher_env_vars.NNI_LOG_DIRECTORY is not None:
logger_file_path = os.path.join(dispatcher_env_vars.NNI_LOG_DIRECTORY, logger_file_path)
Expand Down
24 changes: 16 additions & 8 deletions src/webui/src/components/trial-detail/TableList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -241,13 +241,19 @@ class TableList extends React.Component<TableListProps, TableListState> {
// final result in a succeed trial, it may be a dict.
// get intermediate result dict keys array
const { intermediateKey } = this.state;
let otherkeys: string[] = ['default'];
const otherkeys: string[] = [ ];
if (res.data.length !== 0) {
otherkeys = Object.keys(parseMetrics(res.data[0].data));
// just add type=number keys
const intermediateMetrics = parseMetrics(res.data[0].data);
for(const key in intermediateMetrics){
if(typeof intermediateMetrics[key] === 'number') {
otherkeys.push(key);
}
}
}
// intermediateArr just store default val
Object.keys(res.data).map(item => {
if(res.data[item].type === 'PERIODICAL'){
if (res.data[item].type === 'PERIODICAL') {
const temp = parseMetrics(res.data[item].data);
if (typeof temp === 'object') {
intermediateArr.push(temp[intermediateKey]);
Expand Down Expand Up @@ -278,11 +284,13 @@ class TableList extends React.Component<TableListProps, TableListState> {
// just watch default key-val
if (isShowDefault === true) {
Object.keys(intermediateData).map(item => {
const temp = parseMetrics(intermediateData[item].data);
if (typeof temp === 'object') {
intermediateArr.push(temp[value]);
} else {
intermediateArr.push(temp);
if (intermediateData[item].type === 'PERIODICAL') {
const temp = parseMetrics(intermediateData[item].data);
if (typeof temp === 'object') {
intermediateArr.push(temp[value]);
} else {
intermediateArr.push(temp);
}
}
});
} else {
Expand Down
6 changes: 3 additions & 3 deletions test/generate_ts_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ def update_training_service_config(args):
config[args.ts]['paiConfig']['token'] = args.pai_token
if args.nni_docker_image is not None:
config[args.ts]['trial']['image'] = args.nni_docker_image
if args.nniManagerNFSMountPath is not None:
if args.nni_manager_nfs_mount_path is not None:
config[args.ts]['trial']['nniManagerNFSMountPath'] = args.nni_manager_nfs_mount_path
if args.containerNFSMountPath is not None:
if args.container_nfs_mount_path is not None:
config[args.ts]['trial']['containerNFSMountPath'] = args.container_nfs_mount_path
if args.paiStoragePlugin is not None:
if args.pai_storage_plugin is not None:
config[args.ts]['trial']['paiStoragePlugin'] = args.pai_storage_plugin
if args.vc is not None:
config[args.ts]['trial']['virtualCluster'] = args.vc
Expand Down