Source code for easydel.modules.llama4.llama4_configuration

# Copyright 2025 The EasyDeL Author @erfanzar (Erfan Zare Chavoshi).
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


import typing

from eformer.common_types import ColumnWise, Replicated, RowWise
from eformer.loggings import get_logger

from easydel.infra.base_module import EasyDeLBaseConfig
from easydel.infra.factory import register_config
from easydel.layers.moe.utils import get_moe_partition_spec

logger = get_logger(__name__)


def _get_partition_rules(self, *args, **kwargs):
    """
    Get the partition rules for the model.
    Returns:
        `tp.Tuple[tp.Tuple[str, PartitionSpec]]`: The partition rules.
    """
    pmag = self.partition_manager

    kws = dict(
        fsdp_is_ep_bound=self.fsdp_is_ep_bound,
        sp_is_ep_bound=self.sp_is_ep_bound,
        module_view=True,
        tensors_are_expert=self.use_expert_tensor_mode,
        partition_manager=self.partition_manager,
    )

    eck = get_moe_partition_spec(direction="column", is_bias=False, **kws)
    erk = get_moe_partition_spec(direction="row", is_bias=False, **kws)

    return (
        (r"embed_tokens/embedding", pmag.resolve(ColumnWise)),
        (r"self_attn/(q_proj|k_proj|v_proj)/kernel", pmag.resolve(ColumnWise)),
        (r"self_attn/o_proj/kernel", pmag.resolve(RowWise)),
        (r"self_attn/.*proj/bias", pmag.resolve(Replicated)),
        (r"self_attn/qk_norm/scale", pmag.resolve(Replicated)),
        (r"feed_forward/(gate_proj|up_proj)/kernel", pmag.resolve(ColumnWise)),
        (r"feed_forward/down_proj/kernel", pmag.resolve(RowWise)),
        (r"feed_forward/router/kernel", pmag.resolve(Replicated if self.use_expert_tensor_mode else ColumnWise)),
        (r"feed_forward/experts/gate_up_proj", eck),
        (r"feed_forward/experts/down_proj", erk),
        (
            r"feed_forward/shared_expert/(gate_proj|up_proj)/kernel",
            pmag.resolve(ColumnWise),
        ),
        (r"feed_forward/shared_expert/down_proj/kernel", pmag.resolve(RowWise)),
        (
            r"(input_layernorm|post_attention_layernorm|pre_feedforward_layernorm|post_feedforward_layernorm|norm)/kernel",
            pmag.resolve(Replicated),
        ),
        (r"lm_head/kernel", pmag.resolve(ColumnWise)),
        (r"patch_embedding/linear/kernel", pmag.resolve(ColumnWise)),
        (r"class_embedding", pmag.resolve(Replicated)),
        (r"positional_embedding_vlm", pmag.resolve(ColumnWise)),
        (r"(layernorm_pre|layernorm_post)/scale", pmag.resolve(Replicated)),
        (r"(layernorm_pre|layernorm_post)/bias", pmag.resolve(Replicated)),
        (r"model/layers/\d+/self_attn/o_proj/kernel", pmag.resolve(RowWise)),
        (r"model/layers/\d+/self_attn/.*proj/bias", pmag.resolve(Replicated)),
        (r"model/layers/\d+/mlp/fc1/kernel", pmag.resolve(ColumnWise)),
        (r"model/layers/\d+/mlp/fc2/kernel", pmag.resolve(RowWise)),
        (r"model/layers/\d+/mlp/fc(1|2)/bias", pmag.resolve(Replicated)),
        (r"vision_adapter/mlp/fc1/kernel", pmag.resolve(ColumnWise)),
        (r"vision_adapter/mlp/fc2/kernel", pmag.resolve(RowWise)),
        (r"vision_adapter/mlp/fc(1|2)/bias", pmag.resolve(Replicated)),
        (r"multi_modal_projector/linear_1/kernel", pmag.resolve(ColumnWise)),
        (r"multi_modal_projector/linear_1/bias", pmag.resolve(Replicated)),
        (r"score/kernel", pmag.resolve(RowWise)),
        (r"score/bias", pmag.resolve(Replicated)),
        (r".*bias", pmag.resolve(Replicated)),
        (r".*", pmag.resolve(Replicated)),
    )


[docs]@register_config("llama4_vision_model") class Llama4VisionConfig(EasyDeLBaseConfig): """Configuration for the Llama4 vision tower and projector settings.""" model_type = "llama4_vision_model" base_config_key = "vision_config" def __init__( self, hidden_size: int = 768, hidden_act: str = "gelu", num_hidden_layers: int = 34, num_attention_heads: int = 16, num_channels: int = 3, intermediate_size: int = 5632, vision_output_dim: int = 7680, image_size: int = 448, patch_size: int = 14, norm_eps: float = 1e-5, vision_feature_layer=-1, vision_feature_select_strategy="default", initializer_range: float = 0.02, pixel_shuffle_ratio=0.5, projector_input_dim=4096, projector_output_dim=4096, multi_modal_projector_bias=False, projector_dropout=0.0, attention_dropout=0.0, rope_theta=10000, **kwargs, ): self.hidden_size = hidden_size self.hidden_act = hidden_act self.num_hidden_layers = num_hidden_layers self.num_channels = num_channels self.intermediate_size = intermediate_size self.image_size = image_size self.vision_output_dim = vision_output_dim self.patch_size = patch_size self.norm_eps = norm_eps self.num_attention_heads = num_attention_heads self.initializer_range = initializer_range self.pixel_shuffle_ratio = pixel_shuffle_ratio self.projector_input_dim = projector_input_dim self.projector_output_dim = projector_output_dim self.multi_modal_projector_bias = multi_modal_projector_bias self.projector_dropout = projector_dropout self.attention_dropout = attention_dropout self.vision_feature_layer = vision_feature_layer self.vision_feature_select_strategy = vision_feature_select_strategy self.rope_theta = rope_theta super().__init__(**kwargs) get_partition_rules = _get_partition_rules
[docs]@register_config("llama4_text") class Llama4TextConfig(EasyDeLBaseConfig): """Configuration for the Llama4 text decoder stack.""" model_type = "llama4_text" def __init__( self, vocab_size=202048, hidden_size=5120, intermediate_size=8192, intermediate_size_mlp=16384, num_hidden_layers=48, num_attention_heads=40, num_key_value_heads=8, head_dim=128, hidden_act="silu", max_position_embeddings=4096 * 32, initializer_range=0.02, rms_norm_eps=1e-5, use_cache=True, pad_token_id=None, bos_token_id=1, eos_token_id=2, tie_word_embeddings=False, rope_theta=500000, attention_dropout=0.0, num_experts_per_tok=1, num_local_experts=16, moe_layers=None, interleave_moe_layer_step=1, use_qk_norm=True, output_router_logits=False, router_aux_loss_coef=0.001, router_jitter_noise=0.0, rope_scaling=None, no_rope_layers=None, no_rope_layer_interval=4, attention_chunk_size=8192, attn_temperature_tuning=4, floor_scale=8192, attn_scale=0.1, layer_types: list[str] | None = None, **kwargs, ): super().__init__( pad_token_id=pad_token_id, bos_token_id=bos_token_id, eos_token_id=eos_token_id, tie_word_embeddings=tie_word_embeddings, **kwargs, ) self.attn_temperature_tuning = attn_temperature_tuning self.attn_scale = attn_scale self.floor_scale = floor_scale self.vocab_size = vocab_size self.max_position_embeddings = max_position_embeddings self.hidden_size = hidden_size self.intermediate_size = intermediate_size self.intermediate_size_mlp = intermediate_size_mlp self.num_hidden_layers = num_hidden_layers self.num_attention_heads = num_attention_heads self.rope_scaling = rope_scaling self.attention_bias = False # for backward compatibility if num_key_value_heads is None: num_key_value_heads = num_attention_heads self.num_key_value_heads = num_key_value_heads self.hidden_act = hidden_act self.initializer_range = initializer_range self.rms_norm_eps = rms_norm_eps self.use_cache = use_cache self.rope_theta = rope_theta self.attention_dropout = attention_dropout self.head_dim = head_dim if head_dim is not None else self.hidden_size // self.num_attention_heads self.use_qk_norm = use_qk_norm self.num_experts_per_tok = num_experts_per_tok self.num_local_experts = num_local_experts self.output_router_logits = output_router_logits self.router_aux_loss_coef = router_aux_loss_coef self.router_jitter_noise = router_jitter_noise default_no_rope_layers = [ int((layer_idx + 1) % no_rope_layer_interval != 0) for layer_idx in range(self.num_hidden_layers) ] self.no_rope_layers = no_rope_layers if no_rope_layers else default_no_rope_layers self.interleave_moe_layer_step = interleave_moe_layer_step self.moe_layers = ( moe_layers if moe_layers is not None else list(range(interleave_moe_layer_step - 1, num_hidden_layers, interleave_moe_layer_step)) ) self.attention_chunk_size = attention_chunk_size if layer_types is None: layer_types = ["chunked_attention" if no_rope else "full_attention" for no_rope in self.no_rope_layers] self.layer_types = layer_types get_partition_rules = _get_partition_rules
[docs]@register_config("llama4") class Llama4Config(EasyDeLBaseConfig): """Composite configuration linking Llama4 text and vision components.""" model_type = "llama4" sub_configs: typing.ClassVar = {"text_config": Llama4TextConfig, "vision_config": Llama4VisionConfig} attribute_map: typing.ClassVar = { "image_token_id": "image_token_index", "boi_token_id": "boi_token_index", "eoi_token_id": "eoi_token_index", } def __init__( self, vision_config=None, text_config=None, boi_token_index=200080, eoi_token_index=200081, image_token_index=200092, tie_word_embeddings=False, **kwargs, ): if vision_config is None: self.vision_config = Llama4VisionConfig() logger.info("vision_config is None, using default llama4 vision config") elif isinstance(vision_config, dict): self.vision_config = Llama4VisionConfig(**vision_config) elif isinstance(vision_config, Llama4VisionConfig): self.vision_config = vision_config self.boi_token_index = boi_token_index self.eoi_token_index = eoi_token_index self.image_token_index = image_token_index if text_config is None: self.text_config = Llama4TextConfig() logger.info("text_config is None, using default llama4 text config") elif isinstance(text_config, dict): self.text_config = Llama4TextConfig(**text_config) elif isinstance(text_config, Llama4TextConfig): self.text_config = text_config super().__init__(tie_word_embeddings=tie_word_embeddings, **kwargs) get_partition_rules = _get_partition_rules
__all__ = ["Llama4Config", "Llama4TextConfig", "Llama4VisionConfig"]