Skip to content

Make BatchedUnaryEmbeddingBag constructible on meta/fake tensors - #6116

Open
atubo wants to merge 1 commit into
pytorch:mainfrom
atubo:export-D114802150
Open

Make BatchedUnaryEmbeddingBag constructible on meta/fake tensors#6116
atubo wants to merge 1 commit into
pytorch:mainfrom
atubo:export-D114802150

Conversation

@atubo

@atubo atubo commented Aug 5, 2026

Copy link
Copy Markdown

Summary:
BatchedUnaryEmbeddingBag.split_embedding_weights() sliced self.weight using tensor-valued bounds read out of the table_offsets_tensor buffer. Meta and fake tensors carry shape but no data, so those reads lower to aten::item. Under a dispatch mode that fabricates placeholder scalars for value-less reads, both slice bounds come back as the same constant, so every slice collapses to shape (0, 1) and the assert param.shape == (num_emb, 1) in init_parameters() fails during construction. Because a bare assert carries no message, this surfaces as a blank-message exception.

__init__ now computes the cumulative offsets once as a Python list[int] and derives table_offsets_tensor from it, giving a single source of truth. split_embedding_weights() slices with the Python ints, keeping shapes static.

Behavior on real devices is unchanged - same offsets, same uniform_ bounds, same per-table slices, bit-identical initialization for a given seed. The change additionally removes 2*N*T device-to-host syncs per split_embedding_weights() call on CUDA, and makes the module constructible under torch.device("meta") and FakeTensor, which model-analysis and export tooling depend on.

Differential Revision: D114802150

Summary:
`BatchedUnaryEmbeddingBag.split_embedding_weights()` sliced `self.weight` using tensor-valued bounds read out of the `table_offsets_tensor` buffer. Meta and fake tensors carry shape but no data, so those reads lower to `aten::item`. Under a dispatch mode that fabricates placeholder scalars for value-less reads, both slice bounds come back as the same constant, so every slice collapses to shape `(0, 1)` and the `assert param.shape == (num_emb, 1)` in `init_parameters()` fails during construction. Because a bare `assert` carries no message, this surfaces as a blank-message exception.

`__init__` now computes the cumulative offsets once as a Python `list[int]` and derives `table_offsets_tensor` from it, giving a single source of truth. `split_embedding_weights()` slices with the Python ints, keeping shapes static.

Behavior on real devices is unchanged - same offsets, same `uniform_` bounds, same per-table slices, bit-identical initialization for a given seed. The change additionally removes `2*N*T` device-to-host syncs per `split_embedding_weights()` call on CUDA, and makes the module constructible under `torch.device("meta")` and FakeTensor, which model-analysis and export tooling depend on.

Differential Revision: D114802150
@meta-cla meta-cla Bot added the cla signed label Aug 5, 2026
@meta-codesync

meta-codesync Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

@atubo has exported this pull request. If you are a Meta employee, you can view the originating Diff in D114802150.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant