<FrameworkSwitchCourse {fw} />

# Các mô hình

{#if fw === 'pt'}

<CourseFloatingBanner chapter={2}
  classNames="absolute z-10 right-0 top-0"
  notebooks={[
    {
      label: "Google Colab",
      value:
        "https://colab.research.google.com/github/huggingface/notebooks/blob/master/course/vi/chapter2/section3_pt.ipynb",
    },
    {
      label: "Aws Studio",
      value:
        "https://studiolab.sagemaker.aws/import/github/huggingface/notebooks/blob/master/course/vi/chapter2/section3_pt.ipynb",
    },
  ]}
/>

{:else}

<CourseFloatingBanner chapter={2}
  classNames="absolute z-10 right-0 top-0"
  notebooks={[
    {
      label: "Google Colab",
      value:
        "https://colab.research.google.com/github/huggingface/notebooks/blob/master/course/vi/chapter2/section3_tf.ipynb",
    },
    {
      label: "Aws Studio",
      value:
        "https://studiolab.sagemaker.aws/import/github/huggingface/notebooks/blob/master/course/vi/chapter2/section3_tf.ipynb",
    },
  ]}
/>

{/if}

{#if fw === 'pt'}

<Youtube id="AhChOFRegn4"/>
{:else}
<Youtube id="d3JVgghSOew"/>
{/if}

{#if fw === 'pt'}
Trong phần này, chúng ta sẽ xem xét kỹ hơn về việc tạo và sử dụng một mô hình. Chúng tôi sẽ sử dụng `AutoModel`, rất tiện lợi khi bạn muốn khởi tạo bất kỳ mô hình nào từ một checkpoint.

`AutoModel` và tất cả các lớp họ hàng của nó thực ra là các hàm đóng gói đơn giản trên nhiều loại mô hình có sẵn trong thư viện. Đó là một hàm đóng gói thông minh vì nó có thể tự động đoán kiến trúc mô hình thích hợp cho checkpoint của bạn và sau đó khởi tạo một mô hình với kiến trúc này.

{:else}
Trong phần này, chúng ta sẽ xem xét kỹ hơn về việc tạo và sử dụng một mô hình. Chúng tôi sẽ sử dụng `TFAutoModel`, rất tiện lợi khi bạn muốn khởi tạo bất kỳ mô hình nào từ một checkpoint.

`TFAutoModel` và tất cả các lớp họ hàng của nó thực ra là các hàm đóng gói đơn giản trên nhiều loại mô hình có sẵn trong thư viện. Đó là một hàm đóng gói thông minh vì nó có thể tự động đoán kiến trúc mô hình thích hợp cho checkpoint của bạn và sau đó khởi tạo một mô hình với kiến trúc này.

{/if}

Tuy nhiên, nếu bạn biết loại mô hình bạn muốn sử dụng, bạn có thể sử dụng trực tiếp lớp định nghĩa kiến trúc của nó. Chúng ta hãy xem cách này hoạt động với mô hình BERT.

## Tạo ra một Transformer

Điều đầu tiên ta cần làm để khởi tạo mô hình BERT là tải một cấu hình:

{#if fw === 'pt'}

```py
from transformers import BertConfig, BertModel

# Building the config
config = BertConfig()

# Building the model from the config
model = BertModel(config)
```

{:else}

```py
from transformers import BertConfig, TFBertModel

# Building the config
config = BertConfig()

# Building the model from the config
model = TFBertModel(config)
```

{/if}

Cấu hình chứa nhiều thuộc tính được sử dụng để xây dựng mô hình:

```py
print(config)
```

```python out
BertConfig {
  [...]
  "hidden_size": 768,
  "intermediate_size": 3072,
  "max_position_embeddings": 512,
  "num_attention_heads": 12,
  "num_hidden_layers": 12,
  [...]
}
```

Mặc dù bạn chưa thấy tất cả các thuộc tính này có tác dụng gì, nhưng bạn nên nhận ra một số trong số chúng: thuộc tính `hidden_size` xác định kích thước của vectơ `hidden_states` và `num_hidden_layers` xác định số lớp mà mô hình Transformer có.

### Các phương pháp tải khác nhau

Việc tạo mô hình từ cấu hình mặc định sẽ khởi tạo mô hình đó với các giá trị ngẫu nhiên:

{#if fw === 'pt'}

```py
from transformers import BertConfig, BertModel

config = BertConfig()
model = BertModel(config)

# Model is randomly initialized!
```

{:else}

```py
from transformers import BertConfig, TFBertModel

config = BertConfig()
model = TFBertModel(config)

# Model is randomly initialized!
```

{/if}
Mô hình có thể được sử dụng ở trạng thái này, nhưng nó sẽ trả ra vô nghĩa; nó cần được huấn luyện trước. Chúng ta có thể huấn luyện mô hình từ đầu tác vụ này, nhưng như bạn đã thấy trong [Chương 1](/course/chapter1), điều này sẽ đòi hỏi một thời gian dài và nhiều dữ liệu, và nó sẽ tác động đáng kể tới môi trường. Để tránh nỗ lực không cần thiết và trùng lặp, khả năng chia sẻ và sử dụng lại các mô hình đã được huấn luyện trở nên bắt buộc.

Việc tải một mô hình Transformer đã được huấn luyện trước rất đơn giản - chúng ta có thể thực hiện việc này bằng cách sử dụng phương thức `from_pretrained()`:

{#if fw === 'pt'}

```py
from transformers import BertModel

model = BertModel.from_pretrained("bert-base-cased")
```

Như bạn đã thấy trước đó, chúng ta có thể thay thế `BertModel` bằng `AutoModel` tương đương. Chúng ta sẽ làm điều này từ bây giờ vì điều này tạo ra các đoạn mã checkpoint bất khả tri; nếu mã của bạn hoạt động cho một checkpoint, nó sẽ hoạt động liền mạch với một checkpoint khác. Điều này áp dụng ngay cả khi kiến trúc khác nhau, miễn là checkpoint đã được huấn luyện cho một tác vụ tương tự (ví dụ: một tác vụ phân tích cảm xúc).

{:else}

```py
from transformers import TFBertModel

model = TFBertModel.from_pretrained("bert-base-cased")
```

Như bạn đã thấy trước đó, chúng ta có thể thay thế `BertModel` bằng `TFAutoModel` tương đương. Chúng ta sẽ làm điều này từ bây giờ vì điều này tạo ra các đoạn mã checkpoint bất khả tri; nếu mã của bạn hoạt động cho một checkpoint, nó sẽ hoạt động liền mạch với một checkpoint khác. Điều này áp dụng ngay cả khi kiến trúc khác nhau, miễn là checkpoint đã được huấn luyện cho một tác vụ tương tự (ví dụ: một tác vụ phân tích cảm xúc).

{/if}

Trong đoạn mã ở trên, ta không sử dụng `BertConfig` và thay vào đó, tải một mô hình được đào tạo trước thông qua mã định danh `bert-base-cased`. Đây là một checkpoint mô hình do chính các tác giả của BERT huấn luyện; bạn có thể tìm thêm thông tin chi tiết về nó trong [thẻ mô hình](https://huggingface.co/bert-base-cased).

Mô hình này hiện đã được khởi tạo với tất cả các trọng số của checkpoint. Nó có thể được sử dụng trực tiếp để luận suy về các tác vụ mà nó đã được huấn luyện, và nó cũng có thể được tinh chỉnh trên một tác vụ mới. Bằng cách huấn luyện với trọng số đã được huấn luyện trước chứ không phải từ đầu, chúng ta có thể nhanh chóng đạt được kết quả tốt.

Các trọng số đã được tải xuống và lưu vào bộ nhớ cache (vì vậy các lệnh gọi tới phương thức `from_pretrained()` trong tương lai sẽ không tải xuống lại chúng) trong thư mục bộ nhớ cache, mặc định là _~/.cache/huggingface/transformers_. Bạn có thể tùy chỉnh thư mục bộ nhớ cache của mình bằng cách đặt biến môi trường `HF_HOME`.

Số định danh được sử dụng để tải mô hình có thể là số định danh của bất kỳ mô hình nào trên Model Hub, miễn là nó tương thích với kiến ​​trúc BERT. Toàn bộ danh sách các checkpoint BERT hiện có có thể được tìm thấy [tại đây](https://huggingface.co/models?filter=bert).

### Phương pháp lưu trữ checkpoint

Lưu một mô hình cũng dễ dàng như tải một mô hình - chúng ta sử dụng phương thức `save_pretrained()`, tương tự với phương thức `from_pretrained()`:

```py
model.save_pretrained("directory_on_my_computer")
```

Thao tác này sẽ lưu hai tệp vào đĩa của bạn:

{#if fw === 'pt'}

```
ls directory_on_my_computer

config.json pytorch_model.bin
```

{:else}

```
ls directory_on_my_computer

config.json tf_model.h5
```

{/if}

Nếu bạn xem tệp _config.json_, bạn sẽ nhận ra các thuộc tính cần thiết để xây dựng kiến trúc mô hình. Tệp này cũng chứa một số siêu dữ liệu, chẳng hạn như điểm bắt nguồn của checkpoint và phiên bản 🤗 Transformers bạn đang sử dụng khi bạn lưu checkpoint lần cuối.

{#if fw === 'pt'}

Tệp _pytorch_model.bin_ được gọi là _state dictionary_ (_từ điển trạng thái_); nó chứa tất cả các trọng số mô hình của bạn. Hai tập tin đi đôi với nhau; cấu hình là cần thiết để biết kiến trúc mô hình của bạn, trong khi trọng số mô hình là thông số của mô hình của bạn.

{:else}

Tệp _tf_model.h5_ được gọi là _state dictionary_ (_từ điển trạng thái_); nó chứa tất cả các trọng số mô hình của bạn. Hai tập tin đi đôi với nhau; cấu hình là cần thiết để biết kiến trúc mô hình của bạn, trong khi trọng số mô hình là thông số của mô hình của bạn.

{/if}

## Sử dụng mô hình Transformer để luận suy

Giờ bạn đã biết cách tải và lưu một mô hình, hãy thử sử dụng nó để đưa ra một số dự đoán. Các mô hình Transfomer chỉ có thể xử lý số - các số mà tokenizer tạo ra. Nhưng trước khi chúng ta thảo luận về tokenizer, chúng ta hãy khám phá những yếu tố đầu vào mà mô hình chấp nhận.

Tokenizer có thể đảm nhận việc truyền các đầu vào đến các tensor của khung thích hợp, nhưng để giúp bạn hiểu những gì đang xảy ra, chúng ta sẽ xem xét nhanh những gì phải thực hiện trước khi gửi đầu vào cho mô hình.

Giả sử chúng ta có một vài chuỗi như sau:

```py
sequences = ["Hello!", "Cool.", "Nice!"]
```

Tokenizer chuyển đổi các chỉ số này thành các chỉ mục từ vựng thường được gọi là _ID đầu vào_. Mỗi chuỗi giờ là một danh sách các số! Kết quả đầu ra là:

```py no-format
encoded_sequences = [
    [101, 7592, 999, 102],
    [101, 4658, 1012, 102],
    [101, 3835, 999, 102],
]
```

Đây là danh sách các chuỗi được mã hóa: danh sách các danh sách. Tensor chỉ chấp nhận dạng hình chữ nhật (hãy nghĩ tới ma trận). "Mảng" này đã có dạng hình chữ nhật, vì vậy việc chuyển đổi nó thành một tensor rất dễ dàng:

{#if fw === 'pt'}

```py
import torch

model_inputs = torch.tensor(encoded_sequences)
```

{:else}

```py
import tensorflow as tf

model_inputs = tf.constant(encoded_sequences)
```

{/if}

### Sử dụng tensor làm đầu vào mô hình

Việc sử dụng các tensors với mô hình cực kỳ đơn giản - chúng ta chỉ cần gọi mô hình với các đầu vào:

```py
output = model(model_inputs)
```

Mặc dù mô hình chấp nhận rất nhiều tham số khác nhau, nhưng chỉ các ID đầu vào là cần thiết. Chúng tôi sẽ giải thích những gì các tham số khác làm và khi nào chúng được yêu cầu sau, nhưng trước tiên, chúng ta cần xem xét kỹ hơn các bộ tokenizer tạo ra các đầu vào mà một mô hình Transformer có thể hiểu được.
