Sequence-to-Sequence
Seq2Seq - Chuỗi sang chuỗi
Bạn là phiên dịch viên. Nghe câu "Tôi yêu Việt Nam" xong, bạn dịch sang tiếng Anh. Bạn phải nghe HẾT câu trước rồi mới dịch, hay dịch từng từ ngay lập tức?
Hãy bấm "Tiếp" để xem Seq2Seq dịch "Tôi yêu Việt Nam" sang tiếng Anh — từng bước một!
Hình minh họa
Encoder (Bộ mã hóa)
Context
Vector
Decoder (Bộ giải mã)
Bấm 'Tiếp' để bắt đầu mã hóa câu tiếng Việt.
Seq2Seq = Encoder (mã hóa input → context vector) + Decoder (giải mã context → output). Giống phiên dịch viên: nghe hết → nhớ ý chính → dịch từng từ!
Nhưng có vấn đề: context vector có kích thước cố định. Câu dài 100 từ bị nén vào cùng kích thước với câu 5 từ — như nhét cả quyển sách vào 1 tờ giấy nhớ!
Seq2Seq dịch câu 5 từ tốt, nhưng câu 50 từ lại kém. Tại sao?
Câu ngắn (5 từ)
Vector đủ chỗ chứa!
Câu dài (50 từ)
Cùng kích thước → mất thông tin!
Giải thích
Sequence-to-Sequence (Sutskever et al., Google 2014) gồm Encoder nén input và Decoder sinh output, thường dùng RNN hoặc LSTM làm khối cơ sở, và sau đó được tăng cường bằng attention để khắc phục bottleneck.
Encoder: nén input thành context vector c
Decoder: sinh output từng token một
Google Translate (phiên bản cũ): Dịch tiếng Việt → tiếng Anh dùng Seq2Seq + Attention.
Tóm tắt văn bản: Input = bài báo dài, Output = tóm tắt ngắn.
Chatbot: Input = câu hỏi, Output = câu trả lời.
import torch
import torch.nn as nn
class Encoder(nn.Module):
def __init__(self, vocab_size, embed_dim, hidden_dim):
super().__init__()
self.embedding = nn.Embedding(vocab_size, embed_dim)
self.rnn = nn.LSTM(embed_dim, hidden_dim, batch_first=True)
def forward(self, x):
# x: [batch, seq_len] → "Tôi yêu Việt Nam"
embedded = self.embedding(x)
outputs, (hidden, cell) = self.rnn(embedded)
return hidden, cell # Context vector!
class Decoder(nn.Module):
def __init__(self, vocab_size, embed_dim, hidden_dim):
super().__init__()
self.embedding = nn.Embedding(vocab_size, embed_dim)
self.rnn = nn.LSTM(embed_dim, hidden_dim, batch_first=True)
self.fc = nn.Linear(hidden_dim, vocab_size)
def forward(self, x, hidden, cell):
# x: token trước đó → "I", "love", ...
embedded = self.embedding(x.unsqueeze(1))
output, (hidden, cell) = self.rnn(embedded, (hidden, cell))
prediction = self.fc(output.squeeze(1))
return prediction, hidden, cell # Từ tiếp theoSeq2Seq dùng RNN/LSTM → chậm (xử lý tuần tự). Thêm Attention → tốt hơn nhưng vẫn chậm. Transformer (2017) thay RNN bằng Self-Attention → xử lý song song, nhanh hơn → nền tảng cho BERT, GPT!
- Seq2Seq = Encoder (nén input → context vector) + Decoder (giải mã → output).
- Decoder sinh từng token một (autoregressive): output t-1 → input t.
- Bottleneck: context vector cố định không đủ chứa thông tin câu dài.
- Attention giải quyết bottleneck bằng cách cho decoder nhìn mọi vị trí encoder.
- Ứng dụng: dịch máy, tóm tắt, chatbot — tiền thân của kiến trúc Transformer.
Kiểm tra hiểu biết
Nút thắt cổ chai (bottleneck) của Seq2Seq là gì?