Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Menyahpepijat isu kebocoran memori Pytorch menggunakan penghias konteks

Menyahpepijat isu kebocoran memori Pytorch menggunakan penghias konteks

王林
王林ke hadapan
2023-04-10 11:31:071501semak imbas

Penghias ialah pelaksanaan khusus pengurus konteks python. Artikel ini akan menggambarkan cara menggunakannya melalui contoh penyahpepijatan GPU pytorch. Walaupun ia mungkin tidak berfungsi dalam setiap keadaan, saya dapati ia sangat berguna.

Menyahpepijat isu kebocoran memori Pytorch menggunakan penghias konteks

Menyahpepijat Isu Kebocoran Memori

Terdapat banyak cara untuk nyahpepijat kebocoran memori. Artikel ini akan menunjukkan kaedah yang berguna untuk mengenal pasti baris bermasalah dalam kod anda. Kaedah ini boleh membantu mencari lokasi tertentu dengan cara yang ringkas.

Penyahpepijat manual baris demi baris

Jika anda menghadapi masalah, kaedah klasik dan biasa digunakan ialah menggunakan penyahpepijat untuk menyemak baris demi baris, seperti contoh berikut:

  • Cari coretan kod tentang cara mengira jumlah bilangan semua tensor dalam pytorch dalam enjin carian, seperti: tensor-counter-snippet
  • Tetapkan titik putus dalam kod
  • Gunakan tensor-counter -snippet untuk mendapatkan jumlah kiraan tensor
  • Gunakan penyahpepijat untuk melakukan langkah seterusnya
  • Jalankan semula tensor-counter-snippet dan semak sama ada kiraan tensor meningkat
  • Ulangi Langkah di atas

Ia berfungsi, tetapi ia kelihatan seperti banyak masalah. Kita boleh merangkumnya ke dalam fungsi, yang boleh dipanggil apabila diperlukan, jadi hampir tidak perlu mengubah suai kod sedia ada, yang membawa kita untuk memperkenalkan fungsi penghias.

Python Decorators

Dekorator boleh dibungkus dalam mana-mana bahagian kod. Di sini kita menggunakan alat penghias untuk memeriksa sama ada terdapat tensor tambahan Selain itu, kita juga memerlukan pembilang kerana bilangan tensor perlu dikira sebelum dan selepas pelaksanaan. Coraknya kelihatan seperti ini:

def memleak_wrapper(func):
def wrap(*args, **kwargs):
print("num tensors start is ...")
out = func(*args, **kwargs)
print("num tensors end is ...")
return out
return wrap@memleak_wrapper
 def function_to_debug(x):
print(f"put line(s) of code here. Input is {x}")
out = x + 10
return outout = function_to_debug(x=1000)
 print(f"out is {out}")
 
 #输入类似这样
 #num tensors start is ...
 #put line(s) of code here. Input is 1000
 #num tensors end is ...
 #outis 1010

Untuk menjalankan kod ini, kita perlu meletakkan baris kod yang ingin kita semak ke dalam fungsi (function_to_debug). Tetapi ini bukanlah yang terbaik kerana kita masih perlu memasukkan banyak kod secara manual. Perkara lain ialah jika blok kod menjana lebih daripada satu pembolehubah, anda perlu mencari penyelesaian tambahan untuk menggunakan pembolehubah hiliran ini.

Penghias konteks

Untuk menyelesaikan masalah di atas, kita boleh menggunakan pengurus konteks dan bukannya penghias fungsi. Contoh pengurus konteks yang paling banyak digunakan ialah membuat konteks menggunakan pernyataan dengan. Yang paling biasa digunakan ialah:

with open("file") as f:
…

Menggunakan perpustakaan contextlib Python, pengguna Python boleh membuat pengurus konteks mereka sendiri dengan mudah. Jadi dalam artikel ini kami akan menggunakan ContextDecorator untuk menyelesaikan kerja yang kami cuba gunakan penghias di atas. Kerana ia lebih mudah untuk dibangunkan dan lebih mudah digunakan:

 from contextlib import ContextDecorator
 
 class check_memory_leak_context(ContextDecorator):
def __enter__(self):
print('Starting')
return self
 
def __exit__(self, *exc):
print('Finishing')
return False

ContextDecorator mempunyai 2 kaedah: enter() dan exit() , yang dipanggil apabila kita masuk atau keluar dari konteks. Parameter *exc dalam __exit__ mewakili sebarang pengecualian masuk.

Sekarang mari gunakannya untuk menyelesaikan masalah yang dinyatakan di atas.

Gunakan ContextDecorator untuk mencari kebocoran memori

Oleh kerana kita perlu mengira jumlah bilangan tensor, kita merangkum proses pengiraan ke dalam fungsi get_n_tensors(), supaya tensor boleh dikira pada permulaan dan akhir konteks Kuantiti amaun:

class check_memory_leak_context(ContextDecorator):
def __enter__(self):
self.start = get_n_tensors()
return self def __exit__(self, *exc):
self.end = get_n_tensors()
increase = self.end — self.start
 
if increase > 0:
print(f”num tensors increased with"
f"{self.end — self.start} !”)
else:
print(”no added tensors”)
return False

Jika terdapat peningkatan, cetak ke konsol.

get_n_tensor() menggunakan pemungut sampah (gc) dan disesuaikan untuk pytorch, tetapi boleh diubah suai dengan mudah untuk perpustakaan lain:

 import gc
 def get_n_tensors():
tensors= []
for obj in gc.get_objects():
try:
if (torch.is_tensor(obj) or
(hasattr(obj, ‘data’) and
torch.is_tensor(obj.data))):
tensors.append(obj)
except:
pass
return len(tensors)

Ia sedia untuk digunakan sekarang, kami Gunakan ini konteks untuk mana-mana baris (atau blok) kod:

 x = arbitrary_operation(x)
 ...
 with check_memory_leak_context():
y = x[0].permute(1, 2, 0).cpu().detach().numpy()
x = some_harmless_operation()
 ...
 x = another_arbitrary_operation(x)

Jika tensor baharu dicipta dalam baris yang dibalut oleh penghias konteks, ia akan dicetak.

Ringkasan

Ini adalah coretan kod yang sangat bagus yang boleh anda letakkan dalam fail berasingan semasa pembangunan Berikut ialah kod lengkap untuk artikel ini:

https://. gist.github.com/MarkTension/4783697ebd5212ba500cdd829b364338

Akhir sekali, saya harap artikel kecil ini dapat membantu anda memahami maksud pengurus konteks, cara menggunakan penghias konteks dan cara menggunakannya untuk menyahpepijat pytorch .

Atas ialah kandungan terperinci Menyahpepijat isu kebocoran memori Pytorch menggunakan penghias konteks. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:51cto.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam