Skip to content

Spec/transformer - #5

Closed
giovannic wants to merge 15 commits into
giovannic:masterfrom
mrc-ide:spec/transformer
Closed

giovannic wants to merge 15 commits into
giovannic:masterfrom
mrc-ide:spec/transformer

Conversation

@giovannic

Copy link
Copy Markdown
Owner

Summary

This PR adds comprehensive specifications for the Transformer


Context

Flow Matching for Posterior Estimation

TFMPE uses flow matching to learn the posterior distribution p(θ|x) for simulation-based inference. Flow matching learns a time-dependent vector field v(θ, x, t) that transports samples from a simple base distribution (e.g., standard
normal) to the complex posterior distribution.

The transformer architecture models this vector field by:

  1. Encoding context (observations x) through self-attention encoder blocks
  2. Encoding parameters (θ at time t) through self-attention encoder blocks
  3. Decoding parameters with cross-attention to context to produce the vector field output

This encoder-decoder design allows the model to capture:

  • Complex dependencies within parameter structure (self-attention)
  • Conditional relationships between observations and parameters (cross-attention)
  • Time-dependent dynamics of the flow (time embedding)

Legacy vs New Design

The legacy transformer required manual management of flattened arrays, labels, indices, and masks. This design leverages the Tokens preprocessing interface which already encapsulates this complexity, providing:

  • Unified data structure with data, labels, self_attention_mask, functional_inputs
  • Automatic mask generation from independence structure
  • Cleaner integration between preprocessing and model layers

Design Decisions

1. TokensInterface

Accept Tokens objects directly as inputs instead of separate arrays for data, labels, indices, and masks. The Tokens class already encapsulates all necessary information for the transformer, eliminating ~5 function parameters per
call and enforcing consistency with the preprocessing pipeline.

2. Dataclass Configuration

Use a TransformerConfig dataclass with sensible defaults (latent_dim=128, n_encoder=4, n_decoder=4, etc.) to reduce boilerplate. The dataclass validates constraints like latent_dim % n_heads == 0 in __post_init__ and
groups architecture parameters separately from data-dependent parameters (value_dim, n_labels, index_dim).

3. Performance Benchmarking

Implement two types of automated benchmarks:

Speed benchmarks (pytest-benchmark):

  • Forward and backward pass timing with statistical analysis
  • Parameterized by model size (n_tokens, latent_dim, n_encoder, n_decoder)
  • Uses @pytest.mark.speed for standard configs, @pytest.mark.scale for large configs
  • Enforces time thresholds as test assertions to catch performance regressions

Memory benchmarks (pytest-memray):

  • Peak memory profiling for forward and backward passes
  • Same parameterization as speed benchmarks
  • Enforces memory thresholds critical for GPU-constrained environments
  • Separate markers allow CI to skip expensive large-scale benchmarks

Both benchmark types ensure the transformer scales efficiently to large hierarchical models and prevent performance degradation over time.

giovannic added a commit that referenced this pull request Oct 13, 2025
 * Improved documentation for attention masking
 * Test full matrix in unittests (except if too large)
giovannic added a commit that referenced this pull request Oct 13, 2025
 * Improved documentation for attention masking
 * Test full matrix in unittests (except if too large)
giovannic and others added 9 commits October 13, 2025 14:22
 * 1, 2 and 4 completed
 * 3 - masking still to do
* Move flatten_leaf to flatten.py
* Test flatten_leaf explicitly
* Fix references
* Phase 1 of preprocessing: flattening:

 * 1, 2 and 4 completed
 * 3 - masking still to do

* Preprocessing phase 1: masking

* Implement Tokens class basic functionality

- Add Tokens dataclass with unified interface for parameter data
- Implement from_pytree() to create Tokens from PyTree
- Implement decode() and decode_keys() for reconstruction
- Add sample_shape property
- Support functional inputs with padding
- Add comprehensive tests for basic functionality

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Mark task 5 as complete in tasks.md

* Implement Tokens dynamic functionality (task 6)

Add dynamic slicing, value override, and cross-attention mask methods:
- select_tokens(): Create zero-copy TokenView for key subsets
- TokenView class: Efficient view with cached properties
- cross_attention_mask(): Generate masks between token subsets
- with_values(): Create new Tokens with updated values

Bug fixes:
- Fix update_flat_array to use (*sample, *event, *batch) convention
- Add tests for multi-dim event shapes and sample dimensions

Simplify exports:
- Only export Tokens from preprocessing.__init__.py
- Update test imports to use module paths

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Mark Token (6) and TokenView (7) as complete

* Fix flatten test

* Fix typecheck on test_tokens_basic

* Consolidate fixtures

* Move functional input padding value

* Refactor slice dict into SliceInfo

* Refactor independence to dataclass

---------

Co-authored-by: Claude <noreply@anthropic.com>
* Simplify spec templates

* Add combine_tokens tasks

Add tests for combine_tokens

Implement combine_tokens function (task 7.5.2)

- Combines two Tokens objects by concatenating along sample dimension
- Computes max event_shape per key and updates slices accordingly
- Pads data and functional_inputs to max_n_tokens
- Rebuilds self-attention mask using new slices to preserve independence
- Creates padding_mask to track real vs padded tokens
- Validates key_order and independence compatibility
- Handles functional_inputs (both present, both None, or error)
- Updates test fixtures to use consistent batch shapes per key
- All 17 tests passing with type checking clean

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

Mark 7.5 as complete

* Address PR9
giovannic added a commit that referenced this pull request Feb 3, 2026
Preprocessing phase 1: masking

Response to PR #5:

 * Improved documentation for attention masking
 * Test full matrix in unittests (except if too large)

Phase 1 of preprocessing: flattening:

 * 1, 2 and 4 completed
 * 3 - masking still to do

Respond to PR #2:

* Move flatten_leaf to flatten.py
* Test flatten_leaf explicitly
* Fix references

Preprocessing phase 1: masking

Feat/tokens (#8)

* Phase 1 of preprocessing: flattening:

 * 1, 2 and 4 completed
 * 3 - masking still to do

* Preprocessing phase 1: masking

* Implement Tokens class basic functionality

- Add Tokens dataclass with unified interface for parameter data
- Implement from_pytree() to create Tokens from PyTree
- Implement decode() and decode_keys() for reconstruction
- Add sample_shape property
- Support functional inputs with padding
- Add comprehensive tests for basic functionality

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Mark task 5 as complete in tasks.md

* Implement Tokens dynamic functionality (task 6)

Add dynamic slicing, value override, and cross-attention mask methods:
- select_tokens(): Create zero-copy TokenView for key subsets
- TokenView class: Efficient view with cached properties
- cross_attention_mask(): Generate masks between token subsets
- with_values(): Create new Tokens with updated values

Bug fixes:
- Fix update_flat_array to use (*sample, *event, *batch) convention
- Add tests for multi-dim event shapes and sample dimensions

Simplify exports:
- Only export Tokens from preprocessing.__init__.py
- Update test imports to use module paths

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Mark Token (6) and TokenView (7) as complete

* Fix flatten test

* Fix typecheck on test_tokens_basic

* Consolidate fixtures

* Move functional input padding value

* Refactor slice dict into SliceInfo

* Refactor independence to dataclass

---------

Co-authored-by: Claude <noreply@anthropic.com>

Feat/combine (#9)

* Simplify spec templates

* Add combine_tokens tasks

Add tests for combine_tokens

Implement combine_tokens function (task 7.5.2)

- Combines two Tokens objects by concatenating along sample dimension
- Computes max event_shape per key and updates slices accordingly
- Pads data and functional_inputs to max_n_tokens
- Rebuilds self-attention mask using new slices to preserve independence
- Creates padding_mask to track real vs padded tokens
- Validates key_order and independence compatibility
- Handles functional_inputs (both present, both None, or error)
- Updates test fixtures to use consistent batch shapes per key
- All 17 tests passing with type checking clean

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

Mark 7.5 as complete

* Address PR9
@giovannic giovannic closed this Feb 3, 2026
@giovannic
giovannic deleted the spec/transformer branch February 3, 2026 17:02
giovannic added a commit that referenced this pull request Feb 3, 2026
Preprocessing phase 1: masking

Response to PR #5:

 * Improved documentation for attention masking
 * Test full matrix in unittests (except if too large)

Phase 1 of preprocessing: flattening:

 * 1, 2 and 4 completed
 * 3 - masking still to do

Respond to PR #2:

* Move flatten_leaf to flatten.py
* Test flatten_leaf explicitly
* Fix references

Preprocessing phase 1: masking

Feat/tokens (#8)

* Phase 1 of preprocessing: flattening:

 * 1, 2 and 4 completed
 * 3 - masking still to do

* Preprocessing phase 1: masking

* Implement Tokens class basic functionality

- Add Tokens dataclass with unified interface for parameter data
- Implement from_pytree() to create Tokens from PyTree
- Implement decode() and decode_keys() for reconstruction
- Add sample_shape property
- Support functional inputs with padding
- Add comprehensive tests for basic functionality

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Mark task 5 as complete in tasks.md

* Implement Tokens dynamic functionality (task 6)

Add dynamic slicing, value override, and cross-attention mask methods:
- select_tokens(): Create zero-copy TokenView for key subsets
- TokenView class: Efficient view with cached properties
- cross_attention_mask(): Generate masks between token subsets
- with_values(): Create new Tokens with updated values

Bug fixes:
- Fix update_flat_array to use (*sample, *event, *batch) convention
- Add tests for multi-dim event shapes and sample dimensions

Simplify exports:
- Only export Tokens from preprocessing.__init__.py
- Update test imports to use module paths

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Mark Token (6) and TokenView (7) as complete

* Fix flatten test

* Fix typecheck on test_tokens_basic

* Consolidate fixtures

* Move functional input padding value

* Refactor slice dict into SliceInfo

* Refactor independence to dataclass

---------

Co-authored-by: Claude <noreply@anthropic.com>

Feat/combine (#9)

* Simplify spec templates

* Add combine_tokens tasks

Add tests for combine_tokens

Implement combine_tokens function (task 7.5.2)

- Combines two Tokens objects by concatenating along sample dimension
- Computes max event_shape per key and updates slices accordingly
- Pads data and functional_inputs to max_n_tokens
- Rebuilds self-attention mask using new slices to preserve independence
- Creates padding_mask to track real vs padded tokens
- Validates key_order and independence compatibility
- Handles functional_inputs (both present, both None, or error)
- Updates test fixtures to use consistent batch shapes per key
- All 17 tests passing with type checking clean

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

Mark 7.5 as complete

* Address PR9
giovannic added a commit that referenced this pull request Feb 6, 2026
Preprocessing phase 1: masking

Response to PR #5:

 * Improved documentation for attention masking
 * Test full matrix in unittests (except if too large)

Phase 1 of preprocessing: flattening:

 * 1, 2 and 4 completed
 * 3 - masking still to do

Respond to PR #2:

* Move flatten_leaf to flatten.py
* Test flatten_leaf explicitly
* Fix references

Preprocessing phase 1: masking

Feat/tokens (#8)

* Phase 1 of preprocessing: flattening:

 * 1, 2 and 4 completed
 * 3 - masking still to do

* Preprocessing phase 1: masking

* Implement Tokens class basic functionality

- Add Tokens dataclass with unified interface for parameter data
- Implement from_pytree() to create Tokens from PyTree
- Implement decode() and decode_keys() for reconstruction
- Add sample_shape property
- Support functional inputs with padding
- Add comprehensive tests for basic functionality

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Mark task 5 as complete in tasks.md

* Implement Tokens dynamic functionality (task 6)

Add dynamic slicing, value override, and cross-attention mask methods:
- select_tokens(): Create zero-copy TokenView for key subsets
- TokenView class: Efficient view with cached properties
- cross_attention_mask(): Generate masks between token subsets
- with_values(): Create new Tokens with updated values

Bug fixes:
- Fix update_flat_array to use (*sample, *event, *batch) convention
- Add tests for multi-dim event shapes and sample dimensions

Simplify exports:
- Only export Tokens from preprocessing.__init__.py
- Update test imports to use module paths

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Mark Token (6) and TokenView (7) as complete

* Fix flatten test

* Fix typecheck on test_tokens_basic

* Consolidate fixtures

* Move functional input padding value

* Refactor slice dict into SliceInfo

* Refactor independence to dataclass

---------

Co-authored-by: Claude <noreply@anthropic.com>

Feat/combine (#9)

* Simplify spec templates

* Add combine_tokens tasks

Add tests for combine_tokens

Implement combine_tokens function (task 7.5.2)

- Combines two Tokens objects by concatenating along sample dimension
- Computes max event_shape per key and updates slices accordingly
- Pads data and functional_inputs to max_n_tokens
- Rebuilds self-attention mask using new slices to preserve independence
- Creates padding_mask to track real vs padded tokens
- Validates key_order and independence compatibility
- Handles functional_inputs (both present, both None, or error)
- Updates test fixtures to use consistent batch shapes per key
- All 17 tests passing with type checking clean

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

Mark 7.5 as complete

* Address PR9
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.

1 participant