تکمیل Decoder در Transformer
Decoder در هر Block سه Sub-layer اصلی دارد: Masked Self-Attention، Cross-Attention روی Encoder Output و Feed Forward. Self-Attention اول هم Padding Tokenها و هم Future Tokenها را Mask میکند. در Cross-Attention، Query از Decoder و Key/Value از Encoder میآید.
encoder_outputs = Z
Z = decoder_in
for _ in range(N):
skip = Z
attn_layer = tf.keras.layers.MultiHeadAttention(
num_heads=num_heads, key_dim=embed_size, dropout=dropout_rate)
Z = attn_layer(Z, value=Z,
attention_mask=causal_mask & decoder_pad_mask)
Z = tf.keras.layers.LayerNormalization()(tf.keras.layers.Add()([Z, skip]))
skip = Z
attn_layer = tf.keras.layers.MultiHeadAttention(
num_heads=num_heads, key_dim=embed_size, dropout=dropout_rate)
Z = attn_layer(Z, value=encoder_outputs,
attention_mask=encoder_pad_mask)
Z = tf.keras.layers.LayerNormalization()(tf.keras.layers.Add()([Z, skip]))
skip = Z
Z = tf.keras.layers.Dense(n_units, activation="relu")(Z)
Z = tf.keras.layers.Dense(embed_size)(Z)
Z = tf.keras.layers.LayerNormalization()(tf.keras.layers.Add()([Z, skip]))
Y_proba = tf.keras.layers.Dense(vocab_size, activation="softmax")(Z)
با این بخش، Transformer کامل برای Translation ساخته میشود و با Sparse Categorical Cross-Entropy Train میگردد.
موج Transformer Modelها
سال ۲۰۱۸ نقطهٔ جهش بزرگ NLP بود. ایدهٔ اصلی این بود که Model ابتدا روی Corpus بسیار بزرگ با Task خودنظارتی Pretrain شود و سپس با مقدار کمی دادهٔ Labelدار Fine-tune گردد.
GPT
GPT نشان داد یک Transformer Language Model که روی Text عظیم Pretrain شده است میتواند سپس برای Taskهای مختلف Fine-tune شود. معماری GPT عمدتاً از Decoder Blockهای Transformer و Causal Self-Attention استفاده میکند؛ یعنی Token فقط Tokenهای قبلی را میبیند و Task اصلی پیشبینی Token بعدی است.
BERT و Pretraining دوطرفه
BERT از Encoder Transformer استفاده میکند و Context را از هر دو سمت میبیند. Pretraining اصلی آن دو Task داشت:
- Masked Language Modeling (MLM): بخشی از Tokenها Mask میشوند و Model باید Word اصلی را پیشبینی کند. برای کاهش فاصلهٔ Pretraining و Fine-tuning، همهٔ Tokenهای انتخابشده همیشه با
<mask> جایگزین نمیشوند؛ بعضی با Word تصادفی و بعضی بدون تغییر باقی میمانند.
- Next Sentence Prediction (NSP): Model تشخیص میدهد Sentence دوم واقعاً بعد از Sentence اول آمده است یا نه. پژوهشهای بعدی نشان دادند NSP ضروری نیست و بسیاری از Modelهای جدید آن را حذف کردند.
Token ویژهٔ <CLS> برای Representation کلی Input و <SEP> برای جدا کردن Sentenceها استفاده میشود. Segment Embedding نیز مشخص میکند هر Token متعلق به Sentence A یا B است.
شکل 16-11. BERT و Pretraining دوطرفه
پس از Pretraining، برای Taskهایی مانند Sentiment Analysis فقط Head خروجی تغییر میکند و کل Model یا بخشی از آن Fine-tune میشود.
GPT-2، Scale و Distillation
GPT-2 با بیش از 1.5 میلیارد Parameter نشان داد Language Model بزرگ میتواند برخی Taskها را بدون Fine-tuning و بهصورت Zero-shot انجام دهد. این آغاز رقابت Scale بود و Modelهای صدها میلیارد و حتی تریلیون Parameter ظاهر شدند. Scale هزینهٔ Training، Energy و Memory را بالا میبرد و دسترسی به Model را محدود میکند.
در مقابل، DistilBERT از Knowledge Distillation استفاده میکند: Student کوچکتر بهجای Labelهای سخت، Probabilityهای Teacher را تقلید میکند. این Targetهای نرم اطلاعات بیشتری دربارهٔ Similarity Classها میدهند و Model کوچک میتواند بخش زیادی از کیفیت Teacher را حفظ کند.
T5 و Text-to-Text
T5 همهٔ NLP Taskها را به یک قالب Text-to-Text تبدیل میکند. برای Translation Prefix مانند translate English to Spanish:، برای Summary کلمهٔ summarize: و برای Classification Prefix مناسب به Input اضافه میشود. Output در همهٔ موارد Text است، بنابراین یک Architecture و Training Objective واحد میتواند Taskهای بسیار متنوع را پوشش دهد.
PaLM و Prompting
Modelهای بسیار بزرگ مانند PaLM نشان دادند Scale همراه با Prompt مناسب میتواند قابلیتهای جدیدی در Question Answering، Coding و Reasoning ایجاد کند. یکی از تکنیکهای مطرح در متن کتاب، Chain-of-Thought Prompting است که در Exampleهای Prompt، مراحل میانی حل مسئله نیز نشان داده میشوند تا Model الگوی حل چندمرحلهای را یاد بگیرد.
Vision Transformer و Attention بصری
Attention ابتدا در مدلهای Captioning تصویر در کنار CNN استفاده شد. Decoder هنگام تولید هر Word به بخش مرتبط Image نگاه میکند؛ مثلاً هنگام تولید واژهٔ «frisbee» بیشترین Weight روی خود Frisbee قرار میگیرد.
شکل 16-12. Vision Transformer و Attention بصری
این Attention Map میتواند به Explainability کمک کند: اگر Model Prediction اشتباه دارد، میتوان دید روی چه ناحیهای تمرکز کرده است. البته Attention بهتنهایی توضیح کامل علت تصمیم نیست، اما ابزار مفیدی برای Debugging و تحلیل Behavior است.
ViT: تصویر بهعنوان Sequence از Patchها
Vision Transformer یا ViT تصویر را به Patchهای کوچک، مثلاً 16×16، تقسیم میکند. هر Patch Flatten میشود، Linear Projection میگیرد، Positional Embedding به آن اضافه میشود و Sequence حاصل دقیقاً مانند Word Embedding وارد Transformer Encoder میشود. برای Image RGB، هر Patch 16×16 یک Vector با 768 مقدار خام دارد.
Transformer نسبت به CNN Inductive Bias کمتری دربارهٔ Locality و Translation Equivariance دارد؛ بنابراین معمولاً برای رسیدن به بهترین کیفیت به Data بیشتری نیاز دارد.
Transformerهای Multimodal
در ادامهٔ متن، معماریهایی مانند DETR، Perceiver، DINO و Modelهای Multimodal مطرح میشوند. Perceiver برای کاهش Cost Self-Attention، Input عظیم را ابتدا به Latent Array کوچکتر Cross-Attend میکند. Trend جدید Modelهایی است که Text، Image، Audio و حتی Action را در Architecture مشترک ترکیب میکنند.
کتابخانهٔ Transformers از Hugging Face
Hugging Face یک Ecosystem بزرگ شامل Model Hub، کتابخانهٔ Transformers و Datasets ساخته است. سادهترین API تابع pipeline() است:
from transformers import pipeline
classifier = pipeline("sentiment-analysis")
result = classifier(["The movie was great!", "I did not like it."])
Pipeline Tokenization، Model، Postprocessing و Label Mapping را پشت صحنه انجام میدهد. برای کنترل بیشتر میتوان Tokenizer و TensorFlow Model را جدا Load کرد:
from transformers import AutoTokenizer, TFAutoModelForSequenceClassification
model_name = "bert-base-uncased"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = TFAutoModelForSequenceClassification.from_pretrained(model_name)
token_ids = tokenizer(
["I like soccer. [SEP] We all love soccer!"],
padding=True,
truncation=True,
return_tensors="tf")
outputs = model(token_ids)
proba = tf.nn.softmax(outputs.logits, axis=-1)
Tokenizer خروجیای شبیه Dictionary به نام BatchEncoding میدهد که معمولاً شامل input_ids و attention_mask است و در بعضی Modelها token_type_ids نیز دارد.
Fine-tuning با Keras
sentences = [("Sky is blue", "Sky is red"),
("I love her", "She loves me")]
X_train = tokenizer(sentences, padding=True, return_tensors="tf").data
y_train = tf.constant([0, 2])
loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
model.compile(loss=loss, optimizer="nadam", metrics=["accuracy"])
model.fit(X_train, y_train, epochs=2)
چون Model Logit میدهد نه Probability، Loss باید با from_logits=True ساخته شود. Hugging Face Datasets نیز برای Download و Preprocessing Datasetهای NLP و Multimodal ابزارهای آماده دارد.
تمرینهای فصل ۱۶
- چرا Encoder-Decoderهای Sequence-to-Sequence برای Translation مناسباند و Teacher Forcing چه کمکی میکند؟
- Beam Search چه مزیتی نسبت به Greedy Decoding دارد و Beam Width چه Trade-offی ایجاد میکند؟
- Attention چه Bottleneckی را در Encoder-Decoder حل میکند؟ تفاوت Bahdanau و Luong Attention چیست؟
- چرا Transformer به Positional Encoding نیاز دارد؟
- Self-Attention و Cross-Attention از نظر Query/Key/Value چه تفاوتی دارند؟
- Masked Language Modeling در BERT چگونه کار میکند؟
- یک RNN بسازید که Stringهای مطابق Grammar را از Stringهای نامعتبر تشخیص دهد و Dataset متوازن تولید کنید.
- یک Encoder-Decoder بسازید که Date String را از یک Format به Format دیگر تبدیل کند.
- مثال Keras مربوط به Natural Language Image Search با Dual Encoder را اجرا کنید و Image/Text را در یک Embedding Space مشترک قرار دهید.
- با Hugging Face یک Language Model مولد مانند GPT Download کنید و Text شکسپیری قانعکنندهتری بسازید.