본문 바로가기

AI Theory/NLP

기계 번역의 역사

기계 번역의 역사

신경망 기반 번역기 이전의 역사

  • 규칙 기반 기계 번역(RBMT, Rule Based Machine Translation)
    • 언어 간 번역 규칙을 기반으로 번역. 이 때 규칙들은 언어 간 문법, 어휘 및 구문적 차이 고려
    • 장점: 정교한 언어 규칙을 활용해 특정 도메인의 번역에 효과적
    • 단점: 규칙을 개발하고 유지하는 데 많은 인적 자원, 시간이 필요하며 다양한 언어에 대해 일반화가 어려움
  • 통계적 기계 번역(SMT, Statiscal Machine Translation)
    • 대규모 병렬 말뭉치를 기반으로 통계 모델을 학습하여 번역. 확률 분포를 사용해 다음 단어를 선택함
    • 장점: 대용량의 데이터를 활용해 다양한 언어쌍에 대한 번역 수행 가능, 문맥을 고려한 번역 가능
    • 단점: 훈련 데이터의 부족, 품질 문제가 번역 품질에 영향을 줌, 본적 없는 문장에 대한 모델링 불가능, 문장 어순 고려 안함.
      • 희소 문제: 목표하는 문장이 훈련 데이터에 없을 경우 올바른 문장임에도 확률을 0으로 설정하는 문제
  • 구문 기반 번역(PBMT, Phrase Based Machine Translation)
    • SMT의 한 종류로, 입력 문장을 구문적 단위(구, 구문)으로 분석하고 번역할 때 구 단위로 재조합해 번역
    • 장점: 문장 내 구조를 고려하여 자연스러운 번역 생성 가능
    • 단점: SMT이므로 데이터 부족 및 품질, 모델 복잡성에 문제가 있을 수 있다.
  • 신경망 기계 번역(Neural Machine Translation)
    • 인공신경망을 사용해 번역 모델을 학습하고 입력 문장을 고정 크기의 벡터로 인코딩하고 디코더를 사용해 출력 문장을 생성함
    • 장점: 대용량 데이터, 계산 능력을 사용해 더 자연스러운 번역을 생성하며 다양한 언어 간 번역이 가능함
    • 단점: 모델 학습 및 인퍼런스에 높은 계산 비용이 필요하며 데이터 양이 중요함

모델의 문장생성 알고리즘(3)

1. Greedy Decoding

다음은 문장을 생성하는 예제 코드이다.

def generate_text(model, tokenizer, init_sentence="<start>", max_len=20):
    test_input = tokenizer.texts_to_sequences([init_sentence])
    test_tensor = tf.convert_to_tensor(test_input, dtype=tf.int64)

    end_token = tokenizer.word_index["<end>"]

    while True:
        predict = model(test_tensor)
        predict_word = tf.argmax(tf.nn.softmax(predict, axis=-1), axis=-1)[:, -1]

        test_tensor = tf.concat([test_tensor, tf.expand_dims(predict_word, axis=0)], axis=-1)

        if predict_word.numpy()[0] == end_token: break
        if test_tensor.shape[1] >= max_len: break

    generated = ""
    for word_index in test_tensor[0].numpy():
        generated += tokenizer.index_word[word_index] + " "

    return generated

이 때, 단어를 결정할 때 predict값을 softmax를 통해 확률 값으로 변환한 뒤 가장 높은 확률을 갖는 단어를 다음 단어로 결정하는데 이는 Greedy Decoding을 사용한 것이다.

predict_word = tf.argmax(tf.nn.softmax(predict, axis=-1), axis=-1)[:, -1]

Greedy Decoding이란 미리 정한 기준에 따라 매번 가장 좋아보이는 답을 선택하는 알고리즘이다. 동적 계획법과 마찬가지로 최적화 문제를 푸는데 사용한다. 그러나 탐욕 알고리즘은 동적 계획법보다는 효율적이지만 동적 계획법처럼 반드시 최적의 해를 구해준다는 보장을 하지 못한다.

