이 기사 시리즈에서는 llama3를 처음부터 구현합니다.
Llama3의 전체 아키텍처:
그림
Llama3의 모델 매개변수:
LlaMa 3 모델에서 이러한 매개변수의 실제 값을 살펴보겠습니다.
Pictures
LlaMa 클래스를 인스턴스화할 때 max_seq_len 변수는 컨텍스트 창을 정의합니다. 클래스에는 다른 매개변수도 있지만 이 매개변수는 변환기 모델과 가장 직접적으로 관련됩니다. 여기서 max_seq_len은 8K입니다.
Pictures
Transformer 클래스는 어휘와 레이어 수를 정의하는 모델입니다. 여기서 어휘는 모델이 인식하고 처리할 수 있는 단어(및 토큰) 세트를 나타냅니다. Attention 레이어는 모델에 사용된 변환기 블록(attention 및 피드포워드 레이어의 조합)을 나타냅니다.
Pictures
이 숫자에 따르면 LlaMa 3의 어휘는 128K로 상당히 많습니다. 또한 32개의 변압기 블록이 있습니다.
[3] 기능 차원 및 Attention 헤드
Feature 차원 및 Attention 헤드가 Self-Attention 모듈에 도입되었습니다. 특징 차원은 임베딩 공간에 있는 토큰의 벡터 크기를 나타내며(특징 차원은 입력 데이터 또는 임베딩 벡터의 차원 크기를 나타냄) Attention-heads에는 변환기에서 self-attention 메커니즘을 구동하는 QK 모듈이 포함됩니다.
Pictures
Hidden Dimensions은 피드포워드 신경망(Feed Forward)에서 히든 레이어의 차원 크기를 말합니다. 피드포워드 신경망에는 일반적으로 하나 이상의 숨겨진 레이어가 포함되며 이러한 숨겨진 레이어의 크기에 따라 네트워크의 용량과 복잡성이 결정됩니다. Transformer 모델에서 피드포워드 신경망의 은닉층 차원은 일반적으로 모델의 표현 능력을 높이기 위해 특징 차원의 배수입니다. LLama3에서 숨겨진 차원은 기능 차원의 1.3배입니다. 은닉층과 은닉차원은 두 가지 개념이라는 점에 유의해야 합니다.
숨겨진 레이어 수가 많을수록 네트워크는 더 작은 출력 크기로 다시 투영하기 전에 더 풍부한 표현을 내부적으로 생성하고 조작할 수 있습니다.
Picture
첫 번째 행렬은 Attention Weighted 특성을 생성하기 위해 Attention 레이어에서 처리되는 입력 특성 행렬입니다. 이 이미지에서 입력 특성 행렬의 크기는 5 x 3에 불과하지만 실제 Llama 3 모델에서는 8K x 4096으로 커져 엄청납니다.
다음은 피드포워드 네트워크의 숨겨진 레이어로, 마지막 레이어에서 5325까지 성장했다가 다시 4096으로 감소합니다.
Pictures
LlaMa 3은 위의 32개의 변압기 블록을 결합하고 출력은 마지막 블록에 도달할 때까지 한 블록에서 다음 블록으로 전달됩니다.
Pictures
위의 모든 부분이 시작되면 이제 이 부분들을 하나로 모아서 LlaMa 효과가 어떻게 만들어지는지 살펴보겠습니다.
Pictures
1단계: 먼저 크기가 8K(컨텍스트 창) x 128K(어휘 크기)인 입력 행렬이 있습니다. 이 행렬은 고차원 행렬을 저차원 행렬로 변환하기 위해 임베딩 과정을 거칩니다.
2단계: 이 경우 이 저차원 결과는 4096이 됩니다. 이는 앞서 본 LlaMa 모델의 특징에 대한 지정된 차원입니다.
신경망에서는 차원 강화와 차원 축소가 일반적인 작업이며 각각 다른 목적과 효과를 가지고 있습니다.
차원성 강화는 일반적으로 더 복잡한 특징과 패턴을 포착할 수 있도록 모델의 용량을 늘리기 위해 수행됩니다. 입력 데이터가 더 높은 차원 공간에 매핑되면 모델에서 다양한 기능 조합을 더 쉽게 구분할 수 있습니다. 이는 모델이 더 복잡한 결정 경계를 학습하는 데 도움이 되므로 비선형 문제를 처리할 때 특히 유용합니다.
차원성 감소는 모델의 복잡성과 과적합 위험을 줄이는 것입니다. 특징 공간의 차원을 줄임으로써 모델은 더 세련되고 일반화된 특징 표현을 학습하도록 강제할 수 있습니다. 또한, 차원 축소는 모델의 일반화 능력을 향상시키는 데 도움이 되는 정규화 방법으로 사용될 수 있습니다. 경우에 따라 차원 축소는 계산 비용을 줄이고 모델 운영 효율성을 향상시킬 수도 있습니다.
실제 응용에서는 차원 증가 전략과 차원 축소 전략을 특징 추출 및 변환 과정으로 간주할 수 있습니다. 이 과정에서 모델은 먼저 차원을 높여 데이터의 본질적인 구조를 탐색한 다음 차원을 줄여 가장 유용한 특징과 패턴을 추출합니다. 이 접근 방식은 모델이 충분한 복잡성을 유지하면서 훈련 데이터에 대한 과적합을 방지하는 데 도움이 될 수 있습니다.
3단계: 이 기능은 Transformer 블록을 통해 먼저 Attention 레이어, 그 다음 FFN 레이어에서 처리됩니다. Attention 레이어는 수평으로 기능을 처리하는 반면, FFN 레이어는 수직으로 차원을 처리합니다.
4단계: 트랜스포머 블록의 32개 레이어에 대해 3단계가 반복됩니다. 마지막으로 결과 행렬의 차원은 특징 차원에 사용된 차원과 동일합니다.
5단계: 마지막으로 이 행렬은 원래 어휘 행렬 크기인 128K로 다시 변환되므로 모델은 어휘에서 사용 가능한 단어를 선택하고 매핑할 수 있습니다.
이것이 LlaMa 3가 해당 벤치마크에서 높은 점수를 얻고 LlaMa 3 효과를 생성하는 방법입니다.
쉽게 혼동하기 쉬운 몇 가지 용어를 간략하게 요약하겠습니다.
이것은 모델이 단일 처리에서 허용할 수 있는 최대 토큰 수입니다.
LlaMa 3-8B 모델에서는 이 매개변수가 8,000 토큰, 즉 Context Window Size = 8K로 설정됩니다. 이는 모델이 단일 처리에서 고려할 수 있는 최대 토큰 수가 8,000개임을 의미합니다. 이는 긴 텍스트를 이해하거나 장기적인 대화의 맥락을 유지하는 데 중요합니다.
모델이 인식할 수 있는 다양한 토큰의 개수입니다. 여기에는 가능한 모든 단어, 구두점 및 특수 문자가 포함됩니다. 모델의 어휘는 128,000개이며 어휘 크기 = 128K로 표현됩니다. 이는 모델이 다양한 단어, 문장 부호 및 특수 문자를 포함하는 128,000개의 다양한 토큰을 인식하고 처리할 수 있음을 의미합니다.
Transformer 모델의 주요 구성 요소입니다. 입력 데이터의 어느 부분이 가장 중요한지(즉, 어떤 토큰이 "참석"되는지) 학습하여 입력 데이터 처리를 주로 담당합니다. 모델에는 이러한 레이어가 여러 개 있을 수 있으며, 각 레이어는 서로 다른 관점에서 입력 데이터를 이해하려고 합니다.
LlaMa 3-8B 모델에는 32개의 처리 레이어가 포함되어 있습니다. 즉, 레이어 수 = 32입니다. 이러한 계층에는 여러 주의 계층과 기타 유형의 네트워크 계층이 포함되며, 각 계층은 서로 다른 관점에서 입력 데이터를 처리하고 이해합니다.
일반적으로 하나 이상의 주의 계층과 피드포워드 네트워크를 포함하는 다양한 계층의 모듈을 포함합니다. 모델에는 여러 개의 변압기 블록이 있을 수 있습니다. 이러한 블록은 순차적으로 연결되며 각 블록의 출력은 다음 블록의 입력이 됩니다. 트랜스포머 블록은 디코더 레이어라고도 불릴 수 있습니다.
Transformer 모델의 맥락에서 일반적으로 모델에 "32개의 레이어"가 있다고 말합니다. 이는 모델에 "32개의 Transformer 블록"이 있다고 말하는 것과 동일할 수 있습니다. 각 Transformer 블록은 일반적으로 self-attention 계층과 피드포워드 신경망 계층을 포함합니다. 이 두 하위 계층은 함께 완전한 처리 단위 또는 "계층"을 형성합니다.
따라서 모델에 32개의 Transformer 블록이 있다고 말할 때 실제로는 모델이 32개의 처리 장치로 구성되어 있으며 각 처리 장치는 셀프 어텐션 처리 및 데이터 피드포워드 네트워크 처리가 가능하다는 것을 설명하는 것입니다. 이 프레젠테이션에서는 모델의 계층 구조와 각 수준에서의 처리 기능을 강조합니다.
요약하자면, "32개 레이어"와 "32개 변환기 블록"은 Transformer 모델 구조를 설명할 때 기본적으로 동의어입니다. 둘 다 모델에 self-attention 및 Feedforward 네트워크 작업이 포함된 32개의 독립적인 데이터 처리 주기가 포함되어 있음을 의미합니다.
모델에서 입력 토큰을 벡터로 표현했을 때 각 벡터의 차원입니다.
각 토큰은 모델의 4096개 특징을 포함하는 벡터, 즉 Feature-dimension = 4096으로 변환됩니다. 이러한 높은 차원을 통해 모델은 보다 풍부한 의미 정보와 상황별 관계를 포착할 수 있습니다.
각 Attention-Heads에는 여러 개의 Attention-Heads가 있을 수 있으며, 각 헤드는 서로 다른 관점에서 입력 데이터를 독립적으로 분석합니다.
각 주의 레이어에는 32개의 독립적인 주의 헤드가 포함되어 있습니다. 즉, 주의 헤드 수 = 32입니다. 이러한 헤드는 다양한 측면에서 입력 데이터를 분석하고 보다 포괄적인 데이터 분석 기능을 공동으로 제공합니다.
이것은 일반적으로 피드포워드 네트워크의 레이어 너비, 즉 각 레이어의 뉴런 수를 나타냅니다. 일반적으로 숨겨진 차원은 기능 차원보다 크므로 모델이 내부적으로 더 풍부한 데이터 표현을 생성할 수 있습니다.
피드포워드 네트워크에서 히든 레이어의 차원은 5325, 즉 히든 차원 = 5325입니다. 이는 기능 차원보다 크므로 모델이 내부 레이어 간에 더 깊은 기능 변환 및 학습을 수행할 수 있습니다.
주의 계층과 주의 머리 사이의 관계: 각 주의 계층에는 여러 주의 머리가 포함될 수 있습니다.
수치적 관계: 모델에는 여러 개의 변환기 블록이 있을 수 있으며, 각 블록에는 주의 레이어와 하나 이상의 다른 레이어가 포함되어 있습니다. 각 주의 계층에는 여러 개의 주의 헤드가 있을 수 있습니다. 이러한 방식으로 전체 모델은 다양한 레이어와 헤드에서 복잡한 데이터 처리를 수행합니다.
Llama3 모델의 공식 링크 스크립트를 다운로드하세요: https://llama.meta.com/llama-downloads/
다음 코드는 tiktoken 라이브러리를 사용하여 로드하고 사용하는 방법을 보여줍니다. BPE(바이트 쌍 기반 인코딩) 토크나이저. 이 토크나이저는 특히 자연어 처리 및 기계 학습 모델에 사용하기 위해 텍스트 데이터를 처리하도록 설계되었습니다.
Hello World에 들어가서 단어 분할기가 어떻게 단어 분할을 수행하는지 살펴보겠습니다.
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!"))
Pictures
로드된 모델 파일에 포함된 처음 20개 매개변수 또는 가중치의 이름을 봅니다.
model = torch.load("Meta-Llama-3-8B/consolidated.00.pth")print(json.dumps(list(model.keys())[:20], indent=4))
Pictures
Pictures
전반적으로 이 출력은 Transformer 아키텍처를 기반으로 하는 딥 러닝 모델의 주요 구성 요소를 보여줍니다. 이 모델은 텍스트 분류, 기계 번역, 질문 응답 시스템 등과 같은 자연어 처리 작업에 널리 사용됩니다. 모델이 복잡한 입력 시퀀스 기능을 포착하는 데 도움이 되는 주의 메커니즘, 피드포워드 네트워크 및 정규화 레이어를 포함하여 각 레이어의 구조는 거의 동일합니다.
Llama3 모델의 매개변수 구성 보기:
with open("Meta-Llama-3-8B/params.json", "r") as f:config = json.load(f)config
图片
我们使用这个配置来推断模型的细节,比如:
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"])
图片
代码如下:
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。
图片
代码如下:
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
图片
我们接着使用 RMS 归一化对嵌入进行归一化,也就是图中这个位置:
图片
使用公式如下:
图片
代码如下:
# 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 是归一化时使用的权重。
函数的工作原理如下:
在进行归一化处理后,我们的数据形状仍然保持为 [17x4096],这与嵌入层的形状相同,只不过数据已经过归一化。
token_embeddings = rms_norm(token_embeddings_unnormalized, model["layers.0.attention_norm.weight"])token_embeddings.shape
图片
图片
接下来,我们介绍注意力机制的实现,也就是下图中的红框标注的位置:
图片
图片
计算 ( Q ) 和 ( K ) 的点积。
对点积结果进行缩放。
应用softmax函数得到注意力权重。
用注意力权重乘以值矩阵 ( V ) 得到输出矩阵 ( Z )。
这张图展示了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)
Picture
쿼리 가중치 행렬(wq.weight)의 모양은 [4096, 4096]입니다. 키 가중치 행렬(wk.weight)의 모양은 [1024, 4096]입니다. 값 가중치 행렬(wv.weight)의 모양은 [1024, 4096]입니다. 출력(Output) 가중치 행렬(wo.weight)의 모양은 [4096, 4096]입니다. 출력 결과를 보면 쿼리(Q) 가중치 행렬과 출력(O) 가중치 행렬의 모양이 모두 동일한 것으로 나타났습니다[4096, 4096]. 이는 입력 기능과 출력 기능 모두 쿼리와 출력 모두에 대해 4096의 차원을 갖는다는 것을 의미합니다. 키(K) 가중치 행렬과 값(V) 가중치 행렬의 모양도 모두 동일합니다[1024, 4096]. 이는 키와 값의 입력 특성 차원이 4096이지만 출력 특성 차원은 1024로 압축되었음을 보여줍니다. 이러한 가중치 행렬의 모양은 모델 설계자가 주의 메커니즘의 다양한 부분의 크기를 설정하는 방법을 반영합니다. 특히 키와 값의 차원을 줄여 계산 복잡성과 메모리 소비를 줄이는 반면 쿼리와 출력의 차원을 높게 유지하면 더 많은 정보를 유지할 수 있습니다. 이 디자인 선택은 특정 모델 아키텍처 및 애플리케이션 시나리오에 따라 다릅니다.
이 그림의 주의 메커니즘을 설명하는 구현 프로세스를 단순화하기 위해 "나는 Li Hongzhang을 존경합니다"라는 문장을 예로 들어 보겠습니다. 문장을 입력하세요. 먼저 "나는 이홍장을 존경합니다"라는 문장이 있습니다. 이 문장을 처리하기 전에 문장의 각 단어를 수학적으로 처리 가능한 형식, 즉 단어 벡터로 변환해야 합니다. 이 프로세스를 워드 임베딩이라고 합니다.
워드 임베딩: "나", "감사", "이홍장" 등 각 단어가 고정된 크기의 벡터로 변환됩니다. 이러한 벡터에는 단어의 의미 정보가 포함되어 있습니다.
여러 머리로 분할: 모델이 다양한 관점에서 문장을 이해할 수 있도록 각 단어의 벡터를 여러 부분으로 나눕니다. 여기에 머리가 8개 있습니다. 각 머리는 문장의 다른 측면에 중점을 둡니다.
주의력 계산: 각 머리에 대해 주의력이라는 것을 계산합니다. 이 프로세스에는 세 단계가 포함됩니다. "리홍장에게 감사드립니다"를 예로 들어 "감사"라는 단어에 초점을 맞추려면 "감사"가 검색어이고 "나" 및 "리홍장"과 같은 다른 단어가 사용됩니다. 는 키입니다. 의 벡터는 값입니다.
질의(Q) : 정보를 찾고 싶은 부분입니다. 키(K): 정보를 담고 있는 부분입니다. 값(V): 실제 정보 내용입니다. 스플라이싱 및 출력: 각 머리의 주의력을 계산한 후 이 결과를 연결하고 가중치 행렬 Wo를 통해 최종 출력을 생성합니다. 이 출력은 다음 처리 계층이나 최종 결과의 일부로 사용됩니다.
그림에 대한 댓글에서 언급된 모양 문제는 이러한 벡터를 컴퓨터에서 효율적으로 저장하고 처리하는 방법에 관한 것입니다. 실제 코드 구현에서 효율성을 높이기 위해 개발자는 각 헤더를 개별적으로 처리하는 대신 여러 헤더의 쿼리, 키 및 값 벡터를 함께 패키징할 수 있습니다. 이는 최신 컴퓨터의 병렬 처리 기능을 활용하여 계산 속도를 높일 수 있습니다.
출력 결과는 다음과 같습니다.
이 가중치 행렬의 모양은 모델 디자이너가 주의 메커니즘의 다양한 부분의 크기를 설정하는 방법을 반영합니다. 특히 키와 값의 차원을 줄여 계산 복잡성과 메모리 소비를 줄이는 반면 쿼리와 출력의 차원을 높게 유지하면 더 많은 정보를 유지할 수 있습니다. 이 디자인 선택은 특정 모델 아키텍처 및 애플리케이션 시나리오에 따라 다릅니다.
이 그림에서 주의 메커니즘을 설명하는 구현 프로세스를 단순화하기 위해 "나는 Li Hongzhang을 존경합니다"라는 문장을 예로 사용하겠습니다.
쿼리(Q) : 정보를 찾고 싶은 부분입니다.
키(K) : 정보를 담고 있는 부분입니다.
Value(V) : 실제 정보 내용입니다.
그림에 대한 댓글에서 언급된 모양 문제는 이러한 벡터를 컴퓨터에서 효율적으로 저장하고 처리하는 방법에 관한 것입니다. 실제 코드 구현에서 효율성을 높이기 위해 개발자는 각 헤더를 개별적으로 처리하는 대신 여러 헤더의 쿼리, 키 및 값 벡터를 함께 패키징할 수 있습니다. 이는 최신 컴퓨터의 병렬 처리 기능을 활용하여 계산 속도를 높일 수 있습니다.
가중 행렬 WQ, WK, WV 및 WO의 역할을 설명하기 위해 "Li Hongzhang에게 감사드립니다"라는 문장을 계속 사용합니다.
Transformer 모델에서는 단어 임베딩을 통해 각 단어가 벡터로 변환됩니다. 그런 다음 이러한 벡터는 일련의 선형 변환을 거쳐 주의 점수를 계산합니다. 이러한 선형 변환은 가중치 행렬 WQ, WK, WV 및 WO를 통해 구현됩니다.
전체 과정에서 WQ, WK, WV 및 WO는 모델이 입력 단어 벡터를 다른 표현으로 변환하는 방법과 이러한 표현을 결합하여 최종 출력을 얻는 방법을 결정합니다. 이러한 행렬은 Transformer 모델의 어텐션 메커니즘의 핵심 부분이며 모델이 문장에서 서로 다른 단어 간의 관계를 포착할 수 있도록 해줍니다.
WQ(가중치 행렬 Q), WK(가중치 행렬 K), WV(가중치 행렬 V) 및 WO(가중치 행렬 O)는 모델 학습 과정에서 역전파를 통해 전달됩니다. 알고리즘, 경사하강법 등의 최적화 방법을 통해 학습됩니다.
이 학습 과정이 어떻게 진행되는지 살펴보겠습니다.
在本小节中,我们将从多个注意力头中展开查询向量,得到的形状是 [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
图片
这段代码通过对模型中第一层的查询(Q)权重矩阵进行重塑(reshape),将其分解为多个注意力头的形式,从而揭示了32和128这两个维度。
之所以在这段代码中出现了32和128这两个维度,而在之前的代码段中没有,是因为这段代码通过重塑操作明确地将查询权重矩阵分解为多个注意力头,每个头具有自己的维度。32代表了模型中注意力头的数量,而128代表了分配给每个头的特征维度大小。这种分解是为了实现多头注意力机制,其中每个头可以独立地关注输入的不同部分,最终通过组合这些头的输出来提高模型的表达能力。
访问了第一层第一个头的查询(query)权重矩阵,这个查询权重矩阵的大小是 [128x4096]。
q_layer0_head0 = q_layer0[0]q_layer0_head0.shape
图片
在这里,你可以看到结果形状是 [17x128],这是因为我们有17个令牌,每个令牌都有一个长度为128的查询(每个令牌在一个头上方的查询)。
br
Picture
이 코드는 토큰 임베딩(token_embeddings)을 첫 번째 레이어의 첫 번째 헤드 쿼리 가중치 행렬(q_layer0_head0)의 전치(.T)와 비교하여 행렬 곱셈 작업을 수행합니다. -토큰 쿼리 벡터(q_per_token).
torch.matmul은 PyTorch의 행렬 곱셈 함수로 두 텐서의 곱셈을 처리할 수 있습니다.
token_embeddings는 각각 4096차원 임베딩 벡터로 표현되는 17개의 토큰을 나타내는 [17, 4096] 모양의 텐서여야 합니다.
q_layer0_head0은 첫 번째 레이어의 첫 번째 헤드에 대한 쿼리 가중치 행렬이며 원래 모양은 [128, 4096]입니다. .T는 q_layer0_head0의 모양을 [4096, 128]로 바꾸는 PyTorch의 전치 작업입니다.
이런 식으로 token_embeddings와 q_layer0_head0.T의 행렬 곱셈은 [17, 4096]과 [4096, 128]의 곱셈이고, 그 결과는 [17, 128] 모양의 텐서입니다.
이 코드 줄은 q_per_token 텐서의 모양을 인쇄하여 [17, 128]임을 확인합니다.
이는 입력된 모든 토큰(총 17개)에 대해 이제 128차원 쿼리 벡터를 갖게 된다는 의미입니다. 이 128차원 쿼리 벡터는 토큰 임베딩과 쿼리 가중치 행렬을 곱하여 얻어지며 후속 주의 메커니즘 계산에 사용될 수 있습니다.
요약하자면, 이 코드는 행렬 곱셈을 통해 각 토큰의 임베딩 벡터를 쿼리 벡터로 변환하여 어텐션 메커니즘 구현의 다음 단계를 준비합니다. 이제 각 토큰에는 이에 해당하는 쿼리 벡터가 있으며 이러한 쿼리 벡터는 다른 토큰과 함께 주의 점수를 계산하는 데 사용됩니다.
위 내용은 손으로 찢기 Llama3 레이어 1: 처음부터 llama3 구현의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!