-
Notifications
You must be signed in to change notification settings - Fork 5.8k
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
[air] Accessors for preprocessor in Predictor class #26600
Conversation
python/ray/train/batch_predictor.py
Outdated
return self._override_preprocessor | ||
|
||
checkpoint_data = self._checkpoint.to_dict() | ||
preprocessor = checkpoint_data.get(PREPROCESSOR_KEY) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just fyi This implementation currently won’t work for gbdt predictors as they use directory Checkpoints not dict checkpoints
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What’s the user journey that we are trying to solve by introducing these apis?
It seems by doing this we are making assumptions about the underlying checkpoint structure (assuming there is a PREPROCESSOR_KEY in the checkpoint). So these will only work for checkpoints outputted by our trainers and not for the general case. BatchPredictor will no longer work with any predictor and any checkpoint. I’m wondering if there is an alternative solution here to resolve the user problem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it’s just the ability to override the preprocessor, then we currently have other mechanisms to do this and it might just be a matter of documenting them better
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(moved to slack)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@matthewdeng this is the tricky issue
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added Checkpoint.get_preprocessor()
to unify this logic, though it's not optimized in this PR.
Signed-off-by: Matthew Deng <[email protected]>
Signed-off-by: Matthew Deng <[email protected]>
Signed-off-by: Matthew Deng <[email protected]>
Signed-off-by: Matthew Deng <[email protected]>
Signed-off-by: Matthew Deng <[email protected]>
@@ -42,7 +42,8 @@ def from_checkpoint(cls, checkpoint: Checkpoint) -> "LightGBMPredictor": | |||
``LightGBMTrainer`` run. | |||
|
|||
""" | |||
bst, preprocessor = load_checkpoint(checkpoint) | |||
bst, _ = load_checkpoint(checkpoint) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Leaving this line here for now as load_checkpoint
will be removed with #26651
# Ensure the proper conversion functions are called. | ||
convert_to_pandas_mock.assert_called_once() | ||
convert_from_pandas_mock.assert_called_once() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removing these mocks since they cause the prediction logic to no longer be tested. Didn't seem valuable enough of a test to create a second test that just tests the call logic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm I wrote the mocks after our previous discussions on not writing integration tests for everything.
If we make sure the conversion functions are called and since the conversion functions are also tested, then we don’t need to write tests for predictor against all possible input and output types. This was the original intention but the mocks may not have been the best way to achieve this- do you have any other suggestions to not lose this test coverage?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah gotcha. I think in that case I can extend the mocks to return concrete values and validate the inputs/outputs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed offline, what does the developer api look like?
with framework specific checkpoints we should make the base Checkpoint class a developer api, right? This may be out of scope for this PR, so we can do this in a follow up as well!
# Ensure the proper conversion functions are called. | ||
convert_to_pandas_mock.assert_called_once() | ||
convert_from_pandas_mock.assert_called_once() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm I wrote the mocks after our previous discussions on not writing integration tests for everything.
If we make sure the conversion functions are called and since the conversion functions are also tested, then we don’t need to write tests for predictor against all possible input and output types. This was the original intention but the mocks may not have been the best way to achieve this- do you have any other suggestions to not lose this test coverage?
Actually nvm Checkpoint will still be exposed to Tune users who use trainables directly and not any of the trainers. |
Signed-off-by: Matthew Deng <[email protected]>
Signed-off-by: Matthew Deng <[email protected]>
Signed-off-by: Matthew Deng <[email protected]>
The base class should remain a PublicAPI since all the methods are still publicly accessible. Futhermore, you are always allowed to load a checkpoint generically using the base class. |
Agreed for Checkpoint let's keep it as PublicAPI since it will still be exposed to users who are not using any of the Trainers.
For this case, the pattern that we have been following is the class is DeveloperAPI, but individual methods can be denoted as PublicAPI. This is what we do for |
Signed-off-by: Rohan138 <[email protected]>
Signed-off-by: Stefan van der Kleij <[email protected]>
Why are these changes needed?
There is currently no way to get/set a preprocessor on a BatchPredictor / Predictor once created. This makes it very difficult to figure out how to pass a custom preprocessor to a predictor.
Changes
Checkpoint.get_preprocessor()
to unify Preprocessor retrieval logic.Predictor.get_preprocessor()
andPredictor.set_preprocessor()
.BatchPredictor.get_preprocessor()
andBatchPredictor.set_preprocessor()
.Related issue number
Closes #26528
TODO: