Skip to content

Configure attention and feed-forward norms independently#687

Draft
AkshitaB wants to merge 6 commits into
mainfrom
akshitab/transformer-norm-split
Draft

Configure attention and feed-forward norms independently#687
AkshitaB wants to merge 6 commits into
mainfrom
akshitab/transformer-norm-split

Conversation

@AkshitaB

Copy link
Copy Markdown
Contributor

Summary

Split TransformerBlockConfig.layer_norm into separate attention_norm and feed_forward_norm fields, so the pre-attention and pre-feed-forward layer norms can be configured independently. Previously a single layer_norm config was used to build both.

Backwards compatibility

layer_norm is kept as a deprecated InitVar:

  • When provided, it is copied into both attention_norm and feed_forward_norm.
  • Specifying both the legacy layer_norm and either split field raises OLMoConfigurationError.
  • Because it's an InitVar, it is never stored or serialized — existing on-disk configs that use layer_norm load and round-trip cleanly into the new split fields.

So this is a non-breaking change: configs and scripts that pass layer_norm= continue to work unchanged.

Changes

  • TransformerBlockConfig: new attention_norm / feed_forward_norm fields; layer_norm demoted to a deprecated InitVar with mirroring in __post_init__; num_params reads the split fields.
  • block.py: block constructors (TransformerBlock, LayerNormScaledTransformerBlock, PeriNormTransformerBlock, MoETransformerBlock, MoEHybridTransformerBlockBase) now take attention_norm and feed_forward_norm instead of a single layer_norm. No behavior change when the same norm is used for both.
  • Factories: llama_like and gemma3_like populate both fields.

Tests

  • New unit tests in config_test.py: legacy layer_norm= back-compat mirroring, independent split norms, the conflict error, and factory population of the split fields.
  • Updated block_test.py (builds block modules directly).
  • The existing real-checkpoint config test (which loads a config using layer_norm on disk) passes — validating the back-compat path end to end.
  • pytest src/test/nn/transformer/ passes; make checks (isort/black/ruff/mypy) clean.

🤖 Generated with Claude Code

AkshitaB and others added 3 commits May 26, 2026 19:45
Split `TransformerBlockConfig.layer_norm` into separate `attention_norm`
and `feed_forward_norm` fields so the pre-attention and pre-feed-forward
layer norms can be configured independently. Previously a single
`layer_norm` config was used to build both norms.

For backwards compatibility, `layer_norm` is retained as a deprecated
`InitVar`: when provided it is copied into both `attention_norm` and
`feed_forward_norm`, and specifying both the legacy and split fields
raises an `OLMoConfigurationError`. Since it is an `InitVar` it is not
stored or serialized, so existing on-disk configs that use `layer_norm`
load and round-trip cleanly into the new split fields.

Block constructors now accept `attention_norm` and `feed_forward_norm`
in place of a single `layer_norm`, and the `llama_like` / `gemma3_like`
factories populate both fields. Behavior is unchanged when the same norm
config is used for both.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The merged-config test indexed the serialized block config at
`block["layer_norm"]`, which no longer exists now that the block config
serializes `attention_norm` / `feed_forward_norm`. Point it at
`attention_norm`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@farhatkevin

Copy link
Copy Markdown
Contributor

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 371dd68701

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/olmo_core/nn/transformer/config.py
Comment thread src/olmo_core/nn/transformer/config.py Outdated
AkshitaB and others added 2 commits May 28, 2026 16:23
… separately

PeriNormTransformerBlock builds post_attention_norm from attention_norm and
post_feed_forward_norm from feed_forward_norm, so the two extra norms can have
different parameter counts when configured independently. Count one of each
instead of doubling feed_forward_norm.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The layer_norm InitVar is not serialized, so overrides targeting it through
config.merge() (e.g. model.block.layer_norm.eps=1e-6) silently fail to apply.
Note the limitation in the CHANGELOG and field docstring, directing users to
override attention_norm/feed_forward_norm instead. This matches the existing
behavior of the deprecated `attention` InitVar.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

@farhatkevin

Copy link
Copy Markdown
Contributor

One follow-up concern: since this PR now allows attention_norm and feed_forward_norm to differ, should the HuggingFace export path validate that those configs are equivalent before collapsing them into a single rms_norm_eps?

Today src/olmo_core/nn/hf/config.py uses first_block.feed_forward_norm.eps for HF config export. With this PR, a model could set different attention/feed-forward norm eps values, export successfully, and silently lose the attention norm setting in the HF config. If the target HF architecture only supports one norm epsilon, I think we should raise a clear error when the split norm configs differ; otherwise we should preserve both settings in the exported config.

@AkshitaB
AkshitaB marked this pull request as draft June 9, 2026 21:58
AkshitaB added a commit that referenced this pull request Jul 13, 2026
Pull forward olmo-ddp's context-parallel sequence-sharding helper onto the base
Transformer. It shards input_ids/labels via the existing _cp_load_balancer.batch_shard
and returns the original sequence length so pipeline stages can rebuild RoPE buffers
consistently. Self-contained (core already has the CP load balancer); full CP train
wiring lands with the DDP train module.

The rest of olmo-ddp's shared transformer/block.py + model.py diff is intentionally
not taken: the shared-block norm split (#687) is rejected in favor of core's single
layer_norm, weight-tying is kept, and the v1 MoEHybrid overlap isn't on the OLMoDDP path.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Tianhua Tao <taotianhua@outlook.com>
AkshitaB added a commit that referenced this pull request Jul 14, 2026
Pull forward olmo-ddp's context-parallel sequence-sharding helper onto the base
Transformer. It shards input_ids/labels via the existing _cp_load_balancer.batch_shard
and returns the original sequence length so pipeline stages can rebuild RoPE buffers
consistently. Self-contained (core already has the CP load balancer); full CP train
wiring lands with the DDP train module.

The rest of olmo-ddp's shared transformer/block.py + model.py diff is intentionally
not taken: the shared-block norm split (#687) is rejected in favor of core's single
layer_norm, weight-tying is kept, and the v1 MoEHybrid overlap isn't on the OLMoDDP path.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Tianhua Tao <taotianhua@outlook.com>
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.

2 participants