فاز 19 · درس 35

سرهم‌بندی مدل GPT: پیاده‌سازی معماری 124M و تولید متن

نوع
ساختنی
زمان
حدود 90 دقیقه
زبان‌ها
Python
بلوک‌های ساختمانی منظم و متصل به هم از جنس کریستال که یک هرم یا برج محاسباتی را با نظمی مهندسی و شبکه‌ای تشکیل داده‌اند
فهرست مطالب
  1. اهداف یادگیری
  2. صورت مسئله
  3. مفهوم
  4. اشتراک ماتریس وزن‌ها (Weight tying)
  5. امبدینگ موقعیت یادگیری‌پذیر است، نه سینوسی
  6. تولید متن: دما، top-k و نمونه‌برداری چندجمله‌ای
  7. پیاده‌سازی از صفر
  8. استک فنی
  9. الگوهای محیط عملیاتی
  10. کاربرد عملی
  11. تمرین‌ها
  12. اصطلاحات کلیدی
  13. برای مطالعه‌ی بیشتر

در درس‌های گذشته اجزای درونی ترنسفورمر، از مکانیزم توجه گرفته تا لایه‌های MLP و نرمال‌سازی را به‌تفکیک بررسی کردیم. اما این قطعات تا زمانی که در قالب یک معماری یکپارچه سیم‌کشی نشوند، قادر به پردازش توالی‌های زبانی یا تولید کلمات نیستند. در این درس، تمام این بلوک‌ها را کنار امبدینگ توکن و موقعیت می‌گذاریم تا معماری نام‌آشنای GPT-2 با 124 میلیون پارامتر متولد شود.

درک نحوه‌ی اتصال این بخش‌ها، به‌ویژه تکنیک اشتراک وزن‌ها (Weight Tying) میان امبدینگ و لایه‌ی نهایی، نه‌تنها از مصرف بیهوده‌ی ده‌ها میلیون پارامتر حافظه جلوگیری می‌کند، بلکه استانداردی پایه‌ای برای پیاده‌سازی شبکه‌های مدرن‌تر مانند خانواده‌ی LLaMA به شمار می‌رود. علاوه بر ساخت مدل، پایپ‌لاین تولید خودبازگشتی متن با ابزارهای کنترلی دما و هرس top-k را نیز از صفر می‌سازیم.

برای اجرای این درس به پردازنده‌ی ابری یا سخت‌افزارهای گران‌قیمت خارجی نیازی ندارید؛ تمام مراحل تعریف معماری، بررسی تعداد پارامترها و آزمایش نمونه‌برداری روی پیکربندی‌های کوچک‌تر به‌راحتی روی CPU سیستم شخصی شما قابل اجراست.

روی هم چیدن 12 بلوک، یک امبدینگ توکن، یک امبدینگ موقعیت (position embedding) یادگیری‌پذیر، یک LayerNorm نهایی و یک سر مدل زبانی متصل (tied). کل مدل 124 میلیون پارامتری GPT همین است. در این درس این قطعات را کنار هم می‌گذاریم تا به یک کلاس کامل و آماده‌به‌کار برسیم، پارامترها را می‌شماریم تا مطمئن شویم ابعاد مدل با نسخه‌ی مرجع 124M مو نمی‌زند و در نهایت با نمونه‌برداری چندجمله‌ای (multinomial sampling)، دمای نمونه‌برداری (temperature) و top-k متن تولید می‌کنیم.

اهداف یادگیری

  • سرهم کردن بلوک ترنسفورمر از درس 34 و ساخت مدل کامل GPT: امبدینگ توکن، امبدینگ موقعیت، N بلوک، LayerNorm نهایی و سر مدل زبانی (language model head).
  • پیاده‌سازی دقیق پیکربندی 124 میلیون پارامتری: اندازه‌ی واژگان 50257، طول زمینه 1024، بعد امبدینگ 768، 12 سر اتنشن و 12 لایه.
  • اشتراک ماتریس وزن‌های سر مدل زبانی با امبدینگ توکن (Weight Tying) و توضیح این‌که چرا این کار در این مقیاس حدود 38 میلیون پارامتر صرفه‌جویی می‌کند.
  • تولید متن از روی پرامپت با نمونه‌برداری چندجمله‌ای، تنظیم دما و هرس top-k، همراه با حفظ طول زمینه به کمک پنجره‌ی لغزان (sliding window).
  • سنجش تعداد پارامترها و هزینه‌ی محاسباتی گذر رو به جلو (forward pass) در مقایسه با هدف 124M.

صورت مسئله

یک بلوک ترنسفورمر به‌تنهایی کاری از پیش نمی‌برد. باید شناسه‌های توکن (token ids) را به بردار تبدیل کنید، اطلاعات موقعیت مکانی را با آن‌ها بیامیزید، داده‌ها را از میان دسته‌ی بلوک‌ها عبور دهید و در نهایت دوباره روی لاجیت‌های واژگان تصویر (project) کنید. اگر هر کدام از این چهار مرحله را جا بیندازید، مدل یا در گذر رو به جلو به خطا می‌خورد، یا درک موقعیت مکانی توکن‌ها به‌هم می‌ریزد، یا اصلاً زبان باز نمی‌کند و خروجی متنی نخواهد داشت.

ابعاد و ساختار مدل هم بسیار مهم است. مدل مرجع GPT-2 Small دقیقاً با همین پیکربندی بالا 124 میلیون پارامتر دارد. این اعداد تصادفی نیستند: حاصل‌ضرب واژگان 50257 در بعد امبدینگ 768، اندازه‌ی جدول توکن‌هاست. طول زمینه 1024 در 768، جدول موقعیت‌ها را می‌سازد. 12 بلوک که هر کدام حدود 7 میلیون پارامتر دارند، روی‌هم‌رفته 84 میلیون پارامتر می‌شوند. سر نهایی مدل هم با اشتراک وزن‌ها، دوباره از همان جدول توکن‌ها استفاده می‌کند. این تکه‌ها را جمع بزنید، دقیقاً به 124 میلیون پارامتر می‌رسید. اگر مدلی بسازید که تعداد پارامترهایش با این مرجع هم‌خوانی نداشته باشد، مطمئن باشید گوشه‌ای از کار را اشتباه سیم‌کشی کرده‌اید.

مفهوم

شناسه‌های توکنشکل B, Tامبدینگ توکن50257, 768جستجوی موقعیت0 تا T-1امبدینگ موقعیت1024, 768جمعدراپ‌اوت امبدینگبلاک 1بلاک 2...بلاک 12LayerNorm نهاییسر LMمتصل به امبدینگ توکنلاجیت‌هاشکل B, T, 50257

شناسه‌های توکن به بردارهای توکن تبدیل می‌شوند. شناسه‌های موقعیت مکانی هم به بردارهای موقعیت بدل می‌گردند. این دو بردار با هم جمع شده و به درون دسته‌ی لایه‌ها فرستاده می‌شوند. بخش LayerNorm نهایی، تنها جزء بیرون از بلوک‌هاست که در تمام معماری‌های مدرن امروزی هم دست‌نخورده باقی مانده است. سر مدل زبانی (LM head) از همان ماتریس امبدینگ توکن دوباره استفاده می‌کند؛ معنای اشتراک ماتریس وزن‌ها دقیقاً همین است.

اشتراک ماتریس وزن‌ها (Weight tying)

امبدینگ توکن ابعادی معادل (vocab, d_model) دارد. سر مدل زبانی باید داده‌ها را از d_model دوباره روی vocab تصویر کند. این دو ماتریس ترانهاده‌ی (transpose) یکدیگرند. اشتراک این دو یعنی دقیقاً استفاده از یک تنسور پارامتر یکسان در دو جای مختلف. با واژگان 50257 و بعد مدلی 768، این ماتریس به‌تنهایی 38 میلیون پارامتر دارد. اگر آن‌ها را جدا نگه دارید، هزینه‌ی حافظه‌ی آن را دو بار می‌پردازید. وقتی آن‌ها را هم‌رسان (tied) می‌کنید، یک بار هزینه می‌دهید و از طرفی سیگنال گرادیان تمیزتری هم می‌گیرید، چون امبدینگ و سر خروجی هم‌زمان و هماهنگ با هم به‌روزرسانی می‌شوند.

امبدینگ موقعیت یادگیری‌پذیر است، نه سینوسی

مدل GPT-2 با امبدینگ موقعیت یادگیری‌پذیر (learned position embedding) کار می‌کند. جدول موقعیت، تنسوری با ابعاد (1024, 768) از پارامترهای یادگیری‌پذیر است. مدل در هر گذر رو به جلو، موقعیت‌های 0 تا T-1 را جست‌وجو (lookup) کرده و حاصل را به امبدینگ توکن اضافه می‌کند. این شیوه ساده‌ترین راهکار مدیریت موقعیت است (روش‌های دیگری مثل RoPE ،ALiBi و بایاس نسبی T5 گزینه‌های جایگزین هستند) و مدل مرجع 124M دقیقاً از همین روش استفاده می‌کند.

تولید متن: دما، top-k و نمونه‌برداری چندجمله‌ای

تولید متن به‌صورت خودبازگشتی (autoregressive) انجام می‌شود. مدل در هر گام، برای تک‌تک موقعیت‌ها لاجیت‌هایی روی کل واژگان برمی‌گرداند. شما فقط لاجیت‌های آخرین موقعیت را برمی‌دارید، آن را بر دما تقسیم می‌کنید، در صورت نیاز همه‌ی مقادیر را به‌جز k لاجیت برتر به منفی بی‌نهایت تبدیل می‌کنید (ماسک کردن)، با سافت‌مکس احتمال‌ها را به دست می‌آورید و در نهایت یک توکن از توزیع حاصل نمونه‌برداری می‌کنید.

توکن‌های پرامپتعبور رو به جلوی مدلگرفتن لاجیت‌های موقعیت آخرتقسیم بر دماماسک به k برترسافت‌مکسنمونه‌گیری چندجمله‌ایافزودن به کانتکستبرش کانتکست در صورت ctx_len

سه پیچ تنظیم، سه رفتار کاملاً متفاوت می‌سازند: دمای نزدیک به صفر، رفتار مدل را به حالت حریصانه (greedy) تقلیل می‌دهد. دمای 1 توزیع طبیعی خود مدل را حفظ می‌کند. مقدار top-k برابر با 1 خروجی کاملاً حریصانه می‌دهد، در حالی که top-k برابر با 40 دنباله‌ی کم‌احتمال توزیع را فیلتر می‌کند. ترکیب این‌ها تفاوت زیادی در خروجی رقم می‌زند؛ در درس بعدی که به آموزش مدل اختصاص دارد، از فرایند تولید متن به عنوان یک سیگنال ارزیابی کیفی استفاده خواهیم کرد.

سرهم‌بندی GPTامبدینگ · پشته‌سازی · اشتراک وزن
GPT ASSEMBLYThe whole 124M model is four pieces: a token table, a position table summed into it, twelve identical blocks lit in sequence, a final LayerNorm, and a language-model head. The head is not new weights; it reuses the token-embedding matrix transposed, which is why tying saves roughly 38M parameters at this scale and makes the count land exactly on the reference.شناسه‌های توکن (B, T)امبدینگ توکنامبدینگ موقعیت⊕12 بلوکLayerNorm نهاییسر LM ← لاجیت‌هاوزن‌هامشترکمجموعاً 124M50257 × 768+ 1024 × 768+ 12 بلوکسر بدون هزینه(مشترک)
کل مدل 124M از چهار بخش تشکیل شده است: جدول توکن‌ها، جدول موقعیت که با آن جمع می‌شود، دوازده بلوک یکسان که به‌صورت متوالی اجرا می‌شوند، یک LayerNorm نهایی، و سر مدل زبانی. این سر وزن جدیدی ندارد؛ بلکه از ترانهاده‌ی ماتریس امبدینگ توکن مجدداً استفاده می‌کند. به همین دلیل اشتراک ماتریس وزن‌ها تقریباً 38M پارامتر در این مقیاس صرفه‌جویی می‌کند و تعداد پارامترها را دقیقاً منطبق بر مدل مرجع می‌سازد.

پیاده‌سازی از صفر

فایل code/main.py این موارد را پیاده‌سازی می‌کند:

  • کلاس دیتای class GPTConfig با مقادیر پیش‌فرض مدل 124M: شامل vocab_size=50257، context_length=1024، d_model=768، num_heads=12، num_layers=12، mlp_expansion=4، dropout=0.1، use_bias=True و weight_tying=True.
  • کلاس class GPTModel شامل امبدینگ توکن، امبدینگ موقعیت، دراپ‌اوت امبدینگ، 12 بلوک TransformerBlock، لایه‌ی نهایی LayerNorm و یک lm_head که در صورت فعال بودن پرچم مربوطه، وزن‌هایش با امبدینگ توکن به اشتراک گذاشته می‌شود.
  • تابع کمکی count_parameters که تعداد پارامترهای یکتا را می‌شمارد (تا اثر اشتراک وزن‌ها در شمارش نهایی درست محاسبه شود).
  • تابع generate که دما، top-k، نمونه‌برداری چندجمله‌ای و پنجره‌ی لغزان برای کنترل زمینه را مدیریت می‌کند.
  • یک نمونه‌ی اجرایی (demo) که مدل را می‌سازد، تعداد پارامترهایش را در کنار مدل مرجع 124M چاپ می‌کند و یک توالی کوتاه از روی پرامپتی ثابت تولید می‌کند تا کل پایپ‌لاین را از ابتدا تا انتها نشان دهد.

اجرای کد:

python3 code/main.py

خروجی: تعداد پارامترها در مقایسه با مرجع 124M، شناسه‌های توکن تولیدشده از پرامپت ثابت و تأییدیه‌ای مبنی بر این‌که در صورت فعال بودن اشتراک وزن‌ها، سر مدل زبانی و امبدینگ توکن از حافظه‌ی مشترک استفاده می‌کنند.

برای این‌که اجرای آزمایشی سریع بماند، اسکریپت یک پیکربندی بسیار کوچک (d_model=64, num_layers=2) را هم از ابتدا تا انتها اجرا کرده و توالی توکن‌های تولیدشده را در خروجی نمایش می‌دهد. پیکربندی 124M ساخته می‌شود، اما فقط تعداد پارامترهای آن محاسبه شده و یک گذر رو به جلو روی آن اجرا می‌گردد.

استک فنی

  • کتابخانه‌ی torch برای محاسبات تانسوری، مشتق‌گیری خودکار (autograd) و ساختار ماژول‌ها.
  • فایل code/main.py ساختار بلوک ترنسفورمر درس 34 را مجدداً به‌صورت محلی پیاده می‌کند.

الگوهای محیط عملیاتی

سه تفاوت فنی، مرز میان مدلی را که فقط اجرا می‌شود با مدلی که واقعاً آماده‌ی استقرار در محیط عملیاتی (پروداکشن) است مشخص می‌کنند:

مقداردهی اولیه‌ی کوچک برای ماتریس‌های تصویر پسماند. خروجی تصویر اتنشن و لایه‌ی خطی دوم در MLP، هر دو مستقیماً وارد یک جمع پسماند (residual add) می‌شوند. اگر این وزن‌ها را با همان انحراف معیاری مقداردهی اولیه کنید که بقیه‌ی لایه‌های خطی دارند، جریان پسماند (residual stream) با افزایش عمق شبکه مدام بزرگ‌تر می‌شود و لایه‌ی نهایی LayerNorm را وارد ناحیه‌ای ناپایدار و بیش‌ازحد داغ می‌کند. اگر انحراف معیار این دو تصویر را با ضریب 1 / sqrt(2 * num_layers) مقیاس کنید، جریان پسماند در تمام 12 لایه در محدوده‌ای منطقی و پایدار باقی می‌ماند.

کش کردن تنسور شناسه‌های موقعیت، نه محاسبه‌ی مجدد آن. اجرای torch.arange(T) در هر گذر رو به جلو، حافظه‌ی جدیدی تخصیص می‌دهد. این تنسور را یک بار در __init__ برای حداکثر طول زمینه بسازید، در هر فراخوانی T درایه‌ی اول آن را برش (slice) بزنید و از رفت‌وآمد بیهوده به تخصیص‌دهنده‌ی حافظه جلوگیری کنید.

