Rumah >Peranti teknologi >AI >Cara Memangkas Llama 3.2 dan Model Bahasa Besar yang Sama
Saiz model besar terus meningkatkan prestasi, tetapi permintaan untuk model yang lebih efisien dan padat juga berkembang. Walau bagaimanapun, mengurangkan saiz model tanpa kehilangan fungsi teras adalah tugas yang kompleks.
Teknik -teknik seperti kuantisasi dan pemangkasan sering digunakan untuk mengurangkan saiz model, manakala kaedah seperti penyulingan pengetahuan atau pemindahan pembelajaran membantu mengekalkan atau memulihkan fungsi yang hilang semasa proses pengurangan.
di antara mereka, pemangkasan adalah salah satu strategi yang paling berkesan untuk mengurangkan saiz model. Tidak seperti kuantisasi perwakilan berangka yang mudah, pemangkasan melibatkan membuang bahagian tertentu model, seperti neuron atau keseluruhan lapisan. Tetapi keberkesanan ini datang dengan kos: pemangkasan sukar untuk digunakan dengan betul. Bukan sahaja anda perlu menentukan bahagian model yang akan dipangkas, tetapi anda juga perlu memilih elemen dengan teliti untuk dikeluarkan untuk meminimumkan kesan ke atas keupayaan model.
Apakah pemangkasan dan bagaimana ia mempengaruhi model?
Cabaran utama pemangkasan adalah untuk menentukan bahagian mana model yang akan dikeluarkan. Tidak semua bahagian model mempunyai kesan yang sama pada prestasi;
Untuk menggambarkan ini, mari kita periksa struktur model yang digunakan dalam artikel ini: llama 3.2-1b.
<code>LlamaForCausalLM( (model): LlamaModel( (embed_tokens): Embedding(128256, 2048) (layers): ModuleList( (0-15): 16 x LlamaDecoderLayer( (self_attn): LlamaSdpaAttention( (q_proj): Linear(in_features=2048, out_features=2048, bias=False) (k_proj): Linear(in_features=2048, out_features=512, bias=False) (v_proj): Linear(in_features=2048, out_features=512, bias=False) (o_proj): Linear(in_features=2048, out_features=2048, bias=False) (rotary_emb): LlamaRotaryEmbedding() ) (mlp): LlamaMLP( (gate_proj): Linear(in_features=2048, out_features=8192, bias=False) (up_proj): Linear(in_features=2048, out_features=8192, bias=False) (down_proj): Linear(in_features=8192, out_features=2048, bias=False) (act_fn): SiLU() ) (input_layernorm): LlamaRMSNorm((2048,), eps=1e-05) (post_attention_layernorm): LlamaRMSNorm((2048,), eps=1e-05) ) ) (norm): LlamaRMSNorm((2048,), eps=1e-05) (rotary_emb): LlamaRotaryEmbedding() ) (lm_head): Linear(in_features=2048, out_features=128256, bias=False) )</code>Apabila memeriksa struktur, kita dapat mengenal pasti tiga modul utama yang boleh digunakan sebagai sasaran pemangkasan: embedding, mekanisme perhatian diri, dan lapisan MLP. Untuk menentukan bahagian mana yang harus menjadi tumpuan proses pemangkasan, adalah perlu untuk memahami potensi manfaat dan kesan yang mungkin.
Langkah pertama adalah untuk menilai saiz ruang bahagian -bahagian ini menduduki model untuk memahami potensi pengurangan.
Analisis pengedaran parameter
lapisan embed dan output (embed_tokens, lm_head):
mekanisme perhatian diri (self_attn):
lapisan MLP (MLP):
kita dapat melihat bahawa lapisan MLP menduduki lebih daripada 50% daripada saiz model, jadi mereka adalah calon pemangkasan yang jelas. Walau bagaimanapun, adalah penting untuk memahami sumbangan setiap bahagian kepada tingkah laku model sebelum membuat keputusan ini.
Lapisan embing bertanggungjawab untuk menukar input ke dalam perwakilan vektor padat yang modelnya dapat diproses dengan berkesan. Lapisan embedding pemangkasan boleh menyebabkan model kehilangan keupayaan untuk memahami kata -kata tertentu, atau sekurang -kurangnya mengurangkan keupayaan untuk membuat vektor yang betul menangkap makna semantik input. Sebagai contoh, jika anda ingin membuat model yang sangat spesifik yang hanya menggunakan bahagian -bahagian yang sangat spesifik dari perbendaharaan kata inputnya (contohnya, model untuk analisis kewangan atau perubatan), pemangkasan lapisan ini mungkin menjadi pilihan.
Mekanisme Perhatian membolehkan model memberi tumpuan kepada bahagian -bahagian yang paling relevan dari urutan input apabila memproses setiap penanda. Ia mengira skor kepentingan berwajaran antara setiap pasangan penanda dalam urutan input, yang membolehkan model menangkap konteks dan memberi tumpuan kepada maklumat yang relevan. Pemangkasan Bahagian ini mengurangkan keupayaan model untuk melaksanakan tugas yang memerlukan pemahaman yang luas tentang konteks input, seperti ringkasan teks atau terjemahan. Ia juga mempengaruhi konsistensi teks yang dihasilkan.
Lapisan MLP bersama -sama dengan mekanisme perhatian, meningkatkan keupayaan model untuk memahami corak kompleks melalui satu siri pengembangan dan penguncupan data. Pemangkasan Bahagian ini mengehadkan tindak balas model terhadap tugas -tugas yang tidak dilihat atau tidak dilindungi semasa latihan. Dalam erti kata lain, ia mengurangkan keupayaan generalisasi model dan keupayaannya untuk memberikan respons yang koheren kepada input yang tidak dikenali.
Sebaik sahaja anda memutuskan bahagian mana yang anda ingin sasarkan, langkah seterusnya adalah untuk menentukan sama ada untuk melakukan pemangkasan lebar (mengeluarkan neuron tunggal) atau pemangkasan kedalaman (mengeluarkan keseluruhan lapisan).
Seperti yang anda lihat, model pemangkasan adalah proses yang agak kompleks yang melibatkan banyak keputusan. Anda bukan sahaja harus menilai keupayaan model yang dihasilkan, tetapi juga keupayaan latihannya. Model-model ini direka untuk disesuaikan dengan baik dan sering digunakan untuk tugas-tugas tertentu, jadi mereka lebih cekap untuk tugas-tugas tertentu yang mencipta mereka daripada model yang mendasari.
Arkitek unit linear (GLU) yang dilancarkan biasanya digunakan dalam rangkaian saraf moden, termasuk Llama, Gemma, Mistral, Qwen dan model bahasa besar yang serupa. Glu memperkenalkan mekanisme gating unsur-oleh yang membolehkan model menapis dan mengawal aliran maklumat secara selektif. Senibina ini terdiri daripada pasangan lapisan, biasanya: GATE_PROJ, UP_PROJ, dan DOWN_PROJ (seperti yang ditunjukkan dalam struktur model yang ditunjukkan di atas), yang berfungsi bersama untuk mengembangkan dan mengecilkan data.
Mekanisme ini membolehkan model mengendalikan corak yang lebih kompleks sambil mengekalkan kecekapan. Walau bagaimanapun, ini juga bermakna bahawa lapisan dalam struktur Glu digabungkan dengan ketat dan pemangkasan lapisan ini memerlukan pertimbangan yang teliti.
Sebarang operasi pada lapisan (mis., Mengeluarkan neuron) mesti ditunjukkan dalam lapisan berpasangan yang sepadan. Sebagai contoh, jika anda mengeluarkan neuron dari _gate proj , anda mesti mengeluarkan neuron yang sama dari up_proj dan _down proj lapisan mesti diubah suai dengan sewajarnya. Paling penting, apabila mengira kepentingan neuron untuk menentukan neuron mana yang dikekalkan, pasangan neuron perlu dinilai bersama.
memusnahkan keseimbangan lapisan ini boleh menyebabkan kemerosotan prestasi dan bahkan model itu benar -benar tidak sah, walaupun hanya sebilangan kecil neuron dikeluarkan.
Contohnya akan ditunjukkan menggunakan model Llama, tetapi kod itu juga telah berjaya diuji pada model Gemma dan Qwen.
anda boleh mengakses kod penuh dalam asas kod github saya.
GitHub-Peremartra/bahasa besar-model-notebook-course: Kursus praktikal pada bahasa besar ...
Langkah pertama yang saya lakukan dengan model asal dalam ingatan adalah untuk melaksanakan sedikit petikan dan menyimpan hasilnya. Ini membolehkan saya dengan mudah, intuitif dan cepat memeriksa sama ada model yang dihasilkan melalui proses pemangkasan adalah koheren atau, sebaliknya, kehilangan keupayaan untuk menghasilkan teks yang boleh difahami.
Saya dapat memberi jaminan kepada anda bahawa dalam percubaan pertama saya, teks yang dihasilkan sudah pasti menunjukkan kecacatan asas dalam proses pemangkasan kerana kegagalan untuk mematuhi struktur Glu model.
Prompt asal ialah: "Paris adalah modal ...". Mari kita lihat tindak balas model asal dan bandingkan dengan respons yang dikembalikan oleh percubaan pemangkasan pertama saya.
Model Asas:
"Paris adalah ibu kota Perancis dan salah satu bandar yang paling banyak dikunjungi di dunia. Ia adalah ibu kota seni, budaya, fesyen dan makanan. Bandar ini mempunyai sejarah yang kaya dan merupakan rumah bagi banyak mercu tanda terkenal, termasuk ... ... "
Pemangkasan hanya 20% daripada model yang salah:
"Paris adalah ibukota Perancis. Ini adalah kawasan utama .... ini adalah bandar ... Perancis ..."Jelas sekali, sesuatu tidak berfungsi dalam percubaan pertama. Ini mungkin kelihatan remeh, tetapi pemeriksaan pengalaman seperti ini dapat menjimatkan banyak masa.
Butiran pelaksanaan
<code>LlamaForCausalLM( (model): LlamaModel( (embed_tokens): Embedding(128256, 2048) (layers): ModuleList( (0-15): 16 x LlamaDecoderLayer( (self_attn): LlamaSdpaAttention( (q_proj): Linear(in_features=2048, out_features=2048, bias=False) (k_proj): Linear(in_features=2048, out_features=512, bias=False) (v_proj): Linear(in_features=2048, out_features=512, bias=False) (o_proj): Linear(in_features=2048, out_features=2048, bias=False) (rotary_emb): LlamaRotaryEmbedding() ) (mlp): LlamaMLP( (gate_proj): Linear(in_features=2048, out_features=8192, bias=False) (up_proj): Linear(in_features=2048, out_features=8192, bias=False) (down_proj): Linear(in_features=8192, out_features=2048, bias=False) (act_fn): SiLU() ) (input_layernorm): LlamaRMSNorm((2048,), eps=1e-05) (post_attention_layernorm): LlamaRMSNorm((2048,), eps=1e-05) ) ) (norm): LlamaRMSNorm((2048,), eps=1e-05) (rotary_emb): LlamaRotaryEmbedding() ) (lm_head): Linear(in_features=2048, out_features=128256, bias=False) )</code>Fungsi ini menerima berat lapisan _gate
proj lapisan dan _up proj lapisan, dan seperti yang saya jelaskan, mereka bekerja secara berpasangan. Oleh itu, kepentingan neuron mesti dikira dalam kombinasi.
Pengiraan adalah sangat mudah: ia mengira nilai mutlak berat setiap neuron. Kedua -dua nilai positif dan negatif diambil kira, kerana dalam teori, neuron dengan nilai yang paling melampau mempunyai kesan yang lebih besar terhadap output model dengan mengubah nilai -nilai yang ketara melalui mereka.di sini, saya mesti mengucapkan terima kasih kepada Mariusz Kurman atas sumbangannya untuk memasukkan nilai minimum ke dalam pengiraan. Walaupun kaedah ini berfungsi dengan baik tanpa mereka, termasuk mereka dapat meningkatkan hasilnya.
Kepentingan setiap lapisan dikira secara berasingan, tetapi fungsi mengembalikan nilai gabungan.
<code>LlamaForCausalLM( (model): LlamaModel( (embed_tokens): Embedding(128256, 2048) (layers): ModuleList( (0-15): 16 x LlamaDecoderLayer( (self_attn): LlamaSdpaAttention( (q_proj): Linear(in_features=2048, out_features=2048, bias=False) (k_proj): Linear(in_features=2048, out_features=512, bias=False) (v_proj): Linear(in_features=2048, out_features=512, bias=False) (o_proj): Linear(in_features=2048, out_features=2048, bias=False) (rotary_emb): LlamaRotaryEmbedding() ) (mlp): LlamaMLP( (gate_proj): Linear(in_features=2048, out_features=8192, bias=False) (up_proj): Linear(in_features=2048, out_features=8192, bias=False) (down_proj): Linear(in_features=8192, out_features=2048, bias=False) (act_fn): SiLU() ) (input_layernorm): LlamaRMSNorm((2048,), eps=1e-05) (post_attention_layernorm): LlamaRMSNorm((2048,), eps=1e-05) ) ) (norm): LlamaRMSNorm((2048,), eps=1e-05) (rotary_emb): LlamaRotaryEmbedding() ) (lm_head): Linear(in_features=2048, out_features=128256, bias=False) )</code>
Fungsi ini menghasilkan lapisan baru yang lebih kecil sambil mengekalkan neuron yang paling penting. Proses ini merangkumi:
<code>def compute_neuron_pair_importance(gate_weight, up_weight): """ 计算神经元对重要性分数(最大绝对权重) 参数: - gate_weight:来自 gate_proj 层的权重矩阵。 - up_weight:来自 up_weight 层的权重矩阵。 返回: - importance_scores:每个神经元对的重要性分数。 """ gate_max_abs = torch.max(gate_weight, dim=1).values + torch.abs(torch.min(gate_weight, dim=1).values) up_max_abs = torch.max(up_weight, dim=1).values + torch.abs(torch.min(up_weight, dim=1).values) importance_scores = gate_max_abs + up_max_abs return importance_scores</code>
<code>def prune_neuron_pairs(mlp, prune_percent): """ 减少**gate_proj**、**up_proj**、**down_proj**层的维度,移除不太重要的神经元。 参数: - mlp:要剪枝的层。 - prune_percent:要剪枝的神经元的百分比。 返回: - new_gate_proj, new_up_proj, new_down_proj:新的剪枝层。 - k:新的中间大小。 """ # 从 MLP 层提取权重 gate_weight = mlp.gate_proj.weight.data.float() up_weight = mlp.up_proj.weight.data.float() # 计算重要性分数 importance_scores = compute_neuron_pair_importance(gate_weight, up_weight) original_intermediate_size = gate_weight.size(0) # 计算要保留的神经元 num_neuron_pairs_to_prune = min(int(prune_percent * original_intermediate_size), original_intermediate_size - 1) k = original_intermediate_size - num_neuron_pairs_to_prune # 验证检查 if k < 1: raise ValueError("k must be greater than 0") # 选择要保留的神经元 _, indices_to_keep = torch.topk(importance_scores, k, largest=True, sorted=True) indices_to_keep = indices_to_keep.sort().values # 创建并填充新层 new_gate_proj = nn.Linear(mlp.gate_proj.in_features, k, bias=False).to(device) new_up_proj = nn.Linear(mlp.up_proj.in_features, k, bias=False).to(device) new_down_proj = nn.Linear(k, mlp.down_proj.out_features, bias=False).to(device) # 将选定的权重复制到新层。 new_gate_proj.weight.data = mlp.gate_proj.weight.data[indices_to_keep, :] new_up_proj.weight.data = mlp.up_proj.weight.data[indices_to_keep, :] new_down_proj.weight.data = mlp.down_proj.weight.data[:, indices_to_keep] return new_gate_proj, new_up_proj, new_down_proj, k</code>
Dapatkan tensor yang mengandungi skor kepentingan yang dikira untuk setiap neuron. Skor ini mencerminkan sumbangan setiap neuron kepada output akhir, yang menunjukkan neuron mana yang harus dikekalkan.
<code># 从 MLP 层提取权重 gate_weight = mlp.gate_proj.weight.data.float() up_weight = mlp.up_proj.weight.data.float()</code>
Gunakan peratusan pemangkasan yang disediakan sebagai parameter dan saiz asal lapisan yang akan dipelihara untuk mengira jumlah neuron yang akan dikekalkan.
<code># 计算重要性分数 importance_scores = compute_neuron_pair_importance(gate_weight, up_weight) original_intermediate_size = gate_weight.size(0)</code>
Obor digunakan untuk mengambil neuron dengan skor penting yang paling tinggi, sementara juga meletakkannya dari yang paling penting kepada perintah yang paling tidak penting. Oleh kerana obor mengembalikan data dalam urutan menurun, ia disusun semula dalam urutan menaik menggunakan kaedah jenis, iaitu apa yang kita perlukan.
<code># 计算要保留的神经元 num_neuron_pairs_to_prune = min(int(prune_percent * original_intermediate_size), original_intermediate_size - 1) k = original_intermediate_size - num_neuron_pairs_to_prune</code>
Buat tiga lapisan baru yang dimensi diselaraskan mengikut indeks yang dipilih. Dalam _new_gate proj dan _new_up proj , dimensi input dipelihara semasa dimensi output dikurangkan. Sebaliknya, dalam _new_down proj , dimensi input diselaraskan manakala dimensi output tetap sama.
<code># 选择要保留的神经元 _, indices_to_keep = torch.topk(importance_scores, k, largest=True, sorted=True) indices_to_keep = indices_to_keep.sort().values</code>
Berat yang relevan dipindahkan dari lapisan asal ke lapisan baru, memastikan bahawa hanya berat yang sepadan dengan neuron yang dipilih dikekalkan.
Sekarang, mari kita lihat fungsi yang bertanggungjawab untuk melelehkan semua lapisan dan membina model yang diubah suai.
<code># 创建并填充新层 new_gate_proj = nn.Linear(mlp.gate_proj.in_features, k, bias=False).to(device) new_up_proj = nn.Linear(mlp.up_proj.in_features, k, bias=False).to(device) new_down_proj = nn.Linear(k, mlp.down_proj.out_features, bias=False).to(device)</code>
Fungsi ini melangkah ke atas setiap lapisan model, menggunakan proses pemangkasan dan mengemas kini konfigurasi model untuk mencerminkan seni bina baru.
Jika fail konfigurasi tidak dikemas kini, model tidak boleh digunakan selepas menyimpan, sama ada pada muka memeluk atau tempatan. Ramai perpustakaan (seperti memeluk Transformers Face) bergantung pada model.config untuk menerangkan seni bina model. Sekiranya konfigurasi tidak sepadan dengan struktur sebenar, penalaan halus atau operasi kesimpulan yang dilakukan melalui perpustakaan ini mungkin gagal.
Menggunakan kod ini, saya mencipta beberapa model yang boleh didapati di Hub Face Hugging.
Ini termasuk:
Anda boleh memuat turun model -model ini, dan sebagai tambahan untuk menggunakannya, anda juga boleh mengkaji seni bina mereka dan perubahan yang telah berlaku berbanding dengan model asal yang berdasarkannya.
Marilah kita menganalisis perubahan seni bina selepas menggunakan model Llama3.2-1b kepada pemangkasan 20%.
<code># 将选定的权重复制到新层。 new_gate_proj.weight.data = mlp.gate_proj.weight.data[indices_to_keep, :] new_up_proj.weight.data = mlp.up_proj.weight.data[indices_to_keep, :] new_down_proj.weight.data = mlp.down_proj.weight.data[:, indices_to_keep]</code>
Struktur model tetap tidak berubah kecuali saiz lapisan pertengahan di blok MLP. Seperti yang dapat anda lihat, _gate proj dan _up proj
Perubahan ini sama persis dengan fungsi kod: Ubah suai lapisan ini sambil mengekalkan neuron yang penting untuk prestasi model. Jika kita mengeluarkan 20% daripada 8192, kita akan mendapat 6553.6, yang mengesahkan bahawa bahagian neuron yang betul telah dipangkas.
Sekarang, mari kita lihat bagaimana model yang dipangkas dilakukan dalam ujian ujian:
Paris adalah ibu kota Perancis. Ia juga merupakan salah satu bandar paling indah di dunia. Terdapat begitu banyak perkara yang patut dilihat dan dialami di Paris bahawa mustahil untuk melindungi mereka semua dalam satu hari. Tetapi, ada beberapa perkara ...
Tanggapan tidak sama seperti tindak balas model asal, tetapi ia mengekalkan koheren. Ini menunjukkan bahawa model mengekalkan kebanyakan keupayaannya, dan yang lebih penting, ia dapat memulihkan sebarang kerugian melalui penyulingan pengetahuan atau fine-penuning .
Di samping pemeriksaan empirikal ini, saya juga menilai model menggunakan beberapa tanda aras yang paling biasa. Mari kita menganalisis bagaimana tahap pemangkasan yang berbeza mempengaruhi prestasi model.
Seperti yang telah kita lihat, kesan pemangkasan agak tidak simetris. Ujian Boolq menilai tugas itu tidak mengalami penurunan yang ketara, dan untuk model yang kehilangan 40% neuron dalam lapisan MLP, ia menurun hanya kira -kira 2%.
Sebaliknya, kesan terhadap ujian lambada sangat penting, dengan penurunan ketepatan lebih daripada 50%.
Ini menunjukkan bahawa model mengekalkan kebanyakan pemahamannya tetapi sukar untuk ditangani dalam ujian yang memerlukan lebih banyak generasi terbuka.
Boolq hanya membentangkan teks dan soalan yang perlu dijawab dengan ya/tidak kepada model. Ini adalah ujian yang memberi tumpuan kepada mengukur keupayaan model untuk memahami hubungan dalam teks input.
memeluk muka terbuka llm ranking
Dalam carta ini, kita dapat melihat hasil kedua -dua model.
Dengan mengkaji carta ini, kita dapat membuat kesimpulan berikut: Prestasi purata model selepas pemangkasan adalah lebih baik daripada model asas (4.86 vs 4.03) . Ini menunjukkan bahawa proses pemangkasan secara berkesan mengekalkan atau meningkatkan prestasi dalam bidang utama sambil mengurangkan redundansi.
Kelebihan:
Kekurangan:
Kecekapan tenaga : Model yang dipangkas mempunyai kecekapan tenaga yang lebih tinggi (0.4 kg vs 0.42 kg CO₂), yang selaras dengan matlamat mengurangkan overhead pengiraan sambil mengekalkan prestasi yang kompetitif.
Kajian yang lebih komprehensif mengenai prestasi model dalam ranking yang berbeza diperlukan, tetapi hasil ini menunjukkan bahawa kita mempunyai model yang menjanjikan yang dapat diperbaiki dengan ketara dengan penyulingan pengetahuan yang tepat atau penalaan halus. Paling penting, keputusan ini selaras dengan proses pemangkasan yang dilakukan pada lapisan MLP.Kesimpulan
adalah penting untuk diperhatikan bahawa keputusan ujian diperolehi dengan melaksanakan proses pemulihan keupayaan (mis.
Penyulingan pengetahuan atau Fine-Tuning ) sebelum model pemangkasan, ini biasanya dilakukan pada model yang dipangkas . Kerja Masa Depan Terdapat banyak teknik pemangkasan yang patut diterokai. Mungkin perkara yang paling langsung adalah pemangkasan kedalaman, yang melibatkan penghapusan lapisan yang menyumbang paling sedikit kepada prestasi model.
Satu lagi bidang penyelidikan yang penting ialah proses penyulingan pengetahuan model -model yang dipangkas ini dan menilai sama ada mereka mengekalkan keupayaan untuk mempelajari tugas -tugas baru. Ini boleh membawa prestasi mereka lebih dekat kepada model asas, terutamanya dalam tanda aras di mana model yang dipangkas menunjukkan kerugian maksimum.Artikel ini adalah sebahagian daripada kursus lengkap pada model bahasa yang besar dan boleh didapati di GitHub. Untuk mengetahui tentang kemas kini artikel baru, pertimbangkan untuk mengikuti asas kod atau dibintangi.
Dengan cara ini, anda akan diberitahu apabila menambah kandungan baru.Saya adalah pengarang buku "Projek Model Bahasa Grand: Aplikasi dan Pelaksanaan Strategi Model Bahasa Besar" yang diterbitkan oleh Apress Publishing House.
Saya menulis secara teratur tentang AI generatif, pembelajaran mendalam, dan tensorflow. Sila pertimbangkan untuk mengikuti akaun saya di Sederhana untuk kemas kini mengenai artikel baru. Sudah tentu, anda dialu -alukan untuk menghubungi saya di LinkedIn.
Atas ialah kandungan terperinci Cara Memangkas Llama 3.2 dan Model Bahasa Besar yang Sama. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!