پرش به محتوا
← همهٔ یادداشت‌ها

Jupyter روی GPU ابری: اولین کد PyTorch شما

·۷ دقیقه مطالعه·تیم جی‌پی‌یو

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

اگر می‌خواهید کد پایتون خودتان را روی یک کارت گرافیک قدرتمند اجرا کنید ولی سخت‌افزارش را ندارید، ساده‌ترین راه این است: یک ماشین ساعتی اجاره کنید و Jupyter را در مرورگر باز کنید. در این آموزش قدم‌به‌قدم یاد می‌گیرید چطور با Jupyter GPU ابری کار کنید — نوت‌بوک را باز کنید، فایل‌هایتان را آپلود کنید، و اولین کد PyTorch را واقعاً روی کارت گرافیک اجرا کنید، نه روی CPU.

کل کار حدود نیم ساعت وقت می‌برد و روی یک RTX 3060 با ۱۲ گیگابایت حافظه، در زمان نوشتن این مطلب، از حدود ۱۴ هزار تومان در ساعت شروع می‌شود. چیزی هم لازم نیست روی لپ‌تاپ نصب کنید: تمام محاسبات روی ماشین اجاره‌ای انجام می‌شود و شما فقط یک تب مرورگر باز دارید.

پیش‌نیازها

سه چیز لازم دارید. اول یک حساب در جی‌پی‌یو؛ از صفحهٔ ثبت‌نام شروع کنید. دوم موجودی کیف پول: باید حداقل به اندازهٔ یک ساعت از نرخ همان ماشین موجودی داشته باشید. شارژ با کارت به کارت است (کمترین مبلغ ۵۰ هزار تومان، بعد از تأیید اپراتور اضافه می‌شود).

سوم یک کلید SSH ثبت‌شده در بخش حساب کاربری؛ ورود به ماشین فقط با کلید انجام می‌شود و رمز عبوری وجود ندارد. اگر این مرحله‌ها را انجام نداده‌اید، همه‌شان با جزئیات در پست شروع اجاره GPU: اولین ماشین در ۱۰ دقیقه آمده است. دانستن پایتون در حد چند خط کد هم کافی است.

انتخاب ماشین مناسب

برای یادگیری PyTorch و نوت‌بوک‌های معمولی، ۱۲ گیگابایت VRAM کافی است. گزینهٔ اقتصادی RTX 3060 است که در زمان نوشتن این مطلب از حدود ۱۴ هزار تومان در ساعت اجاره می‌رود. برای دیتاست‌های سنگین‌تر، RTX A4000 با ۱۶ گیگابایت، در زمان نوشتن این مطلب، از حدود ۲۳ هزار تومان در ساعت گزینهٔ میانه است.

اگر سراغ مدل‌های بزرگ‌تر می‌روید، کارت ۲۴ گیگابایتی مثل RTX 3090 بهتر جواب می‌دهد؛ در زمان نوشتن این مطلب از حدود ۴۱ هزار تومان در ساعت. فهرست کامل و قیمت لحظه‌ای همه‌شان در بازار GPU هست و با فیلتر مدل کارت و حافظه پیدا می‌شوند. برای انتخاب دقیق‌تر بر اساس نوع کار، پست انتخاب کارت گرافیک هوش مصنوعی: راهنمای VRAM هر کار را ببینید.

قیمت ساعتی در لحظهٔ اجاره قفل می‌شود؛ بعد از آن نوسان بازار روی هزینهٔ همان ماشین اثری ندارد.

اجاره و راه‌اندازی با قالب PyTorch

ماشین مورد نظرتان را انتخاب کنید و موقع اجاره قالب PyTorch را بردارید؛ محیط PyTorch روی CUDA آماده تحویل داده می‌شود و لازم نیست درایور یا نسخهٔ CUDA را خودتان تنظیم کنید. اگر به کتابخانه‌های بهینه‌شدهٔ انویدیا مثل DALI یا TensorRT نیاز دارید، قالب PyTorch NGC همین کار را با ایمیجی سنگین‌تر می‌کند.

دکمهٔ اجاره را بزنید و چند دقیقه صبر کنید تا وضعیت ماشین «در حال اجرا» شود؛ ایمیج اول باید دانلود شود. وقتی آماده شد، صفحهٔ ماشین این‌ها را می‌دهد، همه یک‌کلیک کپی: دستور SSH آماده، لینک مستقیم Jupyter و توکن آن، دستور «تونل امن»، و فهرست پورت‌های منتشرشده.

باز کردن Jupyter روی GPU ابری

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

اگر ترجیح می‌دهید رابط وب را از بیرون باز نگذارید، از تونل امن استفاده کنید. دستور آمادهٔ آن در صفحهٔ ماشین هست و شکل کلی‌اش این است:

ssh -N -L 8888:localhost:8888 -p <PORT> root@<HOST>

تا وقتی این دستور باز است، http://localhost:8888 روی لپ‌تاپ شما به Jupyter همان ماشین وصل است. اگر توکن را گم کردید، در یک جلسهٔ SSH جدا این را بزنید:

jupyter server list

خروجی، نشانی هر سرور در حال اجرا را همراه با توکنش چاپ می‌کند؛ همان خط را در مرورگر باز کنید. جزئیات در مستندات Jupyter Server هست.

آپلود فایل و انتقال داده

در نوار کناری Jupyter مرورگر فایل را باز کنید و مسیر کاری‌تان (معمولاً /workspace) را انتخاب کنید. دکمهٔ آپلود بالای همان پنل، فایل‌های کوچک — نوت‌بوک، اسکریپت، چند مگابایت داده — را مستقیم از لپ‌تاپ بالا می‌فرستد.

برای فایل‌های بزرگ، آپلود مرورگر کند و شکننده است. دو راه بهتر دارید. اول، از لپ‌تاپ با scp بفرستید:

scp -P <PORT> ./dataset.zip root@<HOST>:/workspace/

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

!wget -P /workspace/data https://example.com/dataset.zip
!unzip -q /workspace/data/dataset.zip -d /workspace/data

اولین کد PyTorch روی کارت گرافیک

مطمئن شوید CUDA واقعاً دیده می‌شود

نوت‌بوک تازه‌ای بسازید (New → Notebook با هستهٔ Python 3) و اولین سلول را این‌طور بنویسید:

import torch

print("torch:", torch.__version__)
print("CUDA:", torch.cuda.is_available())
print("device:", torch.cuda.get_device_name(0))
print("VRAM:", round(torch.cuda.get_device_properties(0).total_memory / 1024**3, 1), "GB")

خروجی باید CUDA: True و نام کارت گرافیک همان ماشین را نشان بدهد. اگر False دیدید، این سلول را بزنید تا ببینید سیستم اصلاً کارت را می‌بیند:

!nvidia-smi

یک محاسبهٔ واقعی روی GPU

حالا تفاوت را خودتان ببینید. ضرب دو ماتریس بزرگ، ساده‌ترین نمونه است:

import time

n = 8192
a = torch.randn(n, n, device="cuda")
b = torch.randn(n, n, device="cuda")

torch.cuda.synchronize()
t0 = time.time()
for _ in range(10):
    c = a @ b
torch.cuda.synchronize()
print("GPU:", round(time.time() - t0, 2))

فراخوانی torch.cuda.synchronize() را حذف نکنید؛ عملیات GPU غیرهمگام اجرا می‌شود و بدون آن زمان‌سنجی غلط است. حالا همان ماتریس‌ها را یک بار روی CPU ضرب کنید تا مقایسه دستتان بیاید:

a_cpu, b_cpu = a.cpu(), b.cpu()
t0 = time.time()
c_cpu = a_cpu @ b_cpu
print("CPU:", round(time.time() - t0, 2))

یک آموزش کوچک و ذخیرهٔ نتیجه

حالا یک حلقهٔ آموزش واقعی. این مثال شبکه‌ای کوچک را روی دادهٔ ساختگی آموزش می‌دهد و همه‌چیز روی کارت گرافیک اجرا می‌شود:

import torch.nn as nn

device = "cuda" if torch.cuda.is_available() else "cpu"

model = nn.Sequential(
    nn.Linear(100, 256),
    nn.ReLU(),
    nn.Linear(256, 1),
).to(device)

opt = torch.optim.Adam(model.parameters(), lr=1e-3)
loss_fn = nn.MSELoss()

x = torch.randn(4096, 100, device=device)
y = (x.sum(dim=1, keepdim=True) > 0).float()

for step in range(200):
    opt.zero_grad()
    loss = loss_fn(model(x), y)
    loss.backward()
    opt.step()
    if step % 50 == 0:
        print(step, round(loss.item(), 4))

torch.save(model.state_dict(), "/workspace/model.pt")

مقدار loss باید پله‌پله پایین بیاید. فایل model.pt هم در مرورگر فایل Jupyter ظاهر می‌شود و با راست‌کلیک و Download روی لپ‌تاپ شما می‌آید. برای دیدن مصرف حافظه هم این دو خط کافی است:

print(round(torch.cuda.memory_allocated() / 1024**3, 2), "GB")
torch.cuda.empty_cache()

اگر به مشکل خوردید

torch.cuda.is_available() برابر False است. اول !nvidia-smi را اجرا کنید. اگر کارت را نشان می‌دهد ولی PyTorch نه، هستهٔ نوت‌بوک در محیط پایتون دیگری اجرا می‌شود؛ از منوی Kernel هستهٔ درست را انتخاب و کرنل را ری‌استارت کنید. اگر nvidia-smi هم چیزی نشان نداد، قالب ماشین PyTorch نبوده است.

خطای CUDA out of memory. یعنی VRAM پر شده. اندازهٔ batch یا همان n را نصف کنید و torch.cuda.empty_cache() را صدا بزنید؛ تنسورهای سلول‌های قبلی تا ری‌استارت کرنل در حافظه می‌مانند. اگر کارتان ذاتاً حافظهٔ بیشتری می‌خواهد، ماشینی با VRAM بالاتر بگیرید.

لینک Jupyter باز نمی‌شود یا خطای ۴۰۴ می‌دهد. یعنی سرویس هنوز کامل بالا نیامده. یکی دو دقیقه صبر کنید و صفحهٔ ماشین را تازه کنید؛ اگر باز هم نشد، با SSH وارد شوید و از تونل امن استفاده کنید.

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

هزینه و صرفه‌جویی

همهٔ این آموزش روی یک RTX 3060 کمتر از نیم ساعت طول می‌کشد؛ در زمان نوشتن این مطلب حدود ۷ هزار تومان. هزینه دقیقه‌ای از کیف پول کم می‌شود و ماشین متوقف‌شده هزینه‌ای ندارد، پس بعد از هر جلسه ماشین را متوقف کنید.

یک هشدار مهم: دیسک ماشین با حذف ماشین پاک می‌شود و ذخیره‌سازی دائمی یا مشترک بین ماشین‌ها وجود ندارد. قبل از حذف، نوت‌بوک‌ها، checkpointها و خروجی‌ها را دانلود کنید. یک requirements.txt هم کنار نوت‌بوک نگه دارید تا دفعهٔ بعد محیط را سریع بازسازی کنید.

قدم بعدی

حالا که Jupyter و PyTorch روی کارت گرافیک کار می‌کنند، دیتاست خودتان را بالا بفرستید و یک مدل واقعی را آموزش بدهید، یا سراغ قالب‌های آماده بروید. اگر تصویر می‌سازید، پست آموزش ComfyUI روی GPU ابری: اولین تصویر با SDXL قدم بعدی خوبی است. برای درک عمیق‌تر رفتار حافظه، راهنمای CUDA در مستندات PyTorch را بخوانید.

پرسش‌های متداول

آیا برای اجرای Jupyter به کارت گرافیک نیاز است؟

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

چطور بفهمم کدم واقعاً روی GPU اجرا می‌شود؟

torch.cuda.is_available() را چاپ کنید و مطمئن شوید True است، و تنسورها را با device="cuda" بسازید. سلول !nvidia-smi را هم حین اجرا بزنید؛ اگر مصرف حافظه و بار کارت بالا رفته باشد، محاسبه روی GPU انجام می‌شود.

فایل‌های نوت‌بوک بعد از حذف ماشین می‌مانند؟

نه. دیسک ماشین با حذف آن پاک می‌شود و ذخیره‌سازی دائمی وجود ندارد. قبل از حذف، فایل‌ها را از مرورگر فایل Jupyter دانلود کنید یا با scp روی سیستم خودتان بیاورید.

هزینهٔ اجرای یک نوت‌بوک چقدر است؟

فقط به مدت روشن بودن ماشین بستگی دارد و دقیقه‌ای حساب می‌شود. در زمان نوشتن این مطلب، یک RTX 3060 با ۱۲ گیگابایت VRAM از حدود ۱۴ هزار تومان در ساعت شروع می‌شود، یعنی یک جلسهٔ نیم‌ساعته حدود ۷ هزار تومان. قیمت لحظه‌ای هر کارت در بازار GPU هست.

اگر خطای CUDA out of memory گرفتم چه کنم؟

اندازهٔ batch یا ابعاد تنسورها را کم کنید و کرنل را ری‌استارت کنید تا تنسورهای قدیمی آزاد شوند. اگر کارتان ذاتاً حافظهٔ بیشتری می‌خواهد، ماشینی با VRAM بالاتر مثل RTX A4000 یا RTX 3090 بگیرید.

تصویر کاور: «Jupiter's iconic Great Red Spot» اثر NASA/JPL-Caltech/SwRI/MSSS/Gerald Eichstädt/Seán Doran، از ویکی‌مدیا کامنز، لایسنس Public Domain.