brunch

You can make anything
by writing

C.S.Lewis

by delight Nov 04. 2023

오픈AI 사용료가 영어가 아닌 언어들에서 더 비싼 이유

학습 차원에서 틈틈이 해외 전문가들이 블로그나 미디어 그리고 책에서 쓴 글을 번역 또는 요약 정리하고 있습니다. 이번 포스팅도 그중 하나고요. 거칠고 오역된 부분이 있을 수 있습니다. 제대로 번역되지 않은 부분은 확인 주시면 반영토록 하겠습니다. 번역 과정에서 의미 전달이 애매한 일부 문장은 삭제했습니다. 이번에는 Leonie Monigatti가 미디엄에 올린 글을 정리한 것입니다.


최근 오픈AI API 비용을 추정하는 방법에 대한 글을 게시한 후, 영어보다 중국어, 일본어, 한국어(한중일)와 같은 다른 언어에서 오픈AI API가 훨씬 더 비싸다는 흥미로운 댓글을 받았다.


나는 이 문제에 대해 잘 몰랐지만 이 분야가 활발히 연구되고 있다는 것을 바로 알게 됐다.


올해 초, Petrov 등의 "언어 모델 토큰화가 언어들 간 불공정성을 야기하다"라는 논문은 "동일한 텍스트가 다른 언어로 번역될 때 토큰화 길이가 크게 달라질 수 있으며, 경우에 따라 최대 15배까지 차이가 날 수 있다"는 사실을 보여줬다.


다시 한 번 설명하자면, 토큰화는 텍스트를 텍스트의 일반적인 문자 시퀀스인 토큰 목록으로 분할하는 프로세스다. 토큰화 길이의 차이는 오픈 API가 1,000토큰 단위로 청구되기 때문에 문제가 된다. 따라서 비슷한 텍스트에 토큰이 최대 15배 더 많으면 API 비용이 15배가 된다.


실험: 다른 언어의 토큰 수

"안녕하세요"라는 문구를 일본어(こんにちは世界)로 번역하고 힌디어로 변환해 보자. 오픈AI의 GPT 모델에 사용된 cl100k_base 토큰화 도구로 새 문구를 토큰화하면 다음과 같은 결과를 얻을 수 있다. 두 가지 흥미로운 점을 관찰할 수 있다. 이 구문의 글자 수는 영어에서 가장 많고 힌디어에서 가장 적지만, 결과 토큰의 수는 영어에서 가장 적고 힌디어에서 가장 많다.


힌디어에서는 글자 수보다 토큰 수가 더 많다. 어떻게 그럴 수 있을까?


기초

영어 이외 언어에서 동일한 구문에 대해 더 많은 토큰이 발생하는 이유를 이해하려면 바이트 쌍(Byte Pair) 인코딩과 유니코드라는 두 가지 기본 개념을 살펴볼 필요가 있다.


바이트 쌍 인코딩

바이트 쌍 인코딩(BPE) 알고리즘은 원래 1994년 Gage에 의해 압축 알고리즘으로 발명됐다.

문자열 "ABABCABCD"로 구성된 가장 작은 텍스트 말뭉치가 있다고 가정해 보자.


1. 모든 바이트 쌍(이 예제에서는 문자)에 대해 말뭉치에서 해당 바이트의 발생 횟수를 계산한다.

2. 발생 횟수가 가장 많은 바이트 쌍을 가져와 사용하지 않는 문자로 바꾼다. 이 경우 "AB" 쌍을 "X"로 바꾼다.

3. 더 이상 압축할 수 없거나 사용되지 않는 바이트(이 예에서는 문자)가 더 이상 남지 않을 때까지 2단계를 반복한다.


유니코드

유니코드는 코드 포인트라고 하는 고유 번호로 서로 다른 문자를 표현하는 방법을 정의하는 인코딩 표준이다. 이 글에서는 유니코드에 대한 모든 세부 사항을 다루지는 않는다. 다음 설명을 위해 알아야 할 것은 텍스트가 UTF-8로 인코딩된 경우 다른 언어의 문자는 다른 바이트가 필요하다는 것이다. 영어 문자는 ASCII 문자로 표현할 수 있으며 1바이트만 필요하다. 그러나 예를 들어 그리스 문자는 2바이트, 일본어 문자는 3바이트가 필요하다.


내부를 보니

이제 언어마다 문자를 숫자로 표현하는 데 필요한 바이트 수가 다르다는 것과 오픈AI GPT 모델에서 사용하는 토큰화가 바이트 수준에서 토큰화하는 BPE 알고리즘이라는 것을 이해했으니, 이제 오프닝 실험을 좀 더 자세히 살펴보자.


영어

먼저 영어로 된 토큰화의 바닐라 예시를 살펴보자. 다음과 같은 사실을 관찰할 수 있다.

하나의 문자는 하나의 코드 포인트와 같다.

유니코드 코드 포인트 하나는 1바이트와 같다.

BPE는 "Hello"의 경우 5바이트, "world"의 경우 6바이트를 두 개 개별 토큰으로 토큰화한다.

이 관찰은 OpenAI 토큰화 사이트의 문장과 일치한다.


영어가 아닌 텍스트를 살펴보자.


일본어

이제 문자가 1바이트가 아니라 여러 바이트에 해당하는 언어에서는 어떻게 될까? UTF-8 인코딩에서 3바이트 길이 CJK 문자를 사용하는 일본어로 번역된 "안녕하세요"라는 문구를 살펴보자. 다음과 같은 사실을 관찰할 수 있다.


하나의 문자는 하나의 코드 포인트와 같다.

하나의 유니코드 코드 포인트는 3바이트다.

BPE는 こんにちは("안녕하세요"를 뜻하는 일본어)의 15바이트를 단일 토큰으로 토큰화한다.

그러나 문자 界는 단일 토큰으로 토큰화된다.

문자 世는 두 개 토큰으로 토큰화된다.


Hindi

하나의 문자가 하나의 코드 포인트가 아니라 여러 코드 포인트로 이루어진 언어에서는 더욱 복잡해진다. 힌디어로 표기된 "안녕하세요"라는 문구를 살펴보자. 힌디어에 사용되는 데바나가리 (Devanāgarī)알파벳은 문자를 여러 개 코드 포인트로 분할해야 하며 각 코드 포인트에는 3바이트가 필요하다. 다음과 같은 사실을 관찰할 수 있다.


하나의 문자는 여러 개의 유니코드 코드 포인트로 구성될 수 있다.

하나의 유니코드 코드 포인트는 3바이트다.

일본어 문자 世와 유사하게 하나의 코드 포인트는 두 개의 토큰으로 나눌 수 있다.

일부 토큰은 두 개 이상의 문자에 걸쳐 있다.


요약

이 글에서는 "안녕하세요"라는 동일한 문구를 일본어로 번역하고 힌디어로 표기하는 방법을 살봤다. 먼저, 오픈AI GPt 모델에 사용되는 토큰화는 바이트 수준에서 이뤄진다는 사실을 알게 됐다. 또 일본어와 데바나가리 문자는 영어와 달리 한 문자를 표현하는 데 1바이트 이상이 필요하다는 것을 확인했다. 따라서 UFT-8 인코딩과 BPE 토큰화 도구가 결과 토큰 수에 큰 역할을 하고 API 비용에 영향을 미친다는 것을 확인했다. 물론 GPT 모델이 다국어 텍스트에 대해 동일하게 훈련되지 않았다는 사실과 같은 다른 요인도 토큰화에 영향을 미친다. 이 글을 쓰는 시점에서 이 문제는 활발히 연구되고 있는 분야이며, 다양한 해결책이 나올지 궁금하다.

브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari