Rumah  >  Artikel  >  Peranti teknologi  >  Llama3 yang mengoyak tangan lapisan 1: Melaksanakan llama3 dari awal

Llama3 yang mengoyak tangan lapisan 1: Melaksanakan llama3 dari awal

WBOY
WBOYasal
2024-06-01 17:45:42976semak imbas

1. Senibina Llama3

Dalam siri artikel ini, kami melaksanakan llama3 dari awal.

Seni bina keseluruhan Llama3:

手撕Llama3第1层: 从零开始实现llama3Gambar

Parameter model Llama3:

Mari kita lihat nilai sebenar parameter ini dalam model LlaMa 3.

手撕Llama3第1层: 从零开始实现llama3Pictures

[1] Tetingkap konteks (tetingkap konteks)

Apabila membuat instance kelas LlaMa, pembolehubah max_seq_len mentakrifkan tetingkap konteks. Terdapat parameter lain dalam kelas, tetapi parameter ini paling berkaitan secara langsung dengan model pengubah. Maks_seq_len di sini ialah 8K.

手撕Llama3第1层: 从零开始实现llama3Gambar

[2] Saiz perbendaharaan kata dan Lapisan Perhatian

Kelas Transformer ialah model yang mentakrifkan perbendaharaan kata dan bilangan lapisan. Perbendaharaan kata di sini merujuk kepada set perkataan (dan token) yang model dapat mengenali dan memproses. Lapisan perhatian merujuk kepada blok pengubah (gabungan lapisan perhatian dan suapan ke hadapan) yang digunakan dalam model.

手撕Llama3第1层: 从零开始实现llama3Gambar

Mengikut nombor ini, LlaMa 3 mempunyai perbendaharaan kata 128K, yang agak besar. Tambahan pula, ia mempunyai 32 blok pengubah.

[3] Dimensi ciri dan ketua perhatian

Dimensi ciri dan ketua perhatian diperkenalkan ke dalam modul Perhatian Kendiri. Dimensi ciri merujuk kepada saiz vektor token dalam ruang benam (dimensi ciri merujuk kepada saiz dimensi data input atau vektor benam), manakala kepala perhatian termasuk modul QK yang memacu mekanisme perhatian kendiri dalam transformer.

手撕Llama3第1层: 从零开始实现llama3Gambar

[4] Dimensi Tersembunyi

Dimensi tersembunyi merujuk kepada saiz dimensi lapisan tersembunyi dalam rangkaian neural suapan hadapan (Feed Forward). Rangkaian saraf suapan hadapan biasanya mengandungi satu atau lebih lapisan tersembunyi, dan dimensi lapisan tersembunyi ini menentukan kapasiti dan kerumitan rangkaian. Dalam model Transformer, dimensi lapisan tersembunyi rangkaian saraf suapan hadapan biasanya merupakan gandaan dimensi ciri untuk meningkatkan keupayaan perwakilan model. Dalam LLama3, dimensi tersembunyi ialah 1.3 kali dimensi ciri. Perlu diingatkan bahawa lapisan tersembunyi dan dimensi tersembunyi adalah dua konsep.

Bilangan lapisan tersembunyi yang lebih tinggi membolehkan rangkaian membuat dan memanipulasi perwakilan yang lebih kaya secara dalaman sebelum menayangkannya semula ke dalam dimensi output yang lebih kecil.

手撕Llama3第1层: 从零开始实现llama3Picture

[5] Gabungkan parameter di atas ke dalam Transformer

Matriks pertama ialah matriks ciri input, yang diproses oleh lapisan Attention untuk menjana ciri Attention Weighted. Dalam imej ini, matriks ciri input hanya bersaiz 5 x 3, tetapi dalam model Llama 3 sebenar ia berkembang kepada 8K x 4096, yang sangat besar.

Seterusnya ialah lapisan tersembunyi dalam Rangkaian Feed-Forward, berkembang kepada 5325 dan kemudian turun semula kepada 4096 pada lapisan terakhir.

手撕Llama3第1层: 从零开始实现llama3Gambar

[6] Pelbagai lapisan blok Transformer

LlaMa 3 menggabungkan 32 blok transformer di atas, dan output dihantar dari satu blok ke blok seterusnya sehingga ia mencapai yang terakhir. .

手撕Llama3第1层: 从零开始实现llama3Gambar

Langkah 1: Mula-mula kita mempunyai matriks input kita dengan saiz 8K (tetingkap konteks) x 128K (saiz perbendaharaan kata). Matriks ini menjalani proses pembenaman untuk menukar matriks berdimensi tinggi ini kepada matriks berdimensi rendah.

Langkah 2: Dalam kes ini, hasil dimensi rendah ini menjadi 4096, iaitu dimensi yang ditentukan bagi ciri dalam model LlaMa yang kita lihat sebelum ini.

Dalam rangkaian saraf, peningkatan dimensi dan pengurangan dimensi adalah operasi biasa, dan setiap satu mempunyai tujuan dan kesan yang berbeza.

Peningkatan dimensi biasanya untuk meningkatkan kapasiti model supaya dapat menangkap ciri dan corak yang lebih kompleks. Apabila data input dipetakan ke dalam ruang dimensi yang lebih tinggi, kombinasi ciri yang berbeza boleh dibezakan dengan lebih mudah oleh model. Ini amat berguna apabila menangani masalah bukan linear, kerana ia boleh membantu model mempelajari sempadan keputusan yang lebih kompleks.

Pengurangan dimensi adalah untuk mengurangkan kerumitan model dan risiko overfitting. Dengan mengurangkan dimensi ruang ciri, model boleh dipaksa untuk mempelajari perwakilan ciri yang lebih halus dan umum. Di samping itu, pengurangan dimensi boleh digunakan sebagai kaedah regularisasi untuk membantu meningkatkan keupayaan generalisasi model. Dalam sesetengah kes, pengurangan dimensi juga boleh mengurangkan kos pengiraan dan meningkatkan kecekapan operasi model.

Dalam aplikasi praktikal, strategi peningkatan dimensi dan kemudian pengurangan dimensi boleh dianggap sebagai proses pengekstrakan dan transformasi ciri. Dalam proses ini, model mula-mula meneroka struktur intrinsik data dengan meningkatkan dimensi, dan kemudian mengekstrak ciri dan corak yang paling berguna dengan mengurangkan dimensi. Pendekatan ini boleh membantu model mengelakkan pemasangan berlebihan pada data latihan sambil mengekalkan kerumitan yang mencukupi.

Langkah 3: Ciri ini diproses melalui blok Transformer, pertama oleh lapisan Attention, dan kemudian oleh lapisan FFN. Lapisan Perhatian memproses merentas ciri secara mendatar, manakala lapisan FFN memproses merentas dimensi secara menegak.

Langkah 4: Langkah 3 diulang untuk 32 lapisan blok Transformer. Akhir sekali, dimensi matriks yang terhasil adalah sama seperti yang digunakan untuk dimensi ciri.

Langkah 5: Akhir sekali, matriks ini ditukar kembali kepada saiz matriks perbendaharaan kata asal, iaitu 128K, supaya model boleh memilih dan memetakan perkataan yang terdapat dalam perbendaharaan kata.

Beginilah cara LlaMa 3 mendapat markah tinggi pada penanda aras tersebut dan mencipta kesan LlaMa 3.

Kami akan meringkaskan beberapa istilah yang mudah dikelirukan dalam bahasa ringkas:

1 max_seq_len (panjang jujukan maksimum)

Ini ialah bilangan maksimum token yang boleh diterima oleh model dalam satu pemprosesan.

Dalam model LlaMa 3-8B, parameter ini ditetapkan kepada 8,000 token, iaitu, Saiz Tetingkap Konteks = 8K. Ini bermakna bilangan maksimum token yang boleh dipertimbangkan oleh model dalam satu pemprosesan ialah 8,000. Ini penting untuk memahami teks panjang atau mengekalkan konteks perbualan jangka panjang.

2. Saiz perbendaharaan kata

Ini ialah bilangan semua token berbeza yang boleh dikenali oleh model. Ini termasuk semua kemungkinan perkataan, tanda baca dan aksara khas. Perbendaharaan kata model ialah 128,000, dinyatakan sebagai Saiz Perbendaharaan Kata = 128K. Ini bermakna model itu dapat mengenali dan memproses 128,000 token berbeza, yang merangkumi pelbagai perkataan, tanda baca dan aksara khas.

3. Lapisan Perhatian

Komponen utama dalam model Transformer. Ia bertanggungjawab terutamanya untuk memproses data input dengan mempelajari bahagian mana data input yang paling penting (iaitu token yang "dihadiri"). Model mungkin mempunyai berbilang lapisan sedemikian, masing-masing cuba memahami data input dari perspektif yang berbeza.

Model LlaMa 3-8B mengandungi 32 lapisan pemprosesan, iaitu Bilangan Lapisan = 32. Lapisan ini termasuk berbilang Lapisan Perhatian dan jenis lapisan rangkaian lain, yang setiap satunya memproses dan memahami data input daripada perspektif yang berbeza.

4. Blok Transformer

Mengandungi modul berbilang lapisan berbeza, biasanya termasuk sekurang-kurangnya satu Lapisan Perhatian dan Rangkaian Suapan Hadapan. Model boleh mempunyai berbilang blok transformer Blok ini disambungkan secara berurutan, dan output setiap blok adalah input blok seterusnya. Blok pengubah juga boleh dipanggil lapisan penyahkod.

Dalam konteks model Transformer, biasanya kita mengatakan bahawa model itu mempunyai "32 lapisan", yang boleh bersamaan dengan mengatakan bahawa model itu mempunyai "32 blok Transformer". Setiap blok Transformer biasanya mengandungi lapisan perhatian kendiri dan lapisan rangkaian saraf suapan ke hadapan Kedua-dua sub-lapisan ini bersama-sama membentuk unit pemprosesan lengkap atau "lapisan".

Jadi, apabila kita katakan bahawa model itu mempunyai 32 blok Transformer, kita sebenarnya menerangkan bahawa model itu terdiri daripada 32 unit pemprosesan sedemikian, yang setiap satunya mampu memproses perhatian sendiri dan pemprosesan rangkaian suapan ke hadapan data. Pembentangan ini menekankan struktur hierarki model dan keupayaan pemprosesannya pada setiap peringkat.

Ringkasnya, "32 lapisan" dan "32 blok Transformer" pada asasnya sinonim apabila menerangkan struktur model Transformer Kedua-duanya bermaksud model tersebut mengandungi 32 kitaran pemprosesan data bebas, dan setiap kitaran termasuk perhatian kendiri dan operasi rangkaian Feedforward.

5. Dimensi ciri

Ini ialah dimensi setiap vektor apabila token input diwakili sebagai vektor dalam model.

Setiap token ditukarkan kepada vektor yang mengandungi 4096 ciri dalam model, iaitu, Dimensi ciri = 4096. Dimensi tinggi ini membolehkan model menangkap maklumat semantik yang lebih kaya dan hubungan kontekstual.

6. Attention-Heads

Dalam setiap Lapisan Perhatian, boleh terdapat berbilang Attention-Heads, dan setiap ketua menganalisis data input secara berasingan daripada perspektif yang berbeza.

Setiap Lapisan Perhatian mengandungi 32 Ketua Perhatian bebas, iaitu Bilangan Ketua Perhatian = 32. Ketua ini menganalisis data input daripada aspek yang berbeza dan bersama-sama menyediakan keupayaan analisis data yang lebih komprehensif.

7. Dimensi Tersembunyi

Ini biasanya merujuk kepada lebar lapisan dalam Rangkaian Feed-Forward, iaitu bilangan neuron dalam setiap lapisan. Biasanya, Dimensi Tersembunyi akan lebih besar daripada Dimensi Ciri, yang membolehkan model mencipta perwakilan data yang lebih kaya secara dalaman.

Dalam Rangkaian Feed-Forward, dimensi lapisan tersembunyi ialah 5325, iaitu Dimensi Tersembunyi = 5325. Ini lebih besar daripada dimensi ciri, membolehkan model melaksanakan terjemahan ciri yang lebih mendalam dan pembelajaran antara lapisan dalaman.

Hubungan dan nilai:

Hubungan antara Lapisan Perhatian dan Ketua Perhatian: Setiap Lapisan Perhatian boleh mengandungi berbilang Ketua Perhatian.

Hubungan berangka: Model mungkin mempunyai berbilang blok pengubah, setiap blok mengandungi Lapisan Perhatian dan satu atau lebih lapisan lain. Setiap Lapisan Perhatian mungkin mempunyai berbilang Ketua Perhatian. Dengan cara ini, keseluruhan model melaksanakan pemprosesan data yang kompleks dalam lapisan dan kepala yang berbeza.

Muat turun skrip pautan rasmi model Llama3: https://llama.meta.com/llama-downloads/

2 Lihat model

Kod berikut menunjukkan cara menggunakan perpustakaan tiktoken untuk memuatkan dan menggunakan a. Pengekodan berasaskan Pasangan Byte (BPE) tokenizer. Tokenizer ini direka bentuk untuk memproses data teks, terutamanya untuk digunakan dalam pemprosesan bahasa semula jadi dan model pembelajaran mesin.

Kami memasuki dunia helo dan melihat cara pembahagian perkataan melakukan pembahagian perkataan.

from pathlib import Pathimport tiktokenfrom tiktoken.load import load_tiktoken_bpeimport torchimport jsonimport matplotlib.pyplot as plttokenizer_path = "Meta-Llama-3-8B/tokenizer.model"special_tokens = ["<|begin_of_text|>","<|end_of_text|>","<|reserved_special_token_0|>","<|reserved_special_token_1|>","<|reserved_special_token_2|>","<|reserved_special_token_3|>","<|start_header_id|>","<|end_header_id|>","<|reserved_special_token_4|>","<|eot_id|>",# end of turn] + [f"<|reserved_special_token_{i}|>" for i in range(5, 256 - 5)]mergeable_ranks = load_tiktoken_bpe(tokenizer_path)tokenizer = tiktoken.Encoding(name=Path(tokenizer_path).name,pat_str=r"(?i:'s|'t|'re|'ve|'m|'ll|'d)|[^\r\n\p{L}\p{N}]?\p{L}+|\p{N}{1,3}| ?[^\s\p{L}\p{N}]+[\r\n]*|\s*[\r\n]+|\s+(?!\S)|\s+",mergeable_ranks=mergeable_ranks,special_tokens={token: len(mergeable_ranks) + i for i, token in enumerate(special_tokens)},)tokenizer.decode(tokenizer.encode("hello world!"))

手撕Llama3第1层: 从零开始实现llama3Gambar

Baca fail model


手撕Llama3第1层: 从零开始实现llama3

Lihat nama 20 parameter atau pemberat pertama yang terkandung dalam fail model.

model = torch.load("Meta-Llama-3-8B/consolidated.00.pth")print(json.dumps(list(model.keys())[:20], indent=4))

手撕Llama3第1层: 从零开始实现llama3Pictures

  1. "tok_embeddings.weight": Ini menunjukkan bahawa model mempunyai lapisan pembenaman perkataan yang menukar perkataan input (atau lebih umum, token) kepada vektor dimensi tetap. Ini adalah langkah pertama dalam kebanyakan model pemprosesan bahasa semula jadi.
  2. "layers.0.attention..." dan "layers.1.attention...": Parameter ini mewakili berbilang lapisan, setiap lapisan mengandungi modul mekanisme perhatian. Dalam modul ini, wq, wk, wv, dan wo masing-masing mewakili matriks berat pertanyaan, kunci, nilai dan output. Ini ialah komponen teras model Transformer dan digunakan untuk menangkap hubungan antara bahagian berlainan jujukan input.
  3. "layers.0.feed_forward..." dan "layers.1.feed_forward...": Parameter ini menunjukkan bahawa setiap lapisan juga mengandungi rangkaian suapan hadapan (Rangkaian Feed Forward), yang biasanya terdiri daripada dua transformasi linear , terdapat fungsi pengaktifan tak linear di tengah. w1, w2 dan w3 mungkin mewakili pemberat lapisan linear yang berbeza dalam rangkaian suapan hadapan ini.
  4. "layers.0.attention_norm.weight" dan "layers.1.attention_norm.weight": Parameter ini menunjukkan bahawa terdapat lapisan normalisasi (mungkin Layer Normalization) di belakang modul perhatian dalam setiap lapisan untuk proses latihan penstabilan.
  5. "layers.0.ffn_norm.weight" dan "layers.1.ffn_norm.weight": Parameter ini menunjukkan bahawa terdapat juga lapisan normalisasi di belakang rangkaian feedforward. Kandungan output kod di atas adalah sama seperti gambar di bawah, iaitu blok transformer dalam Llama3.

手撕Llama3第1层: 从零开始实现llama3Pictures

Secara keseluruhannya, output ini mendedahkan komponen utama model pembelajaran mendalam berdasarkan seni bina Transformer. Model ini digunakan secara meluas dalam tugas pemprosesan bahasa semula jadi, seperti klasifikasi teks, terjemahan mesin, sistem menjawab soalan, dsb. Struktur setiap lapisan adalah hampir sama, termasuk mekanisme perhatian, rangkaian suapan ke hadapan dan lapisan normalisasi, yang membantu model menangkap ciri jujukan input yang kompleks.

Lihat konfigurasi parameter model Llama3:

with open("Meta-Llama-3-8B/params.json", "r") as f:config = json.load(f)config

手撕Llama3第1层: 从零开始实现llama3图片

  1. 'dim': 4096 - 表示模型中的隐藏层维度或特征维度。这是模型处理数据时每个向量的大小。
  2. 'n_layers': 32 - 表示模型中层的数量。在基于Transformer的模型中,这通常指的是编码器和解码器中的层的数量。
  3. 'n_heads': 32 - 表示在自注意力(Self-Attention)机制中,头(head)的数量。多头注意力机制是Transformer模型的关键特性之一,它允许模型在不同的表示子空间中并行捕获信息。
  4. 'n_kv_heads': 8 - 这个参数不是标准Transformer模型的常见配置,可能指的是在某些特定的注意力机制中,用于键(Key)和值(Value)的头的数量。
  5. 'vocab_size': 128256 - 表示模型使用的词汇表大小。这是模型能够识别的不同单词或标记的总数。
  6. 'multiple_of': 1024 - 这可能是指模型的某些维度需要是1024的倍数,以确保模型结构的对齐或优化。
  7. 'ffn_dim_multiplier': 1.3 - 表示前馈网络(Feed-Forward Network, FFN)的维度乘数。在Transformer模型中,FFN是每个注意力层后的一个网络,这个乘数可能用于调整FFN的大小。
  8. 'norm_eps': 1e-05 - 表示在归一化层(如Layer Normalization)中使用的epsilon值,用于防止除以零的错误。这是数值稳定性的一个小技巧。
  9. 'rope_theta': 500000.0 - 这个参数不是标准Transformer模型的常见配置,可能是指某种特定于模型的技术或优化的参数。它可能与位置编码或某种正则化技术有关。

我们使用这个配置来推断模型的细节,比如:

  1. 模型有32个Transformer层
  2. 每个多头注意力块有32个头
  3. 词汇表的大小等等 
dim = config["dim"]n_layers = config["n_layers"]n_heads = config["n_heads"]n_kv_heads = config["n_kv_heads"]vocab_size = config["vocab_size"]multiple_of = config["multiple_of"]ffn_dim_multiplier = config["ffn_dim_multiplier"]norm_eps = config["norm_eps"]rope_theta = torch.tensor(config["rope_theta"])

手撕Llama3第1层: 从零开始实现llama3图片

将Text转化为Token

代码如下:

prompt = "the answer to the ultimate question of life, the universe, and everything is "tokens = [128000] + tokenizer.encode(prompt)print(tokens)tokens = torch.tensor(tokens)prompt_split_as_tokens = [tokenizer.decode([token.item()]) for token in tokens]print(prompt_split_as_tokens)

[128000, 1820, 4320, 311, 279, 17139, 3488, 315, 2324, 11, 279, 15861, 11, 323, 4395, 374, 220]['<|begin_of_text|>', 'the', ' answer', ' to', ' the', ' ultimate', ' question', ' of', ' life', ',', ' the', ' universe', ',', ' and', ' everything', ' is', ' ']

将令牌转换为它们的嵌入表示

截止到目前,我们的[17x1]令牌现在变成了[17x4096],即长度为4096的17个嵌入(每个令牌一个)。

下图是为了验证我们输入的这句话,是17个token。

手撕Llama3第1层: 从零开始实现llama3图片

代码如下:

embedding_layer = torch.nn.Embedding(vocab_size, dim)embedding_layer.weight.data.copy_(model["tok_embeddings.weight"])token_embeddings_unnormalized = embedding_layer(tokens).to(torch.bfloat16)token_embeddings_unnormalized.shape

手撕Llama3第1层: 从零开始实现llama3图片

三、构建Transformer的第一层

我们接着使用 RMS 归一化对嵌入进行归一化,也就是图中这个位置:

手撕Llama3第1层: 从零开始实现llama3图片

使用公式如下:

手撕Llama3第1层: 从零开始实现llama3图片

代码如下:

# def rms_norm(tensor, norm_weights):# rms = (tensor.pow(2).mean(-1, keepdim=True) + norm_eps)**0.5# return tensor * (norm_weights / rms)def rms_norm(tensor, norm_weights):return (tensor * torch.rsqrt(tensor.pow(2).mean(-1, keepdim=True) + norm_eps)) * norm_weights

这段代码定义了一个名为 rms_norm 的函数,它实现了对输入张量(tensor)的RMS(Root Mean Square,均方根)归一化处理。这个函数接受两个参数:tensor 和 norm_weights。tensor 是需要进行归一化处理的输入张量,而 norm_weights 是归一化时使用的权重。

函数的工作原理如下:

  1. 首先,计算输入张量每个元素的平方(tensor.pow(2))。
  2. 然后,对平方后的张量沿着最后一个维度(-1)计算均值(mean),并保持维度不变(keepdim=True),这样得到每个元素的均方值。
  3. 接着,将均方值加上一个很小的正数 norm_eps(为了避免除以零的情况),然后计算其平方根的倒数(torch.rsqrt),得到RMS的倒数。
  4. 最后,将输入张量与RMS的倒数相乘,再乘以归一化权重 norm_weights,得到归一化后的张量。

在进行归一化处理后,我们的数据形状仍然保持为 [17x4096],这与嵌入层的形状相同,只不过数据已经过归一化。

token_embeddings = rms_norm(token_embeddings_unnormalized, model["layers.0.attention_norm.weight"])token_embeddings.shape

手撕Llama3第1层: 从零开始实现llama3图片

手撕Llama3第1层: 从零开始实现llama3图片

接下来,我们介绍注意力机制的实现,也就是下图中的红框标注的位置:

手撕Llama3第1层: 从零开始实现llama3图片

手撕Llama3第1层: 从零开始实现llama3图片

我们一步一步地解释这张图,详细说明每个步骤。

1. 输入句子

  • 描述:这是我们的输入句子。
  • 解释:输入句子被表示为一个矩阵 ( X ),其中每一行代表一个词的嵌入向量。

2. 嵌入每个词

  • 描述:我们对每个词进行嵌入。
  • 解释:输入句子中的每个词被转换为一个高维向量,这些向量组成了矩阵 ( X )。

3. 分成8个头

  • 描述:将矩阵 ( X ) 分成8个头。我们用权重矩阵 ( W^Q )、( W^K ) 和 ( W^V ) 分别乘以 ( X )。
  • 解释:多头注意力机制将输入矩阵 ( X ) 分成多个头(这里是8个),每个头有自己的查询(Query)、键(Key)和值(Value)矩阵。具体来说,输入矩阵 ( X ) 分别与查询权重矩阵 ( W^Q )、键权重矩阵 ( W^K ) 和值权重矩阵 ( W^V ) 相乘,得到查询矩阵 ( Q )、键矩阵 ( K ) 和值矩阵 ( V )。

4. 计算注意力

  • 描述:使用得到的查询、键和值矩阵计算注意力。
  • 解释:对于每个头,使用查询矩阵 ( Q )、键矩阵 ( K ) 和值矩阵 ( V ) 计算注意力分数。具体步骤包括:

计算 ( Q ) 和 ( K ) 的点积。

对点积结果进行缩放。

应用softmax函数得到注意力权重。

用注意力权重乘以值矩阵 ( V ) 得到输出矩阵 ( Z )。

5. 拼接结果矩阵

  • 描述:将得到的 ( Z ) 矩阵拼接起来,然后用权重矩阵 ( W^O ) 乘以拼接后的矩阵,得到层的输出。
  • 解释:将所有头的输出矩阵 ( Z ) 拼接成一个矩阵,然后用输出权重矩阵 ( W^O ) 乘以这个拼接后的矩阵,得到最终的输出矩阵 ( Z )。

额外说明

  • 查询、键、值和输出向量的形状:在加载查询、键、值和输出向量时,注意到它们的形状分别是 [4096x4096]、[1024x4096]、[1024x4096]、[1024x4096] 和 [4096x4096]。
  • 并行化注意力头的乘法:将它们捆绑在一起有助于并行化注意力头的乘法。

这张图展示了Transformer模型中多头注意力机制的实现过程,从输入句子的嵌入开始,经过多头分割、注意力计算,最后拼接结果并生成输出。每个步骤都详细说明了如何从输入矩阵 ( X ) 生成最终的输出矩阵 ( Z )。

当我们从模型中加载查询(query)、键(key)、值(value)和输出(output)向量时,我们注意到它们的形状分别是 [4096x4096]、[1024x4096]、[1024x4096]、[4096x4096]

乍一看这很奇怪,因为理想情况下我们希望每个头的每个q、k、v和o都是单独的

print(model["layers.0.attention.wq.weight"].shape,model["layers.0.attention.wk.weight"].shape,model["layers.0.attention.wv.weight"].shape,model["layers.0.attention.wo.weight"].shape)

手撕Llama3第1层: 从零开始实现llama3Gambar

Bentuk matriks berat pertanyaan (wq.weight) ialah [4096, 4096]. Bentuk matriks berat utama (wk.weight) ialah [1024, 4096]. Bentuk matriks berat nilai (wv.weight) ialah [1024, 4096]. Bentuk matriks berat keluaran (Output) (wo.weight) ialah [4096, 4096]. Keputusan output menunjukkan bahawa bentuk matriks berat pertanyaan (Q) dan output (O) adalah sama, kedua-duanya [4096, 4096]. Ini bermakna kedua-dua ciri input dan ciri output mempunyai dimensi 4096 untuk kedua-dua pertanyaan dan output. Bentuk matriks berat kunci (K) dan nilai (V) juga adalah sama, kedua-duanya [1024, 4096]. Ini menunjukkan bahawa dimensi ciri input untuk kunci dan nilai ialah 4096, tetapi dimensi ciri output dimampatkan kepada 1024. Bentuk matriks berat ini mencerminkan cara pereka model menetapkan dimensi bahagian berlainan mekanisme perhatian. Khususnya, dimensi kekunci dan nilai dikurangkan mungkin untuk mengurangkan kerumitan pengiraan dan penggunaan memori, sementara mengekalkan pertanyaan dan output dalam dimensi yang lebih tinggi mungkin untuk mengekalkan lebih banyak maklumat. Pilihan reka bentuk ini bergantung pada seni bina model tertentu dan senario aplikasi
Mari kita gunakan ayat "Saya mengagumi Li Hongzhang" sebagai contoh untuk memudahkan proses pelaksanaan menerangkan mekanisme perhatian dalam rajah ini. Masukkan ayat: Pertama, kita mempunyai ayat "Saya mengagumi Li Hongzhang". Sebelum memproses ayat ini, kita perlu menukar setiap perkataan dalam ayat tersebut ke dalam bentuk yang boleh diproses secara matematik, iaitu vektor perkataan. Proses ini dipanggil penyisipan perkataan.
Pembenaman perkataan: Setiap perkataan, seperti "Saya", "penghargaan", "Li Hongzhang", akan ditukar menjadi vektor bersaiz tetap. Vektor ini mengandungi maklumat semantik perkataan.
Pecah kepada beberapa kepala: Untuk model memahami ayat dari perspektif yang berbeza, kami membahagikan vektor setiap perkataan kepada beberapa bahagian, berikut ialah 8 kepala. Setiap kepala memberi tumpuan kepada aspek ayat yang berbeza.
Kira perhatian: Untuk setiap kepala, kami mengira sesuatu yang dipanggil perhatian. Proses ini melibatkan tiga langkah: Ambil "Saya menghargai Li Hongzhang" sebagai contoh Jika kita ingin memberi tumpuan kepada perkataan "penghargaan", maka "penghargaan" adalah pertanyaan, dan perkataan lain seperti "Saya" dan "Li Hongzhang". adalah kunci. Vektor ialah nilai.
Pertanyaan (S): Ini adalah bahagian di mana kita ingin mencari maklumat. Kunci (K): Ini adalah bahagian yang mengandungi maklumat. Nilai (V): Ini ialah kandungan maklumat sebenar. Penyambungan dan keluaran: Selepas mengira perhatian setiap kepala, kami menggabungkan keputusan ini dan menjana keluaran akhir melalui matriks berat Wo. Output ini akan digunakan dalam lapisan pemprosesan seterusnya atau sebagai sebahagian daripada hasil akhir.

Masalah bentuk yang dinyatakan dalam ulasan pada rajah adalah tentang cara menyimpan dan memproses vektor ini dengan cekap dalam komputer. Dalam pelaksanaan kod sebenar, untuk meningkatkan kecekapan, pembangun boleh membungkus pertanyaan, kunci dan vektor nilai berbilang pengepala bersama-sama dan bukannya memproses setiap pengepala secara individu. Ini boleh mengambil kesempatan daripada keupayaan pemprosesan selari komputer moden untuk mempercepatkan pengiraan.

  • Bentuk matriks berat pertanyaan (wq.weight) ialah [4096, 4096].
  • Bentuk matriks berat utama (wk.weight) ialah [1024, 4096]. Bentuk
  • matriks berat nilai (wv.weight) ialah [1024, 4096].
  • Bentuk matriks berat keluaran (Output) (wo.weight) ialah [4096, 4096].

Hasil keluaran menunjukkan bahawa:

  • Bentuk matriks berat pertanyaan (Q) dan output (O) adalah sama, kedua-duanya [4096, 4096]. Ini bermakna kedua-dua ciri input dan ciri output mempunyai dimensi 4096 untuk kedua-dua pertanyaan dan output.
  • Bentuk matriks berat kunci (K) dan nilai (V) juga adalah sama, kedua-duanya [1024, 4096]. Ini menunjukkan bahawa dimensi ciri input untuk kunci dan nilai ialah 4096, tetapi dimensi ciri output dimampatkan kepada 1024.

Bentuk matriks berat ini mencerminkan cara pereka model menetapkan dimensi bahagian berlainan mekanisme perhatian. Khususnya, dimensi kekunci dan nilai dikurangkan mungkin untuk mengurangkan kerumitan pengiraan dan penggunaan memori, sementara mengekalkan pertanyaan dan output dalam dimensi yang lebih tinggi mungkin untuk mengekalkan lebih banyak maklumat. Pilihan reka bentuk ini bergantung pada seni bina model tertentu dan senario aplikasi

Mari kita gunakan ayat "Saya mengagumi Li Hongzhang" sebagai contoh untuk memudahkan proses pelaksanaan menerangkan mekanisme perhatian dalam rajah ini.

  • Masukkan ayat: Pertama, kita ada ayat "Saya mengagumi Li Hongzhang". Sebelum memproses ayat ini, kita perlu menukar setiap perkataan dalam ayat tersebut ke dalam bentuk yang boleh diproses secara matematik, iaitu vektor perkataan. Proses ini dipanggil penyisipan perkataan.
  • Pembenaman perkataan: Setiap perkataan, seperti "Saya", "penghargaan", "Li Hongzhang", akan ditukar menjadi vektor bersaiz tetap. Vektor ini mengandungi maklumat semantik perkataan.
  • Pisah kepada berbilang kepala: Untuk membolehkan model memahami ayat dari perspektif yang berbeza, kami membahagikan vektor setiap perkataan kepada beberapa bahagian, berikut ialah 8 kepala. Setiap kepala memberi tumpuan kepada aspek ayat yang berbeza.
  • Kira perhatian: Untuk setiap kepala, kami mengira sesuatu yang dipanggil perhatian. Proses ini melibatkan tiga langkah: Ambil "Saya menghargai Li Hongzhang" sebagai contoh Jika kita ingin memberi tumpuan kepada perkataan "penghargaan", maka "penghargaan" adalah pertanyaan, dan perkataan lain seperti "Saya" dan "Li Hongzhang". adalah kunci. Vektor ialah nilai.

Pertanyaan (S): Ini adalah bahagian di mana kita ingin mencari maklumat.

Kunci (K): Ini adalah bahagian yang mengandungi maklumat.

Nilai (V): Ini ialah kandungan maklumat sebenar.

  • Penyambungan dan keluaran: Selepas mengira perhatian setiap kepala, kami menggabungkan keputusan ini bersama-sama dan menjana output akhir melalui matriks berat Wo. Output ini akan digunakan dalam lapisan pemprosesan seterusnya atau sebagai sebahagian daripada hasil akhir.

Masalah bentuk yang dinyatakan dalam ulasan pada rajah adalah tentang cara menyimpan dan memproses vektor ini dengan cekap dalam komputer. Dalam pelaksanaan kod sebenar, untuk meningkatkan kecekapan, pembangun boleh membungkus pertanyaan, kunci dan vektor nilai berbilang pengepala bersama-sama dan bukannya memproses setiap pengepala secara individu. Ini boleh mengambil kesempatan daripada keupayaan pemprosesan selari komputer moden untuk mempercepatkan pengiraan.

Kami terus menggunakan ayat "Saya menghargai Li Hongzhang" untuk menerangkan peranan matriks berat WQ, WK, WV dan WO.

Dalam model Transformer, setiap perkataan ditukarkan kepada vektor melalui pembenaman perkataan. Vektor ini kemudiannya melalui satu siri transformasi linear untuk mengira skor perhatian. Transformasi linear ini dilaksanakan melalui matriks berat WQ, WK, WV dan WO.

  1. WQ (matriks berat Q): Matriks ini digunakan untuk menukar vektor setiap perkataan menjadi vektor "pertanyaan". Dalam contoh kami, jika kami ingin menumpukan pada perkataan "penghargaan", kami akan mendarabkan vektor "penghargaan" dengan WQ untuk mendapatkan vektor pertanyaan.
  2. WK (matriks berat K): Matriks ini digunakan untuk menukar vektor setiap perkataan menjadi vektor "Kunci". Begitu juga, kami akan mendarabkan vektor setiap perkataan, termasuk "I" dan "Li Hongzhang", dengan WK untuk mendapatkan vektor kunci.
  3. WV (matriks berat V): Matriks ini digunakan untuk menukar vektor setiap perkataan menjadi vektor "nilai". Selepas mendarab setiap vektor perkataan dengan WV, kita mendapat vektor nilai. Ketiga-tiga matriks ini (WQ, WK, WV) digunakan untuk menjana pertanyaan, kunci dan vektor nilai yang berbeza untuk setiap pengepala. Melakukan ini membolehkan setiap kepala menumpukan pada aspek ayat yang berbeza.
  4. WQ (matriks berat Q), WK (matriks berat K), WV (matriks berat V) dan WO (matriks berat O) adalah parameter dalam model Transformer proses. Ia dipelajari daripada kaedah pengoptimuman seperti penurunan kecerunan.

Dalam keseluruhan proses, WQ, WK, WV dan WO dipelajari melalui latihan Mereka menentukan cara model menukar vektor perkataan input kepada perwakilan yang berbeza, dan cara menggabungkan perwakilan ini untuk mendapatkan output akhir. Matriks ini adalah bahagian teras mekanisme perhatian dalam model Transformer, dan ia membolehkan model menangkap hubungan antara perkataan yang berbeza dalam ayat.

WQ (matriks berat Q), WK (matriks berat K), WV (matriks berat V) dan WO (matriks berat O). . Ia dipelajari daripada kaedah pengoptimuman seperti algoritma dan keturunan kecerunan.

Mari kita lihat bagaimana proses pembelajaran ini berfungsi:

  1. 初始化:在训练开始之前,这些矩阵通常会被随机初始化。这意味着它们的初始值是随机选取的,这样可以打破对称性并开始学习过程。
  2. 前向传播:在模型的训练过程中,输入数据(如句子“我欣赏李鸿章”)会通过模型的各个层进行前向传播。在注意力机制中,输入的词向量会与WQ、WK、WV矩阵相乘,以生成查询、键和值向量。
  3. 计算损失:模型的输出会与期望的输出(通常是训练数据中的标签)进行比较,计算出一个损失值。这个损失值衡量了模型的预测与实际情况的差距。
  4. 反向传播:损失值会通过反向传播算法传回模型,计算每个参数(包括WQ、WK、WV和WO)对损失的影响,即它们的梯度。
  5. 参数更新:根据计算出的梯度,使用梯度下降或其他优化算法来更新这些矩阵的值。这个过程会逐渐减小损失值,使模型的预测更加准确。
  6. 迭代过程:这个前向传播、损失计算、反向传播和参数更新的过程会在训练数据上多次迭代进行,直到模型的性能达到一定的标准或者不再显著提升。

    通过这个训练过程,WQ、WK、WV和WO这些矩阵会逐渐调整它们的值,以便模型能够更好地理解和处理输入数据。在训练完成后,这些矩阵将固定下来,用于模型的推理阶段,即对新的输入数据进行预测。

四、展开查询向量

在本小节中,我们将从多个注意力头中展开查询向量,得到的形状是 [32x128x4096] 这里,32 是 llama3 中注意力头的数量,128 是查询向量的大小,而 4096 是令牌嵌入的大小。

q_layer0 = model["layers.0.attention.wq.weight"]head_dim = q_layer0.shape[0] // n_headsq_layer0 = q_layer0.view(n_heads, head_dim, dim)q_layer0.shape

手撕Llama3第1层: 从零开始实现llama3图片

这段代码通过对模型中第一层的查询(Q)权重矩阵进行重塑(reshape),将其分解为多个注意力头的形式,从而揭示了32和128这两个维度。

  1. q_layer0 = model["layers.0.attention.wq.weight"]:这行代码从模型中提取第一层的查询(Q)权重矩阵。
  2. head_dim = q_layer0.shape[0] // n_heads:这行代码计算每个注意力头的维度大小。它通过将查询权重矩阵的第一个维度(原本是4096)除以注意力头的数量(n_heads),得到每个头的维度。如果n_heads是32(即模型设计为有32个注意力头),那么head_dim就是4096 // 32 = 128。
  3. q_layer0 = q_layer0.view(n_heads, head_dim, dim):这行代码使用.view()方法重塑查询权重矩阵,使其形状变为[n_heads, head_dim, dim]。这里dim很可能是原始特征维度4096,n_heads是32,head_dim是128,因此重塑后的形状是[32, 128, 4096]。
  4. q_layer0.shape 输出:torch.Size([32, 128, 4096]):这行代码打印重塑后的查询权重矩阵的形状,确认了其形状为[32, 128, 4096]。

之所以在这段代码中出现了32和128这两个维度,而在之前的代码段中没有,是因为这段代码通过重塑操作明确地将查询权重矩阵分解为多个注意力头,每个头具有自己的维度。32代表了模型中注意力头的数量,而128代表了分配给每个头的特征维度大小。这种分解是为了实现多头注意力机制,其中每个头可以独立地关注输入的不同部分,最终通过组合这些头的输出来提高模型的表达能力。 

实现第一层的第一个头

访问了第一层第一个头的查询(query)权重矩阵,这个查询权重矩阵的大小是 [128x4096]。

q_layer0_head0 = q_layer0[0]q_layer0_head0.shape

手撕Llama3第1层: 从零开始实现llama3图片

我们现在将查询权重与令牌嵌入相乘,以获得令牌的查询

在这里,你可以看到结果形状是 [17x128],这是因为我们有17个令牌,每个令牌都有一个长度为128的查询(每个令牌在一个头上方的查询)。

br

手撕Llama3第1层: 从零开始实现llama3Picture

Kod ini menjalankan operasi pendaraban matriks, membandingkan pembenaman token (token_embeddings) dengan transpose (.T) matriks berat pertanyaan (q_layer0_head0) kepala pertama lapisan pertama Darab untuk menjana per -vektor pertanyaan token (q_per_token).

  1. q_per_token = torch.matmul(token_embeddings, q_layer0_head0.T):

torch.matmul ialah fungsi pendaraban matriks dalam PyTorch, yang boleh mengendalikan pendaraban dua tensor.

token_embeddings hendaklah berupa tensor bentuk [17, 4096], mewakili 17 token, setiap satu diwakili oleh vektor benam 4096 dimensi.

q_layer0_head0 ialah matriks berat pertanyaan bagi kepala pertama lapisan pertama dan bentuk asalnya ialah [128, 4096]. .T ialah operasi transpose dalam PyTorch, yang menukar bentuk q_layer0_head0 kepada [4096, 128].

Dengan cara ini, pendaraban matriks token_embeddings dan q_layer0_head0.T ialah pendaraban bagi [17, 4096] dan [4096, 128], dan hasilnya ialah tensor dengan bentuk [17, 128].

  1. q_per_token.shape dan output: torch.Size([17, 128]):

Baris kod ini mencetak bentuk q_per_token tensor, mengesahkan bahawa ia adalah [17, 128].

Ini bermakna untuk setiap token yang dimasukkan (17 kesemuanya), kami kini mempunyai vektor pertanyaan 128 dimensi. Vektor pertanyaan 128 dimensi ini diperoleh dengan mendarab pembenaman token dan matriks berat pertanyaan dan boleh digunakan untuk pengiraan mekanisme perhatian seterusnya.

Ringkasnya, kod ini menukarkan vektor pembenaman setiap token kepada vektor pertanyaan melalui pendaraban matriks, menyediakan untuk langkah seterusnya melaksanakan mekanisme perhatian. Setiap token kini mempunyai vektor pertanyaan yang sepadan dengannya, dan vektor pertanyaan ini akan digunakan untuk mengira skor perhatian dengan token lain.

Atas ialah kandungan terperinci Llama3 yang mengoyak tangan lapisan 1: Melaksanakan llama3 dari awal. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn