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

update nnicli #2713

Merged
merged 24 commits into from
Aug 12, 2020
Merged

update nnicli #2713

merged 24 commits into from
Aug 12, 2020

Conversation

JunweiSUN
Copy link
Contributor

update nnicli with more flexibility. Add nnicli docs

@chicm-ms chicm-ms closed this Jul 23, 2020
@chicm-ms chicm-ms reopened this Jul 23, 2020
@ultmaster ultmaster requested a review from chicm-ms July 24, 2020 09:08
@scarlett2018 scarlett2018 mentioned this pull request Jul 24, 2020
66 tasks

nc.start_experiment('nni/examples/trials/mnist-pytorch/config.yml', port=9090) # start an experiment

nc.set_endpoint('http://localhost:9090') # set the experiment's endpoint, i.e., the url of Web UI
Copy link
Contributor

Choose a reason for hiding this comment

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

what is this API used for? after an experiment is created, the endpoint is fixed, right? why we need to set it?

Copy link
Contributor

Choose a reason for hiding this comment

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

i see, need to set this endpoint in order to query restful APIs.

Copy link
Contributor

Choose a reason for hiding this comment

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

is it possible to automatically detect this endpoint? because it is counter intuitive that user is required to set endpoint

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agree with you. Maybe we can get the endpoint when user use start_experiment. But if user wants to conduct some operation on other experiments, they still need to set the endpoint by their own.

@@ -0,0 +1,41 @@
# NNI Client

NNI client is a python API of `nnictl`, which implements the most common used commands. Users can use this API to control their experiments, collect experiment results and conduct advanced analyses based on experiment results in python code directly instead of using command line. Here is an example:
Copy link
Contributor

Choose a reason for hiding this comment

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

common used -> commonly used

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

@QuanluZhang
Copy link
Contributor

@JunweiSUN this pr looks good. we can schedule a quick meeting to see how to further improve nnicli

@JunweiSUN
Copy link
Contributor Author

@QuanluZhang Sure. I'll make arrangements for this.

Comment on lines 99 to 107
if _create_process(cmd) != 0:
raise RuntimeError('Failed to start experiment, please check your config.')
else:
if port:
self.port = port
else:
self.port = 8080
self.endpoint = 'http://localhost:{}'.format(self.port)
self.exp_id = self.get_experiment_profile()['id']
Copy link
Contributor

Choose a reason for hiding this comment

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

suggest to put this part into a dedicated private member function

Copy link
Contributor Author

Choose a reason for hiding this comment

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

add a new private function _exec_command

@@ -14,7 +14,7 @@
def validate_digit(value, start, end):
'''validate if a digit is valid'''
if not str(value).isdigit() or int(value) < start or int(value) > end:
raise ValueError('%s must be a digit from %s to %s' % (value, start, end))
raise ValueError('%s must be a digit from %s to %s' % ('value', start, end))
Copy link
Contributor

Choose a reason for hiding this comment

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

it is strange that you add quote on value

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think there used to be a typo here. If the value is 1, it's strange to raise a error like ValueError('1 must be a digit from 1 to 1000' % (value, start, end)). Instead, it should be ValueError('value must be a digit from 1 to 1000' % (value, start, end))

Copy link
Contributor

@QuanluZhang QuanluZhang Aug 10, 2020

Choose a reason for hiding this comment

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

then it should be raise ValueError('value must be a digit from %s to %s' % (start, end)). i still suggest the following:
raise ValueError('value (%s) must be a digit from %s to %s' % (value, start, end))

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Goog idea. Will fix.

@@ -135,17 +135,6 @@ testCases:
validator:
class: ExportValidator

- name: nnicli
Copy link
Contributor

Choose a reason for hiding this comment

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

why remove all the tests?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I used to think that it is difficult to split the test to launchCommand and stopCommand since we use an instance to handle an experiment. Maybe I could connect to an existing experiment in stopCommand. Will add the tests again.

@QuanluZhang
Copy link
Contributor

@JunweiSUN this pr looks good now, please resolve the comments.

@QuanluZhang QuanluZhang requested a review from ultmaster August 11, 2020 03:40
hyper parameters for this trial
value:
final result
id:
Copy link
Contributor

Choose a reason for hiding this comment

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

what is the relation between this id and trialJobId in NNITrialMetricData?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I follow the keys defined in the api, here they should be same value.


