Skip to content

Add parametrization version of weight_norm#103001

Closed
ezyang wants to merge 3 commits into
gh/ezyang/2133/basefrom
gh/ezyang/2133/head
Closed

Add parametrization version of weight_norm#103001
ezyang wants to merge 3 commits into
gh/ezyang/2133/basefrom
gh/ezyang/2133/head

Conversation

@ezyang

@ezyang ezyang commented Jun 5, 2023

Copy link
Copy Markdown
Contributor

Stack from ghstack (oldest at bottom):

This done in the ordinary way, but also:

  • Deprecation warning for the old API, and a migration guide
  • Backwards compatibility for state_dict loading the old weight_norm
  • Test for pickling and deepcopy, which was the motivating reason

weight_norm is still used by HuggingFace Wav2Vec2.

Signed-off-by: Edward Z. Yang [email protected]

Signed-off-by: Edward Z. Yang <[email protected]>

[ghstack-poisoned]
@pytorch-bot

pytorch-bot Bot commented Jun 5, 2023

Copy link
Copy Markdown

🔗 Helpful Links

🧪 See artifacts and rendered test results at hud.pytorch.org/pr/103001

Note: Links to docs will display an error until the docs builds have been completed.

❌ 1 New Failure

As of commit 1cd8a97:

NEW FAILURE - The following job has failed:

This comment was automatically generated by Dr. CI and updates every 15 minutes.

@ezyang ezyang added release notes: nn release notes category topic: new features topic category labels Jun 5, 2023
ezyang added a commit to ezyang/transformers that referenced this pull request Jun 5, 2023
ezyang added a commit that referenced this pull request Jun 5, 2023
This is not actually enabled in the benchmark suite as you need
#103001 and also training
is broken per #101160
but might as well review this part first.

Contains #102979 but
I will probably rebase past that once it lands.

Signed-off-by: Edward Z. Yang <[email protected]>

[ghstack-poisoned]
Comment thread torch/nn/utils/parametrizations.py Outdated
@ezyang

ezyang commented Jun 5, 2023

Copy link
Copy Markdown
Contributor Author

cc @vadimkantorov

This done in the ordinary way, but also:

* Deprecation warning for the old API, and a migration guide
* Backwards compatibility for state_dict loading the old weight_norm
* Test for pickling and deepcopy, which was the motivating reason

weight_norm is still used by HuggingFace Wav2Vec2.

Signed-off-by: Edward Z. Yang <ezyangmeta.com>

[ghstack-poisoned]
ezyang added a commit that referenced this pull request Jun 5, 2023
This is not actually enabled in the benchmark suite as you need
#103001 and also training
is broken per #101160
but might as well review this part first.

Contains #102979 but
I will probably rebase past that once it lands.

Signed-off-by: Edward Z. Yang <ezyangmeta.com>

cc voznesenskym penguinwu anijain2305 EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng Xia-Weiwen wenzhe-nrv jiayisunx ipiszy bertmaher

[ghstack-poisoned]
ezyang added a commit that referenced this pull request Jun 5, 2023
This is not actually enabled in the benchmark suite as you need
#103001 and also training
is broken per #101160
but might as well review this part first.

Contains #102979 but
I will probably rebase past that once it lands.

Signed-off-by: Edward Z. Yang <ezyangmeta.com>

cc voznesenskym penguinwu anijain2305 EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng Xia-Weiwen wenzhe-nrv jiayisunx ipiszy bertmaher

[ghstack-poisoned]
ezyang added a commit that referenced this pull request Jun 5, 2023
This is not actually enabled in the benchmark suite as you need
#103001 and also training
is broken per #101160
but might as well review this part first.

Contains #102979 but
I will probably rebase past that once it lands.

Signed-off-by: Edward Z. Yang <ezyangmeta.com>

ghstack-source-id: 7838c84
Pull Request resolved: #103009
which uses the modern parametrization API. The new ``weight_norm`` is compatible
with ``state_dict`` generated from old ``weight_norm``.

Migration guide:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

10/10 migration guide.

Comment thread torch/nn/utils/parametrizations.py Outdated
Comment thread torch/nn/utils/parametrizations.py Outdated
Comment on lines +302 to +304
# TODO: is the .data necessary?
weight_g = torch.norm_except_dim(weight, 2, self.dim).data
weight_v = weight.data

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Pretty sure it's not necessary in the first one. Not sure about the second one as it's written.

That being said, weight_v shoudl be weight divided by weight_g. When that's written that way, then I'm pretty sure you don't need the .data.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Hmm, but that is not what the original code does?

        module.register_parameter(name + '_g', Parameter(norm_except_dim(weight, 2, dim).data))
        module.register_parameter(name + '_v', Parameter(weight.data))
        setattr(module, name, fn.compute_weight(module))

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I reread the paper and not dividing is correct. What is confusing in the docs is we refer to a direction vector, but we do not actually represent the direction vector directly (because it is required to orthogonal) so classic weight norm also reparametrizes the direction vector into v (the original weight vector) with the direction vector now represented as v / || v ||

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Right, had a look at the paper and indeed it's as you mention.

cccclai added a commit to cccclai/executorch-1 that referenced this pull request Jun 12, 2024
…tensor

Summary:
As title, to fix the error when exporting/lowering lstm, the error message is:
```
Cell In[13], line 3
      1 from executorch.backends.xnnpack.partition.xnnpack_partitioner import XnnpackPartitioner
----> 3 edge_manager = edge_manager.to_backend(XnnpackPartitioner())
      5 print(edge_manager.exported_program())
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/executorch/exir/program/_program.py:1166, in EdgeProgramManager.to_backend(self, partitioner)
   1164 else:  # apply partitioner to every method
   1165     for name, program in self._edge_programs.items():
-> 1166         new_edge_programs[name] = to_backend(program, partitioner)
   1168 config = EdgeCompileConfig(_check_ir_validity=False)
   1169 return EdgeProgramManager(
   1170     new_edge_programs, copy.deepcopy(self._config_methods), config
   1171 )
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/runtime/lib/python3.10/functools.py:889, in singledispatch.<locals>.wrapper(*args, **kw)
    885 if not args:
    886     raise TypeError(f'{funcname} requires at least '
    887                     '1 positional argument')
--> 889 return dispatch(args[0].__class__)(*args, **kw)
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/executorch/exir/backend/backend_api.py:384, in _(edge_program, partitioner_instance)
    381 for tag, _ in partitioner_result.partition_tags.items():
    382     _maybe_duplicate_constant_nodes(tagged_exported_program, tag, edge_program)
--> 384 tagged_graph_module = _partition_and_lower(
    385     tagged_exported_program.graph_module, partitioner_result, edge_program
    386 )
    388 # TODO(angelayi): Update this signature in a less manual way (maybe through
    389 # retracing)
    390 new_signature, new_state_dict, new_constants = _get_new_signature(
    391     edge_program,
    392     tagged_graph_module,
    393 )
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/executorch/exir/backend/backend_api.py:299, in _partition_and_lower(tagged_graph_module, partition_result, owning_program)
    290 def _partition_and_lower(
    291     tagged_graph_module: torch.fx.GraphModule,
    292     partition_result: PartitionResult,
    293     owning_program: ExportedProgram,
    294 ) -> torch.fx.GraphModule:
    295     """
    296     Partitions the graph module into submodules based on tags, and then lowered the nodes with the same tag as one lowered module, including the submodule from control flow
    297     """
--> 299     partitioned_module = _partition_and_lower_one_graph_module(
    300         tagged_graph_module, partition_result, owning_program
    301     )
    303     # Recursively partition and lower for submodules
    304     for name, submod, _node in get_control_flow_submodules(partitioned_module):
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/executorch/exir/backend/backend_api.py:230, in _partition_and_lower_one_graph_module(tagged_graph_module, partition_result, owning_program)
    224 logging.debug(f"Partitioned graph module: {tagged_graph_module}")
    226 submodule_program = create_exported_program_from_submodule(
    227     submodule, owning_program, tag
    228 )
--> 230 lowered_submodule = to_backend(
    231     delegation_spec.backend_id,
    232     submodule_program,
    233     delegation_spec.compile_specs,
    234 )
    236 # call delegate args should only use user_inputs
    237 call_delegate_args = []
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/runtime/lib/python3.10/functools.py:889, in singledispatch.<locals>.wrapper(*args, **kw)
    885 if not args:
    886     raise TypeError(f'{funcname} requires at least '
    887                     '1 positional argument')
--> 889 return dispatch(args[0].__class__)(*args, **kw)
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/executorch/exir/backend/backend_api.py:113, in _(backend_id, edge_program, compile_specs)
    111 for cls in BackendDetails.__subclasses__():
    112     if backend_id == cls.__name__:
--> 113         copied_edge_program = copy.deepcopy(edge_program)
    114         preprocess_result: PreprocessResult = cls.preprocess(
    115             copied_edge_program,
    116             compile_specs,
    117         )
    118         lowered_module = LoweredBackendModule(
    119             edge_program=edge_program,
    120             backend_id=backend_id,
    121             processed_bytes=preprocess_result.processed_bytes,
    122             compile_specs=compile_specs,
    123         )
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/runtime/lib/python3.10/copy.py:172, in deepcopy(x, memo, _nil)
    170                 y = x
    171             else:
--> 172                 y = _reconstruct(x, memo, *rv)
    174 # If is its own copy, don't memoize.
    175 if y is not x:
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/runtime/lib/python3.10/copy.py:271, in _reconstruct(x, memo, func, args, state, listiter, dictiter, deepcopy)
    269 if state is not None:
    270     if deep:
--> 271         state = deepcopy(state, memo)
    272     if hasattr(y, '__setstate__'):
    273         y.__setstate__(state)
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/runtime/lib/python3.10/copy.py:146, in deepcopy(x, memo, _nil)
    144 copier = _deepcopy_dispatch.get(cls)
    145 if copier is not None:
--> 146     y = copier(x, memo)
    147 else:
    148     if issubclass(cls, type):
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/runtime/lib/python3.10/copy.py:231, in _deepcopy_dict(x, memo, deepcopy)
    229 memo[id(x)] = y
    230 for key, value in x.items():
--> 231     y[deepcopy(key, memo)] = deepcopy(value, memo)
    232 return y
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/runtime/lib/python3.10/copy.py:146, in deepcopy(x, memo, _nil)
    144 copier = _deepcopy_dispatch.get(cls)
    145 if copier is not None:
--> 146     y = copier(x, memo)
    147 else:
    148     if issubclass(cls, type):
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/runtime/lib/python3.10/copy.py:231, in _deepcopy_dict(x, memo, deepcopy)
    229 memo[id(x)] = y
    230 for key, value in x.items():
--> 231     y[deepcopy(key, memo)] = deepcopy(value, memo)
    232 return y
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/runtime/lib/python3.10/copy.py:153, in deepcopy(x, memo, _nil)
    151 copier = getattr(x, "__deepcopy__", None)
    152 if copier is not None:
--> 153     y = copier(memo)
    154 else:
    155     reductor = dispatch_table.get(cls)
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/torch/_tensor.py:86, in Tensor.__deepcopy__(self, memo)
     84     return handle_torch_function(Tensor.__deepcopy__, (self,), self, memo)
     85 if not self.is_leaf:
---> 86     raise RuntimeError(
     87         "Only Tensors created explicitly by the user "
     88         "(graph leaves) support the deepcopy protocol at the moment.  "
     89         "If you were attempting to deepcopy a module, this may be because "
     90         "of a torch.nn.utils.weight_norm usage, "
     91         "see pytorch/pytorch#103001"
     92     )
     93 if id(self) in memo:
     94     return memo[id(self)]
RuntimeError: Only Tensors created explicitly by the user (graph leaves) support the deepcopy protocol at the moment.  If you were attempting to deepcopy a module, this may be because of a torch.nn.utils.weight_norm usage, see pytorch/pytorch#103001
```
The reason is the constant tensor has the grad_fn when run it without the contextmgr

Reviewed By: angelayi

Differential Revision: D58436236
cccclai added a commit to cccclai/executorch-1 that referenced this pull request Jun 13, 2024
…tensor (pytorch#3948)

Summary:
Pull Request resolved: pytorch#3948

As title, to fix the error when exporting/lowering lstm, the error message is:
```
Cell In[13], line 3
      1 from executorch.backends.xnnpack.partition.xnnpack_partitioner import XnnpackPartitioner
----> 3 edge_manager = edge_manager.to_backend(XnnpackPartitioner())
      5 print(edge_manager.exported_program())
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/executorch/exir/program/_program.py:1166, in EdgeProgramManager.to_backend(self, partitioner)
   1164 else:  # apply partitioner to every method
   1165     for name, program in self._edge_programs.items():
-> 1166         new_edge_programs[name] = to_backend(program, partitioner)
   1168 config = EdgeCompileConfig(_check_ir_validity=False)
   1169 return EdgeProgramManager(
   1170     new_edge_programs, copy.deepcopy(self._config_methods), config
   1171 )
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/runtime/lib/python3.10/functools.py:889, in singledispatch.<locals>.wrapper(*args, **kw)
    885 if not args:
    886     raise TypeError(f'{funcname} requires at least '
    887                     '1 positional argument')
--> 889 return dispatch(args[0].__class__)(*args, **kw)
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/executorch/exir/backend/backend_api.py:384, in _(edge_program, partitioner_instance)
    381 for tag, _ in partitioner_result.partition_tags.items():
    382     _maybe_duplicate_constant_nodes(tagged_exported_program, tag, edge_program)
--> 384 tagged_graph_module = _partition_and_lower(
    385     tagged_exported_program.graph_module, partitioner_result, edge_program
    386 )
    388 # TODO(angelayi): Update this signature in a less manual way (maybe through
    389 # retracing)
    390 new_signature, new_state_dict, new_constants = _get_new_signature(
    391     edge_program,
    392     tagged_graph_module,
    393 )
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/executorch/exir/backend/backend_api.py:299, in _partition_and_lower(tagged_graph_module, partition_result, owning_program)
    290 def _partition_and_lower(
    291     tagged_graph_module: torch.fx.GraphModule,
    292     partition_result: PartitionResult,
    293     owning_program: ExportedProgram,
    294 ) -> torch.fx.GraphModule:
    295     """
    296     Partitions the graph module into submodules based on tags, and then lowered the nodes with the same tag as one lowered module, including the submodule from control flow
    297     """
--> 299     partitioned_module = _partition_and_lower_one_graph_module(
    300         tagged_graph_module, partition_result, owning_program
    301     )
    303     # Recursively partition and lower for submodules
    304     for name, submod, _node in get_control_flow_submodules(partitioned_module):
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/executorch/exir/backend/backend_api.py:230, in _partition_and_lower_one_graph_module(tagged_graph_module, partition_result, owning_program)
    224 logging.debug(f"Partitioned graph module: {tagged_graph_module}")
    226 submodule_program = create_exported_program_from_submodule(
    227     submodule, owning_program, tag
    228 )
--> 230 lowered_submodule = to_backend(
    231     delegation_spec.backend_id,
    232     submodule_program,
    233     delegation_spec.compile_specs,
    234 )
    236 # call delegate args should only use user_inputs
    237 call_delegate_args = []
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/runtime/lib/python3.10/functools.py:889, in singledispatch.<locals>.wrapper(*args, **kw)
    885 if not args:
    886     raise TypeError(f'{funcname} requires at least '
    887                     '1 positional argument')
--> 889 return dispatch(args[0].__class__)(*args, **kw)
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/executorch/exir/backend/backend_api.py:113, in _(backend_id, edge_program, compile_specs)
    111 for cls in BackendDetails.__subclasses__():
    112     if backend_id == cls.__name__:
--> 113         copied_edge_program = copy.deepcopy(edge_program)
    114         preprocess_result: PreprocessResult = cls.preprocess(
    115             copied_edge_program,
    116             compile_specs,
    117         )
    118         lowered_module = LoweredBackendModule(
    119             edge_program=edge_program,
    120             backend_id=backend_id,
    121             processed_bytes=preprocess_result.processed_bytes,
    122             compile_specs=compile_specs,
    123         )
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/runtime/lib/python3.10/copy.py:172, in deepcopy(x, memo, _nil)
    170                 y = x
    171             else:
--> 172                 y = _reconstruct(x, memo, *rv)
    174 # If is its own copy, don't memoize.
    175 if y is not x:
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/runtime/lib/python3.10/copy.py:271, in _reconstruct(x, memo, func, args, state, listiter, dictiter, deepcopy)
    269 if state is not None:
    270     if deep:
--> 271         state = deepcopy(state, memo)
    272     if hasattr(y, '__setstate__'):
    273         y.__setstate__(state)
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/runtime/lib/python3.10/copy.py:146, in deepcopy(x, memo, _nil)
    144 copier = _deepcopy_dispatch.get(cls)
    145 if copier is not None:
--> 146     y = copier(x, memo)
    147 else:
    148     if issubclass(cls, type):
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/runtime/lib/python3.10/copy.py:231, in _deepcopy_dict(x, memo, deepcopy)
    229 memo[id(x)] = y
    230 for key, value in x.items():
--> 231     y[deepcopy(key, memo)] = deepcopy(value, memo)
    232 return y
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/runtime/lib/python3.10/copy.py:146, in deepcopy(x, memo, _nil)
    144 copier = _deepcopy_dispatch.get(cls)
    145 if copier is not None:
--> 146     y = copier(x, memo)
    147 else:
    148     if issubclass(cls, type):
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/runtime/lib/python3.10/copy.py:231, in _deepcopy_dict(x, memo, deepcopy)
    229 memo[id(x)] = y
    230 for key, value in x.items():
--> 231     y[deepcopy(key, memo)] = deepcopy(value, memo)
    232 return y
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/runtime/lib/python3.10/copy.py:153, in deepcopy(x, memo, _nil)
    151 copier = getattr(x, "__deepcopy__", None)
    152 if copier is not None:
--> 153     y = copier(memo)
    154 else:
    155     reductor = dispatch_table.get(cls)
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/torch/_tensor.py:86, in Tensor.__deepcopy__(self, memo)
     84     return handle_torch_function(Tensor.__deepcopy__, (self,), self, memo)
     85 if not self.is_leaf:
---> 86     raise RuntimeError(
     87         "Only Tensors created explicitly by the user "
     88         "(graph leaves) support the deepcopy protocol at the moment.  "
     89         "If you were attempting to deepcopy a module, this may be because "
     90         "of a torch.nn.utils.weight_norm usage, "
     91         "see pytorch/pytorch#103001"
     92     )
     93 if id(self) in memo:
     94     return memo[id(self)]
RuntimeError: Only Tensors created explicitly by the user (graph leaves) support the deepcopy protocol at the moment.  If you were attempting to deepcopy a module, this may be because of a torch.nn.utils.weight_norm usage, see pytorch/pytorch#103001
```
The reason is the constant tensor has the grad_fn when run it without the contextmgr

Reviewed By: angelayi

Differential Revision: D58436236
facebook-github-bot pushed a commit to pytorch/executorch that referenced this pull request Jun 13, 2024
…tensor (#3948)

Summary:
Pull Request resolved: #3948

As title, to fix the error when exporting/lowering lstm, the error message is:
```
Cell In[13], line 3
      1 from executorch.backends.xnnpack.partition.xnnpack_partitioner import XnnpackPartitioner
----> 3 edge_manager = edge_manager.to_backend(XnnpackPartitioner())
      5 print(edge_manager.exported_program())
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/executorch/exir/program/_program.py:1166, in EdgeProgramManager.to_backend(self, partitioner)
   1164 else:  # apply partitioner to every method
   1165     for name, program in self._edge_programs.items():
-> 1166         new_edge_programs[name] = to_backend(program, partitioner)
   1168 config = EdgeCompileConfig(_check_ir_validity=False)
   1169 return EdgeProgramManager(
   1170     new_edge_programs, copy.deepcopy(self._config_methods), config
   1171 )
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/runtime/lib/python3.10/functools.py:889, in singledispatch.<locals>.wrapper(*args, **kw)
    885 if not args:
    886     raise TypeError(f'{funcname} requires at least '
    887                     '1 positional argument')
--> 889 return dispatch(args[0].__class__)(*args, **kw)
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/executorch/exir/backend/backend_api.py:384, in _(edge_program, partitioner_instance)
    381 for tag, _ in partitioner_result.partition_tags.items():
    382     _maybe_duplicate_constant_nodes(tagged_exported_program, tag, edge_program)
--> 384 tagged_graph_module = _partition_and_lower(
    385     tagged_exported_program.graph_module, partitioner_result, edge_program
    386 )
    388 # TODO(angelayi): Update this signature in a less manual way (maybe through
    389 # retracing)
    390 new_signature, new_state_dict, new_constants = _get_new_signature(
    391     edge_program,
    392     tagged_graph_module,
    393 )
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/executorch/exir/backend/backend_api.py:299, in _partition_and_lower(tagged_graph_module, partition_result, owning_program)
    290 def _partition_and_lower(
    291     tagged_graph_module: torch.fx.GraphModule,
    292     partition_result: PartitionResult,
    293     owning_program: ExportedProgram,
    294 ) -> torch.fx.GraphModule:
    295     """
    296     Partitions the graph module into submodules based on tags, and then lowered the nodes with the same tag as one lowered module, including the submodule from control flow
    297     """
--> 299     partitioned_module = _partition_and_lower_one_graph_module(
    300         tagged_graph_module, partition_result, owning_program
    301     )
    303     # Recursively partition and lower for submodules
    304     for name, submod, _node in get_control_flow_submodules(partitioned_module):
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/executorch/exir/backend/backend_api.py:230, in _partition_and_lower_one_graph_module(tagged_graph_module, partition_result, owning_program)
    224 logging.debug(f"Partitioned graph module: {tagged_graph_module}")
    226 submodule_program = create_exported_program_from_submodule(
    227     submodule, owning_program, tag
    228 )
--> 230 lowered_submodule = to_backend(
    231     delegation_spec.backend_id,
    232     submodule_program,
    233     delegation_spec.compile_specs,
    234 )
    236 # call delegate args should only use user_inputs
    237 call_delegate_args = []
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/runtime/lib/python3.10/functools.py:889, in singledispatch.<locals>.wrapper(*args, **kw)
    885 if not args:
    886     raise TypeError(f'{funcname} requires at least '
    887                     '1 positional argument')
--> 889 return dispatch(args[0].__class__)(*args, **kw)
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/executorch/exir/backend/backend_api.py:113, in _(backend_id, edge_program, compile_specs)
    111 for cls in BackendDetails.__subclasses__():
    112     if backend_id == cls.__name__:
--> 113         copied_edge_program = copy.deepcopy(edge_program)
    114         preprocess_result: PreprocessResult = cls.preprocess(
    115             copied_edge_program,
    116             compile_specs,
    117         )
    118         lowered_module = LoweredBackendModule(
    119             edge_program=edge_program,
    120             backend_id=backend_id,
    121             processed_bytes=preprocess_result.processed_bytes,
    122             compile_specs=compile_specs,
    123         )
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/runtime/lib/python3.10/copy.py:172, in deepcopy(x, memo, _nil)
    170                 y = x
    171             else:
--> 172                 y = _reconstruct(x, memo, *rv)
    174 # If is its own copy, don't memoize.
    175 if y is not x:
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/runtime/lib/python3.10/copy.py:271, in _reconstruct(x, memo, func, args, state, listiter, dictiter, deepcopy)
    269 if state is not None:
    270     if deep:
--> 271         state = deepcopy(state, memo)
    272     if hasattr(y, '__setstate__'):
    273         y.__setstate__(state)
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/runtime/lib/python3.10/copy.py:146, in deepcopy(x, memo, _nil)
    144 copier = _deepcopy_dispatch.get(cls)
    145 if copier is not None:
--> 146     y = copier(x, memo)
    147 else:
    148     if issubclass(cls, type):
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/runtime/lib/python3.10/copy.py:231, in _deepcopy_dict(x, memo, deepcopy)
    229 memo[id(x)] = y
    230 for key, value in x.items():
--> 231     y[deepcopy(key, memo)] = deepcopy(value, memo)
    232 return y
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/runtime/lib/python3.10/copy.py:146, in deepcopy(x, memo, _nil)
    144 copier = _deepcopy_dispatch.get(cls)
    145 if copier is not None:
--> 146     y = copier(x, memo)
    147 else:
    148     if issubclass(cls, type):
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/runtime/lib/python3.10/copy.py:231, in _deepcopy_dict(x, memo, deepcopy)
    229 memo[id(x)] = y
    230 for key, value in x.items():
--> 231     y[deepcopy(key, memo)] = deepcopy(value, memo)
    232 return y
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/runtime/lib/python3.10/copy.py:153, in deepcopy(x, memo, _nil)
    151 copier = getattr(x, "__deepcopy__", None)
    152 if copier is not None:
--> 153     y = copier(memo)
    154 else:
    155     reductor = dispatch_table.get(cls)
File /mnt/xarfuse/uid-27416/e8d86d8d-seed-nspid4026533405_cgpid10356714-ns-4026533402/torch/_tensor.py:86, in Tensor.__deepcopy__(self, memo)
     84     return handle_torch_function(Tensor.__deepcopy__, (self,), self, memo)
     85 if not self.is_leaf:
---> 86     raise RuntimeError(
     87         "Only Tensors created explicitly by the user "
     88         "(graph leaves) support the deepcopy protocol at the moment.  "
     89         "If you were attempting to deepcopy a module, this may be because "
     90         "of a torch.nn.utils.weight_norm usage, "
     91         "see pytorch/pytorch#103001"
     92     )
     93 if id(self) in memo:
     94     return memo[id(self)]
RuntimeError: Only Tensors created explicitly by the user (graph leaves) support the deepcopy protocol at the moment.  If you were attempting to deepcopy a module, this may be because of a torch.nn.utils.weight_norm usage, see pytorch/pytorch#103001
```
The reason is the constant tensor has the grad_fn when run it without the contextmgr

Reviewed By: angelayi

Differential Revision: D58436236

fbshipit-source-id: 565810b662f0eb086d02ffff9e16d7c86c0304c4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ciflow/trunk Trigger trunk jobs on your pull request Merged release notes: nn release notes category topic: new features topic category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants