Artikel ini diilhamkan daripada kursus "Sistem Pembelajaran Dalam Cekap" yang diajar oleh Institut Analisis Data Yandex.
Pengetahuan awal: Adalah diandaikan bahawa pembaca sudah memahami prinsip kerja hantaran hadapan dan hantaran ke belakang rangkaian neural, Ini penting untuk memahami kandungan artikel ini. Artikel ini menggunakan PyTorch sebagai rangka kerja.
Apabila cuba menggunakan model besar (aka gpt-2-xl) dengan lebih 500 juta parameter dan sumber GPU anda terhad dan anda tidak boleh menukarnya Apa yang perlu saya lakukan jika ia dipasang untuk dijalankan pada GPU, atau saiz kelompok yang ditakrifkan dalam kertas tidak boleh dicapai semasa latihan model? Mungkin anda boleh berputus asa dan menggunakan versi model yang lebih ringan, atau mengurangkan saiz kelompok latihan, supaya anda tidak akan mendapat hasil latihan yang diterangkan dalam kertas.
Namun, terdapat beberapa teknik yang boleh membantu menyelesaikan masalah di atas.
Mari kita bincangkan beberapa kaedah, iaitu cara menggunakan kaedah ini untuk memperhalusi model GPT-2-XL dengan 1.5 bilion parameter.
Pertama, mari kita fahami isu memori GPU yang diperlukan untuk memuatkan model ke dalam bahan GPU.
Dengan mengandaikan bahawa model mempunyai parameter FP32 (32-bit floating point), model ini perlu dilatih pada GPU, contohnya, menjalankan pengoptimum Adam .
Melalui pengiraan, hasilnya mengejutkan.
Anggap anda sudah mempunyai NVIDIA dengan memori 12 GB GeForce RTX 3060. Pertama, parameter 1e9 FP32 menggunakan lebih kurang 4 GB memori GPU.
Begitu juga, jumlah memori yang sama akan dikhaskan untuk kecerunan. Oleh itu, sejumlah 8 GB memori telah dikhaskan Memandangkan latihan belum bermula dan pengoptimum belum dimuatkan, memuatkan pengoptimum juga memerlukan sejumlah memori. Pengoptimum Adam perlu menyimpan sandaran pertama dan kedua untuk setiap parameter, yang memerlukan 8 GB memori tambahan. Mengira ini, anda mesti mempunyai kira-kira 16 GB memori GPU untuk memuatkan model dengan betul ke GPU Dalam contoh ini, GPU hanya mempunyai 12 GB memori percuma. Nampak teruk kan?
Walau bagaimanapun, terdapat beberapa cara untuk cuba menyelesaikan masalah ini, berikut adalah yang berkaitan:
Ikhtisar
Jika model lebih besar daripada kapasiti GPU, walaupun menetapkan saiz kelompok kepada 1 tidak mencukupi, jadi apa yang perlu saya lakukan? Terdapat penyelesaian, iaitu menetapkan titik pemeriksaan kecerunan Mari kita lihat konsep ini. Untuk rangkaian neural suapan mudah yang mengandungi n lapisan, rajah pengiraan kecerunan adalah seperti berikut:
Pengaktifan lapisan rangkaian saraf sepadan dengan nod yang ditandakan dengan f, dan semasa hantaran ke hadapan, semua nod ini dikira mengikut turutan. Kecerunan kehilangan yang sepadan dengan pengaktifan dan parameter lapisan ini diwakili oleh nod berlabel b. Semasa hantaran ke belakang, semua nod ini dinilai dalam susunan terbalik. Hasil pengiraan nod f digunakan untuk mengira nod b, jadi semua nod f disimpan dalam ingatan selepas lulus ke hadapan. Hanya apabila perambatan belakang berjalan cukup jauh untuk mengira semua kebergantungan nod f, ia boleh dipadamkan daripada ingatan. Ini bermakna: memori yang diperlukan untuk perambatan balik mudah berkembang secara linear dengan bilangan lapisan rangkaian saraf n.
Berikut ialah susunan pengiraan nod ini Lingkaran berlorek ungu menunjukkan nod yang perlu disimpan ke dalam memori pada masa tertentu.
Gradient Checkpoint
Penyebaran balik mudah seperti yang diterangkan di atas adalah optimum dari segi pengiraan: ia hanya mengira setiap nod sekali. Walau bagaimanapun, jika anda mengira semula nod, anda mungkin menjimatkan banyak memori. Sebagai contoh, setiap nod hanya boleh dikira semula. Susunan pelaksanaan dan memori yang digunakan adalah seperti yang ditunjukkan di bawah:
Strategi ini adalah optimum dari segi ingatan. Walau bagaimanapun, ambil perhatian bahawa bilangan pengiraan nod adalah berskala n² kali, berbanding dengan faktor skala n sebelumnya: setiap n nod dikira semula secara berjujukan n kali. Oleh kerana kelajuan pengiraan yang perlahan, kaedah ini tidak sesuai untuk pembelajaran mendalam.
Untuk mencapai keseimbangan antara ingatan dan pengiraan, strategi perlu dicadangkan yang membolehkan nod dikira semula, tetapi tidak terlalu kerap. Strategi yang digunakan di sini adalah untuk menandakan subset pengaktifan rangkaian saraf sebagai nod pusat pemeriksaan.
Dalam contoh ini, pilih untuk menandakan nod sqrt(n)th sebagai pusat pemeriksaan. Dengan cara ini, bilangan nod pusat pemeriksaan dan bilangan nod antara pusat pemeriksaan adalah antara sqrt(n), yang bermaksud: jumlah memori yang diperlukan juga berskala dalam susunan n. Pengiraan tambahan yang diperlukan oleh strategi ini adalah bersamaan dengan pengiraan yang diperlukan oleh satu laluan ke hadapan melalui rangkaian.
Rutin:
Selepas mempelajari butiran titik pemeriksaan kecerunan, datang Lihat bagaimana untuk menggunakan konsep ini dalam PyTorch, ia tidak kelihatan terlalu sukar:
Ikhtisar
Model pembelajaran mendalam menjadi lebih besar dan lebih besar, dan sukar untuk memasang rangkaian saraf yang begitu besar dalam memori GPU. Oleh itu, anda terpaksa memilih saiz kelompok yang lebih kecil semasa latihan, yang mungkin membawa kepada penumpuan yang lebih perlahan dan ketepatan yang lebih rendah.
Apakah pengumpulan kecerunan?
Apabila melatih rangkaian saraf, data biasanya dibahagikan kepada kelompok, dan rangkaian saraf meramalkan label kelompok, yang digunakan untuk mengira kerugian berbanding sasaran sebenar . Seterusnya, lakukan hantaran ke belakang untuk mengira kecerunan dan mengemas kini berat model. Pengumpulan kecerunan mengubah suai langkah terakhir proses latihan: sebelum meneruskan ke kumpulan mini seterusnya, simpan nilai kecerunan dan tambahkan kecerunan baharu pada kecerunan yang disimpan sebelum ini, bukannya mengemas kini pemberat rangkaian untuk setiap kelompok mini . Pemberat dikemas kini hanya selepas model memproses beberapa kelompok mini. Pengumpulan kecerunan menyerupai saiz kelompok yang lebih besar Jika anda ingin menggunakan 64 imej dalam kelompok kecil, jika saiz kelompok melebihi 8, "ralat memori CUDA..." akan dilaporkan. Dalam kes ini, anda boleh menggunakan 8 kelompok imej dan mengemas kini pemberat sekali selepas model memproses 64/8 = 8 kelompok. Jika anda mengumpul kecerunan daripada setiap 8 kelompok ini, hasilnya akan (hampir) sama dan latihan boleh dilakukan!
Rutin:
Gelung latihan standard tanpa pengumpulan kecerunan biasanya:
Dalam PyTorch, pengumpulan kecerunan boleh dilakukan dengan mudah. Selepas model melengkapkan pemprosesan kumpulan mini menggunakan accumulation_steps, pengoptimuman boleh dilakukan. Accumulation_steps juga boleh digunakan untuk membahagikan running loss mengikut sifat fungsi loss:
Cantik betul kan ? Kecerunan dikira apabila loss.backward() dipanggil dan dikumpul oleh PyTorch sehingga ia dihentikan apabila optimizer.zero_grad() dipanggil.
Mata Utama
Sesetengah seni bina rangkaian menggunakan operasi kelompok khusus, mis menggunakan saiz kumpulan yang sama, hasilnya mungkin sedikit berbeza.
Gambaran Keseluruhan
Latihan ketepatan campuran merujuk kepada menukar beberapa atau semua parameter FP32 kepada format yang lebih kecil seperti FP16, TF16 (tensor titik terapung) atau BF16 (bait titik terapung) ).
Kelebihan Utama
Kelebihan utama latihan ketepatan campuran ialah:
Rutin:
Akibatnya, selepas melengkapkan operasi .half(), model menjadi 2 kali lebih kecil. Kehilangan skala selepas menukar model kepada format yang berbeza (iaitu BF16, TF16) akan dibincangkan dalam artikel seterusnya. Sesetengah operasi tidak dapat diselesaikan dalam FP16, seperti Softmax. PyTorch boleh menggunakan torch.autocast untuk mengendalikan kes khas ini.
Menambah saiz model ialah cara yang berkesan untuk mendapatkan prestasi yang lebih baik. Walau bagaimanapun, melatih model besar memerlukan penyimpanan model, kecerunan dan keadaan pengoptimum (cth., jumlah licin eksponen Adam dan jumlah kuasa dua kecerunan sebelumnya), yang kesemuanya disimpan dalam jumlah memori yang tersedia terhad.
Turunkan taraf pengoptimum 32-bit kepada pengoptimum 8-bit, mengurangkan julat nilai daripada 2³² kepada hanya 2⁸=256, yang akan menjejaskan pengoptimuman terpelihara Jumlah memori membuat perbezaan yang besar.
Penyelidik telah mencadangkan pengoptimum Adam 8-bit baharu asal dalam ingatan".
Pengoptimum 8-bit mempunyai tiga komponen: (1) Pengkuantitian peringkat blok, yang mengasingkan outlier dan mengedarkan ralat secara sama rata kepada setiap bit; Pengkuantitian dinamik untuk mengukur nilai kecil dan besar dengan ketepatan yang tinggi; (3) Lapisan benam yang stabil untuk meningkatkan kestabilan model pengoptimuman pembenaman perkataan.
Dengan komponen ini, pengoptimuman boleh dilakukan terus menggunakan keadaan 8-bit. Kuantiti keadaan pengoptimuman 8-bit kepada 32 bit, lakukan kemas kini, dan kemudian kuantikan keadaan kepada 8 bit untuk penyimpanan. Penukaran 8-bit kepada 32-bit dilakukan mengikut elemen dalam daftar tanpa memerlukan salinan perlahan ke memori GPU atau memori sementara tambahan untuk melakukan pengkuantitian dan penyahkuansian. Untuk GPU, ini bermakna bahawa pengoptimum 8-bit adalah lebih pantas daripada pengoptimum 32-bit biasa.
Mari kita lihat hasil yang memberi inspirasi selepas menggunakan Adam 8-bit:
Seperti yang anda lihat, menggunakan Adam terkuantisasi menjimatkan kira-kira 8.5 GB memori GPU, yang kelihatan sangat hebat!
Setelah memahami kebolehgunaannya, mari kita lihat cara melaksanakannya dengan python.
Pakej Bitsandbytes yang disediakan oleh Facebook ialah pembalut ringan di sekeliling fungsi tersuai CUDA, merangkum fungsi pengoptimuman dan pengkuantitian 8-bit, menggunakannya Penggunaan 8- sedikit Adam dapat disedari.
Rutin:
Seperti yang dinyatakan di atas, pengoptimum terkuantisasi sangat mudah digunakan dan hasilnya bagus.
Berdasarkan semua kaedah di atas, perhalusi GPT-2-XL pada GPU.
Akhir sekali, selepas menguasai kaedah di atas, gunakan kaedah ini untuk menyelesaikan masalah praktikal dan memperhalusi model GPT-2-XL dengan 1.5 bilion parameter. Nampaknya tiada cara untuk memuatkannya ke GPU NVIDIA GeForce RTX 3060 dengan 12 GB RAM. Senaraikan semua kaedah yang boleh digunakan:
Selepas menggunakan semua kaedah di atas, penalaan halus model 16GB GPT-2-XL telah dilaksanakan pada GPU, yang menakjubkan!
Kesimpulan
Atas ialah kandungan terperinci Cara memperhalusi model yang sangat besar dengan sumber GPU yang terhad. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!