콘텐츠로 이동

6. NLP와 언어 데이터

이 챕터의 목적

자연어 처리(Natural Language Processing, NLP)는 사람이 사용하는 언어를 컴퓨터가 분석하거나 생성하도록 만드는 분야다. 이 장의 목표는 특정 언어 모델을 능숙하게 구현하는 것이 아니다. 문장을 그대로 신경망에 넣을 수 없는 이유, 텍스트를 학습 가능한 수열로 바꾸는 과정, 그리고 순환 신경망과 seq2seq가 Attention으로 이어진 이유를 하나의 흐름으로 이해하는 것이 목표다.

이 장을 마치면 다음을 설명할 수 있어야 한다.

  • corpus, token, vocabulary, token ID, embedding의 관계
  • 분류, sequence labeling, 번역, language modeling이 서로 다른 출력 문제인 이유
  • RNN이 과거 정보를 hidden state에 담는 방식
  • 고정 길이 context vector가 긴 수열에서 병목이 되는 이유

먼저 알아볼 항목

엄밀한 증명보다 다음 용어의 역할을 알아보면 충분하다.

  • 범주형 변수와 vector
  • sequence와 순서
  • conditional probability \(p(y \mid x)\)
  • classification과 next-step prediction
  • matrix의 행과 열, vector 내적

1. 언어를 데이터 단위로 나누기

연구자가 모은 전체 텍스트 집합을 corpus라고 한다. Corpus에는 여러 document가 있고, document는 문장과 더 작은 단위로 나눌 수 있다. 신경망이 직접 처리하는 가장 기본적인 단위를 token이라고 한다.

Token은 반드시 단어 하나와 같지 않다.

  • Word tokenization은 문장을 단어 단위로 나눈다. 직관적이지만 새로운 단어와 활용형을 처리하기 어렵다.
  • Character tokenization은 글자 단위로 나눈다. 미등록 단어 문제는 줄지만 수열이 길어진다.
  • Subword tokenization은 자주 등장하는 문자열은 하나로, 드문 문자열은 여러 조각으로 나눈다. 현대 언어 모델에서 널리 쓰이는 절충안이다.

예를 들어 딥러닝을 공부한다는 공백 기준 word tokenization에서는 딥러닝을, 공부한다의 두 token으로 나뉜다. Subword 수준에서는 , 러닝, 처럼 더 잘게 나뉠 수 있다. 정확한 분할은 tokenizer가 사용하는 규칙과 vocabulary에 따라 달라진다.

Vocabulary와 token ID

Vocabulary는 모델이 구분하는 token의 목록이다. Tokenizer는 각 token을 vocabulary의 정수 index인 token ID로 바꾼다. 이 정수는 크기나 거리를 의미하지 않는다. ID 200이 ID 100보다 두 배 큰 개념이라는 뜻이 아니다.

Tokenizer는 단순한 전처리 부품이 아니다. 어떤 정보를 보존하는지, 수열이 얼마나 길어지는지, 희귀한 이름과 과학 기호를 어떻게 나누는지에 영향을 준다. 전문 분야 corpus에서는 일반 tokenizer가 화학식이나 재료명을 지나치게 잘게 나눌 수도 있다.

2. 정수 ID를 vector로 바꾸기

신경망은 token ID 자체보다 연속적인 vector를 입력으로 사용한다. 가장 직접적인 표현은 vocabulary 크기만큼 긴 one-hot vector다. 해당 token 위치만 1이고 나머지는 0이다. 그러나 vocabulary가 크면 매우 길고 희소하며, token 사이의 유사성을 나타내지 못한다.

Embedding은 각 token에 학습 가능한 조밀한 vector를 대응시킨다. Embedding matrix를 \(E\), token ID를 \(i\)라 하면 해당 token의 표현은 행 \(E_i\)를 선택한 것으로 볼 수 있다.

비슷한 맥락에서 쓰이는 token이 학습을 통해 비슷한 vector를 가질 수 있다는 점이 핵심이다. 다만 vector가 가까우면 언제나 사람의 의미 판단과 일치한다는 보장은 없다. 학습 corpus의 편향과 목적함수가 embedding에도 반영된다.

Static embedding과 contextual embedding

Word2Vec 같은 static embedding은 같은 token에 항상 같은 vector를 준다. 따라서 눈이 내린다사람의 눈에서 의 표현이 같다. Contextual embedding은 주변 token을 함께 보고 같은 token에도 문맥에 따라 다른 표현을 만든다. 7장의 Transformer는 contextual representation을 만드는 대표적인 구조다.

3. 길이가 다른 문장을 batch로 만들기

문장은 길이가 서로 다르다. 여러 문장을 하나의 batch tensor로 묶으려면 보통 다음 처리가 필요하다.

  • Padding은 짧은 수열 뒤에 특별한 padding token을 붙여 길이를 맞춘다.
  • Truncation은 최대 길이를 넘는 수열 일부를 자른다.
  • Mask는 padding처럼 계산에서 제외해야 할 위치를 모델에 알려준다.

Truncation은 단순한 메모리 설정이 아니다. 중요한 정보가 문서 뒤쪽에 있다면 입력을 자르는 정책이 성능과 해석을 바꾼다. Mask를 잘못 적용하면 모델이 실제 문장 대신 padding 위치까지 참고한다.

4. 같은 텍스트라도 출력 문제는 다르다

NLP는 하나의 task가 아니라 여러 예측 문제의 모음이다.

  • Text classification은 문서나 문장 전체에 하나의 label을 예측한다. 감성 분류와 문서 주제 분류가 예다.
  • Sequence labeling은 각 token에 label을 예측한다. 품사 태깅과 개체명 인식이 예다.
  • Sequence-to-sequence는 입력 수열로부터 다른 수열을 만든다. 번역과 요약이 예다.
  • Language modeling은 주어진 문맥에서 token의 확률을 학습한다.

Autoregressive language model은 앞의 token \(x_{<t}\)가 주어졌을 때 다음 token의 조건부 확률을 학습한다.

\[ p(x_1, \ldots, x_T) = \prod_{t=1}^{T} p(x_t \mid x_{<t}) \]

이 분해는 문장을 한 번에 외우는 대신, 지금까지의 문맥으로 다음 token을 예측하는 문제로 바꾼다. 다음 token을 하나 고르는 규칙까지 포함해야 실제 생성이 되며, 가장 확률이 높은 token만 고르는 방식과 확률적으로 sampling하는 방식은 서로 다른 결과를 낸다.

신경망 이전의 baseline

Bag-of-WordsTF-IDF는 문서에 어떤 단어가 얼마나 나타나는지를 나타내는 feature 표현이다. 언어 모델 자체는 아니며, 선형 분류기 같은 모델과 결합하면 강력한 baseline이 될 수 있지만 일반적으로 단어 순서를 직접 표현하지 않는다. 이 가운데 n-gram language model은 바로 앞의 제한된 token들을 조건으로 다음 token을 추정하는 언어 모델이다. 이 방법들은 단순하기 때문에 실패 원인을 분석하기 쉽고, 신경망 모델의 개선이 실제로 필요한지 확인하는 비교 기준이 된다.

5. RNN은 순서를 어떻게 처리하는가

Feed-forward network는 고정된 입력을 한 번에 처리한다. 반면 Recurrent Neural Network(RNN)은 수열을 왼쪽에서 오른쪽으로 읽으며 이전 정보를 hidden state에 누적한다.

\[ h_t = f(h_{t-1}, x_t), \qquad y_t = g(h_t) \]

\(x_t\)는 현재 token의 embedding, \(h_{t-1}\)은 이전 단계까지의 요약, \(h_t\)는 갱신된 hidden state다. 같은 update 함수를 모든 시점에 공유하므로 길이가 달라도 같은 원리로 처리할 수 있다.

그러나 긴 수열에서는 먼 시점의 정보를 hidden state에 유지하기 어렵고, 시간 순서대로 계산해야 해서 병렬화가 제한된다. LSTMGRU는 정보를 보존하거나 버리는 gate를 도입해 기본 RNN의 장기 의존성 문제를 완화한다. 이를 완전히 없애는 것은 아니다.

Bidirectional RNN은 왼쪽과 오른쪽 문맥을 모두 본다. 전체 입력이 이미 주어진 분류나 labeling에는 유용하지만, 미래 token을 볼 수 없어야 하는 autoregressive generation에는 그대로 사용할 수 없다.

6. Encoder와 decoder로 수열을 변환하기

번역처럼 입력과 출력의 길이가 다른 문제에서는 encoder-decoder 구조를 사용할 수 있다. Encoder RNN은 입력 문장을 읽어 context vector를 만들고, decoder RNN은 그 vector를 바탕으로 출력 token을 하나씩 생성한다.

학습 중에는 decoder의 이전 입력으로 실제 정답 token을 넣는 teacher forcing을 사용할 수 있다. 추론 중에는 실제 정답이 없으므로 모델이 직전에 생성한 token을 다시 입력해야 한다. 이 차이 때문에 학습 중에는 잘 작동하던 모델이 생성 중 누적 오류를 겪을 수 있다.

초기 seq2seq에서는 입력 전체를 하나의 고정 길이 vector에 압축했다. 짧은 문장에서는 가능하지만 긴 문장의 모든 관계를 한 vector에 보존하기 어렵다. 번역할 출력 단어마다 참고해야 하는 입력 위치도 다르다. 바로 이 병목이 다음 장의 질문을 만든다.

Decoder가 매 시점마다 encoder의 모든 위치를 살펴보고, 지금 필요한 입력에 더 큰 가중치를 줄 수는 없는가?

핵심과 노출 수준 구분

핵심으로 이해할 것

  • 원문에서 token, ID, embedding tensor로 이어지는 변환
  • tokenizer 선택이 vocabulary와 sequence length에 미치는 영향
  • NLP task마다 출력 단위와 학습 목표가 다르다는 사실
  • RNN hidden state와 seq2seq의 고정 context 병목

이름과 위치를 알아둘 것

  • Bag-of-Words, TF-IDF, n-gram
  • Word2Vec의 CBOW와 Skip-gram
  • Byte Pair Encoding(BPE), WordPiece
  • LSTM, GRU, bidirectional model
  • teacher forcing
  • masked-token prediction과 next-token prediction

세부 알고리즘을 모두 유도할 필요는 없다. 어떤 문제를 해결하기 위해 등장했고, 입력과 출력이 무엇인지 말할 수 있으면 된다.

자주 생기는 혼동과 한계

token은 단어와 같지 않다

하나의 단어가 여러 subword token으로 나뉠 수 있고, 공백이나 문장 부호가 독립 token이 될 수도 있다. Token 수와 단어 수를 같은 것으로 해석하면 안 된다.

token ID에는 순서나 의미 거리가 없다

정수 ID는 vocabulary에서 token을 찾기 위한 index다. 의미적 관계는 embedding과 이후 문맥 처리에서 학습된다.

language model은 사실 데이터베이스가 아니다

다음 token의 조건부 분포를 학습했다는 사실만으로 사실성, 최신성, 출처 추적이 보장되지는 않는다.

  • Corpus의 표본 편향과 중복은 모델의 표현과 평가에 영향을 준다.
  • 무작위 train/test 분할은 같은 문서의 중복이나 가까운 문장이 양쪽에 들어가는 leakage를 만들 수 있다.
  • 긴 입력을 자르면 task에 필요한 근거가 사라질 수 있다.
  • 같은 accuracy라도 희귀 class, 고유명사, 전문 용어에서 실패 양상이 다를 수 있다.

공통 분석축으로 정리하기

  • 입력과 출력: token ID 수열을 받아 문장 label, token label 또는 다음 token 분포를 출력한다.
  • 구조적 가정: token의 순서와 주변 문맥이 중요하다.
  • 표현: discrete token을 embedding으로 바꾸고 수열 문맥을 hidden state나 contextual vector에 담는다.
  • 학습 신호: task label, 다음 token 또는 가려진 token이 정답이 될 수 있다.
  • Baseline: majority class, TF-IDF와 선형 분류기, n-gram 모델처럼 단순한 기준을 먼저 둔다.
  • 평가와 shift: 문서 출처, 시간, 도메인, 언어가 달라졌을 때도 성능이 유지되는지 확인한다.

다음 장과의 연결

7장에서는 입력 전체를 하나의 고정 vector로 압축하지 않고, 현재 출력에 필요한 위치를 직접 선택하는 Attention을 다룬다. Tokenization과 embedding은 그대로 유지되지만, 수열의 관계를 모으는 방식이 RNN의 recurrence에서 self-attention으로 바뀐다.

스스로 확인하기

  • Token ID와 embedding vector는 각각 어떤 정보를 담는가?
  • Text classification, sequence labeling, language modeling은 출력 단위가 어떻게 다른가?
  • Static embedding과 contextual embedding은 같은 token을 어떻게 다르게 표현하는가?
  • RNN encoder의 고정 context vector가 Attention의 필요성으로 이어지는 이유는 무엇인가?

더 읽을 자료