Transformers documentation

Configurations par couche

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v5.22.2).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Configurations par couche

Certains points de contrôle sont hétérogènes (non uniformes par couche). Un MLP plus petit dans une couche, moins de têtes clé-valeur dans une autre, ou un agencement différent sur certaines couches signifie qu’une configuration globale unique ne décrit pas fidèlement la pile.

Utilisez per_layer_config sur PreTrainedConfig pour enregistrer ces différences lors de la création ou de l’inspection d’une configuration, et lorsque le code du modèle les consommera. Chaque entrée ne stocke que ce qui diffère de la configuration globale, le reste étant hérité.

Les configurations hétérogènes constituent une fonctionnalité puissante. Si une disposition hétérogène devient une architecture courante ou prépondérante, nous nous efforcerons de la modéliser explicitement dans l’implémentation de l’architecture plutôt que de nous reposer sur per_layer_config. Privilégiez l’architecture explicite lorsqu’elle existe.

Les modèles ci-dessous sont des points de contrôle hétérogènes. Les couches ne sont pas uniformes dans la pile. Ils utilisent une architecture dédiée avec block_configs et leur propre model_type, plutôt que per_layer_config sur une architecture standard.

ModèleDérivé de
nvidia/Llama-3_3-Nemotron-Super-49B-v1_5meta-llama/Llama-3.3-70B-Instruct
nvidia/Llama-3_1-Nemotron-Ultra-253B-v1meta-llama/Llama-3.1-405B-Instruct
nvidia/gpt-oss-puzzle-88Bopenai/gpt-oss-120b
nvidia/NVIDIA-Nemotron-Labs-3-Puzzle-75B-A9B-BF16nvidia/NVIDIA-Nemotron-3-Super-120B-A12B-BF16

Définir des substitutions par couche

Passez per_layer_config à LlamaConfig sous forme d'un mapping des indices de couche vers les attributs à surcharger. Les indices de couche sont basés sur zéro. Seuls les attributs qui diffèrent de la configuration globale doivent être spécifiés.

per_layer_config enregistre et résout les valeurs de configuration. Il ne modifie pas à lui seul les modules créés par un modèle ni la manière dont ces modules s’exécutent. Appliquer une surcharge de taille ou un skip nécessite un code de modèle qui lit la configuration par couche résolue lors de la construction ou de l’exécution de chaque couche. Le LlamaModel actuel construit chaque LlamaDecoderLayer avec la configuration globale, de sorte que les entrées skip ci-dessous restent des valeurs de configuration plutôt que de supprimer des modules après from_pretrained.

L’exemple suivant enregistre des substitutions pour quatre couches : la couche 5 utilise un MLP plus petit, la couche 11 utilise moins de têtes clé-valeur, et les couches 23 et 27 enregistrent des valeurs skip pour les architectures qui les prennent en charge.

from transformers import LlamaConfig


config = LlamaConfig(
    hidden_size=4096,
    intermediate_size=14336,
    num_hidden_layers=32,
    num_attention_heads=32,
    num_key_value_heads=8,
    per_layer_config={
        # Use a smaller MLP in one layer.
        5: {"intermediate_size": 8192},

        # Use fewer key-value heads in another layer.
        11: {"num_key_value_heads": 4},

        # Record a request to skip the MLP in architectures that support it.
        23: {"skip": ["mlp"]},

        # Record a request to skip attention in architectures that support it.
        27: {"skip": ["attention"]},
    },
)

Les sous-modules qu'une architecture peut ignorer (par exemple, "mlp" et "attention") sont définis pour chaque architecture. skip accepte une liste, ce qui permet à une couche d'enregistrer plus d'une substitution de sous-module.

L’accès à config.per_layer_config[layer_idx] renvoie une configuration de couche résolue. La configuration résolue combine la configuration globale avec les substitutions pour cette couche.

# Layer 0 does not define overrides, so it inherits the global values.
config.per_layer_config[0].intermediate_size
# 14336

config.per_layer_config[0].num_key_value_heads
# 8

# Layer 5 overrides the MLP intermediate size.
config.per_layer_config[5].intermediate_size
# 8192

# Layer 11 overrides the number of key-value heads.
config.per_layer_config[11].num_key_value_heads
# 4

# Layer 23 records an MLP skip.
config.per_layer_config[23].skip
# ["mlp"]

# Layer 27 records an attention skip.
config.per_layer_config[27].skip
# ["attention"]

Les configurations qui utilisent per_layer_config prennent en charge le même aller-retour save_pretrained() et from_pretrained() que les autres configurations.

Chaque architecture définit dans son code les attributs qu'elle consomme au niveau de la couche. per_layer_config fournit le mécanisme pour enregistrer ces différences au niveau de la couche et les résoudre par rapport à la configuration globale.

Accès aux attributs globaux

Un attribut avec des remplacements par couche n'a pas de valeur unique pour l'ensemble du modèle. num_key_value_heads peut être 8 sur la plupart des couches et 4 sur certaines couches sélectionnées. Lire config.num_key_value_heads en dehors d'un contexte de couche est ambigu.

Par défaut, cet accès lève AmbiguousGlobalPerLayerAttributeError et vous renvoie vers config.per_layer_config[layer_idx]. L’attribut existe toujours sur la configuration globale, il ne s’agit donc pas d’une AttributeError. Lire cette valeur globale sans un index de couche reste incorrect. Un code qui construit un cache clé-valeur à partir d’un num_key_value_heads global dimensionnerait incorrectement les mauvaises couches.

Définissez allow_global_per_layer_attribute_access=True uniquement si vous avez réellement besoin du repli global et que vous pouvez gérer des configurations hétérogènes. L’accès global est alors autorisé. Un avertissement est émis une seule fois.

config = LlamaConfig(
    hidden_size=4096,
    intermediate_size=14336,
    num_hidden_layers=32,
    num_attention_heads=32,
    num_key_value_heads=8,
    allow_global_per_layer_attribute_access=True,
    per_layer_config={
        11: {"num_key_value_heads": 4},
    },
)

config.num_key_value_heads
# 8
# Emits a one-time warning because num_key_value_heads has a per-layer override.

Sérialisation

per_layer_config sérialise de manière creuse par défaut, et les couches sans surcharge sont omises. Les attributs surchargés qui correspondent à la valeur globale sont également omis.

from transformers import LlamaConfig


config = LlamaConfig(
    hidden_size=4096,
    intermediate_size=14336,
    num_hidden_layers=4,
    num_attention_heads=32,
    num_key_value_heads=8,
    per_layer_config={
        0: {"num_key_value_heads": 8},
        2: {"num_key_value_heads": 4},
    },
)

config.to_dict()["per_layer_config"]
# {"2": {"num_key_value_heads": 4}}

Définissez serialize_explicit_per_layer_config=True pour inclure chaque couche pour les attributs représentés dans per_layer_config. Cela facilite l’inspection de la disposition des couches lorsque certaines valeurs correspondent encore à la configuration globale.

explicit_config = LlamaConfig(
    hidden_size=4096,
    intermediate_size=14336,
    num_hidden_layers=4,
    num_attention_heads=32,
    num_key_value_heads=8,
    serialize_explicit_per_layer_config=True,
    per_layer_config={
        0: {"num_key_value_heads": 8},
        2: {"num_key_value_heads": 4},
    },
)

serialized_per_layer_config = explicit_config.to_dict()["per_layer_config"]

serialized_per_layer_config
# {
#     "0": {"num_key_value_heads": 8},
#     "1": {"num_key_value_heads": 8},
#     "2": {"num_key_value_heads": 4},
#     "3": {"num_key_value_heads": 8},
# }

Utilisez la sérialisation creuse pour des configurations compactes, et la sérialisation explicite lorsque vous avez besoin de la disposition complète par couche pour la lisibilité ou les outils.

Update on GitHub