Pasukan PyTorch secara peribadi mengajar anda cara mempercepatkan inferens model besar.
Pada tahun lalu, AI generatif telah berkembang pesat Antaranya, penjanaan teks sentiasa menjadi bidang yang sangat popular seperti llama.cpp, vLLM, MLC-LLM, dsb untuk mencapai hasil yang lebih baik, pengoptimuman berterusan sedang dijalankan. Sebagai salah satu rangka kerja paling popular dalam komuniti pembelajaran mesin, PyTorch secara semula jadi telah merebut peluang baharu ini dan terus mengoptimumkannya. Untuk membolehkan semua orang memahami dengan lebih baik inovasi ini, pasukan PyTorch telah menyediakan satu siri blog khas untuk memfokuskan pada cara menggunakan PyTorch asli tulen untuk mempercepatkan model AI generatif.
Alamat kod: https://github.com/pytorch-labs/gpt-fast Mari lihat keputusan dahulu Pasukan menulis semula LLM dan kelajuan inferens adalah 10 kali lebih pantas daripada garis dasar tanpa kehilangan ketepatan, menggunakan kurang daripada 1000 baris kod PyTorch asli!
Semua penanda aras dijalankan pada A100-80GB, kuasa terhad kepada 330W. Pengoptimuman ini termasuk:
- Torch.compile: Penyusun model PyTorch, PyTorch 2.0 menambah satu fungsi pengkompil baris baharu yang dipanggil () torch.compile yang mana can.compile yang sedia ada. model;
- GPU kuantisasi: mempercepatkan model dengan mengurangkan ketepatan pengiraan
- Penyahkodan Spekulatif: kaedah pecutan inferens model besar yang menggunakan model "draf" kecil untuk meramalkan "model" yang besar ;
- Tensor Selari: Mempercepatkan inferens model dengan menjalankan model pada berbilang peranti.
Seterusnya, mari lihat bagaimana setiap langkah dilaksanakan. 6 langkah untuk mempercepatkan inferens model besarKajian menunjukkan bahawa sebelum pengoptimuman, prestasi inferens model besar ialah 25.5 tok/s, yang tidak begitu baik: Selepas beberapa penerokaan, akhirnya saya menemui sebabnya: overhed CPU yang berlebihan. Kemudian terdapat proses pengoptimuman 6 langkah berikut.
Langkah 1: Kurangkan overhed CPU dengan Torch.compile dan cache KV statik untuk mencapai 107.0 TOK/S
torch.compile membenarkan pengguna untuk menangkap satu kawasan yang lebih besar ke dalam satu rantau yang lebih besar. ="reduce-overhead" (rujuk kod di bawah), fungsi ini sangat berkesan dalam mengurangkan overhead CPU Selain itu, artikel ini juga menyatakan fullgraph=True untuk mengesahkan bahawa tiada "gangguan graf" dalam model ( Iaitu. , bahagian yang torch.compile tidak boleh compile). Namun, walaupun dengan restu obor.compile, masih terdapat beberapa halangan.
Halangan pertama ialah cache kv. Iaitu, apabila pengguna menjana lebih banyak token, "panjang logik" cache kv akan berkembang. Masalah ini berlaku kerana dua sebab: pertama, adalah sangat mahal untuk mengagihkan semula (dan menyalin) cache kv setiap kali cache berkembang kedua, peruntukan dinamik ini menjadikannya lebih sukar untuk mengurangkan overhed.
Untuk menyelesaikan masalah ini, artikel ini menggunakan cache KV statik, memperuntukkan saiz cache KV secara statik, dan kemudian menutup nilai yang tidak digunakan dalam mekanisme perhatian. Halangan kedua ialah peringkat praisi. Penjanaan teks dengan Transformer boleh dilihat sebagai proses dua peringkat: 1. Peringkat praisi untuk memproses keseluruhan gesaan 2. Nyahkod token.Walaupun cache kv ditetapkan menjadi statik, disebabkan kepanjangan pembolehubah gesaan, Peringkat praisi masih memerlukan lebih banyak dinamik. Oleh itu, strategi kompilasi yang berasingan perlu digunakan untuk menyusun kedua-dua peringkat ini.
Walaupun butiran ini agak rumit, ia tidak sukar untuk dilaksanakan dan peningkatan prestasi adalah besar. Selepas operasi ini, prestasi meningkat lebih daripada 4 kali ganda, daripada 25 tok/s kepada 107 tok/s.
Langkah 2: Kurangkan kesesakan lebar jalur memori melalui kuantiti berat int8 dan capai 157.4 tok/sMelalui perkara di atas, kita telah melihat kesan yang dibawa oleh torch.com, cache, static. dll. Pecutan yang besar, tetapi pasukan PyTorch tidak berpuas hati dengan ini, dan mereka menemui sudut lain untuk pengoptimuman. Mereka percaya bahawa kesesakan terbesar dalam mempercepatkan latihan AI generatif ialah kos memuatkan pemberat daripada memori global GPU ke dalam daftar. Dalam erti kata lain, setiap hantaran hadapan perlu "menyentuh" setiap parameter pada GPU. Jadi, seberapa pantas kita secara teori boleh "mengakses" setiap parameter dalam model?
Untuk mengukur ini, artikel ini menggunakan Model Bandwidth Utilization (MBU), mengiranya adalah sangat mudah seperti berikut:
Sebagai contoh, untuk model parameter 7B, setiap parameter disimpan dalam In fp16 (2 bait setiap parameter), 107 token/s boleh dicapai. A100-80GB mempunyai lebar jalur memori teori 2 TB/s. Seperti yang ditunjukkan dalam rajah di bawah, dengan meletakkan formula di atas ke dalam nilai tertentu, anda boleh mendapat MBU sebanyak 72%! Keputusan ini agak baik, kerana banyak kajian mengalami kesukaran menembusi 85%.
Tetapi pasukan PyTorch juga ingin meningkatkan nilai ini. Mereka mendapati bahawa mereka tidak boleh menukar bilangan parameter dalam model, mahupun lebar jalur memori GPU. Tetapi mereka mendapati bahawa mereka boleh menukar bilangan bait yang disimpan untuk setiap parameter!
Jadi, mereka akan menggunakan kuantiti int8.
Sila ambil perhatian bahawa ini hanyalah pemberat terkuantisasi, pengiraan itu sendiri masih dilakukan dalam bf16. Tambahan pula, dengan torch.compile, adalah mudah untuk menjana kod yang cekap untuk pengkuantitian int8.
Seperti yang ditunjukkan dalam rajah di atas, ia boleh dilihat dari garis biru tua (torch.compile + int8) bahawa apabila menggunakan kuantiti berat torch.compile + int8 sahaja, prestasinya meningkat dengan ketara. Menggunakan pengkuantitian int8 pada model Llama-7B meningkatkan prestasi kira-kira 50% kepada 157.4 token/s. . dimuatkan Kadar kedua.
Walaupun beratnya dikuantisasi, memuatkan berat berulang kali tidak dapat dielakkan. Bagaimana untuk menyelesaikan masalah ini? Ternyata dengan memanfaatkan penyahkodan spekulatif boleh memecahkan pergantungan bersiri yang ketat ini dan meningkatkan kelajuan.
Kajian ini menggunakan model draf untuk menjana 8 token, dan kemudian menggunakan model pengesah untuk memprosesnya secara selari, membuang token yang tidak sepadan. Proses ini memecahkan kebergantungan bersiri. Keseluruhan pelaksanaan mengambil kira-kira 50 baris kod PyTorch asli. . untuk berkurangan.
Untuk menyelesaikan masalah ini, artikel ini menggunakan dua teknik untuk menyelesaikannya: yang pertama ialah mempunyai faktor penskalaan yang lebih halus; yang lain ialah menggunakan strategi pengkuantitian yang lebih maju. Menggabungkan operasi ini bersama-sama, kami mendapat yang berikut: Langkah 5: Menggabungkan segala-galanya bersama-sama, kami mendapat 244.7 tok/s
Akhir sekali, menggabungkan semua teknik 2 bersama-sama.4.2. /s.
Langkah Enam: Tensor Parallelism Setakat ini artikel ini adalah mengenai meminimumkan kependaman pada satu GPU. Malah, ia juga mungkin untuk menggunakan berbilang GPU, supaya kependaman akan dipertingkatkan lagi.
Syukurlah, pasukan PyTorch menyediakan alatan tahap rendah untuk selari tensor yang hanya memerlukan 150 baris kod dan tidak memerlukan sebarang perubahan model.
Semua pengoptimuman yang dinyatakan sebelum ini boleh terus digabungkan dengan keselarian tensor, yang bersama-sama menyediakan kuantisasi int8 untuk model Llama-70B pada 55 token/s.
Akhir sekali, rumuskan secara ringkas isi utama artikel. Pada Llama-7B, artikel ini menggunakan gabungan "kompilasi + kuantiti int4 + penyahkodan spekulatif" untuk mencapai 240+ tok/s. Pada Llama-70B, kertas kerja ini juga memperkenalkan keselarian tensor untuk mencapai kira-kira 80 tok/s, yang hampir dengan atau melebihi prestasi SOTA.
Pautan asal: https://pytorch.org/blog/accelerating-generative-ai-2/Atas ialah kandungan terperinci Dengan kurang daripada 1,000 baris kod, pasukan PyTorch membuat Llama 7B 10 kali lebih pantas. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!