카테고리 없음

스파르타 AI-8기 TIL(11/6) -> 임베딩, Word2Vec

kimjunki-8 2024. 11. 6. 21:09
임베딩
임베딩(Embedding)은 고차원 데이터를 컴퓨터가 이해할 수 있도록 저차원 벡터로 변환하는 기술입니다. 예를 들어, 텍스트나 이미지 같은 고차원 데이터를 숫자 벡터로 표현해 다양한 인공지능 모델이 처리할 수 있게 합니다. 임베딩은 주로 자연어 처리(NLP), 이미지 인식, 추천 시스템 등에서 사용되며, 각 데이터 간의 유사성이나 관계를 벡터 공간에서 나타낼 수 있게 합니다.
1. 단어 임베딩 (Word Embedding)
단어 임베딩은 단어를 벡터로 표현하는 방식입니다. 이를 통해 단어 간의 유사성을 벡터 공간에서 파악할 수 있으며, 대표적으로 Word2Vec과 GloVe가 있습니다. 이 임베딩을 통해 단어 사이의 의미적 유사성을 계산할 수 있습니다.

gensim 라이브러리를 사용하여 Word2Vec 모델을 구현
from gensim.models import Word2Vec

# 예제 문장
sentences = [["I", "love", "machine", "learning"], ["Word", "embedding", "is", "fun"]]

# Word2Vec 모델 학습
model = Word2Vec(sentences, vector_size=10, window=2, min_count=1, workers=4)

# 단어 'machine'의 임베딩 벡터 출력
print(model.wv['machine'])


vector_size는 임베딩 벡터의 차원을, window는 주변 단어 개수를 설정합니다. min_count는 최소 등장 횟수로, 지정한 값보다 적게 나타난 단어는 학습에서 제외됩니다. 
wv는 Word2Vec 모델에서 word vectors의 약자입니다. model.wv는 학습된 단어 벡터를 담고 있는 속성으로, 단어의 임베딩 벡터에 접근할 수 있게 합니다.


2. 문장 임베딩 (Sentence Embedding)
문장 임베딩은 문장을 고차원 벡터로 표현하여 문장 간의 유사성을 측정할 수 있게 합니다. Sentence-BERT와 같은 방법이 많이 쓰입니다.

from sentence_transformers import SentenceTransformer

# 모델 로드
model = SentenceTransformer('all-MiniLM-L6-v2')

# 문장 임베딩
sentence = "I love machine learning."
embedding = model.encode(sentence)

# 임베딩 벡터 출력
print(embedding)

SentenceTransformer에서 미리 학습된 모델을 불러옵니다. 이 모델은 문장 임베딩을 생성하는 데 최적화되어 있습니다. model.encode(sentence)는 입력 문장의 임베딩 벡터를 생성하며, 문장의 의미를 나타내는 벡터가 출력됩니다.

3. 이미지 임베딩 (Image Embedding)
이미지 임베딩은 이미지를 벡터로 변환하여 이미지 간의 유사성을 계산하거나 이미지 분류에 사용됩니다. Convolutional Neural Network (CNN) 기반의 임베딩 방법이 많이 사용됩니다.

import tensorflow as tf
from tensorflow.keras.applications import VGG16
from tensorflow.keras.applications.vgg16 import preprocess_input
from tensorflow.keras.preprocessing import image
import numpy as np

# 사전 학습된 VGG16 모델 불러오기
model = VGG16(weights='imagenet', include_top=False)

# 임베딩할 이미지 불러오기
img_path = 'path_to_image.jpg'
img = image.load_img(img_path, target_size=(224, 224))
img_data = image.img_to_array(img)
img_data = np.expand_dims(img_data, axis=0)
img_data = preprocess_input(img_data)

# 이미지 임베딩 추출
embedding = model.predict(img_data)
print(embedding.shape)

사전 학습된 VGG16 모델을 불러옵니다. include_top=False는 상단의 분류 레이어를 제거해 이미지 특징 벡터만 남깁니다. 지정한 이미지를 모델에 맞는 크기로 조정하고, 전처리합니다. 이미지를 모델에 입력하여 임베딩 벡터를 추출합니다.(코드 설명이 길 것 같아 그냥 '아 이런게 있구나'라고 생각하고 있습니다)

4. 사용자 임베딩 (User Embedding)
추천 시스템에서 사용자의 선호도나 행동을 벡터화하여 유사한 사용자끼리 유사한 추천을 제공할 수 있습니다.

