روش P-tuning یکی از تکنیک‌های پارامتر-کارآمد برای تخصصی‌سازی مدل‌های زبانی است که در آن، به‌جای آموزش یک پیشوند ساده، از یک ساختار پویا مانند LSTM یا MLP برای تولید پرامپت نرم استفاده می‌شود.
این روش، عملکرد مدل را در دامنه‌های خاص با تعداد پارامترهای بسیار کم بهبود می‌دهد.
P-tuning در مقایسه با Prompt Tuning، دقت بالاتری در وظایف پیچیده ارائه می‌دهد.
این تکنیک، در محیط‌هایی که دسترسی به وزن مدل داریم، گزینه‌ای جذاب است.
این راهنما مکانیزم، پیاده‌سازی و کاربردهای P-tuning را به‌صورت فنی بررسی می‌کند.

روش P-tuning یکی از روش‌های پیشرفته در حوزه بهینه‌سازی پارامتر-کارآمد مدل‌های زبانی است که برای حل محدودیت‌های Prompt Tuning و Prefix Tuning توسعه یافته است. این روش، اولین بار در مقاله‌ای با عنوان «GPT Understands, Too» در سال ۲۰۲۱ معرفی شد. برای درک این تکنیک، ابتدا باید با تنظیم پیشوند در پرامپت نویسی و تفاوت پرامپت سخت و نرم آشنا باشیم.

در پروژه‌هایی که به تخصصی‌سازی مدل در دامنه‌های خاص نیاز داشتیم، P-tuning ابزار اصلی برای دستیابی به دقت بالا با کمترین هزینه بوده است. این تکنیک، با استفاده از یک ساختار پویا برای تولید پرامپت نرم، انعطاف‌پذیری بیشتری نسبت به روش‌های ساده‌تر ارائه می‌دهد. اگر با تنظیم پرامپت مبتنی بر گرادیان آشنا هستید، آماده‌اید تا به لایه P-tuning وارد شوید.

روش P-tuning را می‌توان با استفاده از یک مولد متن به‌جای یک متن آماده مقایسه کرد: به‌جای ذخیره‌سازی یک پیشوند ثابت، از یک ساختار پویا برای تولید پیشوند مناسب در هر شرایط استفاده می‌شود. در سامانه‌های LLM، این ساختار پویا همان LSTM یا MLP است که پرامپت نرم را تولید می‌کند. برای مطالعه بیشتر درباره مبانی، می‌توانید صفحه Fine-tuning را در ویکی‌پدیا ببینید.

روش P-tuning دقیقاً چیست؟

روش P-tuning یکی از تکنیک‌های بهینه‌سازی پارامتر-کارآمد است که در آن، به‌جای آموزش یک پیشوند ثابت (مانند Prompt Tuning)، از یک ساختار پویا مانند LSTM یا MLP برای تولید پرامپت نرم استفاده می‌شود.

این روش، سه ویژگی اصلی دارد:

  • پویایی: پرامپت در هر اجرا به‌صورت پویا تولید می‌شود.
  • پارامتر-کارآمدی: تنها بخش کوچکی از پارامترها آموزش می‌بیند.
  • انعطاف‌پذیری: ساختار پویا می‌تواند با دامنه‌های مختلف تطبیق یابد.

در P-tuning، پرامپت نرم از یک فضای پارامتری کوچک‌تر تولید می‌شود. این ویژگی، پارامترهای آموزش‌پذیر را به‌طور چشمگیری کاهش می‌دهد.

تفاوت با Prompt Tuning

در Prompt Tuning، پرامپت یک بردار ثابت آموزش‌پذیر است. در P-tuning، پرامپت از یک ساختار پویا تولید می‌شود. این تفاوت، P-tuning را قدرتمندتر می‌کند.

تفاوت با Prefix Tuning

Prefix Tuning، پیشوند را در همه لایه‌ها اضافه می‌کند. P-tuning معمولاً بر روی لایه ورودی عمل می‌کند اما با ساختار پویا. برای جزئیات، پست تنظیم پیشوند در پرامپت نویسی را ببینید.

P-tuning، پرامپت را به‌عنوان یک خروجی ساختار پویا می‌بیند، نه یک پارامتر ثابت.

چرا P-tuning اهمیت دارد؟

P-tuning به چند دلیل اهمیت دارد:

افزایش دقت در وظایف پیچیده

در وظایف پیچیده، P-tuning معمولاً دقت بالاتری از Prompt Tuning ارائه می‌دهد. دلیل این تفاوت، توانایی ساختار پویا در کشف الگوهای پیچیده‌تر است.

کاهش پارامترهای آموزش‌پذیر

P-tuning با استفاده از یک ساختار پویا، پارامترهای آموزش‌پذیر را به‌طور چشمگیری کاهش می‌دهد. در برخی پیاده‌سازی‌ها، تعداد پارامترها به کمتر از ۰.۱ درصد می‌رسد.

انعطاف‌پذیری

ساختار پویا می‌تواند با دامنه‌های مختلف تطبیق یابد. این ویژگی، P-tuning را برای پروژه‌های چنددامنه‌ای مناسب می‌کند.

حفظ دانش پایه

مانند سایر روش‌های پارامتر-کارآمد، وزن‌های مدل پایه ثابت می‌مانند و دانش پایه حفظ می‌شود.

کارایی در محیط‌های با منابع محدود

در محیط‌هایی که دسترسی به GPUهای قوی محدود است، P-tuning یک گزینه عملی است.

ویژگیPrompt TuningP-tuning
پارامترهای آموزش‌پذیر< ۰.۱٪< ۰.۱٪
ساختارثابتپویا
دقت در وظایف پیچیدهمتوسطبالا
انعطاف‌پذیریمحدودبالا

مکانیزم فنی

مکانیزم P-tuning، بر پایه استفاده از یک ساختار پویا برای تولید پرامپت نرم است.

ساختار پویا

در P-tuning، پرامپت نرم از یک شبکه کوچک تولید می‌شود. این شبکه می‌تواند LSTM، MLP یا ترکیبی از آن‌ها باشد.

روند تولید پرامپت

  1. یک بردار کوچک (anchor) به شبکه داده می‌شود.
  2. شبکه، این بردار را به یک دنباله از بردارهای پرامپت تبدیل می‌کند.
  3. این دنباله، به ورودی مدل اضافه می‌شود.
  4. در طول آموزش، پارامترهای شبکه بهینه می‌شوند.

پیاده‌سازی

import torch
import torch.nn as nn

class PTuning(nn.Module):
    def __init__(self, n_tokens, hidden_dim, lstm_hidden=128):
        super().__init__()
        self.anchors = nn.Parameter(torch.randn(n_tokens, lstm_hidden))
        self.lstm = nn.LSTM(lstm_hidden, hidden_dim, batch_first=True)

    def forward(self):
        anchors = self.anchors.unsqueeze(0)
        output, _ = self.lstm(anchors)
        return output.squeeze(0)

این پیاده‌سازی، یک ساختار ساده LSTM را نشان می‌دهد که پرامپت نرم را از بردارهای anchor تولید می‌کند.

مزیت ساختار پویا

ساختار پویا، امکان هم‌بستگی میان بردارهای پرامپت را فراهم می‌کند. در Prompt Tuning، بردارها مستقل هستند. در P-tuning، بردارها از یک ساختار مشترک تولید می‌شوند و همین ویژگی، دقت را افزایش می‌دهد.

معماری و اجزا

P-tuning از چند جزء اصلی تشکیل می‌شود:

بردارهای Anchor

بردارهای anchor، نقاط شروع برای تولید پرامپت هستند. این بردارها آموزش‌پذیر هستند و در طول آموزش بهینه می‌شوند.

ساختار پویا

ساختار پویا، بردارهای anchor را به پرامپت نرم تبدیل می‌کند. این ساختار می‌تواند LSTM، MLP یا ترکیبی باشد.

مدل پایه

مدل پایه، همان مدل زبانی از پیش آموزش‌دیده است که وزن‌هایش ثابت است.

لایه تزریق

لایه‌ای که پرامپت نرم را به ورودی مدل اضافه می‌کند. در P-tuning ساده، این لایه، لایه ورودی است.

گونه‌ها و نسخه‌های پیشرفته

از زمان معرفی P-tuning، نسخه‌های پیشرفته‌ای توسعه یافته است:

P-tuning v2

در این نسخه، پرامپت نرم در همه لایه‌ها اضافه می‌شود، نه فقط لایه ورودی. این رویکرد، دقت را در وظایف پیچیده‌تر افزایش می‌دهد.

P-tuning با MLP

در این نسخه، از یک شبکه MLP به‌جای LSTM برای تولید پرامپت استفاده می‌شود. این رویکرد، سریع‌تر اما کم‌دقت‌تر است.

P-tuning با Prompt Encoder

در این نسخه، از یک encoder جداگانه برای تولید پرامپت استفاده می‌شود. این رویکرد، امکان استفاده از داده‌های اضافی را فراهم می‌کند.

P-tuning برای مدل‌های چندوجهی

P-tuning می‌تواند برای مدل‌های چندوجهی نیز استفاده شود. برای جزئیات، پست پرامپت نویسی برای مدل‌های چندوجهی را ببینید.

پیاده‌سازی گام‌به‌گام

پیاده‌سازی P-tuning در چند گام انجام می‌شود:

گام اول: بارگذاری مدل پایه

from transformers import AutoModelForCausalLM

model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-2-7b")

# Freeze model
for param in model.parameters():
    param.requires_grad = False

گام دوم: ساخت ساختار P-tuning

n_tokens = 20
hidden_dim = model.config.hidden_size

ptuning = PTuning(n_tokens, hidden_dim)

گام سوم: تزریق پرامپت

پرامپت تولیدشده باید به ورودی مدل اضافه شود. این کار با تغییر forward pass مدل انجام می‌شود.

گام چهارم: آموزش

optimizer = torch.optim.AdamW(ptuning.parameters(), lr=1e-3)

for batch in dataloader:
    optimizer.zero_grad()
    soft_prompt = ptuning()
    outputs = model(batch["input_ids"], soft_prompt=soft_prompt)
    loss = compute_loss(outputs, batch["labels"])
    loss.backward()
    optimizer.step()

گام پنجم: ذخیره و بارگذاری

# Save
torch.save(ptuning.state_dict(), "ptuning.pt")

# Load
ptuning = PTuning(n_tokens, hidden_dim)
ptuning.load_state_dict(torch.load("ptuning.pt"))

مقایسه با سایر روش‌ها

P-tuning در مقایسه با سایر روش‌های پارامتر-کارآمد، ویژگی‌های منحصربه‌فردی دارد.

P-tuning در مقابل Prompt Tuning

Prompt Tuning از یک بردار ثابت استفاده می‌کند. P-tuning از یک ساختار پویا استفاده می‌کند. P-tuning دقت بالاتری دارد اما پیچیده‌تر است.

P-tuning در مقابل Prefix Tuning

Prefix Tuning پرامپت را در همه لایه‌ها اضافه می‌کند. P-tuning معمولاً تنها در لایه ورودی، اما با ساختار پویا. برای جزئیات، پست تنظیم پیشوند در پرامپت نویسی را ببینید.

P-tuning در مقابل LoRA

LoRA بر ماتریس‌های وزن عمل می‌کند. P-tuning بر ورودی. LoRA معمولاً دقت بالاتری دارد اما پارامترهای بیشتری آموزش می‌دهد.

P-tuning در مقابل Adapter

Adapter لایه‌های کوچک اضافه می‌کند. P-tuning بردارهای ورودی اضافه می‌کند.

روشپارامترمکانیزمدقت
Prompt Tuning< ۰.۱٪بردار ثابتمتوسط
Prefix Tuning< ۱٪بردار در همه لایه‌هابالا
P-tuning< ۰.۱٪ساختار پویابالا
P-tuning v2< ۱٪ساختار پویا در همه لایه‌هابسیار بالا
LoRA< ۱٪ماتریس کم‌رتبهبالا

کاربردهای عملی

P-tuning در چند سناریو کاربرد دارد:

وظایف NLU

P-tuning برای وظایف درک زبان طبیعی (NLU) مانند طبقه‌بندی، تشخیص موجودیت و پاسخ به پرسش مناسب است.

وظایف با دامنه تخصصی

در دامنه‌های تخصصی که به دقت بالایی نیاز است، P-tuning عملکرد خوبی دارد.

محیط‌های با منابع محدود

در محیط‌هایی که منابع محاسباتی محدود است، P-tuning به‌دلیل پارامترهای کم، گزینه مناسبی است.

مدل‌های کوچک

P-tuning در مدل‌های کوچک نیز عملکرد خوبی ارائه می‌دهد، در حالی که Prompt Tuning در این مدل‌ها ضعیف عمل می‌کند.

پروژه‌های چنددامنه‌ای

با آموزش چند P-tuning جداگانه، می‌توان یک مدل پایه را برای چند دامنه تخصصی کرد.

پروژه‌های تحقیقاتی

در پژوهش‌هایی که به بررسی رفتار مدل نیاز دارند، P-tuning ابزار مفیدی است.

پارامترهای کلیدی

P-tuning چند پارامتر کلیدی دارد:

طول پرامپت

طول پرامپت (n_tokens) تعیین می‌کند چه تعداد بردار تولید شود. مقادیر معمول بین ۱۰ تا ۱۰۰ است.

نوع ساختار

ساختار پویا می‌تواند LSTM، MLP یا ترکیبی باشد. LSTM دقت بالاتری دارد اما کندتر است.

ابعاد ساختار

ابعاد ساختار، تعداد پارامترهای آموزش‌پذیر را تعیین می‌کند. ابعاد بزرگ‌تر، دقت بیشتر اما هزینه بالاتر.

نرخ یادگیری

نرخ یادگیری مناسب معمولاً بین 1e-3 تا 1e-2 است.

تعداد لایه‌های تزریق

در P-tuning v2، پرامپت در همه لایه‌ها اضافه می‌شود. تعداد لایه‌ها بر دقت اثر می‌گذارد.

محدودیت‌ها

P-tuning، محدودیت‌های خاص خود را دارد:

  • نیاز به وزن مدل: برای استفاده از P-tuning، باید به وزن مدل دسترسی داشته باشید.
  • پیچیدگی پیاده‌سازی: P-tuning پیچیده‌تر از Prompt Tuning است.
  • هزینه استنتاج: ساختار پویا، هزینه استنتاج را کمی افزایش می‌دهد.
  • عدم انتقال‌پذیری: P-tuning آموزش‌دیده برای یک مدل، در مدل دیگر قابل استفاده نیست.
  • پایداری در طول آموزش: در برخی موارد، آموزش P-tuning پایداری کمتری دارد.
  • پیچیدگی تفسیر: پرامپت تولیدشده غیرقابل خواندن است.

پرسش‌های پرتکرار درباره P-tuning

P-tuning چه تفاوتی با Prompt Tuning دارد؟

Prompt Tuning از یک بردار ثابت استفاده می‌کند. P-tuning از یک ساختار پویا برای تولید پرامپت استفاده می‌کند.

P-tuning چه تفاوتی با Prefix Tuning دارد؟

Prefix Tuning پرامپت را در همه لایه‌ها اضافه می‌کند. P-tuning معمولاً تنها در لایه ورودی، اما با ساختار پویا.

آیا P-tuning با API قابل استفاده است؟

خیر. P-tuning نیازمند دسترسی به وزن مدل است.

چند پارامتر در P-tuning آموزش می‌بیند؟

معمولاً کمتر از ۰.۱ درصد پارامترهای مدل پایه. مقدار دقیق به ابعاد ساختار پویا بستگی دارد.

آیا P-tuning در مدل‌های کوچک مؤثر است؟

بله. P-tuning در مدل‌های کوچک نیز عملکرد خوبی ارائه می‌دهد، در حالی که Prompt Tuning در این مدل‌ها ضعیف عمل می‌کند.

آیا P-tuning v2 بهتر از P-tuning است؟

در وظایف پیچیده، P-tuning v2 دقت بالاتری دارد. اما هزینه محاسباتی آن نیز بیشتر است.

آیا P-tuning با LoRA قابل ترکیب است؟

بله. ترکیب این دو روش می‌تواند دقت را بیشتر کند.

آیا P-tuning بر امنیت اثر دارد؟

P-tuning غیرقابل خواندن است و بررسی امنیتی آن دشوارتر است. برای جزئیات، پست بهترین روش‌های امنیت پرامپت را ببینید.

آیا P-tuning بر حریم خصوصی اثر دارد؟

P-tuning اجازه می‌دهد مدل بدون ارسال داده به سرویس بیرونی تخصصی شود. این ویژگی، حریم خصوصی را تقویت می‌کند. برای جزئیات، پست حریم خصوصی در پرامپت نویسی را ببینید.

آیا P-tuning برای همه مدل‌ها کاربرد دارد؟

P-tuning برای اکثر مدل‌های transformer کاربرد دارد، اما پیاده‌سازی آن بین مدل‌ها متفاوت است.

چطور P-tuning آموزش‌دیده را ذخیره کنیم؟

تنها پارامترهای ساختار P-tuning ذخیره می‌شوند، نه کل مدل. حجم ذخیره‌سازی به ابعاد ساختار بستگی دارد.

نتیجه‌گیری کاربردی

روش P-tuning یکی از تکنیک‌های کارآمد برای تخصصی‌سازی مدل‌های زبانی است که با استفاده از یک ساختار پویا برای تولید پرامپت نرم، دقت بالایی با پارامترهای کم ارائه می‌دهد. این روش، نسبت به Prompt Tuning قدرتمندتر و نسبت به Prefix Tuning سبک‌تر است. P-tuning در وظایف NLU و دامنه‌های تخصصی، عملکرد خوبی دارد.

P-tuning، پرامپت را به‌عنوان یک خروجی ساختار پویا می‌بیند، نه یک پارامتر ثابت.

در پروژه‌هایی که به دقت بالا با کمترین پارامتر نیاز داشتیم، P-tuning ابزار اصلی بوده است. توصیه می‌کنم این تکنیک را با Prefix Tuning و LoRA مقایسه کنید و بر اساس نیاز پروژه، انتخاب کنید. اگر تجربه‌ای در پیاده‌سازی P-tuning در پروژه‌های واقعی دارید، برای ما جالب است بدانید کدام ساختار (LSTM، MLP یا ترکیبی) در دامنه شما بهترین عملکرد را داشته است.