Attributes
----------
parameter:
Copy link
Contributor

Choose a reason for hiding this comment

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

please add type for attributes and parameters

Copy link
Contributor

Choose a reason for hiding this comment

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

what is the relation between parameter and NNITrialHyperParameters?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

parameter in TrialResult is the same as parameters in TrialHyperParameters

NNI client is a python API of `nnictl`, which implements the most commonly used commands. Users can use this API to control their experiments, collect experiment results and conduct advanced analyses based on experiment results in python code directly instead of using command line. Here is an example:

```
from nnicli import NNIExperiment
Copy link
Contributor

Choose a reason for hiding this comment

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

I prefer Experiment instead of NNIExperiment

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sounds good. Will change

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed.


Attributes
----------
parameter:
Copy link
Contributor

Choose a reason for hiding this comment

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

Please add types for attributes and parameters

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed.

self.sequence = None
self.data = None
for key in json_obj.keys():
self.__setattr__(key, json_obj[key])
Copy link
Contributor

Choose a reason for hiding this comment

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

setattr(self, key,

self.startTime, self.endTime, self.finalMetricData, self.stderrPath)

class NNIExperiment:
def __init__(self):
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggest ban this __init__ method and implement several class methods including start_experiment, from_existing_experiment.

Copy link
Contributor

Choose a reason for hiding this comment

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

not suggest to use class methods, member function is enough, which is simpler

cmd += '--port {}'.format(port).split(' ')
if debug:
cmd += ['--debug']
self._exec_command(cmd, port)
Copy link
Contributor

Choose a reason for hiding this comment

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

Better if this is a classmethod that creates and returns a new experiment object.

Copy link
Contributor

Choose a reason for hiding this comment

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

it is okay to write in this way :)


class NNIExperiment:
def __init__(self):
self.endpoint = None
Copy link
Contributor

Choose a reason for hiding this comment

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

endpoint, port, exp_id should be properties that does not allow external modification.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed.

parameter index
"""
def __init__(self, json_obj):
self.id = None
Copy link
Contributor

Choose a reason for hiding this comment

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

I think these all should be properties.

Copy link
Contributor Author

@JunweiSUN JunweiSUN Aug 11, 2020

Choose a reason for hiding this comment

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

I think we should allow users to modify these "data".

self.finalMetricData = None
self.stderrPath = None
for key in json_obj.keys():
self.__setattr__(key, json_obj[key])
Copy link
Contributor

Choose a reason for hiding this comment

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

Check hasattr(self, key) before setattr

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed.

@@ -110,8 +110,8 @@ testCases:
config:
maxTrialNum: 4
trialConcurrency: 4
launchCommand: python3 -c 'import nnicli as nc; nc.start_nni("$configFile")'
stopCommand: python3 -c 'import nnicli as nc; nc.stop_nni()'
launchCommand: python3 -c 'from nnicli import NNIExperiment; exp = NNIExperiment(); exp.start_experiment("$configFile")'
Copy link
Contributor

Choose a reason for hiding this comment

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

nnicli.Experiment.start_experiment(...) preferred.

launchCommand: python3 -c 'import nnicli as nc; nc.start_nni("$configFile")'
stopCommand: python3 -c 'import nnicli as nc; nc.stop_nni()'
launchCommand: python3 -c 'from nnicli import NNIExperiment; exp = NNIExperiment(); exp.start_experiment("$configFile")'
stopCommand: python3 -c 'from nnicli import NNIExperiment; exp = NNIExperiment(); exp.connect_experiment("http://localhost:8080/"); exp.stop_experiment()'
Copy link
Contributor

Choose a reason for hiding this comment

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

nnicli.Experiment.from_existing_experiment(...).stop() preferred.

@chicm-ms
Copy link
Contributor

examples/notebooks/retrieve_nni_info_with_python.ipynb needs to be updated.

exp.connect_experiment(rest_endpoint)
print(exp.get_job_statistics())
print(exp.get_experiment_status())
print(exp.list_trial_jobs())
Copy link
Contributor

Choose a reason for hiding this comment

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

missing end of line.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed.

@ultmaster ultmaster merged commit f82ef62 into microsoft:master Aug 12, 2020
LovPe pushed a commit to LovPe/nni that referenced this pull request Aug 17, 2020
(cherry picked from commit f82ef62)
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants