얼마나 잘 맞히나: 루나가 놀라는 정도를 재기

퍼플렉서티와 바이트당 비트: 같은 놀람을 세 가지로 적기

크로스 엔트로피 표에는 숫자가 세 칸 있었다. 바이그램 줄의 2.2833, 3.2940, 9.81은 모두 같은 놀람을 다른 형태로 적은 것이다. 학습 기록은 nat 를, 논문은 퍼플렉서티를, 압축 대회는 바이트당 비트를 즐겨 쓰는데, 숫자가 어떻게 서로 바뀌는지 알면 남의 기록과 우리 루나를 한 줄에 세울 수 있다. 낱말 바이그램과 글자 바이그램처럼 맞히는 단위가 다른 모델을 비교할 때도 이 변환이 필요하다.

nat 와 비트는 로그의 밑만 다르다. ln p = log₂ p × ln 2 이므로, nat 를 ln 2 ≈ 0.6931로 나누면 비트가 된다. 바이그램의 2.2833 nat 를 0.6931로 나누면 3.2940비트다.

퍼플렉서티는 로그를 거꾸로 풀어 놀람을 후보 수로 되돌린 값이다. 공정한 주사위는 면마다 확률이 1/6이라 굴릴 때마다 log₂ 6 = 2.585비트를 놀라는데, 거꾸로 2.585비트를 놀라는 모델은 「매번 똑같이 그럴듯한 후보 여섯 개 가운데서 고르는 것만큼」 헷갈린다고 읽을 수 있다. 그래서 크로스 엔트로피 H(비트)에 대해

퍼플렉서티=2H=eHnat\text{퍼플렉서티} = 2^{\textcolor{#d62728}{H}} = e^{\textcolor{#d62728}{H}_{\text{nat}}}
H크로스 엔트로피(비트)Hnat같은 값을 nat 로 적은 것(=H×ln⁡2)\begin{array}{ll} \textcolor{#d62728}{H} & \text{크로스 엔트로피(비트)} \\ \textcolor{#d62728}{H}_{\text{nat}} & \text{같은 값을 nat 로 적은 것}(= \textcolor{#d62728}{H} \times \ln 2) \end{array}

이고, 이 값을 퍼플렉서티 (헷갈리는 후보 수 / perplexity)라 한다. 고른 분포(256)의 퍼플렉서티가 256.00, 학습 글에 나온 149가지만 고르게 보는 분포가 149.00인 것도 이 뜻대로다. 바이그램의 9.81은 루나가 글자마다 평균으로 열 개 정도의 후보 사이에서 헷갈린다는 뜻이다.

바이트로 나누면 단위가 다른 모델도 비교할 수 있다

글자 하나를 맞히는 모델과 낱말 하나를 맞히는 모델은 「한 번 맞힐 때의 놀람」을 비교할 수 없다. 낱말 하나에는 글자가 여러 개 들어 있어 낱말 모델의 놀람이 더 큰 것이 당연한데, 이럴 때 쓰는 잣대를 선생님이 다시 살펴봤다.

검증 글 전체를 맞히며 놀란 비트를 모두 더한 뒤, 맞히는 단위가 무엇이든 그 글의 원래 바이트 수로 나눈 값이 바이트당 비트 (bits per byte, bpb)다. 지금 루나는 한 번에 바이트 하나를 맞히므로 바이트당 비트가 글자당 비트와 같고, 출력의 bpb 칸이 그 값이다. 글을 더 큰 조각으로 잘라 맞히는 모델이 나와도, 같은 검증 글의 같은 바이트 수로 나누면 이 칸에 함께 적을 수 있다.

낱말 바이그램을 이 표에 바로 올리지 못하는 이유도 여기서 드러난다. 같은 방법으로 낱말을 세어 보면 검증 글의 낱말 가운데 학습 글에 한 번도 없던 것이 나온다.

학습 글 낱말 19,590,139 개 (서로 다른 낱말 67,256), 검증 글 낱말 4,408,824 개
검증 글에서 학습 글에 없던 낱말: 6,997 개 (0.1587%), 서로 다른 것 5,598 개
자주 나온 것: 'Kaylee' x19, 'Shiver' x13, 'Tam' x12, 'Meowny' x11, 'Cha' x11, 'Tibby' x10, 'Reginald' x9, 'Brave' x9

처음 보는 낱말은 대부분 동화 속 새 이름이다. 낱말 표는 「Kaylee」라는 낱말에 확률을 줄 칸 자체가 없어서, 6,997번의 놀람이 모두 무한대가 된다. 칸마다 α를 더하려 해도 어휘가 정해져 있지 않으니 몇 칸에 더할지부터 정할 수 없는 반면, 글자 표는 바이트 256가지로 어떤 글이든 적을 수 있어서 이런 일이 없다. 낱말처럼 큰 조각의 장점과 바이트처럼 무엇이든 적을 수 있는 장점을 함께 얻는 방법은 글을 토큰으로 자를 때 다시 찾는다.

ML에서: 순위표의 숫자 읽기

nanochat 의 학습 기록은 검증 손실을 바이트당 비트로 바꿔 적는다. 토크나이저를 바꾸면 토큰 하나에 든 바이트 수가 달라져 토큰당 손실이 저절로 움직이므로, 토크나이저를 고치는 실험끼리 비교하려면 바이트로 나눈 값이 필요해서다. 퍼플렉서티는 단위가 토큰당인 경우가 많아, 토크나이저가 다른 두 논문의 퍼플렉서티는 그대로 비교하지 않는다.

문제 4. 면이 몇 개인 주사위만큼 헷갈리나

(가) 공정한 주사위 하나를 굴릴 때의 놀람은 몇 비트이고 퍼플렉서티는 얼마인가? (나) 바이그램 루나의 크로스 엔트로피 3.2940비트를 퍼플렉서티로 바꾸고, 유니그램의 4.4150비트도 바꿔라. (다) 퍼플렉서티 9.81은 「루나가 다음 글자를 늘 열 개 후보 가운데서 고른다」는 뜻인가?

김민준 M01
김민준

(가)는 log₂ 6 = 2.585비트, 퍼플렉서티는 6이에요. (나)는 2^3.2940 = 9.81이고, 유니그램은 2^4.4150 = 21.33이에요. 출력의 ppl 칸이랑 같네요.

선생님 T01
선생님

앞 글자 하나를 보는 것만으로 후보 21개가 10개로 준 거예요. (다)는요?

김민준 M02
김민준

그럼 매번 열 개쯤 남는다는 거 아니에요?

이서연 S06
이서연

「q」 다음은 후보가 사실상 하나였어. 놀람이 0비트. 그런데 공백 다음은 「t」가 0.149로 1등일 만큼 퍼져 있었고. 자리마다 후보 수가 전혀 다른데 늘 열 개일 리가 없지.

선생님 T14
선생님

퍼플렉서티는 놀람의 평균을 후보 수로 되돌린 값이에요. 어떤 자리는 하나, 어떤 자리는 수십 개인 것이 평균해서 「열 개 정도의 주사위만큼」이 된 거죠.

김민준 M07
김민준

반 평균 점수가 70점이라고 모두 70점은 아닌 거랑 같네요.

문제 5. 한국어가 더 잘 맞힌다?

한국어 타이니스토리즈(g0ster/TinyStories-Korean, 원본 동화를 EEVE 모델로 기계 번역한 판. 카드에는 MIT 라이선스, 원본은 CDLA-Sharing-1.0)의 검증 파일을 이야기 단위로 9:1로 나눠, 큰 쪽으로 글자 바이그램을 세고 작은 쪽으로 쟀다. 영어도 같은 글자 수만큼 같은 방법으로 쟀다. 아래 결과를 보고 「바이그램은 한국어를 영어보다 두 배 잘 맞힌다」는 말이 맞는지 판단하라.

한국어: 글자 종류 1,555, 바이그램 글자당 3.7430비트, 바이트당 1.5613비트 · 영어: 글자 종류 86, 바이그램 글자당 3.2942비트, 바이트당 3.2931비트 · 글자당 UTF-8 바이트: 한국어 2.397, 영어 1.000

이서연 S01
이서연

바이트당 비트로 보면 1.5613 대 3.2931이라 정말 한국어가 절반이에요.

김민준 M01
김민준

그런데 글자당으로 보면 한국어가 3.7430으로 더 커. 거꾸로잖아.

선생님 T02
선생님

같은 모델, 같은 글인데 단위만 바꿨더니 순서가 뒤집혔어요. 두 줄을 잇는 숫자가 표에 있을 텐데요.

이서연 S07
이서연

글자당 바이트요. 한국어 글자 하나가 평균 2.397바이트라, 3.7430을 2.397로 나누면 1.5615예요. 바이트당 비트가 작은 건 잘 맞혀서 생긴 게 아니에요. 같은 놀람을 바이트 2.4개에 나눠 적었을 뿐이에요.

김민준 M04
김민준

그럼 「두 배 잘 맞힌다」는 틀린 말이네. 글자 하나 맞힐 때는 오히려 한국어에 더 놀라는데. 글자 종류가 1,555개나 되니까.

선생님 T01
선생님

그래요. 바이트당 비트는 같은 글을 서로 다른 모델로 잴 때 쓰는 잣대예요. 언어가 다르면 같은 내용을 담는 바이트 수부터 달라서, 바이트당 비트만으로 「어느 언어를 더 잘 맞히나」를 말할 수 없어요. 게다가 한국어판은 기계 번역이라 글의 품질도 고르지 않고요.