Add configurable bottleneck blocks and aggregation strategies - #73
Merged
Conversation
There was a problem hiding this comment.
Pull request overview
This PR expands the model bottleneck to support configurable frequency aggregation (adding VerticalMean alongside VerticalConv) and introduces an EfficientSelfAttention alternative that uses PyTorch’s scaled dot-product attention, with accompanying config/schema updates and regression tests.
Changes:
- Add
VerticalMeanandEfficientSelfAttentionblocks (plus config models) and extend the layer factory unions accordingly. - Make bottleneck frequency aggregation configurable via
BottleneckConfig.frequency_aggregationand adjust bottleneck construction to match forward execution order. - Update dependency minimums and add regression tests for new blocks, configurable behavior, and bundled checkpoint config-schema loading.
Reviewed changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
uv.lock |
Updates locked metadata/deps consistent with the dependency bumps and new resolution markers. |
pyproject.toml |
Bumps minimum torch/torchaudio versions for SDPA usage. |
src/batdetect2/models/blocks.py |
Adds EfficientSelfAttention and VerticalMean, updates exported symbols and layer config unions, and adjusts LayerGroup to be a Block. |
src/batdetect2/models/bottleneck.py |
Adds configurable frequency_aggregation, introduces a frequency-aggregation builder, and updates bottleneck construction/channel wiring. |
tests/test_models/test_blocks.py |
Adds coverage for VerticalMean and EfficientSelfAttention (including temporary output parity via copied weights). |
tests/test_models/test_bottleneck.py |
Adds tests ensuring post-aggregation layers are built for aggregated channels and that minimal configs remain consistent. |
tests/test_model.py |
Adds a regression test ensuring the bundled checkpoint remains loadable with the current config schema. |
Suppressed comments (3)
src/batdetect2/models/blocks.py:395
torch.nn.functional.scaled_dot_product_attentionin PyTorch 2.0 does not accept thescale=keyword argument. With the current project minimum oftorch>=2.0.0, this will raise aTypeErrorat runtime on Torch 2.0.x.
att = F.scaled_dot_product_attention(
query,
key,
value,
attn_mask=None,
src/batdetect2/models/bottleneck.py:236
build_frequency_aggregationdocstring is out of sync with the signature/behavior:configis not optional/nullable here, and the return value is not always aVerticalConv(it can beVerticalMean).
config : FrequencyAggregationLayerConfig, optional
Configuration specifying the output channel count and any
additional layers. Uses ``VerticalConvConfig`` if ``None``.
Returns
src/batdetect2/models/bottleneck.py:203
- The
BottleneckConfigdocstring is now outdated: it doesn't mentionfrequency_aggregation, and it still says onlySelfAttentionConfigis supported inlayerseven though the type union includesEfficientSelfAttentionConfig. This can mislead config authors and schema consumers.
channels: int
frequency_aggregation: FrequencyAggregationLayerConfig = Field(
default_factory=lambda data: VerticalConvConfig(
channels=data["channels"]
)
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+323
to
+326
| temperature : float | ||
| Scaling factor applied to the weighted values before the final | ||
| linear projection. Defaults to ``1``. | ||
| """ |
Comment on lines
+199
to
+203
| channels: int | ||
| frequency_aggregation: FrequencyAggregationLayerConfig = Field( | ||
| default_factory=lambda data: VerticalConvConfig( | ||
| channels=data["channels"] | ||
| ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
VerticalMeanas a lightweight frequency aggregation block alongside the existingVerticalConv.EfficientSelfAttention, using fused QKV projection and PyTorch scaled dot-product attention, as an alternative bottleneck attention layer.BottleneckConfig.frequency_aggregation.BottleneckConfig.channels.>=2.0.0for scaled dot-product attention support.Rationale
This PR adds more flexibility to how bottlenecks are constructed, with the goal of making the architecture easier to experiment with and potentially leaner and more efficient.
Two bottleneck components are especially worth exploring:
EfficientSelfAttentionvariant that uses PyTorch’s optimized scaled dot-product attention implementation.VerticalConvbefore self-attention. That preserves the desired shape, but it contributes a large share of the model parameters, around half of the total parameter count. This PR addsVerticalMeanas a more parameter-efficient alternative that still collapses the frequency axis to the same shape before attention.Benchmark
In a CPU run, the efficient self-attention layer was about 40% faster than the original implementation.
Keep in mind that this layer is only one part of the full model forward pass, so the overall model speedup is much more modest.
Validation
uv run pytest tests/test_models/test_blocks.py tests/test_models/test_bottleneck.py tests/test_model.py::test_bundled_checkpoint_loads_with_current_config_schemauv run ty check src tests/test_models/test_blocks.py tests/test_models/test_bottleneck.py tests/test_model.pyjust check