이 개념은 샵투스쿨의 “트랜스포머 모델로 GPT만들기” 학습 중 수강생분들이 더 자세히 알고 싶어하시는 용어들을 설명한 것입니다.
인코딩과 디코딩은 일반적으로 상대적인 개념입니다.
인코딩은 일련의 데이터나 정보를 다른 형식으로 변환하는 과정을 의미합니다. 일반적으로 텍스트를 숫자로 인코딩하는 것이 많이 사용됩니다. 이렇게 인코딩된 숫자는 컴퓨터가 이해할 수 있는 형태로 변환됩니다. 예를 들어, 자연어 처리에서 자연어 문장을 원-핫 인코딩 또는 정수 인코딩을 통해 숫자 시퀀스로 변환하는 것이 인코딩의 일반적인 예입니다.
디코딩은 인코딩된 데이터나 정보를 다시 원래 형식으로 되돌리는 과정을 의미합니다. 인코딩된 숫자나 데이터를 다시 텍스트로 디코딩하는 것이 많이 사용됩니다. 예를 들어, 컴퓨터가 출력한 숫자 시퀀스를 자연어 문장으로 디코딩하거나, 이미지를 인코딩된 형식에서 원래의 이미지 형식으로 디코딩하는 것이 디코딩의 일반적인 예입니다.
따라서, 인코딩은 일련의 데이터를 다른 형식으로 변환하는 것이고, 디코딩은 인코딩된 데이터를 원래의 형식으로 변환하는 것입니다.
코드의 예
아래 코드에서 인코딩 작업을 하는 부분은 함수를 사용하고 있습니다.
prompt_tokens = [self.tokenizer.encode(x, bos=True, eos=False) for x in prompts]
위 코드는 `self.tokenizer.encode()` 함수를 호출하여 `prompts` 리스트의 각 요소를 인코딩하여 `prompt_tokens` 리스트에 저장하고 있습니다. `self.tokenizer.encode()` 함수는 주어진 텍스트를 숫자로 인코딩하는 기능을 수행합니다. 따라서 해당 코드에서는 함수를 사용하여 인코딩 작업을 수행하고 있습니다.
`prompt_tokens = [self.tokenizer.encode(x, bos=True, eos=False) for x in prompts]` 코드에서 `x`, `bos=True`, `eos=False`는 다음과 같은 의미를 갖습니다:
– `x`: `prompts` 리스트의 각 요소인 문자열을 나타냅니다. `x`는 각각의 프롬프트 텍스트를 의미합니다.
– `bos=True`: “Beginning of Sentence”의 약자로, 인코딩된 토큰 시퀀스의 시작 부분에 특별한 시작 토큰을 추가할지 여부를 나타냅니다. `bos=True`로 설정하면 시작 토큰이 추가됩니다.
– `eos=False`: “End of Sentence”의 약자로, 인코딩된 토큰 시퀀스의 끝 부분에 특별한 종료 토큰을 추가할지 여부를 나타냅니다. `eos=False`로 설정하면 종료 토큰이 추가되지 않습니다.
따라서 `self.tokenizer.encode(x, bos=True, eos=False)`는 `x`라는 문자열을 토크나이즈하고 인코딩된 토큰 시퀀스를 생성하는 과정에서 시작 토큰을 추가하고 종료 토큰을 추가하지 않는 것을 의미합니다.
시작 토큰을 추가하고 종료 토큰을 추가하지 않는 이유는 다양한 상황과 요구에 따라 다를 수 있습니다. 일반적으로는 다음과 같은 이유로 시작 토큰을 추가하고 종료 토큰을 추가하지 않을 수 있습니다:
1. 문장 생성의 일부로서 특정 문장의 시작을 나타내기 위함: 시작 토큰을 추가함으로써 모델은 특정 문장의 시작을 알 수 있고, 이를 활용하여 문장의 의미와 문맥을 이해하고 유지할 수 있습니다. 예를 들어, “나는”이라는 시작 토큰을 추가하면 모델은 이어지는 문장에서 “나는”에 대한 정보를 활용하여 적절한 문장을 생성할 수 있습니다.
2. 문장의 완성을 강제하지 않기 위함: 종료 토큰을 추가하지 않으면 모델은 텍스트를 계속해서 생성할 수 있습니다. 이는 특정 길이의 문장을 생성하기보다는, 원하는 만큼의 텍스트를 생성하거나 다른 조건에 따라 중단하고 싶을 때 유용합니다. 예를 들어, 텍스트 생성 중에 특정 조건을 만족할 때까지 생성을 계속하고자 할 때 종료 토큰을 추가하지 않을 수 있습니다.
3. 디코딩의 유연성을 높이기 위함: 종료 토큰을 추가하지 않으면 모델은 끝까지 텍스트를 자유롭게 생성할 수 있습니다. 이는 모델이 일정한 패턴이나 길이에 구속되지 않고, 더 다양하고 유연한 텍스트를 생성할 수 있도록 합니다. 종료 토큰을 추가하면 생성된 텍스트가 미리 정해진 길이에 도달하거나 종료 토큰을 만나면 멈추게 됩니다.
따라서 시작 토큰을 추가하고 종료 토큰을 추가하지 않는 것은 모델의 문장 생성을 유연하게 조절하고 다양한 상황에 적용할 수 있는 방법입니다. 실제 사용 시나리오에 따라 적합한 방식을 선택할 수 있습니다.
시작 토큰은 문장의 첫 부분으로 프롬프트에서 선별될 수도 있지만, 그렇지 않을 수도 있습니다. 시작 토큰은 모델의 입력 시퀀스에 추가되는 특수한 토큰으로서, 문장의 시작을 나타내는 역할을 합니다.
프롬프트에 따라 시작 토큰을 선택할 수 있습니다. 예를 들어, “나는”이라는 프롬프트가 주어졌을 때, 시작 토큰으로 “나는”을 선택할 수 있습니다. 이렇게 함으로써 모델은 해당 프롬프트 이후에 이어질 문장에 대한 정보를 갖게 됩니다.
그러나 시작 토큰은 프롬프트의 일부로서만 사용되는 것은 아닙니다. 시작 토큰은 문장의 특정 부분이나 상황을 나타내기 위해 임의로 선택될 수도 있습니다. 예를 들어, “오늘은”이라는 시작 토큰을 사용하여 모델에게 “오늘은 어떤 일이 일어날까?”와 같은 질문을 시작할 수 있습니다. 이 경우 시작 토큰은 프롬프트의 일부가 아니라, 문장의 시작에 특정한 의미를 부여하는 역할을 합니다.
따라서 시작 토큰은 프롬프트에 기반하여 선택될 수도 있고, 원하는 문장의 의도나 상황에 따라 임의로 선택될 수도 있습니다. 사용자는 상황에 맞게 시작 토큰을 선택하여 모델에게 원하는 정보를 전달할 수 있습니다.
시작 토큰을 적절하게 만들기 위해서는 다음과 같은 방법을 고려할 수 있습니다:
1. 문맥과 목적에 맞는 단어 선택: 시작 토큰은 문장의 시작을 나타내는 역할을 합니다. 따라서 해당 문장의 문맥과 목적에 맞는 단어를 선택하는 것이 중요합니다. 예를 들어, 자연어 처리 모델에서 “질문”을 생성하기 위한 프롬프트로 시작할 때, “질문을”이라는 시작 토큰을 선택할 수 있습니다.
2. 특수 토큰 활용: 시작 토큰으로 특수한 의미를 갖는 토큰을 사용하는 것도 좋은 방법입니다. 예를 들어, “CLS”라는 토큰은 일반적으로 시작 토큰으로 사용되는데, 이는 “분류(Classification)” 작업에 주로 활용되는 토큰입니다. 모델에게 문장의 시작과 관련된 정보를 알려주는 역할을 할 수 있습니다.
3. 사용자 정의: 시작 토큰은 모델과 작업에 따라 다양한 방식으로 정의될 수 있습니다. 사용자는 자신의 데이터와 목적에 맞게 시작 토큰을 정의할 수 있습니다. 예를 들어, 특정 도메인에서 작업하는 경우, 해당 도메인에 특화된 시작 토큰을 정의하여 사용할 수 있습니다.
시작 토큰을 적절하게 만들기 위해서는 문맥을 고려하고 원하는 의도를 모델에게 전달할 수 있는 단어나 토큰을 선택하는 것이 중요합니다. 데이터의 특성과 작업의 목적에 맞게 시작 토큰을 선택하고, 이를 모델에 적용하여 원하는 결과를 얻을 수 있습니다.
아래 코드에서는 `tokenizer.decode()` 함수를 사용하여 디코딩 작업을 수행하고 있습니다.
decoded = []
for i, t in enumerate(tokens.tolist()):
# cut to max gen len
t = t[: len(prompt_tokens[i]) + max_gen_len]
# cut to eos tok if any
try:
t = t[: t.index(self.tokenizer.eos_id)]
except ValueError:
pass
decoded.append(self.tokenizer.decode(t))
return decoded
`self.tokenizer.decode(t)` 함수를 호출하여 `t`를 디코딩하고, 디코딩된 결과를 `decoded` 리스트에 추가하고 있습니다. 따라서 해당 코드는 함수를 사용하여 디코딩을 수행하고 있습니다.