image 47 - quochung.cyou PTIT

[SWE học A.I] Tìm hiểu về Attention và Transformer

This entry is part 8 of 8 in the series SWE Học A.I

Word Embedding

Để xây dựng các hệ thống có thể hỗ trợ dịch thuậtsinh văn bản, trước hết chúng ta phải biến đổi văn bản thành một dạng mà máy tính có thể xử lý được. Như thường lệ, mọi thứ cần được chuyển thành con số. Có hai cách phổ biến để làm điều này:


1. Dựa trên ký tự (Character-based)

Trong cách tiếp cận này, ta đánh số tất cả các ký hiệu có thể xuất hiện trong văn bản.

  • Bảng mã ký tự toàn diện nhất hiện nay là Unicode.
  • Phiên bản mới nhất, Unicode 13.0.0 (2020), bao phủ 154 ngôn ngữ viết của con người và liệt kê tới 143.859 ký tự khác nhau (Unicode Consortium, 2020).
  • Mỗi ký hiệu trong bất kỳ hệ thống chữ viết nào đều có thể được gán một số duy nhất, từ 0 đến xấp xỉ 144.000.

Ví dụ, trong chương này, để đơn giản, ta chỉ xét 89 ký tự phổ biến nhất trong tiếng Anh (chữ cái, số, dấu câu, khoảng trắng).

Ví dụ nhỏ:

  • Văn bản: "AI is cool!"
  • Với bảng ký tự chỉ gồm 89 ký hiệu, ta có thể ánh xạ:
    • "A" → 0, "I" → 8, " " (dấu cách) → 26, "s" → 45, "c" → 12, "o" → 22, "l" → 19, "!" → 75
  • Câu "AI is cool!" sẽ được biểu diễn thành một dãy số: [0, 8, 26, 8, 45, 26, 12, 22, 22, 19, 75].

2. Dựa trên từ (Word-based)

Trong cách này, ta đánh số tất cả các từ có thể xuất hiện.

  • Nếu tính tất cả ngôn ngữ trên thế giới, đây là một nhiệm vụ khổng lồ.
  • Ngay cả với tiếng Anh, không có con số chính xác về tổng số từ.
  • Các từ điển hiện đại của tiếng Anh thường có khoảng 300.000 mục từ (Dictionary.com, 2020).

Giả sử ta duyệt qua toàn bộ từ điển và gán cho mỗi từ một số duy nhất, bắt đầu từ 0. Danh sách các từ cùng số hiệu của chúng sẽ tạo thành từ vựng (vocabulary).

Ví dụ nhỏ:

  • Một từ điển mini gồm:
    • {"I": 0, "like": 1, "AI": 2, "because": 3, "it": 4, "is": 5, "fun": 6}
  • Câu "I like AI" sẽ được biểu diễn thành [0, 1, 2].
  • Câu "AI is fun" sẽ là [2, 5, 6].

Với mong muốn cải tiến cách biểu diễn từ thay vì chỉ gán mỗi từ một con số, với mục tiêu là có thể:

  • So sánh từ (tìm từ có ý nghĩa gần giống nhau).
  • Kết hợp từ (trung hòa hoặc biến đổi ý nghĩa giữa hai từ).
  • Thao tác trên không gian vector để tìm ra mối quan hệ ngữ nghĩa tiềm ẩn.

Đây chính là nền tảng để phát triển attention và sau đó là transformer.

Kỹ thuật này gọi là word embedding (hoặc token embedding, khi áp dụng cho token nói chung).

Ví dụ

Giả sử Hôm nay đạo diễn muốn quay cảnh một nhóm động vật đuổi theo nhân vật chính. Văn phòng gửi cho đoàn làm phim một biểu đồ như sau, trục ngang là tốc độ tối đa, trục dọc là cân nặng trung bình của từng loài

image 26 - quochung.cyou PTIT

Nhưng bản in bị lỗi và khi được đưa tới đoàn làm phim thì không có nhãn trục, chỉ còn các điểm động vật nằm trong không gian 2D. Vì vậy đoàn làm phim không biết trục ngang và trục dọc đang biểu diễn cho việc gì.

Đạo diễn nói:

“Tôi muốn trong cảnh quay sẽ là một con ngựa đuổi theo nhân vật chính. Tôi cảm giác được ngựa sẽ phù hợp. Chúng là sự lựa chọn hoàn hảo, đừng mang gì khác tới đây hết.”

image 27 - quochung.cyou PTIT


Đoàn làm phim gật đầu, đưa ngựa vào trường quay. Nhưng chỉ vài phút sau, đạo diễn đã đập tay xuống ghế, quát lớn:

“Không được! Ngựa chạy thì nhanh đấy, nhưng trông chúng quá nhạy, cứ bồn chồn như… cáo ấy. Tôi không muốn thứ gì giống cáo. Hãy mang tới cho tôi một loài vẫn mạnh mẽ như ngựa, nhưng phải bớt cái chất ‘cáo’ đi.”

Đoàn làm phim đứng sững. Trời ạ, “ngựa trừ đi cáo” thì là cái gì? Nhưng rồi anh nhớ tới tấm biểu đồ mà văn phòng gửi. Nếu coi mỗi con vật là một mũi tên trong không gian này, thì việc đạo diễn yêu cầu chẳng khác nào một phép toán vector.

Anh lấy mũi tên của ngựa, trừ đi mũi tên của cáo. Kết quả? Một con… lười khổng lồ (giant sloth).

image 28 - quochung.cyou PTIT

Đoàn làm phim ngập ngừng:

“Thưa đạo diễn, nếu bỏ đi cái tính nhanh nhẹn của cáo khỏi ngựa, chúng ta sẽ có… lười khổng lồ.”

Đạo diễn nhìn rồi hất ly latte xuống đất:

“Không! Lười thì đẹp đấy, nhưng chậm như rùa! Tôi cần thứ gì đó nhanh hơn, phải thật nhanh! Giống như… chim chẳng hạn.”

Anh lại quay vào bảng, lần này cộng thêm vector chim vào kết quả vừa rồi. Và thật bất ngờ, mũi tên mới chỉ thẳng tới… gấu nâu.

image 29 - quochung.cyou PTIT

Đạo diễn khoanh tay, hất tóc, ánh mắt sáng lên:

“Tuyệt. Cuối cùng cũng đúng ý tôi: mạnh mẽ như ngựa, không lắt nhắt như cáo, lại nhanh như chim chạy. Mang gấu tới đây đi.”

Và thế là cảnh rượt đuổi được quay với một đàn gấu nâu hung hãn. Bộ phim sau này trở thành bom tấn, được ca ngợi hết lời.

Kết luận

Có hai yếu tố then chốt trong câu chuyện này. Yếu tố thứ nhất là các loài vật trên biểu đồ của chúng ta đã được sắp xếp theo một cách hữu ích, dù chúng ta không biết cách đó là gì, hay các trục thể hiện điều gì về dữ liệu.

Điểm then chốt thứ hai là cuối cùng chúng ta không cần nhãn trục. Chúng ta có thể định hướng trên biểu đồ chỉ bằng cách cộng và trừ các mũi tên trỏ tới các phần tử trên biểu đồ. Tức là, chúng ta không cố tìm một “con ngựa chậm hơn.” Thay vào đó, ta thao tác trực tiếp với các con vật trên biểu đồ, và các thuộc tính của chúng đi theo một cách ngầm định. Nếu loại bỏ đi tính nhanh nhẹn của cáo khỏi một con vật lớn như ngựa, ta sẽ thu được một con vật to và chậm.

Điều này liên quan gì đến xử lý ngôn ngữ?

Nhúng từ (Embedding Words)

Để áp dụng những gì vừa thấy cho từ ngữ, ta thay các con vật bằng các từ. Và thay vì chỉ dùng hai trục, ta sẽ đặt các từ vào một không gian có hàng trăm chiều.

Chúng ta thực hiện điều này bằng một thuật toán tự động tìm ra ý nghĩa của mỗi trục trong không gian khi đặt từng từ vào vị trí phù hợp. Thay vì gán cho mỗi từ một số đơn lẻ, thuật toán gán cho mỗi từ cả một danh sách số đó là tọa độ của từ trong một không gian lớn.

Ví dụ: từ “Hưng” biểu diễn là [0, 0.5, 1, 50, 4, …]

image 30 - quochung.cyou PTIT

Thuật toán này gọi là embedder, và quá trình đó gọi là nhúng từ vào không gian embedding, tạo ra các word embeddings.

Bộ nhúng tự tìm cách xây dựng không gian và xác định tọa độ của mỗi từ sao cho nó nằm gần những từ tương tự. Ví dụ, nếu nó thấy nhiều câu bắt đầu bằng “I just drank some …”, thì danh từ xuất hiện sau cụm đó sẽ được hiểu là một loại đồ uống và được đặt gần các từ chỉ đồ uống khác. Nếu nó thấy nhiều câu như “I just ate a red …”, thì từ tiếp theo được hiểu là thứ có màu đỏ và có thể ăn được, nên được đặt gần những thứ vừa đỏ vừa có thể ăn được.

Tương tự với hàng chục, thậm chí hàng trăm mối quan hệ khác, cả rõ ràng lẫn tinh tế. Bởi vì không gian có rất nhiều chiều và các trục có thể mang ý nghĩa phức tạp tùy ý, một từ có thể thuộc đồng thời nhiều cụm dựa trên những đặc tính dường như không liên quan.

Điểm hay khi huấn luyện một bộ nhúng trong không gian có hàng trăm (hoặc thậm chí hàng nghìn) chiều là nó có thể sử dụng không gian hiệu quả hơn khả năng trực giác của con người, cho phép biểu diễn đồng thời một số lượng lớn các mối quan hệ.

Những phép “số học từ” vừa nêu là minh chứng thú vị cho không gian nhúng, nhưng quan trọng hơn, chúng cho phép ta thực hiện có ý nghĩa các phép toán trên từ như so sánh, phóng to/thu nhỏ, và cộng trừ tất cả đều hữu ích cho các thuật toán được bàn tới trong chương này.

image 32 - quochung.cyou PTIT

Hình trên trình bày sáu bộ gồm bốn từ liên quan mà chúng ta đưa vào một bộ nhúng tiêu chuẩn. Mức độ tương đồng giữa embedding của hai từ càng lớn thì cặp từ đó càng có điểm cao, nên giao điểm tương ứng càng tối. Đồ thị đối xứng quanh đường chéo từ trên trái xuống dưới phải, vì thứ tự so sánh hai từ không ảnh hưởng kết quả.

Từ hình ta thấy mỗi từ khớp với chính nó mạnh nhất và cũng khớp với những từ liên quan hơn là với những từ không liên quan. Vì ta đặt các từ có liên quan cạnh nhau, đồ thị hiện ra những khối nhỏ thể hiện tương đồng. Tuy nhiên có vài điều thú vị: ví dụ vì sao fish lại khớp hơn mức trung bình với chocolatecoffee, hay vì sao blue lại ghi điểm tốt với caramel? Đây có thể là những hiện tượng phát sinh từ dữ liệu huấn luyện cụ thể mà bộ nhúng dùng.

Các thức uống cà phê và hương vị ghi điểm mạnh với nhau, có lẽ vì người ta thường gọi cà phê kèm các siro hương vị đó. Ngoài ra còn thấy manh mối về mối quan hệ giữa màu sắc và hương vị.

ELMo

Word embeddings là một bước tiến lớn so với việc gán số nguyên cho từ. Nhưng dù mạnh, cách tạo embedding như trên vẫn có một vấn đề: sắc thái ngữ nghĩa (nuance).

Nhiều ngôn ngữ có từ có nhiều nghĩa nhưng viết và phát âm giống nhau. Nếu muốn hiểu đúng nghĩa từ, ta cần phân biệt các nghĩa đó. Một cách là gán cho mỗi nghĩa của một từ một embedding riêng. Ví dụ cupcake chỉ có một nghĩa nên có một embedding; nhưng train có hai nghĩa thực sự khác nhau — một là danh từ (“I rode on a train”) (train là tàu), một là động từ (“I like to train dogs”) (train là huấn luyện), nên cần hai embedding riêng.

Những từ như vậy đặt ra hai thách thức. Thứ nhất, ta phải tạo embedding riêng cho từng nghĩa. Thứ hai, ta phải chọn embedding đúng khi những từ này xuất hiện làm input.

Việc giải quyết hai thách thức này đòi hỏi phải xét ngữ cảnh của mỗi từ. Thuật toán đầu tiên làm việc này ở quy mô lớn gọi là Embeddings from Language Models, hay tên thân mật ELMo (Peters et al. 2018), trùng tên một nhân vật Muppet trong chương trình thiếu nhi Sesame Street. Người ta nói ELMo sinh ra các contextualized word embeddings (embedding phụ thuộc ngữ cảnh).

Attention

Ta đã thấy cách cải thiện chất lượng dịch thuật bằng việc xét đến toàn bộ các từ trong câu. Nhưng khi dịch một từ cụ thể, lại có thể thấy, không phải từ nào trong câu cũng quan trọng, thậm chí nhiều từ còn không liên quan.

Ví dụ: giả sử ta dịch câu:
“I saw a big dog eat his dinner.” – Tôi thấy một chú chó lớn đang ăn

  • Khi dịch từ dog (chó), ta gần như chẳng quan tâm gì đến từ saw. (nhìn thấy)
  • Nhưng để dịch đúng đại từ sở hữu his, ta cần kết nối nó với cụm big dog (chú chó lớn)
  • Nếu ta có thể xác định, với mỗi từ trong đầu vào, những từ nào thực sự ảnh hưởng đến việc dịch, thì ta có thể tập trung xử lý chỉ những từ đó, còn bỏ qua phần còn lại. Điều này tiết kiệm rất nhiều bộ nhớthời gian tính toán.
  • Và nếu ta làm điều này theo cách không phụ thuộc vào việc xử lý tuần tự (word-by-word), thì ta còn có thể tính toán song song.

Thuật toán thực hiện ý tưởng đó gọi là attention, hay cụ thể hơn là self-attention (Bahdanau, Cho & Bengio 2016; Sutskever, Vinyals & Le 2014; Cho et al. 2014).

Attention giúp mô hình tập trung tài nguyên vào những phần quan trọng nhất của đầu vào.

QKV – Query, Key, Value

Phiên bản attention hiện đại thường dựa trên một kỹ thuật gọi là query, key, value (QKV).

Ba từ này vốn xuất phát từ lĩnh vực cơ sở dữ liệu (database), nên khi đưa sang ngữ cảnh NLP có vẻ hơi trừu tượng. Vì vậy, ta sẽ dùng một phép ẩn dụ trực quan để giải thích, rồi sau đó kết nối lại với Q–K–V.

Ví dụ: Mua sơn

Giả sử anh cần mua sơn. Người ta chỉ cho anh mô tả:
“màu vàng nhạt pha một chút cam đậm.”

Ở thị trấn chỉ có một cửa hàng sơn duy nhất. Người bán hàng mới vào nghề, không rành từng màu. Anh và nhân viên đều hiểu rằng để ra màu mong muốn, anh phải pha trộn nhiều loại sơn có sẵn. Nhưng vấn đề là: chọn loại nào, và mỗi loại bao nhiêu?

Người bán đề nghị:

  • “Anh hãy so sánh mô tả của mình với tên trên nhãn từng hộp sơn. Hộp nào khớp nhiều thì múc nhiều, khớp ít thì múc ít. Rồi mình trộn tất cả lại.”

Ví dụ: so với mô tả “màu vàng nhạt pha một chút cam đậm.” (“light yellow with a bit of dark orange”)

  • “Sunny Yellow” (Vàng cam) → khớp nhiều, vừa có vàng và cam.
  • “Orange Crush” → khá khớp
  • “Lunch with Teal” cũng lọt vào một chút, chỉ vì trùng từ “with”.
image 33 - quochung.cyou PTIT

Trong câu chuyện này có 3 thành phần chính:

  1. Yêu cầu (request): “light yellow with a bit of dark orange.”
  2. Mô tả (description): tên trên nhãn mỗi hộp, như “Sunny Yellow”, “Mellow Blue”…
  3. Nội dung (content): bản thân màu sơn trong hộp.

Quy trình: ta so sánh yêu cầu với từng mô tả → mức độ khớp càng cao → càng lấy nhiều nội dung từ hộp đó.

Đây chính là QKV:

  • Cho một yêu cầu, so sánh nó với mô tả của từng mục, rồi trộn nội dung theo mức độ phù hợp.

Trong ngôn ngữ cơ sở dữ liệu:

  • Query (Q): yêu cầu tìm kiếm (tương ứng với “request”).
  • Key (K): khóa định danh, mô tả của từng mục (tương ứng với “description”).
  • Value (V): giá trị thật sự được lưu trữ (tương ứng với “content”).

Cơ sở dữ liệu so sánh query với key để tính điểm khớp, rồi dùng điểm đó quyết định lấy bao nhiêu phần của value.

➡️ Vậy:

  • Request ↔ Query (Q)
  • Description ↔ Key (K)
  • Content ↔ Value (V)

Self-Attention

Giả sử ta có một câu gồm 5 từ đầu vào. Mỗi từ được biểu diễn bằng một vector (embedding). Ta có ba “hộp” neural network nho nhỏ (thường chỉ là các fully connected layer 1 tầng) để biến đổi vector đó thành:

  • Q (query)
  • K (key)
  • V (value)
image 34 - quochung.cyou PTIT

Ví dụ: với từ dog (thứ ta cần dịch):

  • Một mạng (màu đỏ) biến vector “dog” thành Q.
  • Từ dinner được biến thành K (qua mạng xanh) và V (qua mạng xanh lá).

Ta so sánh Q của dog với K của dinner bằng một hàm tính điểm (scoring function, ký hiệu S trong vòng tròn). Hàm này trả về một số từ 0 → 1:

  • Khớp nhiều → điểm cao.
  • Khớp ít → điểm thấp.

Sau đó, ta lấy V của dinner, nhân với điểm này (scaling). Kết quả: giá trị dinner đóng góp nhiều hay ít vào đầu ra của dog tùy mức độ khớp.

Mở rộng ra toàn câu

Trong thực tế, không chỉ so sánh dog ↔ dinner, mà dog được so sánh với tất cả từ trong câu (kể cả chính nó).

Mỗi từ trong câu sẽ đóng góp vào kết quả cuối của dog, với trọng số do điểm khớp quyết định.

image 35 - quochung.cyou PTIT

Lưu ý:

  1. Ta chỉ có 3 mạng duy nhất (Q, K, V), và áp dụng chúng cho tất cả từ → tiết kiệm tính toán.
  2. Sau khi có điểm khớp, ta áp dụng softmax để chuẩn hóa, tránh số quá to/nhỏ, đồng thời làm nổi bật các khớp mạnh.
  3. Cuối cùng, ta cộng tất cả giá trị V đã được scale lại → ra vector mới của dog.
  4. Lặp quy trình này đồng thời cho mọi từ trong câu
image 36 - quochung.cyou PTIT

Embedding đóng vai trò gì?

Hàm scoring sẽ coi hai vector giống nhau → điểm cao. Vậy để hoạt động đúng, các từ có ý nghĩa gần nhau phải được nhúng gần nhau trong không gian embedding.

Ví dụ: trong như cách làm onehot encoding, ta gán số cho từ theo thứ tự (keep = 1003, flint = 1004). Nếu dùng số này so sánh thì keep và flint lại cực kỳ giống nhau (sai hoàn toàn).

Với embedding:

  • keep sẽ gần retain, hold, reserve.
  • Cách xa hẳn flint, dinosaur.

Nhờ embedding, scoring mới có ý nghĩa.

Q/KV Attention

Trong self-attention, Q, K, V đều sinh ra từ cùng một input.

Nhưng có biến thể khác:

  • Q đến từ một nguồn khác, còn K và V vẫn từ input gốc.

Giống như ví dụ mua sơn:

  • Query đến từ khách hàng.
  • Key & Value đến từ cửa hàng.

Đây gọi là Q/KV attention.

  • Thường dùng trong mạng encoder–decoder (ví dụ seq2seq):
    • Q từ encoder.
    • K, V từ decoder.
image 38 - quochung.cyou PTIT

Multi-Head Attention

Ý tưởng của attention là xác định những từ nào có sự tương đồng và tạo ra một phép trộn hữu ích từ chúng. Nhưng “giống nhau” có thể được định nghĩa theo rất nhiều tiêu chí khác nhau.

Ví dụ: ta có thể xem các danh từ là giống nhau, hoặc các màu sắc, hoặc các khái niệm không gian như “lên – xuống”, hoặc các khái niệm thời gian như “hôm qua – ngày mai”. Vậy lựa chọn nào là tốt nhất?

Thực ra không có một câu trả lời duy nhất. Trên thực tế, ta thường muốn so sánh các từ theo nhiều tiêu chí cùng lúc.

  • Khi viết ca từ bài hát, ta có thể muốn đánh giá cao những cặp từ có nghĩa gần giống nhau, có vần cuối giống nhau, có số âm tiết bằng nhau, và thậm chí có nhịp điệu trong trọng âm giống nhau.
  • Nhưng khi viết về thể thao, ta có thể muốn coi những cầu thủ cùng đội, cùng vị trí là “giống nhau”.

Để chấm điểm các từ theo nhiều tiêu chí, ta chỉ cần chạy nhiều mạng attention độc lập cùng lúc. Mỗi mạng như vậy gọi là một head (một “đầu chú ý”). Mỗi head được khởi tạo độc lập, và ta hy vọng rằng trong quá trình huấn luyện, mỗi head sẽ học được một cách riêng để so sánh các đầu vào, theo những tiêu chí hữu ích và khác biệt so với các head khác. Nếu muốn, ta còn có thể thêm cơ chế để ép các head tập trung vào các khía cạnh khác nhau của đầu vào. Cơ chế này gọi là multi-head attention

image 37 - quochung.cyou PTIT

Mỗi head là một mạng attention độc lập. Càng nhiều head, thì mô hình càng có khả năng tập trung vào nhiều khía cạnh khác nhau của dữ liệu đầu vào.

Hình trên minh họa một lớp multi-head attention. Như hình vẽ, ta thường kết hợp đầu ra của tất cả các head thành một danh sách, rồi cho qua một lớp fully connected duy nhất. Nhờ vậy, đầu ra của toàn bộ lớp multi-head có cùng kích thước với đầu vào, điều này cho phép ta dễ dàng xếp chồng nhiều lớp multi-head liên tiếp.

Layer Icons (Biểu tượng các lớp Attention)

  • (a) Self-attention.
  • (b) Multi-head self-attention.
  • (c) Q/KV attention.
  • (d) Multi-head Q/KV attention.
image 39 - quochung.cyou PTIT

(Multi-head attention được vẽ như một khối 3D nhỏ, gợi ý rằng nó là “một chồng” các mạng attention. Với Q/KV attention, trong biểu tượng kim cương có thêm một vạch nhỏ để chỉ đầu vào Q, còn K và V đi vào từ một phía khác.)

Transformers

Mục tiêu của ta là xây dựng một mô hình dịch máy không dựa vào RNN, mà dựa vào attention networks. Ý tưởng chủ chốt: các lớp attention sẽ học cách biến đổi đầu vào thành bản dịch, dựa trên mối quan hệ giữa các từ.

Cách tiếp cận này lần đầu xuất hiện trong bài báo nổi tiếng “Attention Is All You Need” (Vaswani et al., 2017). Tác giả gọi mô hình này là transformer (cái tên hơi “mập mờ” nhưng giờ đã thành chuẩn trong lĩnh vực). Mô hình transformer hoạt động hiệu quả đến mức đã mở ra một thế hệ mới của các mô hình ngôn ngữ, vừa huấn luyện song song dễ dàng, vừa vượt trội hơn RNN trong nhiều tác vụ khác nhau.

Transformer sử dụng thêm ba ý tưởng nữa:

Skip Connections

Ý tưởng đầu tiên gọi là residual connection hay skip connection (He et al., 2015). Nguồn cảm hứng của nó là giảm lượng công việc mà một lớp mạng sâu phải thực hiện.

Một phép so sánh:
Giả sử ta vẽ một bức chân dung bằng sơn acrylic trên một tấm vải. Sau nhiều tuần, bức tranh hoàn thành. Người mẫu xem và nói: “Tôi thích rồi, nhưng tiếc là hôm đó tôi đeo nhẫn sai, lẽ ra phải là cái nhẫn khác. Anh có thể sửa không?”

  • Cách 1: mời người mẫu quay lại, vẽ lại toàn bộ bức tranh từ đầu. Tốn thời gian và công sức khủng khiếp.
  • Cách 2: chỉ cần vẽ chồng cái nhẫn mới lên cái cũ. Nhanh gọn hơn nhiều.

Một lớp trong mạng sâu cũng vậy. Nó nhận tensor đầu vào, xử lý, và tạo ra tensor đầu ra. Nhưng nếu chỉ cần thay đổi một phần nhỏ, thì thật lãng phí nếu lớp đó phải xử lý toàn bộ. Giống như việc vẽ lại cả bức tranh chỉ để thay cái nhẫn. Thay vào đó, lớp chỉ cần tính toán phần thay đổi cần thiết, rồi cộng nó với đầu vào ban đầu để ra đầu ra cuối cùng.

Ý tưởng này hoạt động tuyệt vời trong deep learning:

  • giúp các lớp nhỏ gọn hơn, nhanh hơn,
  • cải thiện truyền gradient trong backpropagation,
  • cho phép huấn luyện hiệu quả các mạng có hàng chục hoặc hàng trăm lớp.
image 40 - quochung.cyou PTIT

Đường nối thêm đưa input đến nút cộng gọi là skip connection (nối tắt), hay residual connection (nối tàn dư, vì nó cộng thêm “phần dư”).

Transformer dùng skip connections không chỉ để tăng hiệu quả, mà còn để theo dõi vị trí của từng phần tử trong đầu vào (sẽ thấy ở phần positional encoding).

Norm-Add

Ý tưởng thứ hai là một rút gọn ký hiệu, thường gọi là norm-add.

Trong transformer, ta thường áp dụng bước chuẩn hóa gọi là layer normalization (layer norm) lên đầu ra của một lớp (Vaswani et al., 2017). Đây là một dạng regularization giống như dropout hay batchnorm, giúp chống overfitting bằng cách giữ cho các giá trị trong mạng không quá lớn hoặc quá nhỏ. Layer norm học cách điều chỉnh giá trị đầu ra của lớp để có dạng gần giống một phân phối chuẩn (mean = 0, std = 1).

Một cách thông dụng: đặt layer norm ngay trước bước cộng của skip connection Vì hai bước này luôn đi kèm nhau, nên người ta gộp chúng thành một khái niệm gọi là norm-add. Biểu tượng norm-add là sự kết hợp của biểu tượng chuẩn hóa và cộng.

image 41 - quochung.cyou PTIT

Có nhiều biến thể khác (đặt norm trước lớp, hoặc sau bước cộng), nhưng nhìn chung hiệu quả tương đương.

Positional Encoding (Mã hóa vị trí)

Ý tưởng thứ ba giải quyết một vấn đề phát sinh khi ta bỏ RNN ra khỏi hệ thống: ta mất thông tin về vị trí của từng từ trong câu.

Trong RNN, thông tin này có sẵn, vì từ đi vào theo thứ tự và trạng thái ẩn có thể ghi nhớ vị trí. Nhưng với attention, nhiều từ bị trộn lẫn vào nhau, vậy làm sao biết từ nào ở chỗ nào?

Giải pháp: thêm thông tin vị trí của mỗi từ trực tiếp vào vector biểu diễn của từ đó. Cách làm này gọi là positional encoding.

  • Cách đơn giản: nối thêm vài bit vào cuối mỗi từ để lưu vị trí. Nhưng cách này tốn bộ nhớ và khó xử lý khi câu quá dài (ví dụ câu càng dài hơn thì số bit cần để lưu vị trí càng tốn). (ảnh trái)
image 42 - quochung.cyou PTIT
  • Cách tốt hơn: dùng một hàm toán học để biến chỉ số vị trí thành một vector đặc trưng (cùng chiều với embedding). Ví dụ: nếu embedding dài 128, thì mỗi vị trí được ánh xạ thành một vector 128 chiều riêng biệt. (ảnh phải)

Thay vì nối thêm vector này, ta cộng trực tiếp nó vào embedding của từ Cách này gọn gàng hơn, không cần thêm bits đặc biệt. Phương pháp này gọi là positional embedding, vì nó giống embedding từ vựng. Biểu tượng minh họa có dạng sóng sin, vì hàm thường dùng chính là sine wave encoding (Vaswani et al., 2017).

Nghe có vẻ lạ: cộng vị trí vào embedding sẽ thay đổi vector của từ. Vậy liệu thông tin vị trí có bị “hòa tan” mất trong quá trình attention không?

Hóa ra là không:

  • Hàm positional embedding chỉ tác động lên một vài bit nhất định (Vaswani et al., 2017; Kazemnejad, 2019).
  • Transformer học được cách phân biệt thông tin nội dung và thông tin vị trí.

Quan trọng hơn: nhờ có skip connections, positional embedding không bao giờ bị mất hoàn toàn. Sau mỗi tầng xử lý, nó lại được cộng thêm vào, luôn đi cùng với từ.

image 43 - quochung.cyou PTIT

Ghép các mảnh ghép

Giờ thì ta đã có đủ nguyên liệu để dựng nên một transformer. Và để tiện theo dõi, ta vẫn sẽ dùng bài toán dịch từ ngữ ở mức độ từng từ làm ví dụ minh họa xuyên suốt.

Điều cần lưu ý trước tiên: cái tên transformer ngày nay được dùng cho một họ mạng nơ-ron rất rộng, tất cả đều lấy cảm hứng từ kiến trúc trong bài báo gốc Attention Is All You Need (Vaswani et al. 2017). Ở đây, ta sẽ không đi vào từng biến thể, mà chỉ bám vào một “phiên bản chung”, một bộ khung chuẩn.

Cấu trúc tổng thể

image 44 - quochung.cyou PTIT
  • Ở bên trái là encoder (mã hóa),
  • ở giữa có một cây cầu dữ liệu,
  • và bên phải là decoder (giải mã).

Một câu đầu vào sẽ đi qua encoder, được xử lý và “chưng cất” thành thông tin. Rồi decoder nhận dòng thông tin đó, dần dần tạo ra câu dịch mới.

Nếu bạn đã quen với seq2seq dùng RNN thì bố cục này trông có chút quen: có phần encoder, phần decoder, và thông tin chảy từ trái sang phải. Nhưng điểm khác biệt then chốt: không còn bất kỳ (recurrent cell) nào nữa. Tất cả được thay bằng các lớp attention.

Trong sơ đồ:

  • E tượng trưng cho một encoder block,
  • D là một decoder block,
  • các nét đứt cho thấy nhiều block giống hệt nhau được lặp lại.

Ở đầu vào, cả encoder và decoder đều bắt đầu bằng word embedding (biểu diễn từ thành vector) cộng thêm positional embedding (mã hóa vị trí từ). Ở đầu ra của decoder, ta có một lớp fully connected + softmax để dự đoán từ kế tiếp.

