# Tokenizers

Tokenizer chuyển đổi văn bản thành các tensor, đây là đầu vào của một mô hình. Nó chuẩn hóa và tách văn bản, áp dụng thuật toán token hóa, thêm các token đặc biệt, và giải mã các id đầu ra trở lại thành văn bản.

```py
from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("google/gemma-2-2b")
tokenizer("Sphinx of black quartz, judge my vow.", return_tensors="pt")
{
    'input_ids': tensor([[     2, 235277,  82913,    576,   2656,  30407, 235269,  11490,    970,  29871, 235265]]),
    'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])
}
```

Hướng dẫn này bao gồm việc nạp, mã hóa, giải mã, xử lý theo lô và các backend tokenizer khả dụng.

## Tải một tokenizer

Tải một tokenizer bằng lớp [AutoTokenizer](/docs/transformers/v5.23.0/vi/model_doc/auto#transformers.AutoTokenizer) hoặc một lớp tokenizer dành riêng cho mô hình.

[AutoTokenizer.from_pretrained()](/docs/transformers/v5.23.0/vi/model_doc/auto#transformers.AutoTokenizer.from_pretrained) đọc cấu hình mô hình, xác định lớp tokenizer phù hợp và trả về một instance của lớp đó. Bạn không cần biết trước lớp tokenizer. Hầu hết các tokenizer được phân giải thành một subclass của [TokenizersBackend](/docs/transformers/v5.23.0/vi/main_classes/tokenizer#transformers.TokenizersBackend), một tokenizer nhanh dựa trên Rust từ thư viện [Tokenizers](https://huggingface.co/docs/tokenizers/index).

Việc tải bằng [AutoTokenizer](/docs/transformers/v5.23.0/vi/model_doc/auto#transformers.AutoTokenizer) là cách tiếp cận được khuyến nghị.

```py
from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("google/gemma-2-2b")
```

Lớp tokenization dành riêng cho một mô hình là một [TokenizersBackend](/docs/transformers/v5.23.0/vi/main_classes/tokenizer#transformers.TokenizersBackend) đã được cấu hình sẵn, sử dụng chính xác cấu hình tokenization (normalizer, pre-tokenizer, các quy ước về token đặc biệt, v.v.) mà mô hình đó đã được huấn luyện.

Sử dụng một lớp cụ thể cho mô hình để khởi tạo một tokenizer trống cho việc huấn luyện hoặc để truyền các đối số cụ thể cho mô hình như `vocab` hoặc `merges` (xem hướng dẫn [Tùy chỉnh tokenizer](./custom_tokenizers) để tìm hiểu cách thực hiện). Một tokenizer trống là tối giản và chỉ chứa các token đặc biệt của mô hình như `<pad>`, `<eos>`, hoặc `<bos>`.

```py
from transformers import GemmaTokenizer

tokenizer = GemmaTokenizer()
corpus = [
    ["Sphinx of black quartz, judge my vow."],
    ["Pack my box with five dozen liquor jugs."],
    ["How vexingly quick daft zebras jump!"],
]
new_tokenizer = tokenizer.train_new_from_iterator(corpus, vocab_size=1000)
```

## Mã hóa và giải mã

Phương thức [TokenizersBackend.__call__()](/docs/transformers/v5.23.0/vi/internal/tokenization_utils#transformers.PreTrainedTokenizerBase.__call__) mã hóa văn bản hoặc một lô văn bản thành `input_ids`, `attention_mask` và các đầu vào mô hình khác. Nó cũng kiểm soát việc đệm, cắt ngắn và chèn token đặc biệt.

```py
from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("google/gemma-2-2b")
tokenizer("Sphinx of black quartz, judge my vow.", return_tensors="pt")
{
    'input_ids': tensor([[     2, 235277,  82913,    576,   2656,  30407, 235269,  11490,    970,  29871, 235265]]),
    'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])
}
```

[TokenizersBackend.encode()](/docs/transformers/v5.23.0/vi/internal/tokenization_utils#transformers.PreTrainedTokenizerBase.encode) tương tự nhưng chỉ trả về `input_ids`.

```py
from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("google/gemma-2-2b")
input_ids = tokenizer.encode("Sphinx of black quartz, judge my vow.")
[2, 235277, 82913, 576, 2656, 30407, 235269, 11490, 970, 29871, 235265]
```

[TokenizersBackend.decode()](/docs/transformers/v5.23.0/vi/internal/tokenization_utils#transformers.PreTrainedTokenizerBase.decode) chuyển đổi một chuỗi hoặc lô các `input_ids` đã được token hóa trở lại thành văn bản.

```py
tokenizer.decode(input_ids)
'<bos>Sphinx of black quartz, judge my vow.'
```

[TokenizersBackend.decode()](/docs/transformers/v5.23.0/vi/internal/tokenization_utils#transformers.PreTrainedTokenizerBase.decode) giữ nguyên khoảng cách token hóa chính xác. Đặt `clean_up_tokenization_spaces` để xóa khoảng trắng trước các dấu câu, và `skip_special_tokens` để loại bỏ các token đặc biệt khỏi đầu ra.

```py
tokenizer.decode(input_ids, skip_special_tokens=True)
'Sphinx of black quartz, judge my vow.'
```

## Token đặc biệt

Token đặc biệt đánh dấu các ranh giới cấu trúc trong một chuỗi, chẳng hạn như vị trí bắt đầu chuỗi hoặc vị trí đệm. Mỗi mô hình định nghĩa bộ token đặc biệt riêng của nó. Bộ phân từ sẽ thêm chúng vào khi bạn gọi nó.

```py
input_ids = tokenizer.encode("Sphinx of black quartz, judge my vow.")
[2, 235277, 82913, 576, 2656, 30407, 235269, 11490, 970, 29871, 235265]
tokenizer.decode(input_ids)
'<bos>Sphinx of black quartz, judge my vow.'
```

Đăng ký các token đặc biệt có tên bổ sung bằng đối số `extra_special_tokens`. Các mô hình đa phương thức sử dụng chúng như các vị trí thay thế cho hình ảnh, video hoặc âm thanh.

```py
from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained(
    "google/gemma-3-4b-pt",
    extra_special_tokens={"image_token": "<image>"}
)
```

## Xử lý theo lô

Xử lý theo lô (batch processing) thực hiện tokenization cho nhiều chuỗi trong một lần gọi. [TokenizersBackend](/docs/transformers/v5.23.0/vi/main_classes/tokenizer#transformers.TokenizersBackend) xử lý các lô lớn nhanh hơn vì backend dựa trên Rust của nó song song hóa công việc trên nhiều luồng.

```py
from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("google/gemma-2-2b")
tokenizer(
    [
        "Sphinx of black quartz, judge my vow.",
        "Pack my box with five dozen liquor jugs.",
        "How vexingly quick daft zebras jump!"
    ],
    return_tensors="pt"
)
```

Xử lý theo lô yêu cầu tất cả các chuỗi phải có cùng độ dài. Việc đệm (padding) và cắt ngắn (truncation) là các chiến lược để xử lý các chuỗi có độ dài khác nhau.

### Đệm

Padding thêm các token đặc biệt để các chuỗi ngắn hơn khớp với chuỗi dài nhất trong một batch. Attention mask đánh dấu các vị trí padding là `0` để mô hình bỏ qua chúng. Đặt `padding=True` để pad đến chuỗi dài nhất hoặc truyền `max_length` để pad đến một kích thước cố định.

```py
from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("google/gemma-2-2b")
tokenizer(
    [
        "Sphinx of black quartz, judge my vow.",
        "Pack my box with five dozen liquor jugs.",
        "How vexingly quick daft zebras jump!"
    ],
    return_tensors="pt",
    padding=True,
)
{
    'input_ids': tensor([
        [     2, 235277,  82913,    576,   2656,  30407, 235269,  11490,    970,  29871, 235265],
        [     0,      2,   6519,    970,   3741,    675,   4105,  25955,  42184, 225789, 235265],
        [     0,      2,   2299,  73378,  17844,   4320, 224463,   4949,  48977,  9902, 235341]
    ]),
    'attention_mask': tensor([
        [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
        [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
        [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
    ])
}
```

> [!NOTE]
> Các mô hình ngôn ngữ lớn chèn padding ở phía *trái* để tránh làm gián đoạn quá trình sinh, vốn dự đoán token tiếp theo từ phía *phải*.

### Cắt ngắn

Truncation cắt bớt các token để một chuỗi nằm trong phạm vi độ dài tối đa. Đặt `truncation=True` và chỉ định `max_length` để bật tính năng này.

Padding và truncation hoạt động cùng nhau. Các chuỗi ngắn nhận thêm các token padding trong khi các chuỗi dài mất đi các token ở cuối. Kết hợp lại, chúng tạo ra một tensor chữ nhật được đóng gói.

```py
from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("google/gemma-2-2b")
tokenizer(
    [
        "Sphinx of black quartz, judge my vow.",
        "Pack my box with five dozen liquor jugs.",
        "How vexingly quick daft zebras jump!"
    ],
    return_tensors="pt",
    padding=True,
    truncation=True,
    max_length=5
)
{
    'input_ids': tensor([
        [     2, 235277,  82913,    576,   2656],
        [     2,   6519,    970,   3741,    675],
        [     2,   2299,  73378,  17844,   4320]
    ]),
    'attention_mask': tensor([
        [1, 1, 1, 1, 1],
        [1, 1, 1, 1, 1],
        [1, 1, 1, 1, 1]
    ])
}
```

## Các backend

Mỗi model tokenizer được định nghĩa trong một tệp duy nhất và hỗ trợ bốn backend tokenization.

| backend                  | implementation                                                | mô tả                                    |
| ------------------------ | ------------------------------------------------------------- | ---------------------------------------------- |
| [TokenizersBackend](/docs/transformers/v5.23.0/vi/main_classes/tokenizer#transformers.TokenizersBackend)    | [Tokenizers](https://huggingface.co/docs/tokenizers)          | mặc định cho hầu hết các mô hình                        |
| [SentencePieceBackend](/docs/transformers/v5.23.0/vi/main_classes/tokenizer#transformers.SentencePieceBackend) | [SentencePiece](https://github.com/google/sentencepiece)      | các mô hình yêu cầu SentencePiece                 |
| [PythonBackend](/docs/transformers/v5.23.0/vi/main_classes/tokenizer#transformers.PythonBackend)        | Python                                                        | các mô hình yêu cầu bộ phân từ tùy chỉnh chuyên dụng |
| [MistralCommonBackend](/docs/transformers/v5.23.0/vi/model_doc/mistral#transformers.MistralCommonBackend) | [mistral-common](https://mistralai.github.io/mistral-common/) | Mô hình Mistral và Pixtral                     |

Tất cả các backend đều kế thừa từ [PreTrainedTokenizerBase](/docs/transformers/v5.23.0/vi/internal/tokenization_utils#transformers.PreTrainedTokenizerBase) và chia sẻ cùng các API cho việc mã hóa, giải mã, đệm, cắt ngắn, lưu trữ và tải. Sự khác biệt nằm ở pipeline tokenization nào được chạy bên dưới.

[AutoTokenizer](/docs/transformers/v5.23.0/vi/model_doc/auto#transformers.AutoTokenizer) sẽ chọn backend khả dụng tốt nhất khi bạn gọi [from_pretrained()](/docs/transformers/v5.23.0/vi/model_doc/auto#transformers.AutoTokenizer.from_pretrained).

1. Nó đọc tệp `tokenizer_config.json` để lấy trường `tokenizer_class`.
2. Registry khớp `tokenizer_class` với tên lớp. Lớp được phân giải kế thừa từ một trong bốn backend. Ví dụ, [GemmaTokenizer](/docs/transformers/v5.23.0/vi/model_doc/gemma#transformers.GemmaTokenizer) kế thừa từ [TokenizersBackend](/docs/transformers/v5.23.0/vi/main_classes/tokenizer#transformers.TokenizersBackend), và [SiglipTokenizer](/docs/transformers/v5.23.0/vi/model_doc/siglip#transformers.SiglipTokenizer) kế thừa từ [SentencePieceBackend](/docs/transformers/v5.23.0/vi/main_classes/tokenizer#transformers.SentencePieceBackend). Một số mô hình, như GLM, ánh xạ trực tiếp đến [TokenizersBackend](/docs/transformers/v5.23.0/vi/main_classes/tokenizer#transformers.TokenizersBackend) vì tệp `tokenizer.json` mô tả đầy đủ pipeline. [GemmaTokenizer](/docs/transformers/v5.23.0/vi/model_doc/gemma#transformers.GemmaTokenizer) tồn tại dưới dạng lớp con vì nó định nghĩa các cài đặt cụ thể cho mô hình bằng Python mà `tokenizer.json` không nắm bắt được. Khi một backend như mistral-common không được cài đặt, [AutoTokenizer](/docs/transformers/v5.23.0/vi/model_doc/auto#transformers.AutoTokenizer) sẽ chuyển sang [TokenizersBackend](/docs/transformers/v5.23.0/vi/main_classes/tokenizer#transformers.TokenizersBackend).

### Dùng TokenizersBackend làm phương án dự phòng

Một số model không có lớp tokenizer chuyên dụng, và một số checkpoint có `tokenizer_class` không khớp với tệp `tokenizer.json` thực tế của chúng. [AutoTokenizer](/docs/transformers/v5.23.0/vi/model_doc/auto#transformers.AutoTokenizer) xử lý cả hai trường hợp bằng cách tải pipeline từ `tokenizer.json` thông qua [TokenizersBackend](/docs/transformers/v5.23.0/vi/main_classes/tokenizer#transformers.TokenizersBackend) tổng quát. Nó ưu tiên tokenizer đã được serialize hơn là tên lớp từ Hub, điều này khắc phục các vấn đề như khi `tokenizer_class` không khớp tạo ra các token id không chính xác.

Một checkpoint được phân giải thành `TokenizersBackend` chung vì một trong ba lý do.

| Lý do                              | Hành vi                                                                                                                                 | Ví dụ                                                                       |
| ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
| Không có lớp tokenizer riêng        | Loại mô hình ánh xạ trực tiếp đến `TokenizersBackend` vì `tokenizer.json` mô tả đầy đủ pipeline.                               | GLM, Granite, OLMo 2, GPT BigCode                                              |
| Lớp tokenizer Hub không chính xác | `tokenizer_class` được ghi trên Hub không khớp với loại mô hình, do đó `AutoTokenizer` bỏ qua nó và tải `tokenizer.json` thay thế. | DeepSeek V3, LLaVA, Qwen2, ModernBERT                                          |
| Ghi đè checkpoint cụ thể        | Một checkpoint mà cấu hình Hub của nó vẫn cần được sửa sẽ được khớp theo model id và bị ép sử dụng backend.                                    | `deepseek-ai/DeepSeek-R1-Distill-*`, `Salesforce/blip2-*`, `google/umt5-small` |

Các loại model và checkpoint bị ảnh hưởng sẽ tăng lên khi các config được sửa trên Hub. Để xem bộ hiện tại, hãy xem định nghĩa `MODELS_WITH_INCORRECT_HUB_TOKENIZER_CLASS` và `MODEL_IDS_TO_TOKENIZERS_BACKEND` trong [tokenization_auto.py](https://github.com/huggingface/transformers/blob/main/src/transformers/models/auto/tokenization_auto.py).

Cơ chế dự phòng diễn ra tự động và không thay đổi cách bạn gọi [from_pretrained()](/docs/transformers/v5.23.0/vi/model_doc/auto#transformers.AutoTokenizer.from_pretrained). Tokenizer kết quả sẽ mã hóa và giải mã chính xác như `tokenizer.json` quy định.

Kiểm tra backend mà một tokenizer đang sử dụng bằng thuộc tính `backend`.

```py
from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("google/gemma-2-2b")
tokenizer.backend
'tokenizers'
```

## Kiểm tra kiến trúc tokenizer

Kiểm tra các thành phần bên trong của tokenizer (normalizer, pre-tokenizer, model, decoder) bằng thuộc tính `_tokenizer`.

```py
from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("google/gemma-2-2b")
print(tokenizer._tokenizer.normalizer)
print(tokenizer._tokenizer.pre_tokenizer)
print(tokenizer._tokenizer.model)
print(tokenizer._tokenizer.decoder)
```

## Tài nguyên

- Bài đăng [Tokenization in Transformers v5](https://huggingface.co/blog/tokenizers) thảo luận về động lực đằng sau các backend tokenization mới.
- Xem lại [hướng dẫn di chuyển](https://github.com/huggingface/transformers/blob/main/MIGRATION_GUIDE_V5.md#tokenization) để có cái nhìn tổng quan về các thay đổi trong tokenization.

