Skip to content

[BugFix] Fix symbolic_trace for one output and the _ sentinel - #2646

Open
YeonwooSung wants to merge 4 commits into
pytorch:mainfrom
YeonwooSung:fix/fx-symbolic-trace-outputs
Open

YeonwooSung wants to merge 4 commits into
pytorch:mainfrom
YeonwooSung:fix/fx-symbolic-trace-outputs

Conversation

@YeonwooSung

Copy link
Copy Markdown

Summary

tensordict.prototype.fx is a prototype. symbolic_trace returns a TDGraphModule whose forward is supposed to match the module that was traced. Two bugs in that forward made the traced result disagree with eager TensorDictModule.

  1. A TensorDictModule with one out key traces a graph that returns a single tensor. The traced forward did _zip_strict(self.out_keys, outputs). A tensor iterates on dim 0, so zip raised ValueError: zip() argument 2 is longer than argument 1, or paired a batch row with the key when the lengths happened to match. The forward now wraps a non-tuple result in a 1-tuple. A graph that already returns a tuple of tensors is left unchanged.

  2. "_" is the sentinel for "do not write this output". Eager TensorDictModule skips it. The tracer stores out keys with _unravel_key_to_tuple, so "_" becomes ("_",). The forward compared that tuple with the string "_", which is never equal, and wrote a key named "_". The check is now out_key != ("_",). A real nested key ("_", "y") is not the sentinel and is still written.

Tests

Extended test/nn/test_fx.py (no new test file):

  • test_tensordictmodule_trace_single_out_key traces TensorDictModule(nn.Linear(3, 2), in_keys=["x"], out_keys=["y"]) and checks that key y matches the eager values. Before the wrap, this raised ValueError: zip() argument 2 is longer than argument 1.
  • test_tensordictmodule_trace_underscore_sentinel traces a module with out_keys=["y", "_"] and checks that the traced keys equal the eager keys. Before the sentinel fix, the traced tensordict had an extra "_" key ({'_', 'y'} vs {'y'}).

python -m pytest test/nn/test_fx.py -q --tb=short: 5 passed.

Ruff check and format are clean on tensordict/prototype/fx.py and test/nn/test_fx.py.

A TensorDictModule that writes a single key traces a graph whose forward
returns one tensor. Zipping out_keys against that tensor iterates dim 0 and
raises ValueError.
A traced module with one output returns that tensor, not a 1-tuple. Wrap a
non-tuple result so zip pairs out_keys with outputs instead of walking dim 0.
A tuple of tensors is left unchanged.
"_" marks an output that eager TensorDictModule does not write. The traced
module unravels that key to ("_",) and the forward check against "_" never
matches, so the traced tensordict contains "_".
symbolic_trace stores out keys with _unravel_key_to_tuple, so "_" becomes
("_",). Compare against that tuple. A nested key ("_", "y") is not the
sentinel and is still written.
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Oct 14, 2026
@github-actions github-actions Bot added bug Something isn't working Test prototype tensordict.prototype module and removed bug Something isn't working labels Oct 14, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. prototype tensordict.prototype module Test

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant