چیتشیت
مقایسهی انواع مختلف اتنشن
Attention Variants Compared
کامل، پنجرهی لغزان، استرایددار، BigBird، تفاضلی و اتنشن تنک نیتیو. هزینه، کش کلید-مقدار، کد، راهحلها.
فهرست مطالب
مقایسهی انواع کنار یکدیگر
مقایسه| نوع | محاسبات | کش کلید-مقدار | کیفیت در مقایسه با کامل |
|---|---|---|---|
| اتنشن کامل | O(N^2) | O(N) به ازای هر لایه | خط مبنا |
| SWA، با پنجرهی 1024 | N ضربدر W | O(W) به ازای هر لایه | -0.1 در ppl، عملکرد خوب با لایههای سراسری |
| محلی + تنک استرایددار | N ضربدر رادیکال N | ترکیبی | مشابه SWA |
| BigBird، محلی + سراسری + تصادفی | تقریباً O(N) | ترکیبی | برابری با اتنشن کامل در بافت 2 برابری |
| تنک نیتیو (DeepSeek-V3.2) | N ضربدر کسر فعال | O(N) | در محدودهی 0.05 از ppl |
| تفاضلی | 2 ضربدر N به توان 2 | O(2N) | -5 تا -10% در ppl |
چه زمانی از چه روشی استفاده کنیم؟
نکتهها- اتنشن کامل: تمام لایهها تا حدود 16 هزار توکن بافت، یا وقتی کیفیت بازیابی در اولویت است.
- ترکیب SWA + سراسری: بافت بلند بالاتر از 32 هزار توکن. استاندارد پیشفرض سال 2026 برای بالای 32 هزار.
- اتنشن بلوکی تنک: کرنل سفارشی، الگوی سفارشی. مناسب برای بازیابی و صوت.
- اتنشن تفاضلی: وقتی سینک اتنشن آسیب میزند، مانند RAG در بافت طولانی و مسئلهی سوزن در انبار کاه.
- DIFF از همان ابتدا: مدل جدیدی که بافت موثر بالای 64 هزار توکن را هدف قرار داده است.
- NSA: پیشآموزش یا ادامهی آموزش برای بافت بالای 64 هزار توکن.
- عدم استفاده از DIFF یا NSA: یک مدل متراکم از پیش آموزشدیده، یا بافت زیر 16 هزار توکن.
سازندههای ماسک
کدpython
def swa_mask(n, window):
M = [[NEG_INF] * n for _ in range(n)]
for i in range(n):
lo = max(0, i - window + 1) # اگر پنجره >= n باشد اتنشن علّی کامل حاصل میشود
for j in range(lo, i + 1):
M[i][j] = 0.0 # 0.0 یعنی اتنشن دارد، NEG_INF ماسک میکند
return M
def strided_mask(n, window, stride): # پنجرهی محلی، سپس:
for j in range(0, i + 1, stride):
M[i][j] = 0.0 # هر توکن به فاصلهی استراید به عقب تا 0
render(swa_mask(8, window=4), "sliding window (W=4)")
render(strided_mask(8, window=2, stride=3), "local (W=2) + strided (stride=3)")
SWA همراه با FlexAttention
کدpython
from torch.nn.attention.flex_attention import flex_attention, create_block_mask
def swa_pattern(b, h, q_idx, kv_idx):
return (q_idx - kv_idx < 1024) & (q_idx >= kv_idx) # پنجرهی 1024، علّی
mask = create_block_mask(swa_pattern, B=batch, H=heads, Q_LEN=n, KV_LEN=n)
out = flex_attention(q, k, v, block_mask=mask) # کامپایل به یک کرنل Triton
NSA: سه branch
معماریحلقهی تایل در فلش اتنشن
گامبهگام- حلقهی بیرونیبارگذاری یک تایل Q، حدود 128 × 128، درون SRAM.
- حلقهی درونیبارگذاری هر تایل K و تایل V درون SRAM.
- در SRAMمحاسبهی
S_tile = Q_tile @ K_tile^T. - در SRAMنگهداشتن یک مقدار جاری
(max, sum)روی تایلها. - در SRAMبازتنظیم مقیاس خروجی قبلی با
exp_oldو افزودن بلوک جدید. - در HBMنوشتن
O_tileدرون HBM. یک بار رفتوبرگشت به HBM برای هر تایل. - نتیجهخروجی از نظر بیتی کاملاً یکسان با اتنشن استاندارد، حافظهی O(N) به جای O(N^2).
وظایف درون کد
کار و کد| وظیفه | کد |
|---|---|
| ماسک علّی SWA | swa_mask(n, window) |
| ماسک محلی بهعلاوهی استرایددار | strided_mask(n, window, stride) |
| شمارش خانههای دارای اتنشن | count_nonmasked(M) |
| بایتهای کش کلید-مقدار | kv_cache_bytes(N, n_layers, n_heads_kv, d_head, dtype=2) |
| سافتمکس به سبک فلش | tiled_softmax_dot(q, Ks, Vs, tile=4) |
| نسبت سیگنال به نویز یک سطر | snr(weights_row, signal_pos) |
| پارامترهای DIFF نسخهی 1 و 2 | compute_param_diff(hidden=4096, n_heads=32, kv_heads=8) |
| کلیدهای NSA به ازای هر پرسوجو | count_nsa(N, l, k, W) |
اعدادی که باید بدانید
پیشفرضها| تنظیم | پیشفرض | توضیح |
|---|---|---|
Llama 3 70B KV per token per layer | 4096 bytes | 80 لایه، 8 هد کش کلید-مقدار، fp16 |
Llama 3 70B KV, 32K context | 10 GiB | روش GQA با 8 هد کش کلید-مقدار |
Gemma 3 layer mix | 5:1 SWA:global | پنجره = 1024 |
SWA KV at 128K context | 128× | پنجرهی 1024، W توکن آخر |
Gemma-3 mix KV | ~6x | در مقایسه با اتنشن کامل خالص |
DIFF `lambda_init` | 0.8 | آموزشدیده به ازای هر هد |
NSA window `W` | 512 | l = 64, k = 16 در بافت 64k، کاهش 25 برابری |
NSA at 128k | 3536 keys | کاهش 36 برابری |
عیبیابی
عیبیابیشکست مدل SWA در بازیابی دوربرد
- علت
- نبود لایههای سراسری
- راهحل
- ترکیب یکدرمیان لایههای کامل، نسبت 5 به 1
نشت وزنها به توکن 0
- علت
- سینک اتنشن ناشی از سافتمکس
- راهحل
- اتنشن تفاضلی
گم شدن در میانه فراتر از 32 هزار توکن
- علت
- رشد کف نویز سافتمکس همگام با افزایش N
- راهحل
- استفاده از DIFF از ابتدا، یا اعمال LoRA روی Q
رمزگشایی DIFF نسخهی 1 کندتر از خط مبناست
- علت
- بارگذاری کش مقدار به میزان دو بار
- راهحل
- DIFF نسخهی 2
ناپایداری در اواخر آموزش برای مدلهای بالای 70B
- علت
- استفاده از RMSNorm به ازای هر هد در نسخهی 1
- راهحل
- نسخهی 2 آن را حذف میکند
استفاده از NSA روی مدل متراکم پیشآموزشدیده
- علت
- امکان تطبیق روی مدل آماده وجود ندارد
- راهحل
- ادامهی آموزش
عدم مشاهدهی برتری NSA در بافت کمتر از 16 هزار
- علت
- سربار معماری سهگانهی branchها
- راهحل
- اتنشن کامل
تنک بودن در زمان استنتاج شتاب کمی میدهد
- علت
- مدل هرگز با چنین مسیری آموزش ندیده است
- راهحل
- تنک بودن ذاتاً آموزشدیده (نیتیو)
پرسش و پاسخ
پرسش و پاسخ- آیا فلش اتنشن محاسبات را کم میکند؟
- خیر. حافظهی اکتیویشن را مخفی میسازد. همچنان همهی توکنها به تمام توکنها اتنشن دارند.
- چرا NSA آموزشپذیر است؟
- گرادیانها از امتیازات branch فشردهشده عبور میکنند. عملگر
top_kتنها بلوکها را برای بارگذاری انتخاب میکند. - چرا DIFF در بافت 128k کمک بیشتری میکند؟
- کف نویز همراه با طول بافت رشد میکند. در بافت 4k این نویز کم است.
- آیا DIFF نسخهی 2 با GQA سازگار است؟
- بله. نسخهی 2 هدهای Q را افزایش میدهد، نه هدهای کلید-مقدار را.
- تعداد کلیدهای NSA در بافت 1024 با l=32، k=4 و w=128 چقدر است؟
- 32 + 128 + 128 = 288 کلید، یعنی 3.5 برابر کمتر.
واژهنامه
اصطلاحها- SWA
- اتنشن پنجرهی لغزان. هر پرسوجو به W توکن آخر خود اتنشن دارد.
- میدان دید
- پشتهای از SWA با L لایه و پنجرهی W تا سقف L × W توکن را پوشش میدهد.
- سینک اتنشن
- مجموع هر سطر 1 است، بنابراین پرسوجوهای کماثر وزن خود را روی موقعیت 0 متمرکز میکنند.
- NSA
- اتنشن تنک نیتیو. تنک بودن بلوکی آموزشدیده، بلوکهای صفر در کرنل نادیده گرفته میشوند.
- DSA
- اتنشن تنک DeepSeek، نسخهی ارتقایافتهی NSA.
- HBM
- حافظهی با پهنای باند بالا. حدود 3 ترابایت بر ثانیه روی پردازندهی H100.
- SRAM
- حافظهی روی چیپ به ازای هر SM. حدود 30 ترابایت بر ثانیه.