greedy decoding의 순서는 다음과 같다. 1.현재 최적의 해를 구하고 이를 집합에 추가한다. 2. 새로운 부분해 집합이 적절한지 검사한다. 3. 새로운 부분해 집합이 문제의 해가 되는지 검사한다. 아직 문제의 해가 완성되지 않았다면 1번부터 시작한다.

greedy decoding을 통해 풀 수 있는 문제로는 최소의 동전으로 거스름돈 거슬러주기, 최소비용 신장트리 등이 있다.

Greedy Decoding은 효율적이지만 최적의 해를 구해준다는 보장이 없다는 단점이 있다.

 

최고의 번역을 하고있지 않아!

훈련 데이터가 실제 세계의 모든 데이터를 포함할 수 없기 때문에 가장 높은 확률을 갖는 토큰들로 번역한다고 하더라도 최고의 번역을 생성하지 못할 수 있다.

 

이러한 문제를 어떻게 해결할 수 있을까? 단어사전으로 만들 수 있는 모든 문장을 만든 후 사용자가 직접 고르는 방법은 어떨까? 수많은 문장들이 생성될 수 있겠지만 최적의 번역을 선택할 수는 있을 것이다. 이러한 아이디어에서 시작된 방식이 Beam Search 방식이다.


2. Beam Search

단어사전으로 만들 수 있는 모든 문장을 만드는 대신 지금 상황에서 가장 높은 확률을 갖는 top-k 문장만 남기는 방식. beam size(beam width)를 설정해 상위 몇개의 문장을 기억할지를 결정할 수 있다. 보통 5나 10으로 설정한다.1

beam search

import math
import numpy as np

def beam_search_decoder(prob, beam_size):
    sequences = [[[], 1.0]]  # 생성된 문장과 점수를 저장

    for tok in prob:
        all_candidates = []

        for seq, score in sequences:
            for idx, p in enumerate(tok): # 각 단어의 확률을 총점에 누적 곱
                candidate = [seq + [idx], score * -math.log(-(p-1))]
                all_candidates.append(candidate)

        ordered = sorted(all_candidates,
                         key=lambda tup:tup[1],
                         reverse=True) # 총점 순 정렬
        sequences = ordered[:beam_size] # Beam Size에 해당하는 문장만 저장 

    return sequences
vocab = {
    0: "<pad>",
    1: "까요?",
    2: "커피",
    3: "마셔",
    4: "가져",
    5: "될",
    6: "를",
    7: "한",
    8: "잔",
    9: "도",
}

# prob_seq은 문장의 각 위치에서 어떤 단어가 생성될지의 확률을 한 번에 정의해둔 것입니다.
# 실제로는 각 단어에 대한 확률이 prob_seq처럼 한번에 정의되지 않기 때문에 실제 문장 생성과정과는 거리가 멉니다.
# 하지만 Beam Search의 동작과정 이해를 돕기위해 이와 같은 예시를 보여드립니다.
# prob_seq의 각 열은 위 vocab의 각 숫자(key)에 대응됩니다.
prob_seq = [[0.01, 0.01, 0.60, 0.32, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01], # 커피 : 0.60
            [0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.75, 0.01, 0.01, 0.17], # 를 : 0.75
            [0.01, 0.01, 0.01, 0.35, 0.48, 0.10, 0.01, 0.01, 0.01, 0.01], # 가져 : 0.48
            [0.24, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.68], # 도 : 0.68
            [0.01, 0.01, 0.12, 0.01, 0.01, 0.80, 0.01, 0.01, 0.01, 0.01], # 될 : 0.80
            [0.01, 0.81, 0.01, 0.01, 0.01, 0.01, 0.11, 0.01, 0.01, 0.01], # 까요? : 0.81
            [0.70, 0.22, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01], # <pad> : 0.91
            [0.91, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01], # <pad> : 0.91
            [0.91, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01], # <pad> : 0.91
            [0.91, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01]] # <pad> : 0.91

prob_seq = np.array(prob_seq)
beam_size = 3

