# Configurações por camada

Alguns checkpoints são heterogêneos (não uniformes por camada). Um MLP menor em uma camada, menos cabeças de chave-valor em outra, ou um layout diferente em camadas selecionadas significa que uma configuração global única não descreve com precisão a pilha.

Use `per_layer_config` em [PreTrainedConfig](/docs/transformers/main/pt/main_classes/configuration#transformers.PreTrainedConfig) para registrar essas diferenças ao criar ou inspecionar uma configuração e quando o código do modelo as consumirá. Cada entrada armazena apenas o que difere da configuração global; o restante é herdado.

> [!NOTE]
> Configurações heterogêneas são um recurso poderoso. Se um layout heterogêneo se tornar uma arquitetura comum ou proeminente, buscaremos modelá-lo explicitamente na implementação da arquitetura, em vez de depender de `per_layer_config`. Prefira a arquitetura explícita quando esta existir.

Os modelos abaixo são checkpoints heterogêneos. As camadas não são uniformes em toda a pilha. Eles utilizam uma arquitetura dedicada com `block_configs` e seu próprio `model_type`, em vez de `per_layer_config` em uma arquitetura padrão.

| Model | Derivado de |
|---|---|
| [nvidia/Llama-3_3-Nemotron-Super-49B-v1_5](https://huggingface.co/nvidia/Llama-3_3-Nemotron-Super-49B-v1_5) | [meta-llama/Llama-3.3-70B-Instruct](https://huggingface.co/meta-llama/Llama-3.3-70B-Instruct) |
| [nvidia/Llama-3_1-Nemotron-Ultra-253B-v1](https://huggingface.co/nvidia/Llama-3_1-Nemotron-Ultra-253B-v1) | [meta-llama/Llama-3.1-405B-Instruct](https://huggingface.co/meta-llama/Llama-3.1-405B-Instruct) |
| [nvidia/gpt-oss-puzzle-88B](https://huggingface.co/nvidia/gpt-oss-puzzle-88B) | [openai/gpt-oss-120b](https://huggingface.co/openai/gpt-oss-120b) |
| [nvidia/NVIDIA-Nemotron-Labs-3-Puzzle-75B-A9B-BF16](https://huggingface.co/nvidia/NVIDIA-Nemotron-Labs-3-Puzzle-75B-A9B-BF16) | [nvidia/NVIDIA-Nemotron-3-Super-120B-A12B-BF16](https://huggingface.co/nvidia/NVIDIA-Nemotron-3-Super-120B-A12B-BF16) |

## Defina substituições por camada

Passe `per_layer_config` para [LlamaConfig](/docs/transformers/main/pt/model_doc/llama2#transformers.LlamaConfig) como um mapeamento de índices de camadas para substituições de atributos. Os índices de camadas começam em zero. Apenas os atributos que diferem da configuração global precisam ser especificados.

`per_layer_config` registra e resolve valores de configuração. Por si só, ele não altera os módulos que um modelo cria nem a forma como esses módulos são executados. Aplicar uma substituição de tamanho ou um `skip` exige código do modelo que leia a configuração por camada resolvida ao construir ou executar cada camada. O `LlamaModel` atual constrói cada `LlamaDecoderLayer` com a configuração global, de modo que as entradas `skip` abaixo permanecem como valores de configuração, em vez de remover módulos após o `from_pretrained`.

O exemplo a seguir registra substituições para quatro camadas: a camada 5 usa um MLP menor, a camada 11 usa menos cabeças de chave-valor, e as camadas 23 e 27 registram valores `skip` para arquiteturas que os suportam.

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

Os submódulos que uma arquitetura pode ignorar (por exemplo, `"mlp"` e `"attention"`) são definidos por arquitetura. `skip` aceita uma lista, de modo que uma camada pode registrar mais de uma substituição de submódulo.

Acessar `config.per_layer_config[layer_idx]` retorna uma configuração de camada resolvida. A configuração resolvida combina a configuração global com as substituições para essa camada.

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

As configurações que usam `per_layer_config` suportam o mesmo ciclo de ida e volta de [save_pretrained()](/docs/transformers/main/pt/main_classes/configuration#transformers.PreTrainedConfig.save_pretrained) e [from_pretrained()](/docs/transformers/main/pt/main_classes/configuration#transformers.PreTrainedConfig.from_pretrained) que as outras configurações.

Cada arquitetura define em seu código quais atributos ela consome no nível da camada. `per_layer_config` fornece o mecanismo para registrar essas diferenças no nível da camada e resolvê-las em relação à configuração global.

## Acesso a atributos globais

Um atributo com substituições por camada não possui um único valor para todo o modelo. `num_key_value_heads` pode ser `8` na maioria das camadas e `4` em camadas selecionadas. Ler `config.num_key_value_heads` fora de um contexto de camada é ambíguo.

Por padrão, esse acesso levanta `AmbiguousGlobalPerLayerAttributeError` e direciona você para `config.per_layer_config[layer_idx]`. O atributo ainda existe no config global, portanto, isso não é um `AttributeError`. Ler esse valor global sem um índice de camada ainda está incorreto. Código que constrói um cache de chave-valor a partir de um `num_key_value_heads` global dimensionaria incorretamente as camadas erradas.

Defina `allow_global_per_layer_attribute_access=True` apenas quando você intencionalmente precisar do fallback global e puder lidar com configurações heterogêneas. O acesso global é então permitido. Um aviso é emitido uma vez.

```py
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.
```

## Serialização

`per_layer_config` serializa de forma esparsa por padrão, e as camadas sem substituições são omitidas. Atributos substituídos que correspondem ao valor global também são omitidos.

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

Defina `serialize_explicit_per_layer_config=True` para incluir todas as camadas dos atributos representados em `per_layer_config`. Isso facilita a inspeção do layout das camadas quando alguns valores ainda correspondem à configuração global.

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

Use a serialização esparsa para configurações compactas e a serialização explícita quando precisar do layout completo por camada para legibilidade ou ferramentas.