import numpy as np
from sklearn.decomposition import TruncatedSVD

# 사용자-아이템 평점 행렬 예시
ratings = np.array([
    [5, 3, 0, 1],
    [4, 0, 0, 1],
    [1, 1, 0, 5],
    [1, 0, 0, 4],
    [0, 1, 5, 4],
])

# SVD 모델 학습
svd = TruncatedSVD(n_components=2)
user_embedding = svd.fit_transform(ratings)

# 사용자 임베딩 벡터 출력
print(user_embedding)

사용자-아이템 상호작용 데이터를 사용하여 행렬을 만듭니다. TruncatedSVD를 사용해 평점 행렬을 저차원 벡터로 변환합니다. 각 사용자에 대한 임베딩 벡터가 생성됩니다.


Wod2Vec
Word2Vec는 단어를 벡터로 표현하여 단어 간의 의미적 유사성을 파악할 수 있게 해주는 도구입니다. 이 모델은 자연어 처리에서 단어와 문장, 문서 간의 관계를 벡터 공간에서 파악할 때 자주 사용됩니다.
Word2Vec의 주요 역할은 단어를 고정 길이의 실수 벡터로 변환하는 것입니다. 이 벡터는 단어의 의미를 반영하며, 단어 간의 유사도나 관계성을 수치적으로 나타낼 수 있습니다. 예를 들어, 학습된 벡터 공간에서는 "king" - "man" + "woman" ≈ "queen"과 같은 관계가 성립할 수 있습니다. 이처럼 Word2Vec은 단어의 의미적 유사성을 벡터 연산을 통해 이해할 수 있도록 돕습니다.

Word2Vec 생성 시 주요 속성들
Word2Vec 모델을 생성할 때 다양한 속성을 설정할 수 있습니다.

1. sentences
학습에 사용될 문장이나 단어 리스트를 제공합니다.
각 문장은 단어 리스트로 전처리된 형태여야 합니다.

2. vector_size
생성할 단어 벡터의 크기를 지정합니다.
큰 값을 지정하면 더 많은 정보를 담을 수 있지만, 계산 비용이 증가합니다. 일반적으로 100~300 사이의 값이 자주 사용됩니다.

3. window
주변 단어를 고려할 범위를 지정합니다.
예를 들어 window=5라면 현재 단어를 기준으로 앞뒤로 5개의 단어를 참고해 학습합니다.
주변 단어를 고려할 범위를 넓히면 전반적인 문맥을 반영할 수 있지만, 특정 의미를 놓칠 가능성도 있습니다.

4. min_count
학습에 포함될 단어의 최소 빈도수를 설정합니다.
이 값보다 적게 등장하는 단어는 모델에서 제외됩니다. 자주 등장하는 단어에 집중하기 위해 주로 사용됩니다.

5. sg
학습 방식을 지정하는 옵션입니다.
sg=0이면 CBOW 방식을 사용하고, sg=1이면 Skip-gram 방식을 사용합니다.
CBOW는 빠르고, 데이터가 적은 경우에 효과적입니다. Skip-gram은 데이터가 많고, 희귀한 단어들에 유리한 방식입니다.

6. epochs
모델이 데이터 전체에 대해 학습할 횟수를 지정합니다.
epochs 값을 높이면 더 오랜 시간 동안 학습할 수 있지만, 과적합의 위험이 커질 수 있습니다.

7. workers
병렬 처리를 위해 사용할 CPU 코어의 수를 지정합니다.
workers를 늘리면 모델 학습 속도가 빨라집니다. (Windows에서는 기본적으로 workers=1로 작동합니다.)

8. hs
계층적 softmax(hierarchical softmax) 사용 여부를 설정합니다.
hs=1로 설정하면, hierarchical softmax가 활성화됩니다. 이는 클래스 수가 많을 때 학습 속도를 높일 수 있습니다.
hs=0이면 네거티브 샘플링(negative sampling)을 사용할 수 있습니다.

9. negative
네거티브 샘플링 시 사용할 단어의 수를 설정합니다.
negative는 hs=0일 때만 사용 가능합니다. 일반적으로 5~20 사이 값을 지정합니다.

10. seed
초기 랜덤 시드를 설정합니다.
이를 통해 모델을 여러 번 실행해도 동일한 결과를 얻을 수 있습니다.

강의 실습 코드
from gensim.models import Word2Vec
from gensim.utils import simple_preprocess
from scipy.spatial.distance import cosine
sentence = [
    'The quick brown fox jumps over the lazy dog.'
    'I love playing with my pet dog'
    'The dog bartks at the stranger'
    'The cat sleeps on the sofa'
]
processed = [simple_preprocess(sentences) for sentences in sentence]
print(processed)
model = Word2Vec(sentences = processed, vector_size = 5, window = 5, min_count = 1, sg = 0)
dog = model.wv['dog']
cat = model.wv['cat']

sim = 1 - cosine(dog,cat)
print(sim)

여기서 simple_preprocess란 것이 있습니다.
simple_preprocess는 Gensim에서 제공하는 텍스트 전처리 함수로, 텍스트를 단어 단위로 분리하고 토큰화하는 역할을 합니다. 이 함수는 tokenizer와 비슷한 역할을 하지만, 몇 가지 추가적인 전처리 작업을 포함하고 있습니다.

simple_preprocess 함수는 간단한 전처리와 토큰화를 수행하여 텍스트를 모델에 적합한 형태로 만들어 줍니다. 주요 기능은 다음과 같습니다:

토큰화 (Tokenization):
텍스트를 단어 단위로 나누어 줍니다. 즉, 문장을 각 단어 단위로 나누어 리스트 형태로 반환합니다.

소문자 변환:
모든 단어를 소문자로 변환합니다. 이렇게 하면 "Dog"와 "dog" 같은 단어가 동일하게 처리됩니다.

특수 문자 제거:
단어가 아닌 특수 문자와 숫자는 제거됩니다. 예를 들어, 구두점(. , , 등)과 같은 문자는 제거되어 깔끔한 단어 리스트를 얻을 수 있습니다.

짧은 단어 필터링:
기본적으로 simple_preprocess는 길이가 2 미만인 단어는 제외합니다. (예: 'a', 'I' 같은 한 글자 단어)

imple_preprocess는 텍스트를 모델 학습에 적합한 형태로 쉽게 만들어주는 전처리 도구입니다. tokenizer와 비슷한 역할을 하지만, 불필요한 문자 제거나 짧은 단어 필터링 같은 추가적인 전처리 작업을 자동으로 포함하여, 일반적인 NLP 작업에서 간단하게 사용할 수 있도록 설계되었습니다.

from gensim.utils import simple_preprocess

text = "The quick brown fox jumps over the lazy dog!"
tokens = simple_preprocess(text)
print(tokens)

예측:

['the', 'quick', 'brown', 'fox', 'jumps', 'over', 'the', 'lazy', 'dog']

즉, 소문자로 변환되고, 특수 문자가 제거된 단어 리스트를 얻을 수 있습니다.

즉, 전처리된 단어들을 전달해 각 연관성을 보는 코드입니다.


실습 코드(BART)
from transformers import BertModel, BertTokenizer
import torch
from scipy.spatial.distance import cosine
model_name = 'bert-base-uncased'
tokenizer = BertTokenizer.from_pretrained(model_name)
model = BertModel.from_pretrained(model_name)
sentences = [
    'The qukck brown fox jumps over the lazy dog',
    'the king is God'
]

input1 = tokenizer(sentences[0], return_tensors = 'pt')
input2 = tokenizer(sentences[1], return_tensors = 'pt')
with torch.no_grad():
    output1 = model(**input1)
    output2 = model(**input2)
embedding1 = output1.last_hidden_state.mean(dim=1).squeeze().cpu().numpy()
embedding2 = output2.last_hidden_state.mean(dim=1).squeeze().cpu().numpy()
similarity = 1 - cosine(embedding1, embedding2)
print(f"Cosine similarity between the two sentences: {similarity:.4f}")

윗 부분은 이미 알고 있으니 생략하겠습니다.
아 참고로 

input1 = tokenizer(sentences[0], return_tensors = 'pt')
input2 = tokenizer(sentences[1], return_tensors = 'pt')

이 부분은 따로 문장을 나누어서 계산을 따로 하는데, 사실 저렇게 안 하고 전체적으로 계산해도 상관은 없습니다.

inputs = tokenizer(sentences, return_tensors='pt')

그리고 **이 뭔지 궁금하실 수 있습니다.
**는 파이썬의 언팩킹(unpacking) 기능을 나타냅니다. 이 문법은 딕셔너리(dictionary) 형태의 데이터를 함수의 인자로 전달할 때 사용됩니다.
**를 사용하면, 딕셔너리의 키-값 쌍을 함수의 인자로 자동으로 변환할 수 있습니다. 즉, 딕셔너리의 각 키는 함수의 매개변수 이름과 일치해야 하며, 해당 키의 값은 함수의 매개변수 값으로 사용됩니다.

def greet(name, age):
    print(f"Hello, {name}! You are {age} years old.")

# 딕셔너리 생성
person_info = {
    'name': 'Alice',
    'age': 30
}

# 언팩킹하여 함수에 전달
greet(**person_info)  # Hello, Alice! You are 30 years old.

embedding1 = output1.last_hidden_state.mean(dim=1).squeeze().cpu().numpy()
embedding2 = output2.last_hidden_state.mean(dim=1).squeeze().cpu().numpy()

embedding1 = output1.last_hidden_state.mean(dim=1).squeeze().cpu().numpy() : output1.last_hidden_state.mean(dim=1): last_hidden_state는 문장의 각 토큰에 대해 BERT가 생성한 마지막 은닉층 벡터를 포함하고 있습니다. mean(dim=1)을 사용해 모든 토큰의 벡터 평균을 계산하여 문장의 전체 임베딩을 만듭니다. 
그리고, squeeze().cpu().numpy(): 불필요한 차원을 제거하고, CPU 메모리로 이동시켜 NumPy 배열로 변환합니다. embedding1과 embedding2는 각각 두 문장의 벡터 표현입니다.
last_hidden_state.mean(dim=1)는 BERT 모델의 출력인 last_hidden_state 텐서에서 각 문장의 임베딩을 계산하는 방법입니다.
여기서, last_hidden_state는 BERT 모델이 입력 문장에 대해 생성한 마지막 은닉층(hidden layer)에서의 출력입니다. 이 출력은 입력 문장의 각 토큰(token)마다 해당하는 벡터 표현으로 이루어져 있습니다.

last_hidden_state는 일반적으로 3차원 텐서 형태를 가지며, 그 형상은 (batch_size, sequence_length, hidden_size)입니다.
batch_size: 한 번에 처리하는 문장 수
sequence_length: 각 문장에서 토큰의 수 (패딩이 포함될 수 있음)
hidden_size: BERT 모델의 은닉 상태의 크기 (예: bert-base-uncased의 경우 768)

mean(dim=1)는 주어진 텐서의 특정 차원에 대해 평균을 계산하는 함수입니다.
여기서 dim=1은 sequence_length 차원을 의미합니다. 즉, 각 문장에 포함된 모든 토큰의 벡터를 평균내어 하나의 벡터로 만듭니다.

input1과 input2: 각각 첫 번째와 두 번째 문장의 토큰화된 텐서 입력입니다.


번역 모델-M2M100
from transformers import M2M100ForConditionalGeneration, M2M100Tokenizer

model_name = 'facebook/m2m100_418M'
tokenizer = M2M100Tokenizer.from_pretrained(model_name)
model = M2M100ForConditionalGeneration.from_pretrained(model_name)

sentence = ['The qukck brown fox jumps over the lazy dog']
encoded_sentence = tokenizer(sentence, return_tensors = 'pt')

tokenizer.src_lang = 'en'
model.config.forced_bos_token_id = tokenizer.get_lang_id('ko')

generated_tokens = model.generate(**encoded_sentence)

translated_token = tokenizer.decode(generated_tokens[0], skip_special_tokens = True)
print(f'Translated text: {translated_token}')
model_name = 'facebook/m2m100_418M'
tokenizer = M2M100Tokenizer.from_pretrained(model_name)
model = M2M100ForConditionalGeneration.from_pretrained(model_name)

facebook/m2m100_418M라는 모델 이름으로 미리 학습된 M2M100 모델과 토크나이저를 불러옵니다. 418M은 이 모델의 파라미터 수를 나타냅니다.

sentence = ['The quick brown fox jumps over the lazy dog']
encoded_sentence = tokenizer(sentence, return_tensors='pt')

번역할 영어 문장 sentence를 설정하고 tokenizer를 사용하여 토큰화합니다. return_tensors='pt'는 PyTorch 텐서로 변환하여 모델에 전달할 수 있도록 합니다.

tokenizer.src_lang = 'en'
model.config.forced_bos_token_id = tokenizer.get_lang_id('ko')

먼저 왜 tokenizer이고 .src_lang이 뭔지 알아보겠습니다.
여기서 토크나이저는 단순히 텍스트를 숫자 토큰으로 바꾸는 역할을 할 뿐만 아니라, M2M100 모델이 문장을 어떤 언어로 인식할지를 결정하는 역할도 합니다. src_lang를 통해 입력 언어를 지정하면, 토크나이저가 입력 언어의 특성을 반영하여 텍스트를 토큰화하고, 모델이 이를 적절히 해석할 수 있도록 도와줍니다.

src_lang는 번역할 소스 언어를 의미하며, 모델이 입력 문장이 어떤 언어인지 알 수 있도록 해줍니다. 이 경우에는 src_lang = 'en'으로 설정했으므로 입력 언어가 영어(English)임을 모델이 알게 됩니다. 이렇게 설정하면 모델이 입력을 영어로 인식하고, 지정된 목표 언어(한국어)로 번역할 준비를 합니다.

tokenizer.src_lang을 설정하면 모델과 토크나이저 모두에 필요한 언어 정보가 한곳에서 관리됩니다. 따라서 모델 사용자가 일일이 언어 설정을 따로 관리할 필요가 줄어들어 사용이 간편해집니다.

그리고 여기서 model.config는 모델의 설정(configuration) 객체입니다. 이 안에 모델이 번역을 수행할 때 참고하는 다양한 설정 값들이 포함되어 있습니다.
모델의 동작 방식을 제어하는 여러 파라미터를 설정할 수 있습니다. 예를 들어 forced_bos_token_id는 그중 하나의 설정입니다.

그리고 forced_bos_token_id는 문장의 시작 토큰을 특정 언어로 강제하는 파라미터입니다.
M2M100 모델은 모든 번역에서 번역된 문장이 어떤 언어로 시작해야 하는지를 이 forced_bos_token_id 설정으로 결정합니다. 이 설정을 통해 모델이 결과 언어를 정확하게 지정된 언어로 번역하게 됩니다.

tokenizer.get_lang_id('ko')는 한국어('ko')에 해당하는 언어 ID를 가져오는 함수입니다. M2M100 모델은 각 언어를 특정 숫자 ID로 관리합니다. 예를 들어, ko는 한국어를 나타내는 고유한 ID가 있고, get_lang_id('ko')를 호출하면 이 ID 값을 반환합니다. 이 ID는 forced_bos_token_id에 할당되어 번역 결과가 한국어로 나오도록 강제하는 역할을 합니다.

요약하면,

tokenizer.src_lang = 'en'은 입력 텍스트의 언어를 지정하는 것입니다. M2M100 모델이 입력 텍스트를 올바르게 해석할 수 있도록, 토크나이저에게 "이 텍스트는 영어"라는 정보를 전달하는 역할을 합니다.
src_lang 설정은 모델이 어떤 언어를 입력으로 받을지 알려주는 역할을 할 뿐, 출력 언어와는 관련이 없습니다.

tokenizer.get_lang_id('ko') 부분은 모델이 출력 텍스트의 언어를 결정하기 위해 필요한 언어 ID를 얻는 것입니다.
get_lang_id('ko')는 "한국어"라는 언어에 대응하는 고유한 숫자 ID를 반환합니다. 이 ID를 model.config.forced_bos_token_id에 설정하면, 모델이 번역 결과를 한국어로 강제하여 생성합니다.

generated_tokens = model.generate(**encoded_sentence)

여기 **encoded_sentence에서 **를 사용하는 이유로는, model.generate(**encoded_sentence)에서 **를 붙이면, 딕셔너리 안의 각 키-값 쌍이 개별 인수로 풀려서 generate 함수에 전달됩니다. 즉, input_ids=encoded_sentence['input_ids'], attention_mask=encoded_sentence['attention_mask']와 같은 형태로 전달됩니다.
따라서 **는 딕셔너리를 풀어서 generate 함수가 필요한 각 인수를 개별적으로 인식할 수 있게 해 주는 역할을 합니다.

게다가 model에서 출력은, model.generate(**encoded_sentence)에서 번역 결과가 한국어로 나오도록 바로 이전 단계에서 **model.config.forced_bos_token_id**에 한국어 ID를 지정했으므로, 한국어로 번역되어 나옵니다.

전체적인 흐름을 보자면,
tokenizer.src_lang = 'en'으로 입력 언어를 영어로 설정했고, 이렇게 하면 모델이 입력 텍스트를 영어로 해석할 준비를 합니다.

model.config.forced_bos_token_id = tokenizer.get_lang_id('ko')로 출력 언어를 한국어로 설정했습니다.
그리고, forced_bos_token_id에 한국어 ID를 지정하면, 모델이 번역 결과를 한국어로 생성하도록 강제됩니다.
model.generate(**encoded_sentence):

이제 generate 함수는 설정된 입력과 출력 언어에 따라 번역을 수행합니다. 이 단계에서는 모델이 이미 입력 언어는 영어, 출력 언어는 한국어로 설정되었기 때문에, 번역 결과가 한국어로 출력됩니다.

translated_token = tokenizer.decode(generated_tokens[0], skip_special_tokens=True)
print(f'Translated text: {translated_token}')


그런데 번역된 결과는 하나뿐이라 generated_tokens[0]에서 첫 번째 결과를 가져오는 것이 조금 의아하게 느껴질 수 있습니다. 하지만 이렇게 generated_tokens[0]을 쓰는 이유는 generate 함수가 여러 개의 번역 결과를 생성할 수 있는 구조이기 때문입니다. 하지만, 기본적으로는 num_return_sequences=1이므로 하나의 결과만 나오지만, generate의 출력은 항상 리스트 형태로 반환됩니다. 따라서, 첫 번째 결과를 가져오려면 generated_tokens[0]을 사용해야 합니다.

다른 번역 모델-NLLB-200
import warnings
warnings.filterwarnings(action = 'ignore')
from transformers import AutoModelForSeq2SeqLM, AutoTokenizer

model_name = 'facebook/nllb-200-distilled-600M'
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForSeq2SeqLM.from_pretrained(model_name)

sentence = ['The qukck brown fox jumps over the lazy dog']
input = tokenizer(sentence, return_tensors = 'pt')

tokenizer.src_lang = 'en'
ko_lang_id = 200 
generated_tokens = model.generate(input.input_ids, 
forced_bos_token_id = ko_lang_id)

translated_text = tokenizer.decode(generated_tokens[0], skip_special_tokens =True)
translated_text

바뀐 부분만 설명하겠습니다.

ko_lang_id = 200

이것은 NLLB 모델에서 제공하는 언어 ID입니다 한국어는 200입니다.

input.input_ids
 

input.input_ids는 Hugging Face Transformers 라이브러리에서 입력 텍스트를 모델이 이해할 수 있는 형식으로 변환한 후의 숫자 표현을 의미합니다.
input.input_ids의 이해
토크나이제이션 (Tokenization):
입력 텍스트가 모델에 의해 처리되기 전에, 텍스트는 토크나이저에 의해 토큰이라는 작은 단위로 분할됩니다. 이러한 토큰은 단어, 서브워드, 또는 문자일 수 있습니다.
예를 들어, "The quick brown fox jumps over the lazy dog"라는 문장은 여러 개의 토큰으로 나누어집니다.

ID 매핑:
각 토큰은 고유한 정수 ID로 매핑됩니다. 이 매핑은 토크나이저의 어휘에 정의되어 있습니다.
예를 들어, "The"라는 단어는 ID 101로, "quick"는 ID 102로 매핑될 수 있습니다. 결과적으로 이러한 ID 목록이 생성되어 모델에 전달됩니다.

구조:
tokenizer(sentence, return_tensors='pt')를 호출하면, 토크나이저는 문장을 처리하여 보통 두 가지 항목이 포함된 딕셔너리를 반환합니다:
input_ids: 토큰에 대한 숫자 ID 목록.
attention_mask: 모델이 주목해야 할 토큰을 나타내는 마스크로, 패딩된 토큰에는 0, 실제 입력된 토큰에는 1이 할당됩니다.
이러한 input_ids는 모델에 전달되어 입력으로 사용됩니다.


예를 들어 "The quick brown fox jumps over the lazy dog"라는 문장은 다음과 같은 방식으로 처리될 수 있습니다:

토큰화된 결과: ["The", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog"]
매핑된 ID: [101, 102, 103, 104, 105, 106, 107, 108, 109] (이 숫자는 예시로 사용된 것일 뿐이며, 실제로는 모델의 어휘에 따라 달라질 수 있습니다.)

즉, 모델은 직접적인 문자열을 처리할 수 없으며, 이를 숫자로 변환해야 하는데, input.input_ids는 이러한 숫자 ID의 목록을 제공하여 모델이 텍스트를 이해할 수 있게 해줍니다.

여기까지..