result = beam_search_decoder(prob_seq, beam_size)

for seq, score in result:
    sentence = ""

    for word in seq:
        sentence += vocab[word] + " "

    print(sentence, "// Score: %.4f" % score)
    
    
"""
커피 를 가져 도 될 까요? <pad> <pad> <pad> <pad>  // Score: 42.5243
커피 를 마셔 도 될 까요? <pad> <pad> <pad> <pad>  // Score: 28.0135
마셔 를 가져 도 될 까요? <pad> <pad> <pad> <pad>  // Score: 17.8983
"""

이렇게 print된 여러 문장들 중 사람이 가장 적합하다고 생각하는 문장을 선택할 수 있다. 그러나 이러한 선택은 학습에 직접 적용할 수 없기 때문에 결국 모델 입장에서는 뭐가 좋은 번역인지를 학습할 수 없다.


3. Sampling

언어 모델은 모두 반복적으로 다음 단어에 대한 확률분포를 생성한다. 따라서 해당 분포를 기반으로 랜덤하게 단어를 뽑아보자는 것이 sampling의 기본 접근 방식이다.

 

위의 예시에서 sampling은 확률적으로 55개의 '내가 사랑하는 귀여운 고양이', 37개의 '내가 사랑하는 귀여운 강아지'  등의 문장을 생성하게 된다.

 

sampling은 간혹 난해한 문장을 생성하는 경우가 있어 실제 서비스에서 거의 사용되지 않으나, 모델을 학습시킬 때 사용되는 경우가 있다. back Translation(역번역), 자연어 처리에 강화학습을 적용하는 경우 등이다.

 


Data Augmentation(3)

훈련 데이터를 수십배까지도 부풀리는 기술

주로 이미지 처리에서 많이 사용된다. 이미지 데이터의 경우 아무리 변화시켜도 왜곡이 크지 않고 일괄적으로 처리할 수 있기 때문이다. 자연어 처리에도 데이터 증강을 시도할 수 있는 여러 방법들이 개발되었다.

 


1. Lexical Substitution(어휘 대체)

  • 동의어 기반 대체
    • 시소러스(Thesaurus)를 활용
    • 시소러스(Thesaurus): 어떤 단어의 동의어, 유의어를 집중적으로 구축해 둔 사전
    • 대표적인 시소러스로는 영어의 워드넷, 한국어의 경우 KorLex, KWN이 있다.
    • 그러나 동의어 기반 대체는 좋은 방법이지만 규칙 기반 기계번역처럼 사람이 모든 것을 정의해야 한다는 단점이 있다.

동의어 기반 대체 사례

 

  • embedding 활용 대체
    • Pre-training Word Embedding을 활용하는 방법
    • Word2Vec, GloVe 등의 기법을 통해 학습된 embedding은 유사한 단어들끼리 비슷한 공간에 밀집된다.
    • 따라서 사람이 정하는 규칙 대신 이 embedding의 유사도를 기반으로 단어를 대체할 수 있다.
    • gensim 라이브러리를 활용해 embedding 활용 대체 방식을 쉽게 사용할 수 있다.

임베딩 활용 대체 사례

 

  • TF-IDF 기반 대체
    • 여러 문서를 기반으로 단어마다 중요도를 부과하는 알고리즘
    • 문서의 핵심이 되는 단어들이 높은 TF-IDF 값을 부여받는다.
    • 낮은 TF-IDF 값을 갖는 단어들은 핵심 단어가 아니기에 다른 단어로 대체해도 문맥이 크게 변하지 않는다는 점에 주목한 아이디어이다.

 

TF-IDF 기반 대체

 


2. Back Translation

번역 모델에 단일 언어 데이터를 학습시키는 방법이다.

 

단일 언어 데이터는 구하기 쉽고 많지만 병렬 쌍을 이룬 언어 데이터를 찾기는 어렵다는 문제를 해결하고자 등장하였다.

Seq2Seq 구조를 살펴보면 Source 문장을 Encoding 하는 부분과 Target 문장을 Decoding 하는 부분을 분리하여 모듈들이 각 언어를 더 잘 처리할 수 있게 하였다. 이때  Encoder에는 Source 언어로 된 문장을, Decoder에는 Target 언어로 된 문장을 좀 더 훈련시켜 성능을 높이고자 하였다.

 

S(Source)-T(Target) 병렬 말뭉치가 있다고 가정하면, S->T 방향 번역 모델 A를 학습함과 동시에 T->S 방향 번역 모델 B도 동시에 학습한다. 후에 T 언어로 된 단일 언어 데이터에 모델 B를 활용해 인공적인 S 언어 데이터를 생성하고 인공적인 S 언어 데이터와 T를 병렬 쌍으로 사용한다. 이때 생성되는 인공적인 S 언어 데이터가 Synthetic Source Sentence이다.

 

Back Translation 기법 중 가장 좋은 성능을 보인 생성 기법은 Beam+Noise 방식이다.

 

 Back Translation은 현재 번역 데이터셋으로 가장 유명한 WMT2014에서 State-of-the-art 성능을 보인 알고리즘이다.

 

https://dev-sngwn.github.io/2020-01-07-back-translation/

 

Back Translation 정리

: 번역기 성능 영혼까지 끌어모으기

dev-sngwn.github.io


3. Random Noise Injection

데이터에 포함된 적당한 noise는 학습에 도움이 될 수 있다. noise를 주는 기준에 다라 방법도 여러가지로 나뉜다.

  • 오타 노이즈 추가
    • 타이핑 시 오타가 발생할 수 있는데 이러한 오타 노이즈를 추가해 data augmentation하는 방법이다.
  • 공백 노이즈 추가
    • _ 토큰(Placeholder Token, 공백토큰) 문장의 일부 단어를 공백 토큰으로 치환하는 방식
    • 학습의 과적합을 방지하는데에 좋은 효과를 볼 수 있다.
    • 이렇게 문장에서 일부 단어를 공백 토큰으로 치환하고, 이를 추측하는 학습 방식을 마스크 언어 모델링(MLM, Masked Language Modeling)이라하며 대표적인 모델로는 BERT, GPT2가 있다.

  • 랜덤 유의어 추가
    • 주어진 문장에서 불용어(Stop word)가 아닌 단어를 랜덤하게 뽑은 후, 해당 단어와 유사한 단어를 골라 문장에 아무렇게나 삽입하는 방식
    • 원본 단어가 손실되지 않으며 유사어를 삽입함으로서 모델의 embedding층이 더 견고해진다는 장점이 있다.

 

랜덤 유의어 추가

 

 

이외에 NLP의 다른 data augmentation 기법에는 random deletion, random swap, paraphrasing 등이 있다.


번역 task에서의 metricㅡBLEU(Bilingual Evaluation Understudy) Score

BLEU(Bilingual Evaluation Understudy)score는 데이터의 X,y가 모두 가 순서정보를 가진 단어들(문장)로 이루어진 경우 사옹되는 성과 지표이다.

 

다음과 같은 공식을 통해 BLEU를 측정할 수 있다.

BLEU 공식

  • precision: n-gram을 통한 순서쌍들이 얼마나 겹치는지(예측문장 기준)
    • 매치되는 경우가 없을 경우 precision값은 0이 되며 이에 따라 BLEU 스코어도 0이 된다.
  • brevity penalty: 문장 길이에 대한 과적합 보정
  • clipping: 같은 단어가 연속적으로 나올 때 과적합되는 것을 보정

BLEU 스코어를 이용해 같은 단어가 반복되어 높은 점수를 받는 것, 어순이 엉망인 문장, 지나치게 짧은 문장이 높은 점수를 받는 것을 방지할 수 있다.

 

 

BLEU 스코어 자세한 설명

https://wikidocs.net/31695

 

14-03 BLEU Score(Bilingual Evaluation Understudy Score)

앞서 언어 모델(Language Model)의 성능 측정을 위한 평가 방법으로 펄플렉서티(perplexity, PPL)를 소개한 바 있습니다. 기계 번역기에도 PPL을 평가에 사…

wikidocs.net

BLEU 스코어 사례

https://donghwa-kim.github.io/BLEU.html

 

BLEU Score

BLEU BLEU(Bilingual Evaluation Understudy)score란 성과지표로 데이터의 X가 순서정보를 가진 단어들(문장)로 이루어져 있고, y 또한 단어들의 시리즈(문장)로 이루어진 경우에 사용되며, 번역을 하는 모델에

donghwa-kim.github.io


챗봇

챗봇 모델의 종류

검색기반 모델(Retrieval-based models)

  • 미리 정해진 응답들의 데이터를 사용해 input, 문맥에 기반한 응답을 선택하는 방식
  • 답변에 문법적 오류가 없으나 미리 정해둔 응답이 없는 경우 처리할 수 없다.
  • 대화의 문맥적 정보를 재위탁할 수 없다

 

생성 모델(Generative models)

  • 미리 정해둔 응답이 아닌 새로운 응답을 생성하는 방식
  • 검색기반 모델보다 영리하다.
  • 그러나 훈련시키기 어렵고 긴 문장에서의 문법 실수가 꽤 많다.
  •  질문만 하는 나라의 언어를 Source언어라고 하고 답변만 하는 나라의 언어를 Target 언어라고 한다면 Source 문장을 Target 문장으로 번역하는 행위가 곧 질문에 답하는 행위가 되므로 학습이 가능해진다.
  • Encoder는 Source 문장을 읽고 이해한 내용을 추상적인 고차원 문맥 벡터로 압축하고, Decoder는 Encoder가 만든 문맥 벡터를 바탕으로 Target 문장을 생성하는, Source 언어의 Embedding 공간 속 문장을 Target 언어의 Embedding 공간으로 매핑하는 과정을 거친다.
  • 위의 방식은 Source 문장에 대해 매핑될 수 있는 고유한 Target 번역이 존재하기 때문에 가능한 방식이다.


open domain VS closed domain

closed domain

특정한 목표를 수행하기 때문에 input, output이 제한적이다.

 

open domain

자유로운 대화가 가능하다.

 


챗봇 모델의 주의점

챗봇 모델은 여러 서비스에서 자주 사용된다. 이를 위해 신경써야할 부분이 몇가지 존재한다.

  1. 사용자가 챗봇에게 말을 걸었을 때 200ms 이내에 답변이 나와야 한다.
  2. 특정 시공간에 의해 결정되는 질문은 단순한 학습으로 답변할 수 없으므로 예외처리를 진행한다.
  3. 모델의 인격(페르소나)에 일관성을 가져야 한다. 이때 서비스의 목적에 맞게 설정되어야 한다. 
  4. 대화에 일관적으로 답변해야한다. 이때 강화학습을 사용해  1) 상대방이 답변하기 좋고, 2) 새로운 정보를 담고 있으며, 3) 일관성이 있는 말을 각각 보상으로 정의하여 이를 최대화하는 방향으로 학습을 진행하는 아이디어가 있다.

대표적인 챗봇들

  • Meena
    • 구글이 제작한 챗봇
    • gpt-2의 2배가량 큰 모델을 9배 더 많은 데이터로 학습
    • evolved transformer 사용
    • 자체적 평가지표 SSA 제안
    • SSA: 대화의 일관성을 위해 "Hi!" 로 대화를 시작하며, 이후 평가자는 챗봇이 생성한 발언에 대해 구체적인지와 합리적인지를 T/F로 평가한다
  • Blender
    • Facebook
    •  모델에 페르소나를 부여하고자 함
    • 자체적인 평가 지표 ACUTE-Eval을 제안
    •  ACUTE-Eval: 생성된 2개의 긴 대화를 보고 평가자가 선택
    • Blended Skill Task를 통해 데이터를 그냥 학습시키는 것이 아닌 모델에게 특정 부분에 대해 초점을 맞추고 학습하게끔 함.