Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add nnictl command to list trial results with highest/lowest metric #2747

Merged
merged 15 commits into from
Aug 12, 2020

Conversation

tabVersion
Copy link
Contributor

nnictl experiment head
nnictl experiment tail

@SparkSnail
Copy link
Contributor

What is the user scenario of this command? How do you handle dict metric?

else:
print_error('Restful server is not Running')

def experiment_tail(args):
Copy link
Contributor

Choose a reason for hiding this comment

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

experiment_tail and experiment_head can be implemented with one function, use the sort order as parameter.

if int(args.num) > len(content):
print_error('Required number is too large.')
return
content = sorted(content, key=lambda x: float(x['data'][2: -2]), reverse=True)
Copy link
Contributor

Choose a reason for hiding this comment

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

If the metric is of dict type, use 'default' key to sort.

@tabVersion
Copy link
Contributor Author

It is for users who can not access webui on the server. I saw the demand in the NNI group in WeChat.
The Dict metric is not handled currently. I use the metric-data-latest API, which only contains data of default metric.

'n trials with the highest metric')
parser_experiment_head.add_argument('id', nargs='?', help='the id of experiment')
parser_experiment_head.add_argument('--num', default=10, help='the number of items to be listed')
parser_experiment_head.set_defaults(func=experiment_head)
Copy link
Contributor

Choose a reason for hiding this comment

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

Can nnictl trial ls with sorting do the same work?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Users usually want to focus on top maximal/minimal trials. I think nnictl trials ls offer too much info and users cannot clearly see the overall situation of the experiment.
I want to provide an interface to the general situation of the experiment just like ↓.
image

Copy link
Contributor

@chicm-ms chicm-ms Jul 31, 2020

Choose a reason for hiding this comment

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

OK, got it, suggest to reuse nnictl trial command since we are listing the trials.
Consider following options :

  1. add options to nnictl trial ls, such as nnictl trial ls -n 10 --sort asc --detail
  2. nnictl trial head 10 , nnictl trial tail 10

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The latter looks good to me. How about nnictl trial head 10 --reverse True instead of nnictl trial tail 10.

Copy link
Contributor

Choose a reason for hiding this comment

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

head 10 --reverse maybe misunderstood as reverse sorting the the top 10, not bottom 10. The meaning of tail 10 is clear.

@tabVersion
Copy link
Contributor Author

tabVersion commented Jul 31, 2020

It can handle dict metric by keeping only the default part.
For example, if give {'acc': 0.5, 'default': 0.7}, this command will sort on key default and only show default part.
Here is an instance:

$nnictl trial head Xhc1YImB -n 5 -r
INFO:  ----------------------------------------------------------------------------------------
                Experiment Top Minimal Trials
Trial id: eZ5ci         Default metric: 93.64
Trial id: bRVNu         Default metric: 94.24
Trial id: MkYEz         Default metric: 95.36
Trial id: EiL7P         Default metric: 95.62
Trial id: FtMIJ         Default metric: 96.49

----------------------------------------------------------------------------------------

@tabVersion
Copy link
Contributor Author

I have a concern to use eval when dealing with serialized data because eval is not safe.

@tabVersion tabVersion closed this Aug 6, 2020
@tabVersion tabVersion reopened this Aug 6, 2020
@tabVersion tabVersion closed this Aug 7, 2020
@tabVersion tabVersion reopened this Aug 7, 2020

Note that if `--num` exceeds the number of trials, all trial results are listed.

* __nnictl trial tail__
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 merge tail and head into nnictl trial ls. what do you think? @chicm-ms @SparkSnail

Copy link
Contributor

Choose a reason for hiding this comment

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

agree, nnictl trial ls show all of trial results, and this nnictl trial tail filter trial results, we can merge them to nnictl trial ls --tail {number} to simplify nnictl.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My concern is that nnictl trial ls shows too much information and it is displayed in JSON format. Users cannot see the desired results at first glance even if trial results are sorted. Can we show the information in tables?

Copy link
Contributor

Choose a reason for hiding this comment

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

@tabVersion i don't get. what do you mean?

@ultmaster ultmaster mentioned this pull request Aug 12, 2020
66 tasks
@@ -102,6 +102,8 @@ def parse_args():
parser_trial_subparsers = parser_trial.add_subparsers()
parser_trial_ls = parser_trial_subparsers.add_parser('ls', help='list trial jobs')
parser_trial_ls.add_argument('id', nargs='?', help='the id of experiment')
parser_trial_ls.add_argument('--head', type=int)
parser_trial_ls.add_argument('--tail', type=int)
Copy link
Contributor

Choose a reason for hiding this comment

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

please follow other commands' coding style

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

@@ -259,6 +274,15 @@ def trial_ls(args):
response = rest_get(trial_jobs_url(rest_port), REST_TIME_OUT)
if response and check_response(response):
content = json.loads(response.text)
if args.head:
assert int(args.head) > 0, 'The number of requested data must be greater than 0.'
args.head = min(int(args.head), len(content))
Copy link
Contributor

Choose a reason for hiding this comment

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

why use int(args.head)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry, I don't know if specify the arg's type as int, it will be converted to int.

Comment on lines 279 to 281
args.head = min(int(args.head), len(content))
content = sorted(filter(lambda x: 'finalMetricData' in x, content),
key=cmp_to_key(final_metric_data_cmp), reverse=True)[:args.head]
Copy link
Contributor

Choose a reason for hiding this comment

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

this logic is not correct

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

elif args.tail:
assert int(args.tail) > 0, 'The number of requested data must be greater than 0.'
args.tail = min(int(args.tail), len(content))
content = sorted(content, key=cmp_to_key(final_metric_data_cmp))[:args.tail]
Copy link
Contributor

Choose a reason for hiding this comment

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

no filter here

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 QuanluZhang merged commit 44954e0 into microsoft:master Aug 12, 2020
LovPe pushed a commit to LovPe/nni that referenced this pull request Aug 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants