[Decoder Generator]
이전 포스팅에서 설명한 코드들이 어떻게 작동하는지 알아본다.
우선 이전 포스팅에서 설명한 SimpleModel class의 instance를 만들고 불러온다.
model = SimpleModel().to(device)
m = model
.to(device) 부분은 colab의 gpu사용 시, model과 data가 모두 gpu에 올라와 있어야 하기 때문에 첨부된 코드이다.
앞서 만든 xb, yb를 가져와서 model을 실행한다. 이 과정에서 SimpleModel class의 forward 멤버 함수가 작동한다.
#xb, yb = get_batch('train')
logits, loss = m(xb, yb)
forward 함수의 실행 결과로 logit과 loss가 반환된다. logit은 256*65 값으로, 각각의 row가 a, b, c,... 일 확률을 나타낸다.
여기까지 진행하였을 때는 아직 training이 되기 전이다. 일단 training이 되지 않은 단계에서 앞서 SimpleModel class에서 정의한 generate 함수를 실행하여 그 결과값을 살펴보면, 아직은 아무런 말도 되지 않는 문자들의 나열이 출력된다.
context = torch.zeros((1,1), dtype=torch.long, device=device)
print(decode(m.generate(context, max_new_tokens=1000)[0].tolist()))
optimizer를 정의하고 본격적으로 training을 시작하면 그 결과가 어떻게 바뀌는지 살펴볼 것이다.
optimizer = torch.optim.AdamW(m.parameters(), lr=learning_rate)
for iter in range(max_iters):
xb, yb = get_batch('train')
logits, loss = m(xb, yb)
optimizer.zero_grad(set_to_none=True)
loss.backward()
optimizer.step()
if iter % 200 == 0:
print(iter, loss.item())
max_iter 만큼 우리가 만든 모형들은 반복하여 통과시켜 가며 training한다. loss에 대한 backward propagation을 진행하고 parameter를 update한다. 올바른 Training 메커니즘을 구현하였다면, Training을 계속 반복하여서 더 정확한 결과를 얻을 수 있을 것이다.
3000번 이 과정을 반복하여 loss를 1.91까지 줄인 후 다시 generate하면,
아직은 말이 되지 않지만 점점 영문 극본의 양식에 가까워져가고 있다.
여기까지의 과정이 주어진 input을 가지고 training하여 점점 자연어에 가까운 모델을 만들어내는 과정을 문장 레벨이 아닌 character level로 간단히 구현한 것이다.