Decoder lại còn có một vòng lặp: mỗi từ mà nó sinh ra sẽ được đưa trở lại vào chính nó, để sinh tiếp từ sau. Đó là cơ chế autoregressive.

Encoder block

image 45 - quochung.cyou PTIT
  1. Lớp đầu tiên: multi-head self-attention (ví dụ 8 head). Vì đây là self-attention, nên queries, keys, values đều được rút ra từ chính input của block.
    • Lớp này được bao quanh bởi skip connection + layer norm (norm-add), vừa để giữ số liệu “gọn gàng” (phân phối Gaussian đẹp), vừa để bảo toàn thông tin vị trí.
  2. Lớp kế tiếp: một cặp feed-forward pointwise (thường hiểu như 2 convolution 1×1).
    • Lớp đầu có activation ReLU, lớp sau thì không.
    • Chức năng: tinh chỉnh đầu ra từ attention, loại bỏ dư thừa, giữ lại phần cốt lõi.
    • Như thường lệ, cả cụm này cũng được gói trong skip connection + norm-add.

Vậy encoder block = attention → feed-forward → norm-add bao quanh.

Decoder block

Tiếp theo là decoder block. Bố cục hơi giống encoder block, nhưng có thêm một bước attention đặc biệt.

image 46 - quochung.cyou PTIT
  1. Bước đầu tiên: multi-head self-attention (giống encoder).
    • Input chính là các từ mà decoder đã sinh ra cho đến nay. Nếu mới bắt đầu, thì chỉ có token [START].
    • Nhờ self-attention, hệ thống học cách xem từ nào liên quan từ nào trong dãy đầu ra tạm thời này.
    • Vẫn có skip connection + norm-add bao quanh.
    • Nhưng ở đây có thêm một chi tiết: masking (hình tam giác nhỏ trong sơ đồ).
  2. Bước thứ hai: multi-head Q/KV attention.
    • Query (Q) đến từ output của self-attention trước đó.
    • Keys và Values đến từ tất cả các encoder block (nguyên câu nguồn đã được mã hóa).
    • Nhờ thế, decoder biết cách “nhìn sang” câu gốc để chọn thông tin nào cần dùng khi dịch tiếp.
    • Bước này cũng được bọc skip connection + norm-add.
  3. Cuối cùng: một cặp convolution 1×1 (giống encoder block).

Ghép lại thành Transformer

Khi ráp mọi mảnh, ta có sơ đồ:

  • Nhiều encoder block chồng nhau bên trái.
  • Nhiều decoder block chồng nhau bên phải.
  • Các lớp convolution 1×1 thường được ký hiệu bằng 2 hộp nhỏ xếp đôi.
  • Nét đứt = lặp lại nhiều lần.
image 47 - quochung.cyou PTIT

Vấn đề song song & Masking

Một ưu điểm tuyệt vời của attention là: xử lý song song. Dù ta đưa vào 5 từ hay 500 từ, lớp attention vẫn chạy trong cùng một thời gian. Điều này khác hẳn RNN, vốn phải xử lý tuần tự từng bước.

Nhưng khi huấn luyện mô hình để dự đoán từ kế tiếp, sẽ nảy sinh một vấn đề.
Ví dụ câu: “My dog loves taking long walks.”

  • Nếu ta đưa vào “My dog loves taking long” và muốn dự đoán từ thứ 6 (walks), thì ổn.
  • Nhưng đồng thời, ta cũng muốn mô hình dự đoán từ thứ 5 (long), dự đoán từ thứ 4 (taking), … tất cả song song.
  • Vấn đề: khi dự đoán long, mô hình thấy luôn từ long trong input. Quá dễ, và không còn ý nghĩa học.

Cách giải: masking.
Trong self-attention của decoder, ta chèn một lớp mặt nạ, để tại mỗi bước dự đoán, mô hình chỉ được nhìn thấy các từ trước đó, không được nhìn “tương lai”.

  • Khi dự đoán từ thứ 1 → không thấy gì.
  • Khi dự đoán từ thứ 2 → chỉ thấy “My”.
  • Khi dự đoán từ thứ 3 → chỉ thấy “My dog”.
  • … và cứ thế.

Nhờ masking, mô hình vừa chạy song song và không bị “nhìn thấy” dữ liệu. Ta cố tình ẩn bớt dữ liệu đi để mô hình có thể học thêm.

Tham khảo:

  • Deep Learning (Andrew Glassner)

SWE Học A.I

[SWE học A.I] Phần 8: Model Training & Evaluation

Published by

Nguyễn Quốc Hưng

I'm delighted to see you here :>

Leave a Reply