جلسه ۱۱ از ۱۱، بخش ۲: سیستم‌های سرویس‌دهی LLM

مبانی سرویس‌دهی LLM: GPU

متنی ۴۰ دقیقه به‌روز شده در ۱۰ آبان ۱۴۰۵

در این جلسه
  1. GPU یک ماشین توان عملیاتی است
  2. سه مشخصه که هر GPU را محدود می‌کنند
  3. قاعده‌ی طلایی
  4. مدل roofline
  5. درون H200
  6. شتاب‌دهنده‌های دیگر، در یک نگاه
  7. جمع‌بندی
  8. پرسش‌هایی برای فکر کردن
  9. منابع

جلسه‌ی قبل گفت prefill «محدود به محاسبه» و decode «محدود به پهنای باند» است. این جلسه توضیح می‌دهد این جمله‌ها دقیقاً یعنی چه و چطور با یک حساب سرانگشتی می‌شود زمان اجرا را پیش‌بینی کرد. هدف شهود است، نه برنامه‌نویسی CUDA.

GPU یک ماشین توان عملیاتی است#

پردازنده‌ی سرور ۶۴ هسته‌ای NVIDIA H200 SXM
واحدهای موازی ۶۴ هسته ۱۳۲ SM، ۱۶۸۹۶ هسته‌ی FP32
نخ‌های در جریان ۱۲۸ ۲۷۰٬۳۳۶ (۲۰۴۸ در هر SM)
پهنای باند حافظه حدود ۰٫۴۶ ترابایت بر ثانیه (DDR5) ۴٫۸ ترابایت بر ثانیه (HBM3e)
محاسبه‌ی متراکم بیشینه حدود ۵ ترافلاپ FP32 ۹۸۹ ترافلاپ BF16
تأخیر را چطور پنهان می‌کند کش و اجرای خارج از ترتیب جابه‌جایی به یک warp آماده

CPU مثل یک خودروی اسپرت است: برای دو مسافر سریع‌ترین است. GPU مثل ناوگان اتوبوس است: کندتر، اما هزاران نفر را جابه‌جا می‌کند. LLM دقیقاً کار اتوبوسی است: برای هر توکن همان ضرب‌های ماتریسی روی همان وزن‌ها به‌طور موازی انجام می‌شود.

warp و SIMT#

یک warp گروهی از ۳۲ نخ است که یک دستور را هم‌زمان روی داده‌های مختلف اجرا می‌کنند (SIMT: یک دستور، چند نخ):

// each thread computes one element
i = threadIdx.x;
y[i] = a * x[i] + b;

یک بار واکشی، یک بار رمزگشایی و یک تصمیم زمان‌بندی، ۳۲ مسیر را جلو می‌برد. هزینه‌اش واگرایی شاخه است:

if (i % 4 == 0)  a = f(x[i]);   // 8 of 32 threads
else             a = g(x[i]);   // 24 of 32 threads

warp هر دو مسیر را پشت سر هم اجرا می‌کند و در هر مسیر بخشی از نخ‌ها بیکارند.

پنهان کردن تأخیر با جابه‌جایی warp#

خواندن از حافظه‌ی اصلی صدها چرخه طول می‌کشد. CPU این تأخیر را با کش‌های بزرگ و پیش‌بینی پنهان می‌کند. GPU روش دیگری دارد: هر SM تا ۶۴ warp را هم‌زمان نگه می‌دارد و وقتی یکی منتظر حافظه است، بی‌هزینه به warp دیگری که آماده است می‌پرد. چون حالت همه‌ی نخ‌ها مقیم است، جابه‌جایی رایگان است.

GPU از این می‌گذرد تا این را به دست آورد
سرعت تک‌نخی مساحت و توان برای هزاران واحد حسابی
موازی‌سازی ضمنی موازی‌سازی صریح؛ کار کوچک تراشه را بیکار می‌گذارد
کش و پیش‌بینی پنهان کردن تأخیر با جابه‌جایی warp
کنترل مستقل هر نخ کنترل مشترک گروه‌های ۳۲تایی
حافظه‌ی زیاد برای هر نخ حدود ۲۴۰ بایت برای هر نخ در اشغال کامل

سه مشخصه که هر GPU را محدود می‌کنند#

A100 H200 B200 Rubin (مقدماتی)
محاسبه‌ی BF16 ۳۱۲ ترافلاپ بر ثانیه ۹۸۹ ۲۲۵۰ حدود ۴۰۰۰
ظرفیت حافظه ۸۰ گیگابایت ۱۴۱ گیگابایت ۱۸۰ گیگابایت ۲۸۸ گیگابایت
پهنای باند حافظه ۲٫۰ ترابایت بر ثانیه ۴٫۸ ۸ حدود ۲۲
  • محاسبه: ریاضی با چه سرعتی انجام می‌شود. موتور خودرو.
  • پهنای باند: وزن‌ها و KV با چه سرعتی خوانده می‌شوند. لوله‌ی سوخت.
  • ظرفیت: چند وزن و چند مدخل KV جا می‌شوند. باک.

قاعده‌ی طلایی#

kernel_time ≈ max( bytes_moved / memory_bandwidth ,  FLOPs / peak_FLOPs )

زمان اجرای هر kernel تقریباً بیشینه‌ی دو عدد است: زمانی که جابه‌جایی داده طول می‌کشد و زمانی که محاسبه طول می‌کشد. هر کدام بزرگ‌تر بود، همان گلوگاه است.

دو مثال با Llama 3 8B روی یک H200:

decode با batch برابر ۱. برای یک توکن باید حدود ۱۶ گیگابایت وزن از HBM خوانده شود:

زمان خواندن:  16 GB ÷ 4.8 TB/s ≈ 3.3 ms
زمان محاسبه:  ~16 GFLOP ÷ 989 TFLOP/s ≈ 0.016 ms

هسته‌های محاسباتی ۹۹٫۵٪ وقت بیکارند. هر وزن فقط یک بار استفاده می‌شود و ریاضی منتظر حافظه می‌ماند.

prefill با ۲۰۴۸ توکن. هر وزنی که خوانده می‌شود برای ۲۰۴۸ توکن استفاده می‌شود:

محاسبه: 2 × 8B × 2048 ≈ 33 TFLOP  ←  33 TFLOP ÷ 989 TFLOP/s ≈ 33 ms

خواندن زود تمام می‌شود و حالا ریاضی سرعت را تعیین می‌کند.

مدل roofline#

شدت حسابی یعنی چند FLOP به ازای هر بایتی که از HBM جابه‌جا می‌شود:

شدت حسابی = FLOP انجام‌شده ÷ بایت جابه‌جاشده
نقطه‌ی شکست (ridge) = محاسبه‌ی بیشینه ÷ پهنای باند
                    = 989 TFLOP/s ÷ 4.8 TB/s ≈ 206 FLOP/B   (برای H200)
  performance
  (FLOP/s)
     │                     ┌──────────────── compute roof: 989 TFLOP/s
     │                    ╱
     │                   ╱   compute-bound: prefill, large GEMM
     │                  ╱
     │                ╱
     │              ╱   memory-bound: decode, GEMV
     │            ╱     speed = bandwidth × intensity
     │          ╱
     └────────────────────┬────────────────── arithmetic intensity (FLOP/B)
                         206

سمت چپ نقطه‌ی شکست، سرعت را پهنای باند تعیین می‌کند (decode). سمت راست، سقف محاسبه تعیین می‌کند (prefill و ضرب ماتریس‌های بزرگ).

شدت حسابی عملیات رایج (b = بایت هر عنصر؛ در BF16 برابر ۲):

عملیات شدت با BF16
جمع برداری 1/(3b) حدود ۰٫۱۷
ضرب ماتریس در بردار (decode) حدود 2/b حدود ۱
attention در decode 2/b حدود ۱
ضرب ماتریس مربعی N×N 2N/(3b) حدود ۲۷۳۰ برای N=8192

تمرین: H200 در decode با batch برابر ۱ چقدر مشغول است؟#

شدت حدود ۱ FLOP بر بایت است، پس:

کارایی ≈ 4.8 TB/s × 1 FLOP/B = 4.8 TFLOP/s   ←   4.8 ÷ 989 ≈ 0.5%  از توان محاسباتی

نیم درصد. decode با batch کوچک بیش از ۹۹٪ توان GPU را هدر می‌دهد. راه‌حل‌ها از خود فرمول می‌آیند:

  • batch بزرگ‌تر: هر وزنی که خوانده می‌شود برای چند درخواست استفاده می‌شود و شدت بالا می‌رود
  • کوانتیزه‌سازی: بایت کمتر برای هر وزن
  • کم کردن ترافیک KV: GQA، MLA و فشرده‌سازی (جلسه‌ی قبل)

آیا batching در decode کافی است؟#

با batch برابر B، هر وزنی که خوانده می‌شود B بار استفاده می‌شود، پس شدت حسابی ضرب‌های وزن تقریباً B برابر می‌شود. نموداری در اسلاید شدت را برای batch از ۱ تا ۲۵۶ در BF16 رسم می‌کند: با بزرگ شدن batch، ضرب‌های وزن به نقطه‌ی شکست ۲۰۶ نزدیک می‌شوند. اما attention در decode روی 2/b می‌ماند، چون KV هر درخواست مال خودش است و فقط یک بار استفاده می‌شود. با بلند شدن کانتکست، خواندن KV بر هزینه غالب می‌شود:

Llama 3 8B، batch ۱۶، BF16 (وزن‌ها ۱۶٫۱ گیگابایت، KV حدود ۱۲۸ کیلوبایت به ازای هر توکن):

طول کانتکست ۱K ۴K ۸K ۱۶K ۳۲K
بایت خوانده‌شده در هر قدم ۱۸٫۲ GB ۲۴٫۷ GB ۳۳٫۳ GB ۵۰٫۵ GB ۸۴٫۸ GB
زمان هر قدم (÷ ۴٫۸ TB/s) ۳٫۸ ms ۵٫۱ ms ۶٫۹ ms ۱۰٫۵ ms ۱۷٫۷ ms

در ۳۲K، KV چهار برابر خود وزن‌هاست. برای ایجنت‌ها با کانتکست صدها هزار توکنی، decode تقریباً تماماً خواندن KV است.

def decode_step_ms(weights_gb, kv_kib_per_token, batch, context, bw_tb_s=4.8):
    """تخمین زمان یک قدم decode وقتی محدود به پهنای باند است."""
    kv_gb = batch * context * kv_kib_per_token * 1024 / 1e9
    return (weights_gb + kv_gb) / (bw_tb_s * 1e3) * 1e3      # GB ÷ (GB/ms)

for ctx in (1024, 32 * 1024, 200 * 1024):
    print(ctx, round(decode_step_ms(16.1, 128, 16, ctx), 1), "ms")
# 1024 3.8 ms | 32768 17.7 ms | 204800 92.8 ms

در خط آخر، KV به تنهایی حدود ۴۳۰ گیگابایت است و اصلاً در حافظه‌ی ۱۴۱ گیگابایتی H200 جا نمی‌شود. یعنی پیش از آنکه سرعت مسئله شود، ظرفیت مسئله می‌شود.

دقت پایین‌تر، نقطه‌ی شکست را جابه‌جا می‌کند#

GPU پهنای باند HBM BF16 FP8 FP4
A100 SXM ۲٫۰۴ TB/s ۱۵۳ — —
H100 SXM ۳٫۳۵ TB/s ۲۹۵ ۵۹۱ —
H200 ۴٫۸ TB/s ۲۰۶ ۴۱۲ —
B200 ۸ TB/s ۲۸۱ ۵۶۳ ۱۱۲۵
AMD MI355X ۸ TB/s ۳۱۵ ۶۲۹ ۱۲۵۹
Rubin (مقدماتی) ۲۲ TB/s ۱۸۲ ۷۹۵ ۱۵۹۱

در FP32 نقطه‌ی شکست خیلی پایین است: حدود ۹٫۶ در A100، ۲۰ در H100، ۱۴ در H200 و ۹٫۴ در B200. یعنی kernelهای FP32 تقریباً همیشه محدود به حافظه‌اند. در طرف دیگر، NVFP4 متراکم در Rubin حدود ۱۶۰۰ FLOP به ازای هر بایت لازم دارد تا محدود به محاسبه شود.

(اعداد جدول نقطه‌ی شکست بر حسب FLOP بر بایت‌اند.) از A100 تا Rubin، توان محاسباتی سریع‌تر از پهنای باند رشد کرده است. پس هر نسل، kernelهای بیشتری محدود به حافظه می‌شوند. بهینه‌سازی جابه‌جایی داده روزبه‌روز مهم‌تر می‌شود.

درون H200#

┌─────────────────── H200 ───────────────────┐
│  132 × SM   ┌────┐┌────┐ ... ┌────┐        │   each SM: 4 partitions, each with
│             │ SM ││ SM │     │ SM │        │   a warp scheduler, 32 FP32 cores
│             └────┘└────┘     └────┘        │   and one Tensor Core
│                                            │   registers 256 KB, shared/L1 256 KB
│                 L2: 50 MB                  │
│        HBM3e: 141 GB at 4.8 TB/s           │──── NVLink 900 GB/s to other GPUs
└────────────────────────────────────────────┘

Tensor Core#

یک دستور MMA در سطح warp حاصل D = A × B + C را روی کاشی‌هایی مثل ۱۶×۱۶ و ۱۶×۸ حساب می‌کند: ۲۰۴۸ ضرب و جمع با یک دستور. بیش از ۹۹٪ FLOPهای LLM ضرب ماتریس است و روی Tensor Core اجرا می‌شود. softmax و نرمال‌سازی روی هسته‌های معمولی FP32 اجرا می‌شوند. برای مقایسه، H200 با Tensor Core در BF16 به ۹۸۹ ترافلاپ می‌رسد و با هسته‌های FP32 معمولی فقط به ۶۷.

دلیل سرعت Tensor Core: مسیر داده‌ی تخصصی برای کل کاشی، دستور کمتر به ازای هر FLOP، استفاده‌ی دوباره از عملوندها و دقت پایین‌تر با جمع‌کردن در دقت بالاتر.

سلسله‌مراتب حافظه#

سطح ظرفیت تأخیر پهنای باند
ثبات‌ها ۲۵۶ KB در هر SM درون خط لوله بیشترین
حافظه‌ی مشترک و L1 ۲۵۶ KB در هر SM حدود ۳۰ تا ۴۰ چرخه حدود ۳۳ TB/s در کل تراشه
L2 ۵۰ MB حدود ۲۵۰ چرخه حدود ۱۲ TB/s
HBM3e ۱۴۱ GB حدود ۵۰۰ چرخه ۴٫۸ TB/s
حافظه‌ی CPU و GPUهای دیگر — میکروثانیه NVLink ۴۵۰ GB/s در هر جهت؛ PCIe 5 حدود ۶۴ GB/s

FlashAttention که در جلسه‌ی قبل دیدیم دقیقاً از همین سلسله‌مراتب استفاده می‌کند: کاشی‌ها را در حافظه‌ی مشترک نگه می‌دارد تا ماتریس بزرگ امتیازها هرگز به HBM نرود.

حافظه به‌عنوان یک لوله: قانون Little#

پهنای باند = بایت‌های در جریان ÷ تأخیر

اگر تأخیر حافظه حدود ۲۵۰ نانوثانیه باشد، برای رسیدن به ۴٫۸ ترابایت بر ثانیه باید 4.8 TB/s × 250 ns ≈ 1.2 MB داده هم‌زمان در راه باشد، یعنی حدود ۹ کیلوبایت برای هر SM. یک kernel ساده که هر نخ ۴ بایت می‌خواند فقط حدود ۴ کیلوبایت در هر SM در راه دارد و به حدود ۴۵٪ پهنای باند می‌رسد.

طول لوله را سخت‌افزار تعیین می‌کند، پس تنها راه پهنای باند بیشتر، داده‌ی بیشتر در جریان است: بارگذاری‌های ۱۶ بایتی، چند بارگذاری مستقل در هر نخ، و کپی‌های گروهی ناهمگام. هر نسل جدید این عدد را بالاتر می‌برد و ویژگی‌های جدید هر نسل هم بیشتر برای همین ساخته شده‌اند:

H200 (Hopper) B200 (Blackwell) Rubin
تعداد SM ۱۳۲ ۱۴۸ ۲۲۴
HBM ۱۴۱ GB HBM3e ۱۸۰ GB HBM3e ۲۸۸ GB HBM4
پهنای باند HBM ۴٫۸ TB/s ۸ TB/s ۲۲ TB/s
داده‌ی در جریان، کل GPU ۱٫۲ MB ۲٫۰ MB ۵٫۵ MB
داده‌ی در جریان، هر SM ۹ KB ۱۴ KB ۲۵ KB
ویژگی جدید TMA، clusterها TMEM، MMA دو-SM descriptorهای درون‌خطی TMA

ابزارهای Hopper و Blackwell برای داده‌ی بیشتر در جریان (پیشرفته)#

ویژگی چه می‌کند
coalescing وقتی ۳۲ نخ واژه‌های ۴ بایتی پشت سر هم را می‌خوانند، درخواست‌ها در یک درخواست ۱۲۸ بایتی ادغام می‌شوند
بارگذاری برداری ۱۶ بایتی یک دستور warp به جای ۱۲۸ بایت، ۵۱۲ بایت جابه‌جا می‌کند؛ چهار برابر
cp.async (از Ampere) کپی از حافظه‌ی اصلی به حافظه‌ی مشترک، بدون گذشتن از ثبات‌ها
TMA (Hopper) یک نخ کپی کل یک کاشی (مثلاً ۱۲۸×۶۴) را شروع می‌کند و سخت‌افزار آدرس‌ها را می‌سازد. چند کیلوبایت با یک دستور در جریان قرار می‌گیرد و ثبات‌ها آزاد می‌مانند.
TMA multicast تا ۸ thread block در یک cluster یک خواندن از L2 را به اشتراک می‌گذارند، پس ترافیک L2 برای هر SM کم می‌شود
TMEM (Blackwell) در Hopper نتیجه‌ی ضرب ماتریس در ثبات‌ها می‌ماند. Blackwell آن را به ۲۵۶ KB «حافظه‌ی tensor» می‌برد و ثبات‌ها برای بارگذاری‌های بیشتر آزاد می‌شوند.
MMA دو-SM (Blackwell) دو SM با هم یک ضرب ماتریس روی کاشی دو برابر بزرگ‌تر انجام می‌دهند و هر کدام نصف کاشی مشترک را بار می‌کند

بزرگ‌تر از یک GPU#

  • مقیاس به بالا: ۸ GPU در یک سرور با NVSwitch (در H200، NVLink با ۹۰۰ GB/s برای هر GPU)، یا ۷۲ GPU در یک رک GB200 NVL72
  • مقیاس به بیرون: شبکه‌ی RDMA بین سرورها (حدود ۵۰ GB/s برای هر GPU در H200)

فاصله‌ی HBM (۴٫۸ TB/s) تا NVLink (۰٫۹ TB/s) و تا شبکه (۰٫۰۵ TB/s) نشان می‌دهد چرا تقسیم مدل روی چند GPU هزینه دارد و چرا جای قرار گرفتن هر بخش مهم است. این موضوع جلسه‌ی موازی‌سازی است.

دو دهه GPU انویدیا (پیشرفته)#

نسل (سال، تراشه) چه چیزی اضافه شد
Tesla (۲۰۰۶، G80) shaderهای یکپارچه، CUDA، thread block، حافظه‌ی مشترک
Fermi (۲۰۱۰، C2050) کش واقعی L1 و L2، ECC، فضای آدرس یکپارچه، FP64 سریع
Kepler (۲۰۱۲، K20X) warp shuffle، موازی‌سازی پویا، Hyper-Q
Maxwell (۲۰۱۴، M40) تقسیم SM به چهار بخش؛ جهش بزرگ در کارایی به ازای هر وات
Pascal (۲۰۱۶، P100) HBM2، NVLink، حافظه‌ی یکپارچه با page fault، FP16 دو برابر
Volta (۲۰۱۷، V100) Tensor Core، زمان‌بندی مستقل نخ‌ها، L1 و حافظه‌ی مشترک یکپارچه
Turing (۲۰۱۸، T4) Tensor Core برای INT8 و INT4، هسته‌های ray tracing
Ampere (۲۰۲۰، A100) TF32، BF16، پراکندگی ۲:۴، cp.async، MIG، L2 چهل‌مگابایتی
Hopper (۲۰۲۲، H100) FP8، TMA، cluster و حافظه‌ی مشترک توزیع‌شده، wgmma، محاسبه‌ی محرمانه
Blackwell (۲۰۲۴، B200) دو die، FP6 و FP4 با block scaling، TMEM، tcgen05، NVL72
Blackwell Ultra (۲۰۲۵، B300) ۲۸۸ GB HBM3e، ۱۵ پتافلاپ NVFP4 متراکم، exp سریع‌تر، FP64 خیلی کمتر
Rubin (۲۰۲۶، NVL72) HBM4، NVLink 6، TMEM و حافظه‌ی مشترک بزرگ‌تر (مقدماتی)

سال‌های ۲۰۰۶ تا ۲۰۱۷ GPU را از گرافیک به محاسبه‌ی عمومی برد و ۲۰۱۸ تا ۲۰۲۶ آن را به سمت موتور هوش مصنوعی با دقت پایین. از G80 تا B300 توان محاسباتی بیشینه حدود ۴۳ هزار برابر شده و پهنای باند فقط حدود ۹۰ برابر. این همان دلیلی است که kernelها روزبه‌روز محدود به حافظه‌تر می‌شوند.

شتاب‌دهنده‌های دیگر، در یک نگاه#

تراشه ایده‌ی اصلی
AMD MI355X ۸ تراشه‌ی محاسباتی در یک بسته که برای نرم‌افزار یک GPU است؛ ۲۵۶ MB کش Infinity جلوی HBM؛ wavefront ۶۴ نخی به جای warp سی‌ودوتایی. برنامه‌نویسی با ROCm و HIP (شبیه CUDA؛ ابزار hipify کد CUDA را تبدیل می‌کند). PyTorch، vLLM و SGLang روی ROCm اجرا می‌شوند.
Google TPU Ironwood آرایه‌های systolic: هر وزن در خانه‌ی خودش می‌ماند، فعال‌سازی‌ها از چپ وارد می‌شوند و جمع‌های جزئی به پایین جریان دارند. برخلاف GPU، عملوندها در هر دستور از ثبات خوانده و نوشته نمی‌شوند. برنامه‌نویسی با JAX یا PyTorch/XLA و Pallas برای kernel سفارشی.
Amazon Trainium3 ۸ NeuronCore، هر کدام با موتورهای جدای tensor (systolic)، vector و scalar؛ ۳۲ MB SRAM برای هر هسته که موتورهای DMA پرش می‌کنند و کش سخت‌افزاری ندارد. بهبودها از MXFP8 و MXFP4 می‌آید. برنامه‌نویسی با Neuron SDK و NKI؛ CUDA ندارد و kernelها موتورها را هدف می‌گیرند، نه نخ‌ها را.

مقایسه با B200:

B200 MI355X TPU Ironwood Trainium3
محاسبه‌ی متراکم FP8 ۴٫۵ PF ۵٫۰ PF ۴٫۶ PF ۲٫۵ PF (MXFP8)
HBM ۱۸۰ GB ۲۸۸ GB ۱۹۲ GB ۱۴۴ GB
پهنای باند HBM ۸ TB/s ۸ TB/s ۷٫۴ TB/s ۴٫۹ TB/s
دامنه‌ی scale-up ۷۲ (NVL72) ۸ GPU ۹۲۱۶ تراشه در توروس سه‌بعدی ۱۴۴ تراشه

شتاب‌دهنده‌هایی که بر حافظه‌ی روی تراشه (SRAM) تکیه می‌کنند:

تراشه SRAM روی تراشه حافظه‌ی بیرونی مصالحه
Cerebras WSE-3 ۴۴ GB ندارد کل یک wafer یک تراشه است؛ مدل‌های بزرگ‌تر وزن‌ها را جریان می‌دهند
Groq LPU ۲۳۰ MB ندارد یک مدل ۷۰ میلیاردی با ۸ بیت حدود ۳۰۰ تراشه لازم دارد
Microsoft Maia 200 ۲۷۲ MB ۲۱۶ GB HBM3e SRAM داده‌ی داغ را نگه می‌دارد؛ فقط داخل Azure

جمع‌بندی#

  1. GPU سرعت تک‌نخی را با هزاران هسته‌ی موازی معاوضه می‌کند.
  2. محاسبه، پهنای باند و ظرفیت هر kernel را محدود می‌کنند.
  3. نقطه‌ی شکست roofline (۲۰۶ FLOP بر بایت در H200) kernelهای محدود به حافظه را از kernelهای محدود به محاسبه جدا می‌کند.
  4. batching خواندن وزن‌ها را به نقطه‌ی شکست نزدیک می‌کند، اما خواندن KV محدود به حافظه می‌ماند.
  5. نسل‌های جدید نقطه‌ی شکست را به راست می‌برند، پس kernelهای بیشتری محدود به پهنای باند می‌شوند.

اتصال به بخش اول مجموعه: وقتی در جلسه‌ی ۸ گفتیم «کانتکست کوچک‌تر نگه دارید»، این فقط صرفه‌جویی در صورت‌حساب API نیست. در سطح سخت‌افزار، هر توکن اضافه در کانتکست یعنی بایت‌های بیشتری که در هر قدم decode از HBM خوانده می‌شوند.

پرسش‌هایی برای فکر کردن#

  • اگر Llama 3 8B را با وزن‌های ۴ بیتی اجرا کنید، زمان یک قدم decode با batch برابر ۱ تقریباً چقدر می‌شود؟ آیا decode دیگر محدود به حافظه نیست؟
  • یک ایجنت با کانتکست ۲۰۰ هزار توکنی روی Llama 3 8B و batch ۱۶: چند درصد بایت‌های هر قدم مال وزن‌هاست؟ prefix caching چه کمکی می‌کند و چه کمکی نمی‌کند؟

منابع#