Add heterogeneous model support (per-layer config and modeling)#45332
Add heterogeneous model support (per-layer config and modeling)#45332eladsegal wants to merge 44 commits into
Conversation
|
@askliar |
ArthurZucker
left a comment
There was a problem hiding this comment.
Hey! thanks for the PR!
One thing that's super important to stay aligned with transformers philo is that is not somthing we want to ship to old models! We'll be super happy to create new models with modular that do have heterogenous configs per layer, but adding this to llama break llama. GPT OSS does NOT have this, as such it should not support it. Happy to have heterogen_gpt_oss !
This removes code paths, and the if is_heterogeneous etc.
Given this, I think it would mostly be a change in the config to have per_layer_config.
We can find a good way to serialize all args in order to reduce the bloat potentially (meaning all attributes are list, at init time this creates a list of config per-layer) this simplifies code changes in modeling_heterogenous_gpt_oss for example, that would just get per_layer_config[i]
Furthermore I don't understand the skip idea can you give a concrete example? you want to skip an entire layer, but you can just set it to nn.Identity for example? or just re-index them?
|
[For maintainers] Suggested jobs to run (before merge) run-slow: gpt_oss |
… for custom caches
CI recapDashboard: View test results in Grafana |
What does this PR do?
Adds heterogeneous model support - the ability for individual layers to differ from the global config (e.g., different
intermediate_size,num_key_value_heads) and to skip sub-modules entirely (MLP, attention, etc.). This enables models where layers are not uniform, as in pruned, distilled, or NAS-derived architectures.Examples of such models:
These models previously required
trust_remote_code=Trueto modify the classes of the model they are derived from. With this PR, checkpoints derived from the architectures with built-in support (seesupported_models.py) work out of the box, and any other model - including custom models - can opt in with a few lines.This PR contains the modeling, cache, and masking layers. It builds on the configuration layer (
per_layer_config) introduced in the configuration PR #45333.How it works
Configuration (
per_layer_config) - recapIntroduced in #45333, recapped here since everything below consumes it.
per_layer_configonPreTrainedConfigmaps layer indices to attribute overrides:config.per_layer_config[i]returns the resolved configuration for layeri, combining the global values with that layer's overrides. See #45333 for validation, serialization, and global-attribute-access behavior.Modeling (automatic layer patching)
Architecture support is declared with a
HeterogeneousModelingSpec. Built-in specs live insupported_models.py; any other model opts in by setting_heterogeneous_modeling_specon itsPreTrainedModelbase class.At model init time, the framework monkey-patches
layer_cls.__init__to:config.per_layer_config[layer_idx]to the original__init__skipentries, replace the corresponding sub-modules with parameter-free no-op replacementssliding_window/attention_chunk_sizevary per layer, patch the layerforwardto select the attention mask matching its own valueThe patching uses a
ContextVarto pass per-model context to the layer__init__wrapper. Cleanup happens automatically after model init (via__init_subclass__wrapping).The spec names the layer class and layer-index argument; sub-module skipping additionally requires skip descriptors:
The skip type names ("attention", "mlp") are what configurations reference in their
skiplists. Replacement keys are member names, optionally restricted to a member class -("mixer", NemotronHAttention)- for layers whose member class varies.replaces_kv_cache_updaterstates whether the skip replaces the member that updates the layer's KV cache (see below).Note: a spec without
skip_descriptorsis sufficient for attribute heterogeneity (varying dimensions across layers).Cache, masks, and KV state
When
sliding_windoworattention_chunk_sizevaries per layer:DynamicCacheandStaticCachecreate per-layer sliding window layers with the correct window sizescreate_sliding_window_causal_mask/create_chunked_causal_maskreturn anAttentionMasksByAttributeValuemapping keyed by distinct window sizes (deduplicated), and each layer's forward selects its own mask; this composes withcreate_masks_for_generate's layer-type-keyed outputA layer whose attention is skipped never updates its KV cache, which breaks the long-standing assumption that any layer can report cache metadata:
Cache.get_seq_length()(no layer argument) and attention mask creation now read a representative layer that actually holds KV statereplaces_kv_cache_updaterresolves the KV-disabled layer indices onto the config at model construction, soStaticCache(config, ...)picks correct representative layers statically and compiled decoding stays a single graphtorch.exportwithDynamicCachepreserves skipped-layer positions in the pytree round-trip instead of compacting KV states into wrong layersKey changes
src/transformers/integrations/heterogeneity/package - modeling spec and layer patching, skip replacements (SkipDescriptor,get_skip_replacement/ReturnEntry), heterogeneous mask construction, and the built-in spec registry (the package's configuration utilities come from Add heterogeneous config support (per-layer configuration) #45333)modeling_utils.py- auto-callsapply_heterogeneous_modelingat model init, wraps subclass__init__for cleanup via__init_subclass__cache_utils.py- per-layer sliding window resolution inDynamicCache/StaticCache; representative-KV-layer selection for cache metadatamasking_utils.py- heterogeneous dispatch for sliding/chunked mask creation; mask layer selection prefers layers holding KV stateintegrations/executorch.py-DynamicCachepytree export support preserves the layer layout of caches with skipped layersmodels/gpt_oss/modeling_gpt_oss.pyandintegrations/mxfp4.py- Fix homogeneity assumptions in order to support heterogeneous configurationsheterogeneous_modeling.md)Tests
Comprehensive test suite in
tests/heterogeneity/covering 4 architectures (Llama, GptOss, Llama4, NemotronH):Covers structure verification, forward/generate equivalence against manually-constructed reference models, model save/load round-trips, heterogeneous cache behavior (including
torch.compilesingle-graph decoding andtorch.exportround-trips), mask construction, and edge cases. (test_configuration_utils.pyis part of #45333.)Concrete example: Llama-3.1-8B-Instruct with 4 layers of attention skipped
Code snippet (click to expand)
Who can review?
@ArthurZucker
@hmellor