DataLens

NumPy ↔ tensor; device (CPU/GPU)

Pindahkan data antara NumPy, pandas, dan PyTorch tanpa kejutan, pahami memori yang dipakai bersama, dan tempatkan tensor serta model di device yang tepat.

Level: Dasar · 7 menit baca

Latihan modul ini

Soal-soal untuk pelajaran ini berjalan di browser-mu dan langsung mengecek jawabanmu.

Idenya

Proyek sungguhan mencampur beberapa library: data datang sebagai DataFrame pandas, preprocessing dilakukan di NumPy atau scikit-learn, model berjalan di PyTorch, dan hasilnya kembali ke DataFrame atau grafik Plotly. Dua hal membuat serah-terima ini mulus:

  1. tahu kapan konversi menyalin data dan kapan berbagi memori;
  2. tahu di device mana (CPU atau GPU) sebuah tensor berada.

Dari NumPy ke PyTorch

Datamu biasanya berawal di NumPy atau pandas, jadi langkah pertama sebagian besar proyek PyTorch adalah mengonversinya. Ada dua cara, dan perbedaannya penting:

import numpy as np
import torch

arr = np.array([1.0, 2.0, 3.0])
shared = torch.from_numpy(arr)       # shares memory with arr
copied = torch.tensor(arr)           # an independent copy

arr[0] = 100.0
print(shared)
print(copied)
print(shared.dtype)
tensor([100.,   2.,   3.], dtype=torch.float64)
tensor([1., 2., 3.], dtype=torch.float64)
torch.float64
X = torch.from_numpy(np.random.default_rng(0).random((3, 2))).float()
print(X.dtype, X.shape)
torch.float32 torch.Size([3, 2])

Dari PyTorch ke NumPy

Dan kembali lagi: setelah pelatihan, kamu sering ingin prediksinya sebagai array NumPy, untuk dibuat grafik atau dimasukkan ke DataFrame:

t = torch.tensor([0.25, 0.5, 0.75])
a = t.numpy()           # shares memory (CPU tensors only)
t[0] = 9.0
print(a)
[9.   0.5  0.75]

Dua aturan untuk .numpy():

Dari pandas

Sebagian besar data sungguhan datang sebagai DataFrame, seperti tabel churn dari track ML. Jalurnya yang biasa melewati NumPy:

import pandas as pd

df = pd.DataFrame({"tenure_months": [12, 33, 5], "orders_90d": [7, 4, 0], "churned": [0, 0, 1]})
X = torch.tensor(df[["tenure_months", "orders_90d"]].to_numpy(), dtype=torch.float32)
y = torch.tensor(df["churned"].to_numpy(), dtype=torch.float32)
print(X)
print(y)
tensor([[12.,  7.],
        [33.,  4.],
        [ 5.,  0.]])
tensor([0., 0., 1.])

Jalur yang biasa adalah DataFrame → NumPy (.to_numpy()) → tensor, dengan memilih dtype=torch.float32 secara eksplisit.

Device

Sebuah tensor berada di sebuah device: CPU, GPU NVIDIA ("cuda"), atau GPU Apple Silicon ("mps"). Perhitungan hanya bisa menggabungkan tensor yang berada di device yang sama.

device = (
    "cuda" if torch.cuda.is_available()
    else "mps" if torch.backends.mps.is_available()
    else "cpu"
)
print("using", device)

t = torch.ones(3)
print(t.device)
t = t.to(device)       # copies to the device (no-op if it's already there)
using mps
cpu

Device yang tercetak bergantung pada mesinmu: cuda di mesin dengan GPU NVIDIA, mps di Mac dengan Apple Silicon, cpu selain itu.

Pola standarnya: pilih device sekali di bagian atas, lalu pindahkan model dan setiap batch ke sana:

model = MyModel().to(device)
for X_batch, y_batch in loader:
    X_batch, y_batch = X_batch.to(device), y_batch.to(device)
    predictions = model(X_batch)

Lupa satu .to(device) saja dan kamu mendapat error terkenal "Expected all tensors to be on the same device, but found at least two devices, cuda:0 and cpu". Bacalah sebagai checklist: tensor mana yang belum dipindahkan?

Ide utama

Pilih device sekali; pindahkan model dan setiap batch ke sana; bawa hasilnya kembali dengan .detach().cpu().numpy(). from_numpy dan .numpy() berbagi memori; torch.tensor(...) menyalin.

Kapan GPU membantu?

GPU cepat untuk perhitungan tensor yang besar dan paralel: perkalian matriks besar atas batch yang besar. Untuk model tabular kecil (beberapa ribu baris, network kecil), waktu yang dihabiskan untuk menyalin data ke GPU bisa melebihi waktu yang dihemat, dan CPU sudah lebih dari cukup. Ukur dulu sebelum berasumsi.

Mengapa ini penting untuk kode yang bersih

Simpan konversi di tepi kodemu: konversi sekali saat data masuk ke kode model, dan sekali saat hasilnya keluar. Variabel device yang didefinisikan di satu tempat (sering dari file konfigurasi) membuat script yang sama bisa berjalan di laptop maupun server GPU tanpa diedit. Panggilan .cuda() yang tersebar adalah versi PyTorch dari path file yang di-hard-code.

Rangkuman

Latihan modul ini

Soal-soal untuk pelajaran ini berjalan di browser-mu dan langsung mengecek jawabanmu.

Berikutnya: Autograd: cara kerja gradient →