Sequence-to-Sequence Models
시퀀스-투-시퀀스(seq2seq) 모델은 번역, 요약 또는 음성 처리처럼 입력 시퀀스를 길이가 다른 출력 시퀀스로 매핑합니다.
시퀀스-투-시퀀스(seq2seq) 모델은 길이가 달라질 수 있는 한 시퀀스를 다른 시퀀스로 변환합니다. 예를 들어 영어 문장을 프랑스어 번역으로, 긴 기사를 요약문으로, 오디오 클립을 전사문으로 변환합니다. 대부분 인코더-디코더 구조를 사용합니다. 인코더가 전체 입력을 내부 표현으로 읽고, 디코더는 해당 표현과 이미 생성한 토큰을 조건으로 한 번에 출력을 생성하며 토큰을 하나씩 출력합니다. 이 접근 방식은 2014년 Google의 Sutskever, Vinyals, Le가 신경망을 사용한 시퀀스-투-시퀀스 학습을 발표하고, Cho 외 연구진이 기계 번역을 위한 RNN 인코더-디코더를 설명하면서 현대적인 형태를 갖추었습니다. 2017년 이후 대부분의 seq2seq 모델은 트랜스포머로 구축되었습니다.
Seq2Seq 모델 작동 방식#
2014년 모델에서는 인코더 장단기 메모리(LSTM) 네트워크가 원문 문장을 단어 단위로 읽어 하나의 고정 길이 벡터로 압축하고, 디코더 LSTM이 이 벡터를 펼쳐 번역문을 생성했습니다. Sutskever 외 연구진은 4개 층으로 구성된 LSTM을 사용했고, 원문 단어의 순서를 뒤집으면 학습이 더 쉬워진다는 사실을 발견했으며, WMT'14 영어-프랑스어 테스트 세트에서 BLEU 점수 34.8을 기록했습니다. 모든 문장을 하나의 벡터로 압축하면 긴 입력의 성능이 저하되므로, Bahdanau, Cho, Bengio는 공동 정렬 및 번역 학습을 통한 신경 기계 번역에서 어텐션 메커니즘을 도입했습니다. 이에 따라 디코더는 각 단계에서 모든 인코더 상태를 다시 살펴볼 수 있게 되었습니다. 트랜스포머는 이 인코더-디코더 구조를 유지하면서 순환 구조를 셀프 어텐션으로 대체하고, 두 부분을 크로스 어텐션으로 연결했습니다. 추론 시 디코더는 루프를 실행합니다:
디코더가 종료 토큰을 출력하면 루프가 멈추므로 출력 길이는 예제별로 학습됩니다. 디코딩에는 보통 빔 탐색을 사용해 여러 출력 후보를 유지하며, 이는 번역과 음성 인식에서 표준적으로 사용하는 방법입니다.
교사 강요를 사용한 학습#
학습 중에는 디코더가 루프를 실행할 필요가 없습니다. 교사 강요 방식에서는 정답 타깃 시퀀스를 한 위치 오른쪽으로 이동해 입력하고, 인과 마스크를 적용하여 각 위치가 앞선 타깃만 보도록 하면서 한 번의 병렬 패스에서 다음 토큰을 모두 예측합니다. 손실은 예측과 실제 다음 토큰 사이의 교차 엔트로피입니다. PyTorch의 nn.Transformer는 원래의 인코더-디코더 구조를 구현합니다:
import torch
from torch import nn
torch.manual_seed(0)
src_vocab, tgt_vocab, d_model = 1000, 800, 64
embed_src, embed_tgt = nn.Embedding(src_vocab, d_model), nn.Embedding(tgt_vocab, d_model)
model = nn.Transformer(d_model, nhead=4, num_encoder_layers=2, num_decoder_layers=2, batch_first=True)
to_logits = nn.Linear(d_model, tgt_vocab)
source = torch.randint(0, src_vocab, (1, 9)) # a 9-token source sentence
target = torch.randint(0, tgt_vocab, (1, 7)) # start token + a 6-token translation
# Teacher forcing: the decoder reads the correct previous tokens and predicts every next token in parallel
decoder_input, labels = target[:, :-1], target[:, 1:]
causal_mask = nn.Transformer.generate_square_subsequent_mask(decoder_input.size(1))
logits = to_logits(model(embed_src(source), embed_tgt(decoder_input), tgt_mask=causal_mask))
loss = nn.functional.cross_entropy(logits.flatten(0, 1), labels.flatten())
print(f"Source tokens: {source.shape[1]} -> decoder logits: {tuple(logits.shape)}")
print(f"Training loss: {loss.item():.2f}")한 번의 패스에서 9개 토큰으로 된 원문을 입력받아 계산한 결과로, 타깃 위치 6개 각각에 대해 타깃 어휘 800개에 대한 예측값 Source tokens: 9 -> decoder logits: (1, 6, 800)을 출력합니다. 학습되지 않은 모델의 손실은 6.73으로, 균일한 추측의 손실인 ln(800) ≈ 6.68에 가깝습니다. 학습 중에는 항상 이전 정답 토큰을 입력하지만 추론 중에는 모델이 자체적으로 추측한 토큰을 입력하므로, 추론 시 오류가 누적될 수 있습니다. 이를 노출 편향이라고 합니다.
Seq2Seq와 관련 아키텍처 비교#
- BERT와 같은 인코더 전용 모델: 입력을 양방향으로 읽고 토큰마다 하나의 표현을 출력하므로 분류와 태깅에 적합합니다.
- 디코더 전용 대규모 언어 모델(LLM): GPT와 같은 모델은 입력과 출력을 하나의 시퀀스에 배치하고 프롬프트를 이어 쓰는 방식으로 seq2seq 작업을 처리합니다. 오늘날 대부분의 텍스트 생성은 이 방식으로 이루어집니다.
- 순환 신경망(RNN) 및 GRU: 2014년 초기 인코더와 디코더 내부에 사용된 순환 계층입니다. Cho 외 연구진은 인코더-디코더를 소개한 같은 논문에서 게이트 순환 유닛을 제안했습니다.
응용 분야#
Google은 2016년에 Google Translate를 어텐션이 포함된 8계층 LSTM 인코더-디코더인 GNMT 시스템으로 이전했습니다. 기계 번역은 여전히 대표적인 시퀀스-투-시퀀스 작업입니다. Google의 T5는 자연어 처리(NLP)의 모든 작업을 텍스트-투-텍스트로 표현했으며, 텍스트 요약과 질의응답도 포함했습니다. OpenAI의 Whisper는 오디오 68만 시간으로 학습한 음성 인식용 인코더-디코더 트랜스포머입니다. 비전 모델은 같은 패턴을 이미지 캡셔닝과 광학 문자 인식(OCR)에 사용합니다. Microsoft의 Florence-2는 하나의 시퀀스-투-시퀀스 모델에서 캡셔닝, 그라운딩, 감지를 텍스트 출력으로 처리하며, Large 버전은 자동 주석을 위해 Ultralytics Platform에서 실행됩니다. Google의 Pix2Seq는 각 객체를 양자화된 좌표 4개와 클래스 하나, 총 5개의 이산 토큰으로 표현해 객체 감지를 시퀀스-투-시퀀스 작업으로 다룹니다. Ultralytics 패키지에서 실행되는 Baidu의 실시간 감지기 RT-DETR은 인코더와 교차 어텐션 디코더를 유지하되, 디코더가 객체 쿼리 300개를 병렬로 정제하므로 모든 박스를 한 번에 출력합니다.










