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

Use a fixed seed value when seed=None in GridSampler #5490

Merged
merged 9 commits into from
Jun 27, 2024

Conversation

nzw0301
Copy link
Member

@nzw0301 nzw0301 commented Jun 13, 2024

Motivation

Resolve #5489. I'm happy to hear the opinion on this change because I'm not sure why this shuffle was introduced.

Description of the changes

Remove the shuffle.

For distributed optimisation, optuna docs suggest not setting seed for samplers or set different values. In this PR, call shuffle when seed=0.

@eukaryo
Copy link
Collaborator

eukaryo commented Jun 13, 2024

FYI: This shuffling is introduced in PR #4918.

@eukaryo
Copy link
Collaborator

eukaryo commented Jun 13, 2024

When I introduced this PR, I believed that GridSampler should search in a random order. This is because when n_trials < len(self._all_grids), there is no guarantee that the regions searched earlier will have good values. In such cases, RandomSampler tends to evaluate the same point multiple times, whereas GridSampler (with shuffling) is expected to evaluate each point once without duplication. Of course, I agree that the issue should be resolved. However, I believe that the lack of a shuffling option results in a performance loss.

Copy link
Collaborator

@eukaryo eukaryo left a comment

Choose a reason for hiding this comment

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

I have suggested a change. PTAL.

optuna/samplers/_grid.py Outdated Show resolved Hide resolved
@eukaryo
Copy link
Collaborator

eukaryo commented Jun 13, 2024

@not522 could you review this PR? I suppose you are the appropriate reviewer because you were also a reviewer of PR #4918.

Co-authored-by: Hiroki Takizawa <contact@hiroki-takizawa.name>
@nzw0301
Copy link
Member Author

nzw0301 commented Jun 13, 2024

Thank you for your explanation! I agree with you to shuffle the grid!

@nzw0301 nzw0301 changed the title Not shuffle _all_grids Shuffle _all_grids when seed is given Jun 13, 2024
@nzw0301
Copy link
Member Author

nzw0301 commented Jun 13, 2024

Should I add a note or update seed docstring on this? This is still issue when user specify different random seeds among processes.

@eukaryo
Copy link
Collaborator

eukaryo commented Jun 13, 2024

Yes, it would be a great help if you could do that.

@nzw0301
Copy link
Member Author

nzw0301 commented Jun 13, 2024

Thanks. Sure!

Copy link
Collaborator

@eukaryo eukaryo left a comment

Choose a reason for hiding this comment

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

LGTM!

@eukaryo eukaryo added this to the v4.0.0 milestone Jun 17, 2024
@eukaryo eukaryo added the bug Issue/PR about behavior that is broken. Not for typos/examples/CI/test but for Optuna itself. label Jun 17, 2024
@eukaryo eukaryo removed their assignment Jun 17, 2024
@not522
Copy link
Member

not522 commented Jun 21, 2024

This PR makes the order of trials fixed for seed=None. It will be a breaking change, so I'm thinking how to resolve #5489 without this problem...

@eukaryo
Copy link
Collaborator

eukaryo commented Jun 22, 2024

In my current understanding, the requirements can be organized and enumerated as follows:

  1. If seed=None, search order should be shuffled. (From the historical background; initial implementation bahaves that way.)
  2. If seed=None, search order should be shuffled differently each time. (Because someone may have set up an experimental system that assumes this (expecially in a non-distributed environment).)
  3. If seed=None, duplicates should not occur in a distributed environment (issue#5489).
  4. _get_unvisited_grid_ids calls get_all_trials internally, which is heavy and I wanted to avoid calling it (PR#4918). Additionally, the process including _get_unvisited_grid_ids is not atomic, so it cannot prevent duplication perfectly.

The second request means that the self._rng = LazyRandomState(seed) should be resulted identical across all processes of any distibuted environment when seed=None.

If we want all processes to have an unique value in a distributed environment, the only way is to share the value using storage and appropriate transaction process. The only time when this is possible is not during __init__, but during before_trial, because it needs study received as an argument. Therefore, it is simplest to perform transaction processing and shuffling as necessary at the time of before_trial.

This discussion is somewhat complicated, but since it involves historical circumstances and a distributed environment, I believe such complexity is inevitable and unavoidable.

To implement the above plan, we need to enable set_study_system_attr to do "as single transaction, write the value only if the key does not exist, otherwise do nothing". It is necessary to add an optional argument (or new methods) to BaseStorage and all derived storages.

@eukaryo
Copy link
Collaborator

eukaryo commented Jun 25, 2024

After discussion with @not522 -san and others, I have reconsidered the second of the above requirements is not necessary. (It is a little strange that only GridSampler behaves deterministic with seed=None while other Samplers etc. behave stochastic, but I think it is acceptable if explained in the docstring.) Adding functionality to the storage module should be done with the most caution and should not be tied to this PR, nor is it necessary.
Partial revert of PR #4918 is another option, but then Issue #4627 will recur.

Copy link
Collaborator

@nabenabe0928 nabenabe0928 left a comment

Choose a reason for hiding this comment

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

Thank you for the PR!
I added a suggestion to the doc-string.

optuna/samplers/_grid.py Outdated Show resolved Hide resolved
optuna/samplers/_grid.py Outdated Show resolved Hide resolved
Copy link
Collaborator

@nabenabe0928 nabenabe0928 left a comment

Choose a reason for hiding this comment

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

nzw0301 and others added 4 commits June 26, 2024 11:18
Co-authored-by: Naoto Mizuno <gobou522@gmail.com>
Co-authored-by: Shuhei Watanabe <47781922+nabenabe0928@users.noreply.github.com>
@nzw0301 nzw0301 changed the title Shuffle _all_grids when seed is given Use a fixed seed value when seed=None in GridSampler Jun 26, 2024
@nzw0301
Copy link
Member Author

nzw0301 commented Jun 26, 2024

Thank you for your comments and discussions. I've updated the PR by following the suggestions.

Copy link
Collaborator

@nabenabe0928 nabenabe0928 left a comment

Choose a reason for hiding this comment

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

Thank you for the changes!
I added another nit comment.

optuna/samplers/_grid.py Outdated Show resolved Hide resolved
Co-authored-by: Shuhei Watanabe <47781922+nabenabe0928@users.noreply.github.com>
Copy link
Member

@not522 not522 left a comment

Choose a reason for hiding this comment

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

Thank you for your update. It looks good to me.
@nabenabe0928 If you approve this PR, please merge it.

Copy link
Collaborator

@nabenabe0928 nabenabe0928 left a comment

Choose a reason for hiding this comment

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

LGTM!

@nabenabe0928 nabenabe0928 merged commit 38dd5a5 into optuna:master Jun 27, 2024
14 checks passed
@nzw0301 nzw0301 deleted the not-shuffle-grid branch June 27, 2024 02:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issue/PR about behavior that is broken. Not for typos/examples/CI/test but for Optuna itself.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

GridSampler: Duplicates
4 participants