블로그를 준비하고 있어요
잠시만 기다려주세요...
밑바닥부터 만들면서 배우는 LLM 3장 독서 후기밑바닥부터 만들면서 배우는 LLM 3장 독서 후기
일반
맥북에 물을 한바가지 쏟은 후, 멘붕이 와서 3~4일 정도를 허비했다.
지금 생각해보니 그냥 어차피 맥북은 나간거고, 수리 맡긴다고 생각하고 뭐라도 할걸 그랬나 싶다.
어쨌든 조금 늦었지만, 그래도 끝까지 달려봐야 한다는 생각에 3장 후기를 남긴다.
1. 어텐션 메커니즘
3장의 주 내용은 어텐션 메커니즘이다.
어텐션은 말 그대로 문장에서 어떤 부분을 주목하고 싶은지를 나타낸다.
예를들어 나는 어제 밥을 먹었다 는 문장을 이해한다고 해보자.
우리는 자연스럽게 나, 어제, 밥, 먹었다와 같은 단어들에 집중하게 될 것이다.
이처럼 처리중인 단어를 이해하기 위해서는 어떤 단어들과의 결합이 필요하고, 어텐션 메커니즘을 통해 단어들의 조합으로 문맥을 이해하도록 하는 것이다.

2. 셀프 어텐션
셀프 어텐션은 문장 안에서 토큰들 사이의 관계를 구하는 것이다.
이미 토큰을 아래와 같이 임배딩 벡터로 구현했다고 하자.
import torch
inputs = torch.tensor(
[[0.43, 0.15, 0.89],
[0.55, 0.87, 0.66],
[0.57, 0.85, 0.64],
[0.22, 0.58, 0.33],
[0.77, 0.25, 0.10],
[0.05, 0.80, 0.55]]
)
여기서 원하는 토큰 하나에 대해서 다른 토큰들의 점곱(dot)을 통해 토큰들 간의 관계를 어텐션 점수로 얻는다.
이때 점곱이라는 개념이 새롭게 보이겠지만, 행렬에서의 점곱은 벡터에서의 내적과 같다.
이 말은 두 벡터의 방향성이 비슷할수록 큰 값을 가지고, 서로 수직일 경우는 0과 같은 값을 가진다는 것.
이를 통해 두 임배딩이 얼만큼의 유사성을 가지고 있는지 확인할 수 있다.
벡터 자체를 보는 것이 아니라 두 벡터의 유사성을 보는 이유는 임배딩을 초기화 할 때 의미없는 벡터들을 흩뿌렸기 때문이다.
따라서 벡터 자체를 측정하는것은 의미가 없다.
그리고 어텐션 가중치의 합이 1이 되도록 정규화 한 후, 입력 벡터와 어텐션 가중치를 곱하고 합해준다.
어텐션 가중치가 높을수록 문맥 벡터에 영향이 크므로, 각 임배딩들 사이에서 쿼리로 입력한 임배딩의 적절한 위치의 방향을 벡터로 얻게 된다.
이런식으로 모든 임배딩에 대해 계산하면 아래와 같은 형태의 텐서를 얻게 된다.
tensor([[0.4421, 0.5931, 0.5790],
[0.4419, 0.6515, 0.5683],
[0.4431, 0.6496, 0.5671],
[0.4304, 0.6298, 0.5510],
[0.4671, 0.5910, 0.5266],
[0.4177, 0.6503, 0.5645]])
텐서의 구조 자체는 2차원이지만, 내부에 담고 있는 내용은 3차원 문맥 벡터이다.
이를 이용해 각 임배딩들이 가지는 관계를 방향성으로서 표현할 수 있다.
3. 훈련 가능한 셀프 어텐션
훈련가능한 셀프 어텐션에서는 각각의 키, 쿼리 값을 더 낮은 차원으로 축소시킨다.
이때 최초에 처리하는 값들은 모두 임의의 값이다.
처리 이후 역전파 과정을 통해 업데이트 하는 것.
torch.manual_seed(123)
W_query = torch.nn.Parameter(torch.rand(d_in, d_out), requires_grad=False)
W_key = torch.nn.Parameter(torch.rand(d_in, d_out), requires_grad=False)
W_value = torch.nn.Parameter(torch.rand(d_in, d_out), requires_grad=False)
위에서 최초의 query, key, value 값을 보면 모두 rand르 하는 것을 볼 수 있다.
최초의 값은 모두 의미가 없겠지만, 이후 훈련을 통해 의미있는 값으로 변하게 된다.
이런 과정을 통해 우리는 하나의 단어에 대한 문맥벡터를 얻을 수 있다.
4. 코잘 어텐션
코잘 어텐션은 토큰에 마스크를 씌우는 방식이다.
미래를 예측함으로서 다음의 문맥을 예측할 수 있도록 만드는 방식이다.
처음에 이 내용을 접했을 때, 과적합 문제가 먼저 떠올랐지만...
모델이 실제 언어 생성 방향(왼→오)대로 문맥을 학습하도록 돕는다.
이렇게 학습된 문맥 벡터는 문장의 의미를 파악며 새로운 문장을 생성하고, 추론과 유추까지 가능하게 만든다.
5. 질문들
챗 지피티랑 정말 오랫동안 이야기 했는데 결론은 아래와 같다.
정답을 알고 있음
--> 모델이 예측이 아니라 복사만 하게 됨
--> 손실이 거의 0이 됨 (계산은 가능함)
--> 경사(gradient)가 거의 0
--> 업데이트가 거의 없음
--> 역전파에 의미 있는 변화가 없음
--> 학습이 사실상 안 됨
예를 들면, 어두운 방에서 물건을 찾으려고 손으로 더듬으며 탐색해야 한다고 하자.
이 과정이 공간을 이해하고 물건을 찾는 능력을 길러준다.
그런데 이미 물건 위치를 알고 있다면 더듬을 필요가 없기 때문에 결국 ‘찾는 방법’을 학습하지 못한다.
언어 모델에서 미래 토큰을 보는 것도 비슷하게 정답을 알고 있다면 학습 예측 능력을 잃게 되는 것이다.
그래서 코잘 어텐션(casual attention)은 손실을 유도하는 함수이다.
코잘 어텐션은 미래를 가려 손실이 발생하게 만들고, 이 손실을 바탕으로 문맥 벡터가 업데이트된다.
이렇게 예측 오류를 줄여가는 과정 속에서 모델은 문맥을 더 깊이 이해하고, 그에 따라 추론, 유추, 평가 능력도 발달한다.
6. 후기
맥북에 물을 쏟으면서 한주가 미뤄지고, 그에 조바심이 났다.
그래서 빠르게 읽고 넘어가려고 했으나 그럴수 없었다.
처음보는 문장 하나 하나가 어렵고 새롭게 다가왔다.
왜 여기서 차원 축소한 행렬을 곱하지? 왜 여기서 뜬금없이 마스킹을하지?
이런 의문에 대해 질문을 찾아가는 과정이 상당히 길고 고루했다.
AI는 질문을 하면 거기에 대답해 주었지만, 거기에 대해 내가 새롭게 해석을 내리면 그것에 대해서는 항상 틀렸다고 말하기에 무엇이 옳은 의미인지를 정말 길게 고민했다.
이러한 고민의 과정이 나를 성장시켜 주지 않을까 하는 생각을 해본다.
4장은 무엇을 또 배울 수 있을지 기대가 된다.
댓글을 불러오는 중...