# Cơ chế hoạt động của Transformer?

<CourseFloatingBanner
    chapter={1}
    classNames="absolute z-10 right-0 top-0"
/>

Trong phần này, chúng ta sẽ tìm hiểu kiến trúc của các mô hình Transformer.

## Lịch sử phát triển của Transformers

Dưới đây là một số mốc tham khảo trong lịch sử (ngắn) phát triển của các mô hìnhn Transformer:

<div class="flex justify-center">
<img class="block dark:hidden" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/transformers_chrono.svg" alt="A brief chronology of Transformers models.">
<img class="hidden dark:block" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/transformers_chrono-dark.svg" alt="A brief chronology of Transformers models.">
</div>

[Kiến trúc Transformer](https://arxiv.org/abs/1706.03762) được giới thiệu vào tháng 6 năm 2017. Trọng tâm của nghiên cứu ban đầu hướng tới các tác vụ dịch thuật. Tiếp theo là sự ra đời của một số mô hình có ảnh hưởng, bao gồm:

- **06/2018**: [GPT](https://cdn.openai.com/research-covers/language-unsupervised/language_understanding_paper.pdf), mô hình Transformer được huấn luyện trước đầu tiên, được sử dụng để tinh chỉnh các tác vụ NLP khác nhau và thu được kết quả tốt nhất lúc bấy giờ.

- **10/2018**: [BERT](https://arxiv.org/abs/1810.04805), một mô hình lớn được huấn luyện trước khác, mô hình này được thiết kế để tạo ra các bản tóm tắt câu tốt hơn (sẽ đề cập thêm trong chương tiếp theo!).

- **02/2019**: [GPT-2](https://cdn.openai.com/better-language-models/language_models_are_unsupervised_multitask_learners.pdf), một phiên bản GPT cải tiến (và lớn hơn) nhưng không được phát hành công khai ngay lập tức do lo ngại về vấn đề đạo đức.

- **10/2019**: [DistilBERT](https://arxiv.org/abs/1910.01108), phiên bản nhẹ của BERT với tốc độ nhanh hơn 60%, bộ nhớ nhẹ hơn 40%, và vẫn giữ được 97% hiệu suất của BERT.

- **10/2019**: [BART](https://arxiv.org/abs/1910.13461) and [T5](https://arxiv.org/abs/1910.10683), hai mô hình lớn được đào tạo trước sử dụng cùng một kiến trúc với mô hình Transformer gốc (mô hình đầu tiên làm như vậy).

- **05/2020**, [GPT-3](https://arxiv.org/abs/2005.14165), phiên bản thậm chí còn lớn hơn của GPT-2, có thể thực hiện tốt nhiều tác vụ khác nhau mà không cần tinh chỉnh (còn được gọi là _zero-shot learning_)

Danh sách này vẫn chưa đầy đủ và chỉ nhằm mục đích làm nổi bật một vài số mô hình Transformer khác nhau. Nhìn chung, chúng có thể được chia thành ba loại:

- Giống GPT (còn được gọi là _auto-regression_ Transformer)
- Giống BERT (còn được gọi là _auto-encoding_ Transformer)
- Giống BART/T5 (còn được gọi là _sequence-to-sequence_ Transformer)

Chúng ta sẽ đi sâu hơn vào các nhóm này ở các phần sau.

## Transformers là mô hình ngôn ngữ

Tất cả các mô hình Transformer được đề cập ở trên (GPT, BERT, BART, T5, v.v.) được huấn luyện thành các _mô hình ngôn ngữ_. Điều này có nghĩa là chúng đã được huấn luyện trên một lượng lớn văn bản thô theo phương pháp tự giám sát. Học tự giám sát là một loại hình huấn luyện trong đó mục tiêu được tính toán tự động từ các đầu vào của mô hình. Điều đó có nghĩa là con người không cần thiết phải gắn nhãn dữ liệu!

Loại mô hình này phát triển theo sự hiểu biết thống kê về ngôn ngữ mà nó đã được huấn luyện, nhưng nó không hữu ích lắm cho các tác vụ cụ thể trong thực tế. Do đó, mô hình được huấn luyện chung chung trước sau đó sẽ trải qua một quá trình được gọi là _học chuyển giao_. Trong quá trình này, mô hình được tinh chỉnh theo cách có giám sát - nghĩa là sử dụng các nhãn do con người gán - trên một tác vụ nhất định.

Ví dụ về một tác vụ có thể kể đến dự đoán từ tiếp theo trong một câu đã đọc cho trước _n_ từ trước đó. Đây được gọi là _mô hình ngôn ngữ nhân quả_ bởi vì đầu ra phụ thuộc vào các đầu vào trong quá khứ và hiện tại, nhưng không phụ thuộc vào các đầu vào trong tương lai.

<div class="flex justify-center">
<img class="block dark:hidden" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/causal_modeling.svg" alt="Example of causal language modeling in which the next word from a sentence is predicted.">
<img class="hidden dark:block" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/causal_modeling-dark.svg" alt="Example of causal language modeling in which the next word from a sentence is predicted.">
</div>

Another example is _masked language modeling_, in which the model predicts a masked word in the sentence.

<div class="flex justify-center">
<img class="block dark:hidden" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/masked_modeling.svg" alt="Example of masked language modeling in which a masked word from a sentence is predicted.">
<img class="hidden dark:block" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/masked_modeling-dark.svg" alt="Example of masked language modeling in which a masked word from a sentence is predicted.">
</div>

## Transformers là mô hình lớn

Ngoài một số ngoại lệ (như DistilBERT), chiến lược chung để đạt được hiệu suất tốt hơn là tăng kích thước của các mô hình cũng như lượng dữ liệu mà chúng được huấn luyện trước.

<div class="flex justify-center">
<img src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/model_parameters.png" alt="Number of parameters of recent Transformers models" width="90%">
</div>

Tiếc thay, việc huấn luyện một mô hình, đặc biệt là một mô hình lớn, đòi hỏi một lượng lớn dữ liệu. Điều này trở nên rất tốn kém về mặt thời gian và tài nguyên tính toán. Nó thậm chí còn chuyển thành tác động môi trường, như có thể thấy trong biểu đồ sau.

<div class="flex justify-center">
<img class="block dark:hidden" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/carbon_footprint.svg" alt="The carbon footprint of a large language model.">
<img class="hidden dark:block" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/carbon_footprint-dark.svg" alt="The carbon footprint of a large language model.">
</div>

<Youtube id="ftWlj4FBHTg" />

Và điều này cho thấy một dự án cho một mô hình (rất lớn) được dẫn dắt bởi một nhóm có ý thức cố gắng giảm tác động môi trường của quá trình huấn luyện trước. Dấu chân của việc chạy nhiều thử nghiệm để có được siêu thông số tốt nhất sẽ còn cao hơn.

Hãy tưởng tượng nếu mỗi lần một nhóm nghiên cứu, một tổ chức sinh viên hoặc một công ty muốn huấn luyện một mô hình, họ sẽ thực hiện như vậy từ đầu. Điều này sẽ dẫn đến chi phí khổng lồ, không cần thiết!

Đây là lý do tại sao việc chia sẻ các mô hình ngôn ngữ là điều tối quan trọng: chia sẻ các trọng số đã được huấn luyện và xây dựng trên các trọng số đã được huấn luyện giúp giảm chi phí tính toán tổng thể và lượng khí thải carbon tới cộng đồng.

## Học chuyển giao

<Youtube id="BqqfQnyjmgg" />

_Huấn luyện trước_ là hành động huấn luyện một mô hình từ đầu: các trọng số được khởi tạo ngẫu nhiên và quá trình huấn luyện bắt đầu mà không cần biết trước bất kỳ điều gì.

<div class="flex justify-center">
<img class="block dark:hidden" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/pretraining.svg" alt="The pretraining of a language model is costly in both time and money.">
<img class="hidden dark:block" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/pretraining-dark.svg" alt="The pretraining of a language model is costly in both time and money.">
</div>

Việc huấn luyện trước này thường được thực hiện trên một lượng dữ liệu rất lớn. Do đó, nó yêu cầu một kho dữ liệu rất lớn và quá trình huấn luyện có thể mất đến vài tuần.

Mặt khác, _tinh chỉnh_ là quá trình huấn luyện được thực hiện **sau khi** một mô hình đã được huấn luyện trước. Để thực hiện việc tinh chỉnh, trước tiên bạn cần có một mô hình ngôn ngữ đã huấn luyện trước, sau đó thực hiện huấn luyện bổ sung với một tập dữ liệu cụ thể cho tác vụ của bạn. Khoan - tại sao không đơn giản là huấn luyện trực tiếp cho tác vụ cuối cùng? Có một vài lý do như sau:

- Mô hình được huấn luyện trước đã được huấn luyện trên một bộ dữ liệu có một số điểm tương đồng với bộ dữ liệu tinh chỉnh. Do đó, quá trình tinh chỉnh có thể tận dụng kiến thức có được bởi mô hình ban đầu trong quá trình huấn luyện trước (ví dụ: với các vấn đề NLP, mô hình được huấn luyện trước sẽ có một số hiểu biết thống kê về ngôn ngữ bạn đang sử dụng cho tác vụ của mình).
- Vì mô hình được huấn luyện trước đã được đào tạo trên nhiều dữ liệu, nên việc tinh chỉnh yêu cầu ít dữ liệu hơn để có được kết quả tốt.
- Với lý do tương tự, lượng thời gian và nguồn lực cần thiết để đạt được kết quả tốt thấp hơn nhiều.

Ví dụ: người ta có thể tận dụng một mô hình huấn luyện trước được huấn luyện trên ngôn ngữ tiếng Anh và sau đó tinh chỉnh nó trên kho ngữ liệu arXiv, trả về một mô hình dựa trên khoa học/nghiên cứu. Việc tinh chỉnh sẽ chỉ yêu cầu một lượng dữ liệu hạn chế: kiến thức mà mô hình được huấn luyện trước được "chuyển giao", do đó ta có thuật ngữ _học chuyển giao_.

<div class="flex justify-center">
<img class="block dark:hidden" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/finetuning.svg" alt="The fine-tuning of a language model is cheaper than pretraining in both time and money.">
<img class="hidden dark:block" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/finetuning-dark.svg" alt="The fine-tuning of a language model is cheaper than pretraining in both time and money.">
</div>

Do đó, việc tinh chỉnh một mô hình có chi phí thời gian, dữ liệu, tài chính và môi trường thấp hơn. Việc lặp lại các bước tinh chỉnh khác nhau cũng nhanh hơn và dễ dàng hơn, vì quá trình huấn luyện ít bị ràng buộc hơn so với huấn luyện trước từ đầu.

Quá trình này cũng sẽ đạt được kết quả tốt hơn so với huấn luyện từ đầu (trừ khi bạn có nhiều dữ liệu), đó là lý do tại sao bạn nên luôn cố gắng tận dụng một mô hình được huấn luyện trước - một mô hình càng gần với tác vụ bạn có trong tay càng tốt - và điều chỉnh nó.

## Kiến trúc tổng quan

Trong phần này, chúng ta sẽ xem xét kiến trúc chung của mô hình Transformer. Đừng lo lắng nếu bạn không hiểu một số khái niệm; có các phần sau bao gồm chi tiết từng thành phần.

<Youtube id="H39Z_720T5s" />

## Giới thiệu

Về cơ bản, mô hình bao gồm hai khối:

- **Bộ mã hóa (bên trái)**: Bộ mã hóa nhận đầu vào và xây dựng biểu diễn (các đặc trưng của nó). Điều này có nghĩa là mô hình được tối ưu hóa để có được sự hiểu biết từ đầu vào.
- **Bộ giải mã (bên phải)**: Bộ giải mã sử dụng biểu diễn (đặc trưng) của bộ mã hóa cùng với các đầu vào khác để tạo chuỗi đích. Điều này có nghĩa là mô hình được tối ưu hóa để tạo ra kết quả đầu ra.

<div class="flex justify-center">
<img class="block dark:hidden" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/transformers_blocks.svg" alt="Architecture of a Transformers models">
<img class="hidden dark:block" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/transformers_blocks-dark.svg" alt="Architecture of a Transformers models">
</div>

Mỗi phần có thể được sử dụng độc lập, tùy thuộc vào tác vụ:

- **Các mô hình chỉ dùng bộ mã hóa**: Phù hợp với các tác vụ yêu cầu hiểu rõ về đầu vào, chẳng hạn như phân loại câu và nhận dạng thực thể được đặt tên.
- **Các mô hình chỉ dùng bộ giải mã**: Tốt cho các tác vụ tổng hợp như tạo văn bản.
- **Các mô hình bộ mã hóa-giải mã** hoặc **mô hình chuỗi-sang-chuỗi**: Tốt cho các tác vụ tổng hợp yêu cầu đầu vào, chẳng hạn như dịch máy hoặc tóm tắt.

Chúng ta sẽ đi sâu vào các kiến trúc đó một cách độc lập trong các phần sau.

## Các lớp Attention

Một tính năng chính của các mô hình Transformer là chúng được xây dựng với các lớp đặc biệt được gọi là _Attention_. Trên thực tế, tiêu đề của bài báo giới thiệu kiến trúc Transformer là ["Attention is all you need"](https://arxiv.org/abs/1706.03762) hay "Sự chú ý là tất cả những gì bạn cần"! Chúng ta sẽ khám phá chi tiết về các lớp Attention ở phần sau của khóa học; hiện tại, tất cả những gì bạn cần biết là lớp này sẽ yêu cầu mô hình chú ý cụ thể đến các từ nhất định trong câu bạn đã chuyển nó (và ít nhiều bỏ qua những từ khác) khi xử lý biểu diễn của từng từ.

Để đặt điều này vào ngữ cảnh, cùng xem tác vụ dịch văn bản từ tiếng Anh sang tiếng Pháp. Với đầu vào là "You like this course" ("Bạn thích khóa học này"), một mô hình dịch cũng sẽ cần phải chú ý vào từ liền kề "You" để có được bản dịch thích hợp cho từ "like", bởi vì trong tiếng Pháp, động từ "like" được chia khác nhau tùy thuộc vào chủ ngữ. Tuy nhiên, phần còn lại của câu không hữu ích cho việc dịch từ đó. Tương tự như vậy, khi dịch "this", mô hình cũng sẽ cần chú ý đến từ "course", bởi vì "this" dịch khác nhau tùy thuộc vào việc danh từ liên quan là giống đực hay giống cái. Một lần nữa, các từ khác trong câu sẽ không thành vấn đề đối với bản dịch của "this". Với các câu phức tạp hơn (và các quy tắc ngữ pháp phức tạp hơn), mô hình sẽ cần đặc biệt chú ý đến các từ có thể xuất hiện ở xa hơn trong câu để dịch đúng từng từ.

Khái niệm tương tự cũng áp dụng cho bất kỳ tác vụ nào liên quan đến ngôn ngữ tự nhiên: một từ tự nó đã có nghĩa, nhưng nghĩa đó bị ảnh hưởng sâu sắc bởi ngữ cảnh, có thể là bất kỳ từ nào khác (hoặc các từ) trước hoặc sau từ được học.

Giờ bạn đã nắm được ý tưởng về tất cả các lớp Attention, chúng ta hãy xem xét kỹ hơn về kiến trúc Transformer.

## Kiến trúc gốc

Kiến trúc Transformer ban đầu được thiết kế phục vụ cho dịch máy. Trong quá trình huấn luyện, bộ mã hóa nhận đầu vào (câu) bằng một ngôn ngữ nhất định, trong khi bộ giải mã nhận các câu tương tự bằng ngôn ngữ đích mong muốn. Trong bộ mã hóa, các lớp Attention có thể sử dụng tất cả các từ trong một câu (vì, như chúng ta vừa thấy, bản dịch của một từ nhất định có thể phụ thuộc vào những gì đứng sau cũng như trước nó trong câu). Tuy nhiên, bộ giải mã hoạt động tuần tự và chỉ có thể chú ý đến các từ trong câu mà nó đã được dịch (vì vậy, chỉ những từ trước từ hiện đang được tạo). Ví dụ: khi chúng ta dự đoán ba từ đầu tiên của mục tiêu đã dịch, chúng ta đưa chúng cho bộ giải mã, sau đó sử dụng tất cả các đầu vào của bộ mã hóa để cố gắng dự đoán từ thứ tư.

Để tăng tốc độ mọi thứ trong quá trình huấn luyện (khi mô hình có quyền truy cập vào các câu đích), bộ giải mã được cung cấp toàn bộ nhãn, nhưng nó không được phép sử dụng các từ trong tương lai (nếu nó có quyền truy cập vào từ ở vị trí 2 khi cố gắng dự đoán từ ở vị trí 2, vấn đề sẽ không khó lắm!). Ví dụ: khi cố gắng dự đoán từ thứ tư, lớp Attention sẽ chỉ có quyền truy cập vào các từ ở vị trí 1 đến 3.

Kiến trúc Transformer gốc trông như sau, với bộ mã hóa ở bên trái và bộ giải mã ở bên phải:

<div class="flex justify-center">
<img class="block dark:hidden" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/transformers.svg" alt="Architecture of a Transformers models">
<img class="hidden dark:block" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/transformers-dark.svg" alt="Architecture of a Transformers models">
</div>

Lưu ý rằng lớp Attention đầu tiên trong bộ giải mã chú ý đến tất cả đầu vào (quá khứ) của bộ giải mã, nhưng lớp Attention thứ hai sử dụng đầu ra của bộ mã hóa. Do đó, nó có thể truy cập toàn bộ câu đầu vào để dự đoán tốt nhất từ hiện tại. Điều này rất hữu ích vì các ngôn ngữ khác nhau có thể có các quy tắc ngữ pháp đặt các từ theo thứ tự khác nhau hoặc một số ngữ cảnh được cung cấp sau trong câu có thể hữu ích để xác định bản dịch tốt nhất của một từ nhất định.

_Attention mask_ cũng có thể được sử dụng trong bộ mã hóa/ giải mã để ngăn mô hình chú ý đến một số từ đặc biệt - ví dụ: từ đệm đặc biệt được sử dụng để làm cho tất cả các đầu vào có cùng độ dài khi ghép các câu lại với nhau.

## Các kiến trúc và checkpoints

Khi chúng ta đi sâu và các mô hình Transformer trong hoá học này, bạn sẽ bắt gặp những cụm từ như _kiến trúc_, _checkpoint_ cũng như _mô hình_. Các thuật ngữ này mang ý nghĩa hơi khác nhau:

- **Kiến trúc**: Đây là khung của mô hình -- định nghĩa từng lớp và từng hoạt động xảy ra trong mô hình.
- **Checkpoints**: Đây là những trọng số sẽ được sử dụng trong một kiến trúc nhất định.
- **Mô hình**: Đây là một thuật ngữ bao trùm và không thể giải thích chính xác như "kiến trúc" hay "checkpoint": nó có thể mang cả hai nghĩa. Khoá học này sẽ chỉ ra khi nào là _kiến trúc_ và _checkpoint_ để giảm bớt sự mơ hồ khi cần thiết.

Ví dụ, BERT là 1 kiến trúc trong khi `bert-base-cased`,tập hợp các trọng số được huấn luyện bởi đội ngũ Google cho phiên bản đầu tiên của BERT, là 1 chekcpoint. Tuy nhiên, ta có thể nói "mô hình BERT" và "mô hình `bert-base-cased`".
