binary_mapper
binary_mapper
¶
Binary mapper for discrete latent sampling with gradient pass-through.
Based on "The Free Transformer" (Fleuret, 2025) - arXiv:2510.17558 Section 3.2: https://arxiv.org/abs/2510.17558
The binary mapper converts continuous features to discrete one-hot latent codes using independent Bernoulli sampling per bit, with a proper straight-through gradient estimator that computes the full soft distribution over all 2^H codes.
BinaryMapper
¶
Bases: Module
Binary mapper for discrete latent sampling with gradient pass-through.
Converts continuous logits to discrete one-hot latent codes using independent Bernoulli sampling per bit, with the paper's exact straight-through estimator.
For gradients, computes the full soft distribution G_t over all 2^H codes: G_{t,d} = ∏{h=0}^{H-1} [σ(L]})^{b_h} · (1-σ(L_{t,h}))^{1-b_h
Uses straight-through: Y_t + G_t - detach(G_t)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
latent_bits
|
int
|
Number of bits in the latent code (H in paper, typically 16) |
16
|
embedding_dimension
|
int
|
Input feature dimension |
256
|
Initialize binary mapper.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
latent_bits
|
int
|
Number of bits for the latent code (default: 16, giving 2^16 = 65536 codes) |
16
|
embedding_dimension
|
int
|
Dimension of input features |
256
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If dimensions are not positive. |
Source code in src/versatil/models/layers/free_transformer/binary_mapper.py
forward
¶
Map features to discrete latent codes with proper gradient flow.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
features
|
Tensor
|
Input features (B, T, embedding_dimension) or (B, embedding_dimension) |
required |
deterministic
|
bool
|
If True, use hard threshold instead of sampling |
False
|
Returns:
| Type | Description |
|---|---|
tuple[Tensor, Tensor]
|
Tuple of: - one_hot: One-hot latent codes (B, T, latent_dim) or (B, latent_dim) - logits: Raw logits before sampling (B, T, latent_bits) or (B, latent_bits) |