Transformers documentation

Конфигурации для каждого слоя

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

Конфигурации для каждого слоя

Некоторые контрольные точки гетерогенны (не имеют однородной структуры по слоям). Более малый MLP в одном слое, меньшее количество ключевых и значимых головок в другом или иной макет в выбранных слоях означают, что единая глобальная конфигурация не описывает стек точно.

Используйте per_layer_config в PreTrainedConfig, чтобы фиксировать эти различия при создании или проверке конфигурации, а также когда код модели будет их использовать. Каждая запись хранит только то, что отличается от глобальной конфигурации, остальное наследуется.

Гетерогенные конфигурации — это мощная возможность. Если гетерогенная компоновка станет распространённой или преобладающей архитектурой, мы будем стремиться явно моделировать её в реализации архитектуры, а не полагаться на per_layer_config. При наличии явной архитектуры отдавайте ей предпочтение.

Модели, перечисленные ниже, представляют собой гетерогенные контрольные точки. Слои в стеке не являются однородными. Они используют выделенную архитектуру с block_configs и собственным model_type, а не per_layer_config в стандартной архитектуре.

МодельПолучено из
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

Определение переопределений для каждого слоя

Передайте per_layer_config в LlamaConfig как отображение индексов слоёв на переопределения атрибутов. Индексы слоёв нумеруются с нуля. Необходимо указать только те атрибуты, которые отличаются от глобальной конфигурации.

per_layer_config фиксирует и разрешает значения конфигурации. Сам по себе он не изменяет модули, которые создаёт модель, и не влияет на то, как эти модули выполняются. Применение переопределения размера или skip требует, чтобы код модели читал разрешённую по-слойную конфигурацию при построении или выполнении каждого слоя. Текущая LlamaModel создаёт каждый LlamaDecoderLayer с глобальной конфигурацией, поэтому записи skip ниже остаются значениями конфигурации, а не удаляют модули после from_pretrained.

В следующем примере записываются переопределения для четырёх слоёв: слой 5 использует меньший MLP, слой 11 — меньшее количество ключевых и значимых головок, а слои 23 и 27 записывают значения skip для архитектур, которые их поддерживают.

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"]},
    },
)

Подмодули, которые архитектура может пропустить (например, "mlp" и "attention"), определяются для каждой архитектуры. skip принимает список, поэтому слой может зафиксировать более одного переопределения подмодуля.

Обращение к config.per_layer_config[layer_idx] возвращает разрешённую конфигурацию слоя. Разрешённая конфигурация объединяет глобальную конфигурацию с переопределениями для данного слоя.

# 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"]

Конфигурации, использующие per_layer_config, поддерживают тот же цикл save_pretrained() и from_pretrained(), что и другие конфигурации.

Каждая архитектура определяет в своём коде, какие атрибуты она использует на уровне слоя. per_layer_config предоставляет механизм для записи этих различий на уровне слоя и их разрешения относительно глобальной конфигурации.

Доступ к глобальным атрибутам

Атрибут с переопределениями для отдельных слоёв не имеет единого значения для всей модели. num_key_value_heads может быть 8 в большинстве слоёв и 4 в выбранных слоях. Чтение config.num_key_value_heads вне контекста слоя неоднозначно.

По умолчанию такой доступ вызывает AmbiguousGlobalPerLayerAttributeError и указывает на config.per_layer_config[layer_idx]. Атрибут по-прежнему существует в глобальной конфигурации, поэтому это не AttributeError. Чтение этого глобального значения без индекса слоя всё равно является ошибкой. Код, создающий кэш ключей и значений на основе глобального num_key_value_heads, будет неверно рассчитывать размеры для неправильных слоёв.

Устанавливайте allow_global_per_layer_attribute_access=True только в том случае, если вам намеренно необходим глобальный fallback и вы готовы работать с неоднородными конфигурациями. В этом случае глобальный доступ разрешён. Предупреждение выводится один раз.

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.

Сериализация

per_layer_config по умолчанию сериализуется разреженно, и слои без переопределений пропускаются. Переопределённые атрибуты, совпадающие с глобальным значением, также пропускаются.

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}}

Установите serialize_explicit_per_layer_config=True, чтобы включить в per_layer_config все слои для представленных в нём атрибутов. Это упрощает проверку структуры слоёв, когда некоторые значения всё ещё совпадают с глобальной конфигурацией.

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},
# }

Используйте разреженную сериализацию для компактных конфигураций, а явную сериализацию — когда для читаемости или работы с инструментами требуется полная поуровневая структура.

Update on GitHub