Skip to content

Conversation

Landanjs
Copy link
Contributor

@Landanjs Landanjs commented Mar 5, 2022

I may have misunderstood the assignment, but attempting to address #640 and #510.

Essentially:

  • Added a check for range objects in ensure_tuple() since these were the last type of Sequence we did not support.
  • Changed T | Tuple[T] | List[T] in Many to T | Sequence[T]
  • Changed docstrings and instances of T | Tuple | List to Many

If this actually looks right, I will add tests for ensure_tuple and every sequence type.

Side note: I'm a little confused when to use PytorchSchedulers vs ComposerSchedulers

@Landanjs Landanjs requested a review from ravi-mosaicml March 5, 2022 01:57
@Landanjs Landanjs changed the title First pass fix ensure_tuple Fix ensure_tuple() to work with all Sequence types Mar 5, 2022
@ravi-mosaicml
Copy link
Contributor

There's some additional typing stuff will need to be adjust in iter_helpers.pyi -- specifically we'll need an additional overload methods to take a generic sequence and for str, bytes, and range objects.



def ensure_tuple(x):
def ensure_tuple(x) -> Tuple[Any, ...]:
Copy link
Contributor

Choose a reason for hiding this comment

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

iter_helpers.py is the exception to the rule and does not contain any type annotations itself. Instead, iter_helpers.pyi contains all the type annotations for iter_helpers.py

if isinstance(x, tuple):
return x
if isinstance(x, list):
if isinstance(x, (tuple, list, range)):
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
if isinstance(x, (tuple, list, range)):
if isinstance(x, (tuple, list, range, collections.abc.Sequence)):

@ravi-mosaicml
Copy link
Contributor

Side note: I'm a little confused when to use PytorchSchedulers vs ComposerSchedulers

