9-bo‘lim

Qurilma va tezlik

CPU va GPU, device-agnostik kod yozish, .to() bilan ko'chirish, oqimlar soni va float32 ning ahamiyati.

🕑 9 daqiqa o‘qish 📄 579 so‘z 👁 0 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Qurilmani tekshirish
  2. Ko'chirish
  3. GPU qachon foyda beradi
  4. Tezlikni o'lchash
  5. CPU oqimlari
  6. float32 va float64
  7. Xulosa

Shu paytgacha kod CPU da ishladi. Katta modellarda esa GPU 10-50 barobar tezlik beradi. Yaxshi xabar shundaki, PyTorch da bunga o'tish uchun kodni qayta yozish shart emas.

Qurilmani tekshirish #

Python
import torch

print("PyTorch:", torch.__version__)
print("CUDA mavjud:", torch.cuda.is_available())

qurilma = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print("tanlangan qurilma:", qurilma)
print("oqimlar soni:", torch.get_num_threads())
Natija
PyTorch: 2.14.0+cpu
CUDA mavjud: False
tanlangan qurilma: cpu
oqimlar soni: 4

Bu darslik CPU li mashinada yozilgan, shuning uchun False chiqdi. Muhimi shundaki, kod ikkala holatda ham ishlaydi.

Doim shu ikki qatorni yozing
Python
qurilma = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = model.to(qurilma)

Shu ikki qator kodingizni har qanday mashinada ishlaydigan qiladi. GPU bo'lsa ishlatadi, bo'lmasa CPU da davom etadi. .cuda() ni to'g'ridan- to'g'ri yozmang - GPU yo'q mashinada dastur yiqiladi.

Ko'chirish #

Python
x = torch.randn(3, 3)
print("tenzor qurilmasi:", x.device)

x = x.to(qurilma)
print("ko'chirilgandan keyin:", x.device)

import torch.nn as nn
model = nn.Linear(3, 1).to(qurilma)
print("model parametri:", next(model.parameters()).device)
Natija
tenzor qurilmasi: cpu
ko'chirilgandan keyin: cpu
model parametri: cpu
NimaQanday ko'chiriladiEslatma
Tenzorx = x.to(qurilma)Yangi tenzor qaytaradi - natijani saqlang
Modelmodel.to(qurilma)Joyida o'zgaradi, lekin model = model.to(...) yozish xavfsiz
Paketxb, yb = xb.to(q), yb.to(q)Har paketda sikl ichida bajariladi
«Expected all tensors to be on the same device»

Bu GPU da eng ko'p uchraydigan xato. Model GPU da, ma'lumot esa CPU da qolib ketgan bo'ladi.

O'quv siklida har bir paketni ko'chirishni unutmang:

Python
for xb, yb in oquv_dl:
    xb, yb = xb.to(qurilma), yb.to(qurilma)
    ...

x.to(qurilma) natijani qaytaradi, tenzorni joyida o'zgartirmaydi - x = x.to(...) deb yozing.

GPU qachon foyda beradi #

CPU va GPU: ishning turiga bog'liq CPU kam yadro, har biri kuchli Kichik modellar va jadval ma'lumoti Ma'lumotni tayyorlash va o'qish Kodni sinash va xato qidirish Bitta namuna uchun bashorat bu darslikning 1-12 bo'limlari GPU minglab yadro, parallel ishlaydi Konvolyutsion tarmoqlar (13-bo'lim) Katta paketlar va katta rasmlar Til modellari va transformerlar Uzoq davom etadigan o'qitish 10-50 barobargacha tezlik Kichik modelda GPU ba'zan sekinroq: ko'chirishga ketgan vaqt yutuqdan katta bo'ladi
GPU ning kuchi parallel amallarda; kichik modelda ko'chirish xarajati foydani yeydi

Tezlikni o'lchash #

Taxmin qilish o'rniga o'lchang:

Python
import time

a = torch.randn(2000, 2000)
b = torch.randn(2000, 2000)

a @ b  # birinchi chaqiruv - isitish uchun

t = time.perf_counter()
for _ in range(5):
    c = a @ b
print(f"2000x2000 matritsa ko'paytmasi: {(time.perf_counter()-t)/5*1000:.1f} ms")
Natija
2000x2000 matritsa ko'paytmasi: 54.8 ms
Birinchi chaqiruvni hisobga olmang

Birinchi amal har doim sekinroq: xotira ajratiladi, kutubxona ichki jadvallarni tayyorlaydi. GPU da bu farq yanada kattaroq. Shuning uchun o'lchashdan oldin bir marta «isitish» chaqiruvi qilinadi.

CPU oqimlari #

CPU da PyTorch bir nechta yadrodan foydalanadi:

Python
for n in [1, 2, 4]:
    torch.set_num_threads(n)
    a @ b
    t = time.perf_counter()
    for _ in range(3):
        c = a @ b
    print(f"  {n} oqim: {(time.perf_counter()-t)/3*1000:7.1f} ms")
Natija
  1 oqim:   141.6 ms
  2 oqim:    68.8 ms
  4 oqim:    52.9 ms

1 dan 2 oqimga o'tganda tezlik deyarli ikki barobar oshdi. 2 dan 4 ga o'tganda esa foyda kamaydi - bu odatiy hol, chunki yadrolar xotira kanalini baham ko'radi.

float32 va float64 #

Python
X = torch.randn(4096, 512)
W = torch.randn(512, 512)

for nom, dt in [("float32", torch.float32), ("float64", torch.float64)]:
    xa, wa = X.to(dt), W.to(dt)
    xa @ wa
    t = time.perf_counter()
    for _ in range(3):
        xa @ wa
    print(f"  {nom}: {(time.perf_counter()-t)/3*1000:7.1f} ms   xotira = {xa.element_size()*xa.nelement()/1048576:.1f} MB")
Natija
  float32:     8.3 ms   xotira = 8.0 MB
  float64:    12.1 ms   xotira = 16.0 MB

float64 ikki barobar xotira oldi va sekinroq ishladi - hech qanday foyda bermasdan.

TurHajmiQachon
float324 baytStandart - deyarli har doim shu
float16 / bfloat162 baytGPU da tezlik va xotira uchun (mixed precision)
float648 baytIlmiy hisob-kitob; chuqur o'rganishda kerak emas
NumPy dan kelgan float64

NumPy massivining sukut turi float64. Uni to'g'ridan-to'g'ri torch.tensor(...) ga bersangiz, tenzor ham float64 bo'ladi va modelning float32 parametrlari bilan to'qnashadi:

Natija
RuntimeError: expected scalar type Double but found Float

Yechim - turni ochiq ko'rsatish: torch.tensor(arr, dtype=torch.float32) yoki tensor.float().

Amaliy topshiriq
  1. torch.cuda.is_available() natijasini o'z mashinangizda tekshiring.
  2. device o'zgaruvchisini yaratib, uni chop eting.
  3. Tenzorni .to(qurilma) bilan ko'chiring va .device ni tekshiring.
  4. x.to(...) natijasini saqlamasdan sinab, tenzor o'zgarmaganini ko'ring.
  5. 8-bo'limdagi o'quv siklini device-agnostik qilib qayta yozing.
  6. 2000x2000 matritsa ko'paytmasi vaqtini o'lchang.
  7. Isitish chaqiruvisiz o'lchab, farqni ko'ring.
  8. set_num_threads ni 1, 2 va 4 qilib, uchta natijani jadvalga yozing.
  9. float32 va float64 tezligi hamda xotirasini solishtiring.
  10. NumPy massividan float64 tenzor yasab, modelga berib, xatoni o'qing va tuzating.

Xulosa #

  • torch.cuda.is_available() GPU bor-yo'qligini aytadi.
  • Device-agnostik kod yozing: torch.device("cuda" if ... else "cpu").
  • .cuda() ni to'g'ridan-to'g'ri yozmang - GPU yo'q mashinada yiqiladi.
  • Tenzor uchun x = x.to(qurilma) - natijani saqlang, u joyida o'zgarmaydi.
  • Model va har bir paket bir xil qurilmada bo'lishi shart.
  • «Expected all tensors to be on the same device» - eng ko'p uchraydigan GPU xatosi.
  • GPU ning foydasi katta modellarda ko'rinadi; kichik modelda ko'chirish xarajati yutuqni yeydi.
  • Tezlikni o'lchashda birinchi «isitish» chaqiruvini hisobga olmang.
  • CPU da set_num_threads tezlikka sezilarli ta'sir qiladi.
  • Chuqur o'rganishda float32 standart; float64 faqat xotira va vaqt yeydi.

Keyingi bo'limda o'qitilgan modelni saqlash va qaytadan yuklashni ko'ramiz.

Xatolik topdingizmi?

Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.