Transformers documentation
Dikkat arka uçları
Dikkat arka uçları
Tüm dikkat (attention) uygulamaları aynı hesaplamayı gerçekleştirir. Her token, diğer tüm tokenlarla karşılaştırılır. Fark, hesaplamanın nasıl gerçekleştirildiğidir. Temel dikkat, tam dikkat matrisini bellekte somutlaştırarak ölçeklenmede yetersiz kalır ve çıkarımı yavaşlatan darboğazlar oluşturur. Optimize edilmiş uygulamalar, daha hızlı ve daha uygun maliyetli çıkarım için bellek trafiğini azaltacak şekilde matematiği yeniden düzenler.
AttentionInterface, optimize edilmiş dikkat (attention) uygulamaları sağlar. Dikkat uygulamasını model uygulamasından ayırarak farklı fonksiyonlarla deney yapmayı basitleştirir. Bu tutarlı arayüz sayesinde yeni arka uçları (backend) kolayca ekleyebilirsiniz.
| Dikkat arka ucu | Açıklama |
|---|---|
"flash_attention_3" | işlemleri de üst üste bindirerek ve ileri ile geri geçişleri daha sıkı bir şekilde birleştirerek FlashAttention-2'yi iyileştirir |
"flash_attention_2" | hesaplamaları daha küçük bloklara böler ve hızlı çip üstü belleği kullanır |
"flex_attention" | Düşük seviye çekirdekleri elle yazmadan özel dikkat desenlerini (seyrek, blok-yerel, kayan pencere) belirtmek için bir çerçeve |
"sdpa" | yerleşik PyTorch ölçekli nokta çarpımı dikkati uygulaması |
"paged|flash_attention_3" | FlashAttention-3'ün sayfalı sürümü |
"paged|flash_attention_2" | FlashAttention-2'nin sayfalı sürümü |
"paged|sdpa" | SDPA'nın sayfalı sürümü |
"paged|eager" | Eager'ın sayfalı sürümü |
Dikkat arka ucunu ayarlayın
Belirli bir dikkat işleviyle bir model oluşturmak için from_pretrained() içindeki attn_implementation argümanını kullanın.
import torch
from transformers import AutoModelForCausalLM
model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-3.2-1B", attn_implementation="flash_attention_2"
)Modeli yeniden yüklemeye gerek kalmadan çalışma zamanında dikkat (attention) arka uçları arasında geçiş yapmak için set_attn_implementation() kullanın.
model.set_attn_implementation("sdpa")Çekirdekler
Derlenmiş hesaplama çekirdeklerini çalışma zamanında doğrudan Hub'dan indirip Kernels kütüphanesiyle yükleyin. Bu, uyumsuz PyTorch veya CUDA sürümlerinden kaynaklanan paketleme sorunlarını önler.
Kernels, algılama anında AttentionInterface üzerine otomatik olarak kaydedilir. FlashAttention paketini açıkça kurmanıza gerek yoktur. FlashAttention adıyla istendiğinde de Hub kerneline geri düşülür, bkz. FlashAttention fallback.
import torch
from transformers import AutoModelForCausalLM
model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-3.2-1B", attn_implementation="kernels-community/flash-attn2"
)SDPA bağlam yöneticisi
PyTorch’un ölçekli nokta çarpımı dikkati (SDPA), CUDA arka uçları için en hızlı dikkat işlevini otomatik olarak seçer. Diğer arka uçlar için varsayılan olarak PyTorch C++ uygulamasını kullanır.
SDPA'nın torch.nn.attention.sdpa_kernel bağlam yöneticisiyle belirli bir uygulamasını kullanmasını zorlayın.
import torch
from torch.nn.attention import SDPBackend, sdpa_kernel
from transformers import AutoModelForCausalLM
model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-3.2-1B", attn_implementation="sdpa"
)
with sdpa_kernel(SDPBackend.FLASH_ATTENTION):
outputs = model.generate(**inputs)Backbone'a özgü dikkat
Çok modlu modeller, her mod için farklı omurga (backbone) kullanır. Performansı optimize etmek için her omurgaya belirli dikkat (attention) işlevleri atayın. Örneğin, bazı görme omurgaları fp32'de daha iyi performans gösterir ve FlashAttention bunu desteklemez.
Görsel omurgayı bir sözlük ile farklı dikkat işlevlerine eşleyin; metin omurgası FlashAttention kullanmaya devam eder. Dikkat uygulamasındaki anahtarlar, alt yapılandırma adlarıyla eşleşmelidir.
from transformers import AutoModelForImageTextToText
attention_implementation_per_backbone = {"vision_config": "sdpa", "text_config": "flash_attention_2"}
for key in attention_implementation_per_backbone:
assert key in model.config.sub_configs, f"Invalid key in `attention_implementation`"
model = AutoModelForImageTextToText.from_pretrained(
"facebook/chameleon-7b", attn_implementation=attention_implementation_per_backbone
)Belirli omurgaları sözlükten atlayarak varsayılan dikkat işlevini (SDPA) kullanın.
model = AutoModelForImageTextToText.from_pretrained(
"facebook/chameleon-7b", attn_implementation={"text_config": "flash_attention_2"}
)Tüm omurgalar için aynı dikkat işlevini tek bir dize ile ayarlayın.
model = AutoModelForImageTextToText.from_pretrained(
"facebook/chameleon-7b", attn_implementation="eager"
)Boş bir anahtarla dikkat işlevini küresel olarak ayarlayın.
model = AutoModelForImageTextToText.from_pretrained(
"facebook/chameleon-7b", attn_implementation={"": "eager"}
)Yeni bir dikkat (attention) fonksiyonu oluşturun
Dikkat işlevlerini AttentionInterface.register() ile dikkat kayıt defterine ekleyerek özelleştirin veya yeni işlevler oluşturun. Modeller bu işlevlere attn_implementation argümanı üzerinden erişir.
Özel bir dikkat fonksiyonu kaydederken eşleşen bir dikkat maskesi fonksiyonu da kaydedin. Özel
attn_implementationadı AttentionMaskInterface içinde kayıtlı değilse, Transformers mask oluşturma işlemini atlar ve dikkat katmanlarınaattention_mask=Noneiletir. Dikkat fonksiyonunuz, nedensellik, dolgu, paketleme veya kayan pencere kısıtlamalarını kendisi ele almalıdır; aksi takdirde bu kısıtlamalar sessizce düşürülebilir.
Bu örnek, her katman için bir ifade yazdırmak üzere dikkat işlevini özelleştirir. masking_utils.sdpa_mask işlevini dikkat maskesi işlevi olarak kaydederek maskenin orijinal uygulamadaki haliyle korunmasını sağlar.
import torch
from transformers import AutoModelForCausalLM, AttentionInterface, AttentionMaskInterface
from transformers.integrations.sdpa_attention import sdpa_attention_forward
from transformers.masking_utils import sdpa_mask
def my_new_sdpa(*args, **kwargs):
print("I just entered the attention computation")
return sdpa_attention_forward(*args, **kwargs)
AttentionInterface.register("my_new_sdpa", my_new_sdpa)
AttentionMaskInterface.register("my_new_sdpa", sdpa_mask) # must have the same name as the registered attention function
model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3.2-1B", attn_implementation="my_new_sdpa")
model(torch.ones(1, 5, dtype=int))Dikkat fonksiyonuna yeni argümanlar da ekleyebilirsiniz. AttentionInterface destekleyen modeller, kwargs'ları dikkat katmanlarına ve dikkat fonksiyonuna iletir. Argümanları, modelin forward fonksiyonunda kwargs olarak geçirin. Özel dikkat fonksiyonları bu imzaya ve dönüş biçimine uymalıdır.
import torch
from transformers import AutoModelForCausalLM, AttentionInterface, AttentionMaskInterface
from transformers.integrations.sdpa_attention import sdpa_attention_forward
from transformers.masking_utils import sdpa_mask
def custom_attention(
module: torch.nn.Module, # required arg
query: torch.Tensor, # required arg
key: torch.Tensor, # required arg
value: torch.Tensor, # required arg
attention_mask: Optional[torch.Tensor], # required arg
a_new_kwargs = None, # You can now add as many kwargs as you need
another_new_kwargs = None, # You can now add as many kwargs as you need
**kwargs, # You need to accept **kwargs as models will pass other args
) -> tuple[torch.Tensor, Optional[torch.Tensor]]
... # do your magic!
return attn_output, attn_weights # attn_weights are optional here
AttentionInterface.register("custom", custom_attention)
AttentionMaskInterface.register("custom", sdpa_mask) # to leave the existing mask untouched
model = AutoModelForCausalLM.from_pretrained(model_id, attn_implementation="custom")
model(torch.ones(1, 5, dtype=int), a_new_kwargs=..., another_new_kwargs=...)Bir modelin modeling kodunu inceleyerek dikkat fonksiyonuna hangi argümanları ve kwargs'ları gönderdiğini doğrulayın.
AttentionMaskInterface
AttentionMaskInterface, etkin dikkat arka ucunun beklediği formata bir maskenin dönüştürülmesi için create_*_mask işlevlerinin başvurduğu kayıt defteridir. FlexAttention bir BlockMask gerektirir, SDPA 4B bir tensör gerektirir ve FlashAttention temel 2B dolgu maskesini gerektirir. Özel bir arka uç kaydedin veya mevcut bir arka uç için biçimlendiriciyi geçersiz kılın: AttentionMaskInterface.register().
import torch
from transformers import AttentionMaskInterface
from transformers.masking_utils import sdpa_mask
def my_new_sdpa_mask(*args, **kwargs):
print("I just entered the attention mask computation")
return sdpa_mask(*args, **kwargs)
AttentionMaskInterface.register("my_new_sdpa_mask", my_new_sdpa_mask)Aktif attn_implementation için kayıtlı bir biçimlendirici yoksa, maske oluşturma atlanır ve attention_mask=None dikkat katmanlarına iletilir.
Kayıtlı fonksiyonlar bu imzayla eşleşmelidir.
def custom_attention_mask(
batch_size: int, # required arg
q_length: int, # required arg
kv_length: int, # required arg
q_offset: int = 0, # required arg
kv_offset: int = 0, # required arg
mask_function: Callable = causal_mask_function, # required arg
attention_mask: Optional[torch.Tensor] = None, # required arg
**kwargs, # a few additional args may be passed as kwargs, especially the model's config is always passed
) -> Optional[torch.Tensor]:mask_function argümanı, PyTorch’un mask_mod işlevlerini taklit eden bir Callable’dır. 4 indeks alır (batch_idx, head_idx, q_idx, kv_idx) ve o konumun dikkat (attention) hesabına katkıda bulunup bulunmadığını gösteren bir boolean döndürür. Bu, Dikkat maskesi oluşturma bölümündeki or_mask_function ve and_mask_function işlevlerinde kullanılan aynı temel yapıdır.
mask_functionbir maske oluşturamazsa, torch.export için bu çözüm yolunu kullanın.
Dikkat maskesi oluşturun
Dikkat maskelerini transformers.masking_utils içindeki create_*_mask işlevleriyle oluşturun. Her işlev, model yapılandırmasından etkin dikkat arka ucunu okur, arka ucun mask biçimlendiricisini AttentionMaskInterface içinde arar ve o arka ucun beklediği biçimi döndürür. Maskenin ters çevrilmesi, genişletilmesi veya dönüştürülmesi için kendiniz işlem yapmanıza gerek yoktur.
Dikkat desenine uyan işlevi seçin.
| function | kullanım senaryosu |
|---|---|
create_causal_mask | her tokenin kendisine ve önceki tokenlere dikkat ettiği (attends) yalnızca çözücü (decoder-only) modeller |
create_bidirectional_mask | encoder modelleri veya decoder'dan encoder durumlarına cross-attention |
create_sliding_window_causal_mask | kayan pencere dikkat desenine sahip decoder modeller |
create_chunked_causal_mask | diziyi sabit boyutlu bloklara bölen decoder modelleri |
create_bidirectional_sliding_window_mask | kayan pencere dikkat desenine sahip kodlayıcı modeller |
Eski çağrılabilir maske yardımcıları -
get_extended_attention_mask,create_extended_attention_mask_for_decoder,invert_attention_mask- artık bir kullanım dışı bırakma uyarısı üretir ve gelecekteki bir sürümde kaldırılacaktır. Bunun yerinecreate_*_maskişlevlerini kullanın.
Decoder ileri geçişinde create_causal_mask çağırın. Yapılandırma, giriş gömme değerleri, kullanıcı tarafından sağlanan 2B attention_mask ve önbelleği iletin. İşlev, gömme değerlerini kullanarak parti boyutunu, sorgu uzunluğunu, veri türünü ve cihazı okur; anahtar uzunluğunu hesaplamak için önbelleği kullanır.
from transformers.masking_utils import create_causal_mask
attention_mask = create_causal_mask(
config=self.config,
inputs_embeds=inputs_embeds,
attention_mask=attention_mask,
past_key_values=past_key_values,
)Encoder öz-dikkati için create_bidirectional_mask çağırın. Encoder'lar önbellekleme yapmadığı için past_key_values parametresini kaldırın.
from transformers.masking_utils import create_bidirectional_mask
attention_mask = create_bidirectional_mask(
config=self.config,
inputs_embeds=embedding_output,
attention_mask=attention_mask,
)Çapraz dikkat için, maskenin decoder'ın sorgu uzunluğu yerine encoder'ın anahtar ve değer uzunluğunu kullanması için encoder durumlarını encoder_hidden_states olarak iletin.
encoder_attention_mask = create_bidirectional_mask(
config=self.config,
inputs_embeds=embedding_output,
attention_mask=encoder_attention_mask,
encoder_hidden_states=encoder_hidden_states,
)Taban maskenin üzerine ek kısıtlamalar eklemek için or_mask_function ve and_mask_function argümanlarını kullanın. or_mask_function ile ek konumların dikkat etmesine izin verin, and_mask_function ile taban desenini daha da daraltın. İkisi de AttentionMaskInterface içinde açıklanan 4 indeksli mask_function imzasını takip eder. (batch_idx, head_idx, q_idx, kv_idx) alır ve bir boolean döndürür.
or_mask_functionveand_mask_functionherhangi bir dikkat desenini ifade edebilir, ancak yerleşik desenlerden daha yavaştır ve ExecuTorch ile uyumlu değildir. Bu ek yük, özellikle daha küçük modellerde (~200M parametre) en belirgin şekilde hissedilir; bu modellerde maske oluşturma, ileri geçiş süresinin daha büyük bir payını oluşturur. Bunlara, standartcreate_*_maskfonksiyonlarının ihtiyacınızı karşılayamadığı durumlarda başvurun.
Örneğin, her yerde True döndüren bir fonksiyonu nedensel bir maske üzerine bindirerek onu tamamen çift yönlü hale getirebilirsiniz. Nedensel desenle birleşim, her token'ın diğer tüm token'lara dikkat etmesini sağlar.
mask_kwargs = {
"config": self.config,
"inputs_embeds": inputs_embeds,
"attention_mask": attention_mask,
"past_key_values": past_key_values,
"position_ids": position_ids,
"or_mask_function": lambda *args: torch.tensor(True, dtype=torch.bool),
}
attention_mask = create_causal_mask(**mask_kwargs)Oluşturma sırasında generate(), model yapılandırmasına göre doğru create_*_mask işlevine yönlendiren create_masks_for_generate üzerinden maskeleri oluşturur. Oluşturma için özel bir maskeleme stratejisi uygulamak için bunu bir model sınıfında geçersiz kılın.
Özel bir 4D dikkat maskesi geçirin
Kendi 4B maskenizi, create_*_mask işlevlerinin ifade edemeyeceği bir dikkat desenine ihtiyacınız olduğunda iletin. 4B maskenin şekli (batch_size, 1, query_length, kv_length)'dir; burada 1, aynı maskenin tüm dikkat başlarına yayılmasını sağlar. Transformers, maskenin olduğu gibi algılanıp kullanıldığını tespit eder ve create_*_mask işlevlerini atlar.
4D bir maske, iki değer sözleşmesinden birini kullanır.
| dtype | katılmak | maskele |
|---|---|---|
| boolean | True | False |
| float | 0.0 | -inf |
Float sözleşmesi, softmax'tan önce maskenin dikkat puanlarına eklenmesini sağlar. Bir puana 0.0 eklenirse değişmez, dolayısıyla konum katkıda bulunur. Bir puana -inf eklenirse softmax'tan sonra sıfıra düşer, dolayısıyla konum hariç tutulur.
Kabul edilen sözleşme, dikkat (attention) arka ucuna bağlıdır.
sdpabir boolean veya float maske alır.eagermaskenin puanlara eklenmesini gerektirdiğinden yalnızca float maske alır.flash_attention_2veflex_attentionkendi formatlarını kullanır (2B dolgu maskesi ve BlockMask) ve ham 4B maske kabul etmez.
Yaygın bir hata, 2B dolgu maskesinin 1/0 sözleşmesinin, float 4B maske içinde yeniden kullanılmasıdır. Maske puanlara eklendiğinden, 0.0 bir konumu korurken 1.0 yalnızca küçük bir önyargı ekler.
Aşağıdaki örnek, hatalı bir maskenin doğru bir maske ile karşılaştırmasını gösterir. İkisi de aynı 1/0 nedensel deseninden başlar.
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
model = AutoModelForCausalLM.from_pretrained("TinyLlama/TinyLlama-1.1B-Chat-v1.0", attn_implementation="sdpa")
tokenizer = AutoTokenizer.from_pretrained("TinyLlama/TinyLlama-1.1B-Chat-v1.0")
input_ids = tokenizer("my favorite condiment on a", return_tensors="pt").input_ids
seq_len = input_ids.shape[1]
# 1 attends, 0 masks
causal = torch.tril(torch.ones(seq_len, seq_len))
# wrong: 1.0/0.0 floats are added to the scores, so 0.0 keeps a token and 1.0 barely changes it
wrong_mask = causal[None, None]
# correct: 0.0 attends, -inf masks
correct_mask = torch.where(causal.bool(), 0.0, float("-inf"))[None, None]Yanlış maske, 0.0 maskeleme değeri olduğu için hiçbir şeyi dışlamadığından tüm konumları korur.
wrong_mask correct_mask
(1 attends, 0 masks) (0 attends, -inf masks)
k0 k1 k2 k3 k4 k0 k1 k2 k3 k4
q0 1 0 0 0 0 q0 0 -inf -inf -inf -inf
q1 1 1 0 0 0 q1 0 0 -inf -inf -inf
q2 1 1 1 0 0 q2 0 0 0 -inf -inf
q3 1 1 1 1 0 q3 0 0 0 0 -inf
q4 1 1 1 1 1 q4 0 0 0 0 0Çift yönlü dikkat
Decoder-only modeller varsayılan olarak nedensel (tek yönlü) dikkat kullanır; bu durumda her token yalnızca kendisine ve önceki token'lara dikkat eder. is_causal=False değerini ayarlayarak, her token'ın diğer tüm token'lara dikkat ettiği çift yönlü dikkete geçebilirsiniz. Bu, örneğin gömme (embedding) üretmek için decoder-only modelleri metin kodlayıcı olarak kullanmanızı sağlar.
Bu yalnızca nedensel (decoder) modeller için geçerlidir. Encoder modellerini decoder modellerine dönüştürmez.
Her ileri geçiş için çift yönlü dikkati varsayılan yapmak için model yapılandırmasında is_causal=False değerini ayarlayın.
from transformers import AutoModel, AutoConfig
config = AutoConfig.from_pretrained("meta-llama/Llama-3.2-1B")
config.is_causal = False
model = AutoModel.from_pretrained("meta-llama/Llama-3.2-1B", config=config)
# all forward passes now use bidirectional attention
outputs = model(**inputs)Modeli iki kez yüklemeye gerek kalmadan nedensel ve çift yönlü dikkat arasında geçiş yapmak için model yapılandırması yerine ileri çağrıda is_causal parametresini geçirin. Bu anahtar kelime argümanı, yapılandırmayı geçici olarak devre dışı bırakır ve çağrıdan sonra geri yüklenir.
from transformers import AutoModel
model = AutoModel.from_pretrained("meta-llama/Llama-3.2-1B")
# run with bidirectional attention
outputs = model(**inputs, is_causal=False)
# run with default causal attention
outputs = model(**inputs)