Good point; this will need to be clarified in the docs somewhere. At a high level, ComposerSchedulers are acceptable to use when constructing the trainer, but they are converted to PyTorchSchedulers which are used internally. (ComposerSchedulers simply return the learning rate factor and don't update the optimizer; instead, the trainer "compiles" them into a PyTorch LambdaLR scheduler)

@Landanjs
Copy link
Contributor Author

Landanjs commented Mar 7, 2022

I think I addressed most comments, but I'm not very familiar with interfaces so it's likely a set that up wrong 😅.

I will start making tests now

I have a couple of docstring consistency questions that maybe should be addressed somewhere else:

  1. Should I remove the :attr:from types in the state docstring (specifically inState`)? They don't seem necessary, but not sure if that is the appropriate format. The dataloaders don't seem to have these.
  2. Should we use the aliases Tensor and Optimizer in docstrings? To me, it adds an extra click to figure out the actual type with little benefit.
  3. Should Algorithms and Callbacks have the same type format as optimizers and schedulers i.e. they accept a single object or a sequence of objects? Right now, they are Sequence[Algorithms]
  4. To align with removing plurals, should Tensors -> Tensor | Sequence[Tensor] in docstrings?

@Landanjs Landanjs requested a review from ravi-mosaicml March 7, 2022 19:54
@Landanjs
Copy link
Contributor Author

Landanjs commented Mar 7, 2022

Errr, there are a lot of Sequence object errors now... For example:

    first_optimizer = state.optimizers[0]
    expected_param_groups = deepcopy(first_optimizer.param_groups)
    

The second line gets error: Cannot access member "param_groups" for type "Sequence[Optimizer]". Do these need to be manually cast?

@ravi-mosaicml
Copy link
Contributor

ravi-mosaicml commented Mar 10, 2022

I think I addressed most comments, but I'm not very familiar with interfaces so it's likely a set that up wrong sweat_smile.

I will start making tests now

I have a couple of docstring consistency questions that maybe should be addressed somewhere else:

  1. Should I remove the :attr:from types in the state docstring (specifically inState`)? They don't seem necessary, but not sure if that is the appropriate format. The dataloaders don't seem to have these.

It depends on what is being referenced; sometimes, :attr: is needed to get sphinx to link properly.
Ideally, we would use :attr: notation for every attribute, but I think we're doing it only for stuff not set on init.

  1. Should we use the aliases Tensor and Optimizer in docstrings? To me, it adds an extra click to figure out the actual type with little benefit.

Good point; let's go with the torch types. I'd eventually like to remove types.py or make it significantly leaner.

  1. Should Algorithms and Callbacks have the same type format as optimizers and schedulers i.e. they accept a single object or a sequence of objects? Right now, they are Sequence[Algorithms]

Yes, let's do the "singleton or sequence" approach.

  1. To align with removing plurals, should Tensors -> Tensor | Sequence[Tensor] in docstrings?

Yup!

@ravi-mosaicml
Copy link
Contributor

Errr, there are a lot of Sequence object errors now... For example:

    first_optimizer = state.optimizers[0]
    expected_param_groups = deepcopy(first_optimizer.param_groups)
    

The second line gets error: Cannot access member "param_groups" for type "Sequence[Optimizer]". Do these need to be manually cast?

It shouldn't need a manual cast; double check the type annotation for ensure_tuple.

@ravi-mosaicml
Copy link
Contributor

@Landanjs I pushed a commit that (hopefully?) fixes the type errors with the ensure_tuple change.
If you could finish up the docs fixes in this PR, that'd be awesome.

@Landanjs
Copy link
Contributor Author

The recent change tries to:

  1. Use PyTorch's Tensor, Optimizer, Module classes where possible
  2. Remove Tenors
  3. Attempts to fix missing docstring links by prepending types.
  4. Remove the illusion of multiple optimizer from docstrings

I did not convert Callbacks and Loggers to "singleton or sequence" format since these are converted into lists instead of tuples and I'm not confident the functionality is the same? But maybe should be changed in the future

Copy link
Contributor

@ravi-mosaicml ravi-mosaicml left a comment

Choose a reason for hiding this comment

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

Looking good! Main feedback is to remove the plural types from types.py (sorry I didn't mention this before) and the rest of the codebase (so we'll specify Unions in the type annotations, where necessary). Then I think it should be good to merge!

initialize optimizers.
Tensor (torch.Tensor): Alias for :class:`torch.Tensor`.
Tensors (Tensor | Tuple[Tensor, ...] | List[Tensor]): Commonly used to represent e.g. a set of inputs,
Tensors (torch.Tensor | Sequence[torch.Tensor]): Commonly used to represent e.g. a set of inputs,
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you remove this docstring (and the associated type alias below in the code)?

Metrics (Metric | MetricCollection): Union type covering common formats for representing metrics.
Optimizer (torch.optim.Optimizer): Alias for :class:`torch.optim.Optimizer`
Optimizers (Optimizer | List[Optimizer] | Tuple[Optimizer, ...]): Union type for indeterminate amounts of optimizers.
Optimizers (torch.optim.Optimizer | Sequence[torch.optim.Optimizer]): Union type for indeterminate amounts of
Copy link
Contributor

Choose a reason for hiding this comment

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

Same as above -- can you remove this docstring (and the associated type alias below in the code)?

as :class:`torch.optim.lr_scheduler.ConstantLR`
Scaler (torch.cuda.amp.grad_scaler.GradScaler): Alias for :class:`torch.cuda.amp.GradScaler`.
JSON (str | float | int | None | List['JSON'] | Dict[str, 'JSON']): JSON Data
Evaluators (Many[Evaluator]): Union type for indeterminate amounts of evaluators.
Copy link
Contributor

Choose a reason for hiding this comment

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

Same as above -- can you remove this docstring (and the associated type alias below in the code)?


T = TypeVar('T')
Many = Union[T, Tuple[T, ...], List[T]]
Many = Union[T, Sequence[T]]
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's remove Many too


Tensor = torch.Tensor
Tensors = Many[Tensor]
Tensors = Union[Tensor, Sequence[Tensor]]
Copy link
Contributor

Choose a reason for hiding this comment

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

Same thing...removing the aliases here will ensure that we removed them throughout the entire codebase, and use the underlying Union[X, Sequence[X]] notation in the codebase throughout.

.. seealso:: :mod:`composer.optim` for the different optimizers built into Composer.
schedulers (Schedulers, optional): The learning rate schedulers. If ``[]`` or ``None``, will be set to
``[constant_scheduler]``. (default: ``None``).
schedulers (types.PyTorchScheduler or Sequence[types.PyTorchScheduler], optional):
Copy link
Contributor

Choose a reason for hiding this comment

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

The trainer takes both pytorch schedulers or composer schedulers.

Suggested change
schedulers (types.PyTorchScheduler or Sequence[types.PyTorchScheduler], optional):
schedulers (types.ComposerScheduler | types.PyTorchScheduler | Sequence[types.ComposerScheduler | types.PyTorchScheduler], optional):

schedulers (Schedulers, optional): The learning rate schedulers. If ``[]`` or ``None``, will be set to
``[constant_scheduler]``. (default: ``None``).
schedulers (types.PyTorchScheduler or Sequence[types.PyTorchScheduler], optional):
The learning rate schedulers. If ``[]`` or ``None``, will be set to ``[constant_scheduler]``.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
The learning rate schedulers. If ``[]`` or ``None``, will be set to ``[constant_scheduler]``.
The learning rate schedulers. If ``[]`` or ``None``, the learning rate will be constant.

@Landanjs Landanjs requested a review from ravi-mosaicml March 16, 2022 00:09
@ravi-mosaicml
Copy link
Contributor

There appear to be a few docstring formatting warnings that need to be fixed (Docstring warnings are treated as errors and cause the build to fail).

00:04:06.043  /home/mosaicml/.local/lib/python3.9/site-packages/composer/trainer/trainer.py:docstring of composer.trainer.trainer.Trainer:39: WARNING: Field list ends without a blank line; unexpected unindent.
00:04:06.043  /home/mosaicml/.local/lib/python3.9/site-packages/composer/trainer/trainer.py:docstring of composer.trainer.trainer.Trainer:42: WARNING: Inline substitution_reference start-string without end-string.
00:04:06.043  /home/mosaicml/.local/lib/python3.9/site-packages/composer/trainer/trainer.py:docstring of composer.trainer.trainer.Trainer:44: WARNING: Definition list ends without a blank line; unexpected unindent.

ravi-mosaicml and others added 8 commits March 16, 2022 12:19
Remove re-exported types from types.py. This should help with code readability, as now the underlying type is directly imported.
`Dict[str, Any]` is almost as short but clearer on what it is (a dictionary with string keys).
Copy link
Contributor

@ravi-mosaicml ravi-mosaicml left a comment

Choose a reason for hiding this comment

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

LGTM!

@Landanjs Landanjs changed the title Fix ensure_tuple() to work with all Sequence types Remove plural types and aliases for native pytorch types Mar 16, 2022
@Landanjs Landanjs merged commit 9387d5c into mosaicml:dev Mar 16, 2022
@Landanjs Landanjs deleted the landan/fix_ensure_tuple branch March 16, 2022 22:27
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.

Update ensure_tuple to support generic sequences for non-strings. Confusing Scheduler and Schedulers types
3 participants