Skip to content

feat: JumpStart alternative config parsing #4566

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

Merged
merged 18 commits into from
Apr 16, 2024

Conversation

Captainia
Copy link
Collaborator

@Captainia Captainia commented Apr 8, 2024

Issue #, if available:

Description of changes:

Initial round of reading and parsing the JumpStart alternative configs.

Class structures that goes from bottom to top:

                       JumpStartMetadataBaseFields 
             (inherits) /                       \(inherits)
       JumpStartModelSpecs             JumpStartConfigComponent   
          (includes)/                            \ (consists)
   JumpStartMetadataConfigs                    JumpStartMetadataConfig
                                                         \ (consists)
                                                JumpStartMetadataConfigs

Testing done:

Merge Checklist

Put an x in the boxes that apply. You can also fill these out after creating the PR. If you're unsure about any of them, don't hesitate to ask. We're here to help! This is simply a reminder of what we are going to look for before merging your pull request.

General

  • I have read the CONTRIBUTING doc
  • I certify that the changes I am introducing will be backward compatible, and I have discussed concerns about this, if any, with the Python SDK team
  • I used the commit message format described in CONTRIBUTING
  • I have passed the region in to all S3 and STS clients that I've initialized as part of this change.
  • I have updated any necessary documentation, including READMEs and API docs (if appropriate)

Tests

  • I have added tests that prove my fix is effective or that my feature works (if appropriate)
  • I have added unit and/or integration tests as appropriate to ensure backward compatibility of the changes
  • I have checked that my tests are not configured for a specific region or account (if appropriate)
  • I have used unique_name_from_base to create resource names in integ tests (if appropriate)

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

return json_obj

@property
def resolved_config(self) -> Dict[str, Any]:
Copy link
Member

Choose a reason for hiding this comment

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

this logic won't work for dicts inside dicts. can you instead do:


def deep_override_dict(dict1: dict, dict2: dict) -> dict:
    """Overrides any overlapping contents of dict1 with the contents of dict2."""
    flattened_dict = flatten(dict1)
    flattened_dict.update(flatten(dict2))
    return unflatten(flattened_dict) if flattened_dict else {}

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I remembered I used something similar before to this but right now I don't see a native Python supported method flatten. There's something similar but doesn't seem it trivially support unflatten: https://pandas.pydata.org/docs/reference/api/pandas.json_normalize.html

class JumpStartPresetComponent(JumpStartMetadataBaseFields):
"""Data class of JumpStart config component."""

slots = ["component_name", "component_override_fields"]
Copy link
Member

Choose a reason for hiding this comment

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

what is component_override_fields?

Copy link
Member

Choose a reason for hiding this comment

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

i guess this is fine, gives us flexibility in the future

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It is the fields that this particular component will override to the JumpStartMetadataBaseFields. Each JumpStartPresetComponent inherits the base class so contains all the base fields, but since we only want to override to these specific fields so I kept a separate list only for them.

@Captainia Captainia marked this pull request as ready for review April 12, 2024 15:54
@Captainia Captainia requested a review from a team as a code owner April 12, 2024 15:54
@Captainia Captainia requested review from nargokul and removed request for a team April 12, 2024 15:54
continue
return self.configs[config_name]

return None
Copy link
Contributor

Choose a reason for hiding this comment

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

The return type should be Optional right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, I'll address this in my next PR, thanks for catching

model_type: enums.JumpStartModelType = enums.JumpStartModelType.OPEN_WEIGHTS,
) -> Dict[str, List[JumpStartMetadataConfig]]:
"""Returns metadata configs for the given model ID and region."""
model_specs = verify_model_region_and_return_specs(
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: this block of code appears 3 times in get_jumpstart_configs, get_benchmark_stats, and get_config_names

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yea I think it's required because we use verify_model_region_and_return_specs as the entry point to get specs in all these utils, and each function can be called standalone. But I think we can probably choose a better naming of verify_model_region_and_return_specs and move outside of utils as it's used heavily everywhere.

@knikure knikure self-assigned this Apr 16, 2024
@@ -1028,22 +1038,23 @@ class JumpStartPresetComponent(JumpStartMetadataBaseFields):

__slots__ = slots + JumpStartMetadataBaseFields.__slots__

def __init__(
def __init__( # pylint: disable=super-init-not-called
Copy link
Member

Choose a reason for hiding this comment

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

why aren't we calling the superclass constructor? This isn't good OOP design IMO, it violates Liskov Substution Principle

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'll update, I left the component to only have its specific fields but not construct all the parent class fields which are optional, but it should work with superclass constructor. Good callout

@knikure knikure merged commit 8bb857f into aws:master Apr 16, 2024
10 checks passed
"""
self.from_json(spec)
self.from_json(fields)
Copy link
Contributor

Choose a reason for hiding this comment

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

how does this work, I don't mypy should accept this signature given that from_json accepts a Dict[str, Any] and get passed an Optional[Dict[str, Any]]. This could cause null pointer errors.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Sorry this is confusing typing, the fields object is Dict[str, Any] but not optional. I think mypy is not checking these typings, updated in my next PR

self.incremental_training_supported: bool = bool(
json_obj.get("incremental_training_supported", False)
json_obj.get("incremental_training_supported")
)
Copy link
Contributor

Choose a reason for hiding this comment

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

all these types are de facto Optional[*] now?

malav-shastri pushed a commit to malav-shastri/sagemaker-python-sdk that referenced this pull request Jun 20, 2024
* add alternative config parsing

* rename a few functions

* refactor based on new mock

* remove commented files

* add interfaces and utils

* various fixes and add some tests

* add more tests

* address comments

* swap presets with configs

* fix: docstyle

* fix: doc

* fix: docstyle

* updates

* typing
jiapinw pushed a commit to jiapinw/sagemaker-python-sdk that referenced this pull request Jun 25, 2024
* add alternative config parsing

* rename a few functions

* refactor based on new mock

* remove commented files

* add interfaces and utils

* various fixes and add some tests

* add more tests

* address comments

* swap presets with configs

* fix: docstyle

* fix: doc

* fix: docstyle

* updates

* typing
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.

8 participants