Transformers documentation
레이어별 구성
레이어별 구성
일부 체크포인트는 이질적(레이어 균일하지 않음)입니다. 특정 레이어에서 더 작은 MLP, 다른 레이어에서 더 적은 key-value 헤드, 또는 선택된 레이어에서 다른 레이아웃은 단일 전역 구성이 스택을 정확히 설명하지 못함을 의미합니다.
per_layer_config를 PreTrainedConfig에 사용하여 config를 작성하거나 검사할 때, 그리고 모델 코드가 이를 사용할 때 해당 차이를 기록합니다. 각 항목은 전역 구성과 다른 부분만 저장하고, 나머지는 상속합니다.
이질적 구성은 강력한 기능입니다. 이질적 레이아웃이 일반적이거나 두드러지는 아키텍처가 되면,
per_layer_config에 의존하기보다 아키텍처 구현에서 이를 명시적으로 모델링하도록 노력할 것입니다. 명시적인 아키텍처가 존재하는 경우 이를 우선 사용하세요.
아래 모델들은 이질적인 체크포인트입니다. 스택 전반에 걸쳐 레이어가 균일하지 않습니다. 표준 아키텍처의 per_layer_config 대신, block_configs와 자체 model_type를 사용하는 전용 아키텍처를 사용합니다.
레이어별 오버라이드 정의
per_layer_config를 LlamaConfig에 레이어 인덱스에서 속성 오버라이드로의 매핑으로 전달합니다. 레이어 인덱스는 0부터 시작합니다. 전역 설정과 다른 속성만 지정하면 됩니다.
per_layer_config은 구성 값을 기록하고 해석합니다. 이 자체로는 모델이 생성하는 모듈이나 해당 모듈의 실행 방식을 변경하지 않습니다. 크기 오버라이드나 skip를 적용하려면 각 레이어를 구성하거나 실행할 때 해석된 레이어별 구성을 읽는 모델 코드가 필요합니다. 현재 LlamaModel은 모든 LlamaDecoderLayer를 전역 구성으로 구성하므로, 아래 skip 항목은 from_pretrained 이후 모듈을 제거하는 것이 아니라 구성 값으로 남아 있습니다.
다음 예시에서는 네 개의 레이어에 대한 오버라이드를 기록합니다. 레이어 5는 더 작은 MLP를 사용하고, 레이어 11은 더 적은 key-value head를 사용하며, 레이어 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는 이러한 레이어 레벨의 차이를 기록하고 전역 config와 비교하여 해결하는 메커니즘을 제공합니다.
전역 속성 접근
레이어별 오버라이드가 있는 속성은 모델 전체에 적용되는 단일 값을 가지지 않습니다. num_key_value_heads는 대부분의 레이어에서 8이고 선택된 레이어에서 4일 수 있습니다. 레이어 컨텍스트 외부에서 config.num_key_value_heads를 읽으면 모호합니다.
기본적으로 해당 접근은 AmbiguousGlobalPerLayerAttributeError를 발생시키며 config.per_layer_config[layer_idx]를 가리킵니다. 해당 속성은 여전히 전역 config에 존재하므로 이는 AttributeError가 아닙니다. 레이어 인덱스 없이 해당 전역 값을 읽는 것은 여전히 잘못된 동작입니다. 전역 num_key_value_heads에서 키-밸류 캐시를 구성하는 코드는 잘못된 크기의 레이어를 잘못 생성하게 됩니다.
allow_global_per_layer_attribute_access=True는 전역 폴백이 의도적으로 필요하고 이질적인 구성을 처리할 수 있는 경우에만 설정하세요. 그러면 전역 접근이 허용됩니다. 경고가 한 번 출력됩니다.
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},
# }컴팩트한 설정을 위해 sparse serialization을 사용하고, 가독성이나 도구 사용에 전체 레이어별 레이아웃이 필요할 때는 explicit serialization을 사용하세요.
Update on GitHub