이번 강의는 Andrej Karpathy 의 Neural Networks: Zero to Hero 코스의 두 번째 강의 The spelled-out intro to language modeling: building makemore 였다. 이름 약 3.2만 개를 학습해 "이름 같은" 새 이름을 만들어내는 글자 단위 언어 모델(makemore)을 밑바닥부터 만든다.

강의를 들으면서 메모


  • 단어 하나가 사실은 여러 개의 학습 예제다. emma 는 시작·끝을 점으로 감싸 .emma. 가 되고, 거기서 .e / em / mm / ma / a. 처럼 5개의 (앞 글자 → 다음 글자) 예제가 나온다. 이름 3.2만 개면 약 22.8만 개의 예제가 된다.
  • bigram 의 gram 이 뭔지 궁금했는데, 그리스어로 "글자(쓴 것)" 였다. telegram, diagram, grammar 에 들어있는 그 gram 이다. bi(둘) + gram(글자) = "글자 2개". 그러니 bigram 은 "이진(binary)" 이 아니라 그냥 "글자 2개" 라는 뜻이다.
  • 제일 어려웠던 건 broadcasting(모양이 다른 배열끼리 자동으로 크기를 맞춰 계산하는 규칙) 과 keepdim 옵션이었다. 텐서의 모양(shape) 하나 때문에, 행을 정규화하려던 게 열이 정규화되는 조용한 버그가 난다. 에러도 안 나서 더 위험하다. 2×2 짜리 작은 표로 직접 손으로 나눠보고 나서야 감이 잡혔다.
  • 손실 함수(NLL)에 왜 마이너스를 붙이나 했는데, "손실 = 벌점(낮을수록 좋음)" 인데 log likelihood(모델이 정답에 매긴 확률값) 는 "높을수록 좋음" 이라, 방향을 뒤집으려고 음수를 붙이는 거였다.
  • 늘 제일 그럴듯한 글자 하나만 고르면(argmax) 매번 똑같은 이름만 나온다. 그래서 확률대로 무작위로 뽑는(multinomial) 거구나 하고 이해했다.

강의 내용 간단 요약


  • [00:00:00 ~ 00:09:24] makemore 와 bigram 언어 모델: 글자 단위 언어 모델은 단어를 글자들의 시퀀스로 보고 "다음 글자" 를 예측한다. bigram 모델은 그중 제일 단순한 형태로, 바로 앞 글자 하나만 보고 다음 글자를 맞힌다. 약하지만 출발점으로 좋다.
  • [00:09:24 ~ 00:24:02] 세서 학습하기: 글자 쌍이 데이터에 몇 번 나오는지 세어 27×27 표(N)에 담는다. 이 "세기" 가 bigram 모델의 학습 전부다. 단어의 시작과 끝은 특수 토큰 . 하나로 표시한다(27 = 글자 26개 + 점 1개).
  • [00:24:02 ~ 00:36:17] 샘플링으로 이름 생성: 카운트를 확률로 바꾼 뒤(각 행을 합으로 나눠 정규화), 확률대로 다음 글자를 뽑기를 점이 나올 때까지 반복해 이름을 만든다. 결과는 형편없지만, 아무것도 안 배운 무작위 모델보다는 확실히 이름다웠다. 모델이 뭔가 배우긴 한 것이다.
  • [00:36:17 ~ 00:50:14] broadcasting 과 keepdim 함정: 매번 다시 계산하는 낭비를 줄이려고 확률표 P 를 미리 한 번에 만든다. 이 과정에서 텐서 모양을 한 끗 틀리면 행이 아니라 열을 정규화하는 버그가 난다. 강의에서 "broadcasting 을 존중하라" 며 가장 조심하라고 강조하는 대목이다.
  • [00:50:14 ~ 01:02:57] 품질 측정(NLL 손실)과 smoothing: 모델이 얼마나 좋은지를 숫자 하나로 요약한다. 정답들에 매긴 확률을 모두 곱한 값(likelihood)에 log 를 씌워 합으로 바꾸고, 음수를 붙여 "낮을수록 좋은" 손실(negative log likelihood)로 만든다. 이 모델은 약 2.45. 학습에 없던 글자 쌍의 확률이 0 이 되면 손실이 무한대로 터지므로, 모든 칸에 가짜 카운트 +1 을 더해(smoothing) 막는다.
  • [01:02:57 ~ 01:35:49] 같은 모델을 신경망으로 (Part 2): 이번엔 세지 않는다. 글자를 one-hot 벡터(해당 자리만 1, 나머지는 0 인 벡터)로 바꿔 입력하고, 가중치 행렬 W 하나(선형층)를 곱해 logits 를 얻은 뒤, softmax(지수를 취해 양수로 만들고 합이 1 이 되게 정규화)로 확률을 만든다. 표를 직접 채우는 대신 W 를 랜덤으로 시작해 찾아간다.
  • [01:35:49 ~ 01:47:49] 경사하강법 학습 루프: forward(확률 계산) → 손실(NLL) → backward(자동 미분, 1강 micrograd 에서 손으로 만든 그 역전파) → W 업데이트. 이걸 반복하면 손실이 세기 방식과 똑같이 약 2.45 로 수렴한다.
  • [01:47:49 ~ 01:57:20] 두 방식은 같은 모델이라는 결론: one-hot 벡터에 W 를 곱하는 건 결국 W 의 한 행을 골라내는 것이고, 그 행은 세서 만든 확률표의 한 행과 같다. smoothing 도 신경망에선 regularization(가중치를 0 쪽으로 당기는 항)과 같은 역할을 한다. 결국 세기와 경사하강법은 같은 결과에 도달하지만, 신경망 방식만 입력 글자 수를 늘려 트랜스포머(GPT)까지 확장된다.

생각한 것들과 교훈


  • AI에게 유튜브 description에 제공된 강의 자료 기반으로 유튜브 자막 correction하고 전처리하라고 하니까 더 정확한 전사를 얻을 수 있었음. 시간이 꽤 오래 걸리므로 다음 강의도 미리 해놓는 게 좋을 듯.
  • 어려운 주제일수록 모국어로 먼저 이해하는 게 빨랐다. 이번엔 강의를 한국어로 풀어가며 개념을 잡고, 영어 연습은 따로 분리했다. 언어 장벽과 개념 장벽을 동시에 넘으려 하지 않으니 머리에 더 잘 들어왔다.
  • 추상적인 게 안 잡힐 땐 제일 작은 예시로 직접 손계산을 해보면 된다. broadcasting 도 2×2 표 하나를 손으로 나눠보고 나서야 뚫렸다.
  • "안다고 착각" 을 거르는 데는 스스로 답해보는 이해 체크가 효과적이었다. NLL 에 왜 음수를 붙이는지 같은 데서 실제로 막혔고, 막힌 걸 알았기에 다시 짚을 수 있었다.
  • 용어의 어원을 파보면(bi + gram) 개념이 더 단단히 붙는다.
  • 이 강의의 핵심은 "같은 bigram 모델을 세기와 신경망 두 방식으로 만들 수 있고, 둘이 같은 결과에 도달한다" 는 것이다. 다만 세기 방식은 글자 수를 늘리면 표가 폭발해 확장이 안 되고, 신경망 방식만 트랜스포머까지 간다. (Part 2 는 다음에 직접 코드로 확인할 예정)