اشتراک وزن‌ها در سطح پارامتر، نه صرفاً کپی کردن. نوشتن عبارت lm_head.weight = token_embedding.weight خود تنسور را به اشتراک می‌گذارد؛ در حالی که کپی کردن این کار را نمی‌کند. بهینه‌ساز (optimizer) باید فقط یک پارامتر را به‌روزرسانی کند و گراف مشتق‌گیری خودکار باید فقط یک بار تجمع گرادیان داشته باشد. اگر داده‌ها را صرفاً کپی کنید، با گذشت زمان سر خروجی از امبدینگ فاصله می‌گیرد و عملاً هیچ سودی از اشتراک وزن‌ها نمی‌برید.

کاربرد عملی

  • کلاس مدلی که در این درس پیاده شد، دقیقاً همان ساختاری را دارد که در درس بعدی آموزش می‌دهیم.
  • با جایگزینی امبدینگ موقعیت یادگیری‌پذیر با RoPE، بدون نیاز به دست زدن به ساختار بلوک‌ها یا سر خروجی، به معماری خانواده‌ی LLaMA می‌رسید.
  • جایگزینی تابع فعال‌سازی GELU با SiLU و تعویض LayerNorm با RMSNorm، باقی تغییرات خانواده‌ی LLaMA را برایتان تکمیل می‌کند.
  • تابع تولید متن این درس با هر منبعی از لاجیت‌ها کار می‌کند و مختص این مدل نیست. می‌توانید در درس 37 لاجیت‌ها را از فایل مدل ازپیش‌آموزش‌دیده‌ی GPT-2 بخوانید و از همین حلقه‌ی تولید متن استفاده کنید.

تمرین‌ها

  1. حالت اشتراک وزن‌ها را بین سر مدل زبانی و امبدینگ توکن غیرفعال کنید و پارامترها را دوباره بشمارید. بررسی کنید که اختلاف دقیقاً حاصل 50257 در 768 یعنی 38 میلیون پارامتر باشد.
  2. امبدینگ موقعیت یادگیری‌پذیر را با یک جدول سینوسی جایگزین کنید که در زمان ساخت مدل محاسبه می‌شود. تأیید کنید که گذر رو به جلو هنوز کار می‌کند و تعداد پارامترها 786432 عدد کاهش می‌یابد.
  3. یک پرچم greedy=True به تابع تولید متن اضافه کنید که از مرحله‌ی نمونه‌برداری عبور کند و مستقیماً مقدار argmax را بردارد. مطمئن شوید خروجی در اجراهای مختلف کاملاً قطعی و تکرارپذیر است.
  4. پارامتر تنظیمی جدیدی به نام repetition_penalty اضافه کنید که لاجیت هر توکن موجود در پرامپت یا متن تولیدشده تا این لحظه را پیش از سافت‌مکس بر مقداری ثابت تقسیم کند. روی یک پرامپت ثابت نشان دهید که مقادیر بزرگ‌تر از 1 چطور دفعات تکرار توکن‌ها را در خروجی کاهش می‌دهند.
  5. نمونه‌برداری top_p (هسته‌ای یا nucleus) را در کنار top_k پیاده‌سازی کنید. یک بررسی دوخطی اضافه کنید که نشان دهد مجموع احتمال‌های توکن‌های باقی‌مانده از top_p بیشتر باشد.

اصطلاحات کلیدی

اصطلاح در گفت‌وگوها چه می‌گویند معنای دقیق فنی
اشتراک ماتریس وزن‌ها (Weight tying) «امبدینگ‌های متصل» (Tied embeddings) سر مدل زبانی و امبدینگ توکن از یک تنسور پارامتر مشترک استفاده می‌کنند؛ این کار به اندازه‌ی ضرب واژگان در d_model پارامتر صرفه‌جویی کرده و با معماری مرجع GPT-2 مطابقت دارد.
امبدینگ موقعیت (Position embedding) «موقعیت‌های یادگیری‌پذیر» جدولی جداگانه با ابعاد (طول زمینه، d_model) که به بردارهای توکن اضافه می‌شود و در طول فرایند آموزش، به‌صورت سراسری یاد گرفته می‌شود.
زمینه‌ی پنجره‌ی لغزان (Sliding window context) «سقف طول زمینه» وقتی مجموع طول پرامپت و توکن‌های تولیدشده از حداکثر طول زمینه بیشتر می‌شود، قدیمی‌ترین توکن‌ها حذف می‌شوند تا طول ورودی فعال در پنجره جا بگیرد.
نمونه‌برداری Top-k (Top-k sampling) «هرس K تایی» فقط K لاجیت با بالاترین مقادیر حفظ شده و بقیه به منفی بی‌نهایت تبدیل می‌شوند؛ سپس روی گزینه‌های باقی‌مانده سافت‌مکس اعمال می‌شود.
دما (Temperature) «دمای نمونه‌برداری» لاجیت‌ها پیش از اعمال سافت‌مکس بر مقدار T تقسیم می‌شوند؛ دمای کمتر از 1 توزیع را تیزتر، دمای 1 توزیع طبیعی مدل را حفظ و دمای بیشتر از 1 آن را یکنواخت‌تر و مسطح می‌کند.

برای مطالعه‌ی بیشتر

  • بخش 19 درس 34: بررسی بلوکی که در این مدل روی هم چیده شد.
  • بخش 19 درس 36: حلقه‌ی آموزش مدل با تابع زیان (loss) انتروپی متقاطع.
  • بخش 19 درس 37: بارگذاری وزن‌های ازپیش‌آموزش‌دیده‌ی GPT-2 روی همین معماری دقیق.
  • بخش 7 درس 07 (مدل‌سازی علّی زبان GPT): مبانی ریاضیاتی پیش‌بینی توکن بعدی.
  • بخش 10 درس 04 (پیش‌آموزش Mini GPT): فرایند اولیه‌ی آموزش روی همین معماری.

خودآزمایی

به سؤال‌ها جواب بدهید تا ببینید چقدر از درس در ذهنتان مانده است.

  1. پیش از درسپیکربندی مرجع GPT-2 small که این درس آن را بازتولید می‌کند چیست؟
  2. حین درساشتراک ماتریس وزن‌ها (Weight Tying) در سرهم‌بندی مدل به چه معناست؟
  3. حین درسفرایند تولید متن چگونه پنجره‌ی بافتار خود را می‌لغزاند؟
  4. حین درسچرا لایه‌ی تصویر خروجی اتنشن و لایه‌ی خطی دوم MLP با انحراف معیار کمتری نسبت به بقیه مقداردهی اولیه می‌شوند؟
  5. پس از درسدما (temperature) در زمان نمونه‌برداری چه نقشی ایفا می‌کند؟
  6. پس از درسفیلتر top-k قبل از نمونه‌برداری چه کاری انجام می‌دهد؟

سؤالات متداول

تکنیک اشتراک وزن‌ها (Weight Tying) چیست و چه مزیتی در مدل 124 میلیونی GPT دارد؟

در این روش، ماتریس وزن امبدینگ توکن با سر مدل زبانی (LM head) به اشتراک گذاشته می‌شود؛ این کار جلوی تخصیص دوباره‌ی ماتریس 50257 در 768 را می‌گیرد و حدود 38 میلیون پارامتر از حافظه صرفه‌جویی می‌کند.

چرا مدل مرجع GPT-2 به جای امبدینگ سینوسی از امبدینگ موقعیت یادگیری‌پذیر استفاده می‌کند؟

در این معماری، بردار موقعیت مکانی به‌صورت یک جدول پارامترهای یادگیری‌پذیر با ابعاد 1024 در 768 تعریف می‌شود تا مدل در طول آموزش، نحوه‌ی بهینه‌ی نمایش توالی‌ها را خود یاد بگیرد.

نقش پارامترهای دما (Temperature) و top-k در تولید متن چیست؟

دما میزان تصادفی بودن خروجی را با مقیاس‌بندی لاجیت‌ها کنترل می‌کند (دمای کمتر از 1 خروجی را قطعی‌تر می‌کند) و top-k نیز دنباله‌ی لاجیت‌های با احتمال پایین را فیلتر کرده و تنها k گزینه‌ی برتر را در نظر می‌گیرد.

ما رو توی گوگل بیشتر ببین

با افزودن نکست ادمین به «منابع ترجیحی» گوگل، درس‌ها و مطالب ما را در بخش اخبار برتر جستجو بیشتر می‌بینید.