Mengapa functorch? | Instal Panduan | Transformasi | Dokumentasi | Rencana masa depan
Perpustakaan ini saat ini sedang dalam pengembangan besar - jika Anda memiliki saran tentang API atau kasus penggunaan yang ingin Anda lindungi, silakan buka masalah gitub atau jangkau. Kami ingin mendengar tentang bagaimana Anda menggunakan perpustakaan.
functorch adalah transformasi fungsi komposisi seperti jax untuk pytorch.
Ini bertujuan untuk menyediakan transformasi vmap dan grad yang dapat dikomposisikan yang bekerja dengan modul Pytorch dan Pytorch Autograd dengan kinerja mode yang baik.
Selain itu, ada fungsionalitas eksperimental untuk dilacak melalui transformasi ini menggunakan FX untuk menangkap hasil transformasi ini sebelumnya. Ini akan memungkinkan kami untuk menyusun hasil VMAP atau lulusan untuk meningkatkan kinerja.
Ada sejumlah kasus penggunaan yang rumit untuk dilakukan di Pytorch hari ini:
Mengubah transformasi vmap , grad , vjp , dan jvp memungkinkan kita untuk mengekspresikan di atas tanpa merancang subsistem terpisah untuk masing -masing. Gagasan transformasi fungsi yang dapat dikomposisi ini berasal dari kerangka kerja Jax.
Ada dua cara untuk menginstal Functorch:
Kami merekomendasikan mencoba beta functorch terlebih dahulu.
Ikuti instruksi dalam buku catatan Colab ini
Pada 9/21/2022, functorch hadir di samping biner Pytorch malam. Harap instal pratinjau (malam) Pytorch Binary; Lihat https://pytorch.org/ untuk instruksi.
Setelah selesai, jalankan cek kewarasan cepat di Python:
import torch
from functorch import vmap
x = torch . randn ( 3 )
y = vmap ( torch . sin )( x )
assert torch . allclose ( y , x . sin ()) Pada 9/21/2022, functorch datang dipasang bersama Pytorch dan berada di pohon sumber Pytorch. Silakan instal Pytorch dari Sumber, maka, Anda akan dapat import functorch .
Cobalah menjalankan beberapa tes untuk memastikan semuanya baik -baik saja:
pytest test/test_vmap.py -v
pytest test/test_eager_transforms.py -vAotautograd memiliki beberapa persyaratan opsional tambahan. Anda dapat menginstalnya melalui:
pip install networkx Untuk menjalankan tes Functorch, silakan instal dependensi pengujian kami ( expecttest , pyyaml ).
Ikuti instruksi di sini
Prasyarat: Instal Pytorch
pip install functorchAkhirnya, jalankan cek kewarasan cepat di Python:
import torch
from functorch import vmap
x = torch . randn ( 3 )
y = vmap ( torch . sin )( x )
assert torch . allclose ( y , x . sin ())Saat ini, kami mendukung transformasi berikut:
grad , vjp , jvp ,jacrev , jacfwd , hessianvmapSelain itu, kami memiliki beberapa utilitas untuk bekerja dengan modul Pytorch.
make_functional(model)make_functional_with_buffers(model) Catatan: vmap memberlakukan pembatasan pada kode yang dapat digunakan. Untuk detail lebih lanjut, silakan baca DocString -nya.
vmap(func)(*inputs) adalah transformasi yang menambahkan dimensi ke semua operasi tensor di func . vmap(func) Mengembalikan fungsi baru yang memetakan func atas beberapa dimensi (default: 0) dari setiap tensor dalam inputs .
vmap berguna untuk menyembunyikan dimensi batch: Seseorang dapat menulis fungsi func yang berjalan pada contoh dan kemudian mengangkatnya ke fungsi yang dapat mengambil batch contoh dengan vmap(func) , yang mengarah ke pengalaman pemodelan yang lebih sederhana:
from functorch import vmap
batch_size , feature_size = 3 , 5
weights = torch . randn ( feature_size , requires_grad = True )
def model ( feature_vec ):
# Very simple linear model with activation
assert feature_vec . dim () == 1
return feature_vec . dot ( weights ). relu ()
examples = torch . randn ( batch_size , feature_size )
result = vmap ( model )( examples ) grad(func)(*inputs) mengasumsikan func mengembalikan tensor elemen tunggal. Ini menghitung gradien output func WRT ke inputs[0] .
from functorch import grad
x = torch . randn ([])
cos_x = grad ( lambda x : torch . sin ( x ))( x )
assert torch . allclose ( cos_x , x . cos ())
# Second-order gradients
neg_sin_x = grad ( grad ( lambda x : torch . sin ( x )))( x )
assert torch . allclose ( neg_sin_x , - x . sin ()) Saat disusun dengan vmap , grad dapat digunakan untuk menghitung per-gradien:
from functorch import vmap
batch_size , feature_size = 3 , 5
def model ( weights , feature_vec ):
# Very simple linear model with activation
assert feature_vec . dim () == 1
return feature_vec . dot ( weights ). relu ()
def compute_loss ( weights , example , target ):
y = model ( weights , example )
return (( y - target ) ** 2 ). mean () # MSELoss
weights = torch . randn ( feature_size , requires_grad = True )
examples = torch . randn ( batch_size , feature_size )
targets = torch . randn ( batch_size )
inputs = ( weights , examples , targets )
grad_weight_per_example = vmap ( grad ( compute_loss ), in_dims = ( None , 0 , 0 ))( * inputs ) Transformasi vjp func untuk inputs dan mengembalikan fungsi baru yang menghitung VJP memberikan beberapa tensor cotangents .
from functorch import vjp
outputs , vjp_fn = vjp ( func , inputs ); vjps = vjp_fn ( * cotangents ) Transformasi jvp menghitung produk Jacobian-vektor dan juga dikenal sebagai "iklan mode maju". Ini bukan fungsi orde tinggi tidak seperti kebanyakan transformasi lainnya, tetapi mengembalikan output func(inputs) serta jvp s.
from functorch import jvp
x = torch . randn ( 5 )
y = torch . randn ( 5 )
f = lambda x , y : ( x * y )
_ , output = jvp ( f , ( x , y ), ( torch . ones ( 5 ), torch . ones ( 5 )))
assert torch . allclose ( output , x + y ) Transformasi jacrev mengembalikan fungsi baru yang mengambil x dan mengembalikan Jacobian of torch.sin sehubungan dengan x menggunakan iklan mode terbalik.
from functorch import jacrev
x = torch . randn ( 5 )
jacobian = jacrev ( torch . sin )( x )
expected = torch . diag ( torch . cos ( x ))
assert torch . allclose ( jacobian , expected ) Gunakan jacrev untuk menghitung Jacobian. Ini dapat disusun dengan VMAP untuk menghasilkan Jacobians yang batch:
x = torch . randn ( 64 , 5 )
jacobian = vmap ( jacrev ( torch . sin ))( x )
assert jacobian . shape == ( 64 , 5 , 5 ) jacfwd adalah pengganti drop-in untuk jacrev yang menghitung Jacobian menggunakan iklan mode maju:
from functorch import jacfwd
x = torch . randn ( 5 )
jacobian = jacfwd ( torch . sin )( x )
expected = torch . diag ( torch . cos ( x ))
assert torch . allclose ( jacobian , expected ) Menyusun jacrev dengan dirinya sendiri atau jacfwd dapat menghasilkan hessians:
def f ( x ):
return x . sin (). sum ()
x = torch . randn ( 5 )
hessian0 = jacrev ( jacrev ( f ))( x )
hessian1 = jacfwd ( jacrev ( f ))( x ) The hessian adalah fungsi kenyamanan yang menggabungkan jacfwd dan jacrev :
from functorch import hessian
def f ( x ):
return x . sin (). sum ()
x = torch . randn ( 5 )
hess = hessian ( f )( x ) Kami juga dapat melacak transformasi ini untuk menangkap hasil sebagai kode baru menggunakan make_fx . Ada juga integrasi eksperimental dengan kompiler NNC (hanya berfungsi pada CPU untuk saat ini!).
from functorch import make_fx , grad
def f ( x ):
return torch . sin ( x ). sum ()
x = torch . randn ( 100 )
grad_f = make_fx ( grad ( f ))( x )
print ( grad_f . code )
def forward ( self , x_1 ):
sin = torch . ops . aten . sin ( x_1 )
sum_1 = torch . ops . aten . sum ( sin , None ); sin = None
cos = torch . ops . aten . cos ( x_1 ); x_1 = None
_tensor_constant0 = self . _tensor_constant0
mul = torch . ops . aten . mul ( _tensor_constant0 , cos ); _tensor_constant0 = cos = None
return mulTerkadang Anda mungkin ingin melakukan transformasi sehubungan dengan parameter dan/atau buffer nn.module. Ini bisa terjadi misalnya dalam:
Solusi kami untuk ini saat ini adalah API yang, diberi nn.module, menciptakan versi tanpa kewarganegaraan yang dapat disebut seperti fungsi.
make_functional(model) mengembalikan versi fungsional model dan model.parameters()make_functional_with_buffers(model) mengembalikan versi fungsional model dan model.parameters() dan model.buffers() .Berikut adalah contoh di mana kami menghitung per-sampel menggunakan lapisan NN.linear:
import torch
from functorch import make_functional , vmap , grad
model = torch . nn . Linear ( 3 , 3 )
data = torch . randn ( 64 , 3 )
targets = torch . randn ( 64 , 3 )
func_model , params = make_functional ( model )
def compute_loss ( params , data , targets ):
preds = func_model ( params , data )
return torch . mean (( preds - targets ) ** 2 )
per_sample_grads = vmap ( grad ( compute_loss ), ( None , 0 , 0 ))( params , data , targets ) Jika Anda membuat ansambel model, Anda dapat menemukan combine_state_for_ensemble berguna.
Untuk dokumentasi lebih lanjut, lihat situs web dokumen kami.
torch._C._functorch.dump_tensor : dumps Dispatch Keys di stack torch._C._functorch._set_vmap_fallback_warning_enabled(False) Jika spam peringatan VMAP mengganggu Anda.
Pada akhirnya, kami ingin meningkatkan ini menjadi Pytorch begitu kami menyetrika detail desain. Untuk mengetahui detailnya, kami membutuhkan bantuan Anda - silakan kirimkan kasus penggunaan Anda dengan memulai percakapan di pelacak masalah atau mencoba proyek kami.
Functorch memiliki lisensi gaya BSD, seperti yang ditemukan dalam file lisensi.
Jika Anda menggunakan Functorch dalam publikasi Anda, silakan mengutipnya dengan menggunakan entri Bibtex berikut.
@Misc { functorch2021 ,
author = { Horace He, Richard Zou } ,
title = { functorch: JAX-like composable function transforms for PyTorch } ,
howpublished = { url{https://github.com/pytorch/functorch} } ,
year = { 2021 }
}