Pytorch
TensorFlow

#
Kết hợp lại

Trong vài phần trước, chúng ta đã cố gắng hết sức để làm hầu hết các tác vụ bằng tay. Chúng ta đã khám phá cách thức hoạt động của các công cụ tokenize và xem xét quá trình tokenize, chuyển đổi dữ liệu sang ID đầu vào, đệm, cắt bớt và các lớp che attention.

Tuy nhiên, như chúng ta đã thấy trong phần 2, API 🤗 Transformers có thể xử lý tất cả những điều này cho chúng ta bằng một chức năng cấp cao mà chúng ta sẽ đi sâu vào đây. Khi bạn gọi trực tiếp `tokenizer` trên câu, bạn sẽ nhận lại được các thông tin đầu vào sẵn sàng chuyển qua mô hình của bạn:

    from transformers import AutoTokenizer

    checkpoint = "distilbert-base-uncased-finetuned-sst-2-english"
    tokenizer = AutoTokenizer.from_pretrained(checkpoint)

    sequence = "I've been waiting for a HuggingFace course my whole life."

    model_inputs = tokenizer(sequence)

Ở đây, biến `model_inputs` chứa mọi thứ cần thiết để một mô hình hoạt động tốt. Đối với DistilBERT, điều đó bao gồm các ID đầu vào cũng như lớp che attention. Các mô hình khác chấp nhận đầu vào bổ sung cũng sẽ có đầu ra đó từ đối tượng `tokenizer`.

Như chúng ta sẽ thấy trong một số ví dụ bên dưới, phương pháp này rất mạnh mẽ. Đầu tiên, nó có thể mã hóa một chuỗi duy nhất:

    sequence = "I've been waiting for a HuggingFace course my whole life."

    model_inputs = tokenizer(sequence)

Nó cũng xử lý nhiều chuỗi cùng một lúc mà không cần thay đổi trong API:

    sequences = ["I've been waiting for a HuggingFace course my whole life.", "So have I!"]

    model_inputs = tokenizer(sequences)

Nó có thể đệm thêm tuỳ theo một số mục tiêu như sau:

    # Sẽ đệm thêm vào chuỗi sao cho độ dài bằng độ dài tối đa của chuỗi
    model_inputs = tokenizer(sequences, padding="longest")

    # Sẽ đệm thêm vào chuỗi sao cho độ dài bằng độ dài tối đa của mô hình
    # (512 cho BERT hoặc DistilBERT)
    model_inputs = tokenizer(sequences, padding="max_length")

    # Sẽ đệm thêm vào chuỗi sao cho độ dài bằng độ dài tối đa được chỉ định
    model_inputs = tokenizer(sequences, padding="max_length", max_length=8)

Nó cũng có thể cắt bớt các chuỗi:

    sequences = ["I've been waiting for a HuggingFace course my whole life.", "So have I!"]

    # Sẽ cắt bớt chuỗi cho bằng độ dài tối đa của mô hình
    # (512 cho BERT hoặc DistilBERT)
    model_inputs = tokenizer(sequences, truncation=True)

    # Sẽ cắt bớt chuỗi có độ dài dài hơn độ dài tối đa được chỉ định
    model_inputs = tokenizer(sequences, max_length=8, truncation=True)

Đối tượng `tokenizer` có thể xử lý việc chuyển đổi sang các tensor cụ thể, sau đó có thể được gửi trực tiếp đến mô hình. Ví dụ: trong đoạn mã sau, chúng tôi đang nhắc tokenizer trả về tensors từ các khung khác nhau - `"pt"` trả về tensors PyTorch, `"tf"` trả về tensors TensorFlow và `"np"` trả về mảng NumPy:

    sequences = ["I've been waiting for a HuggingFace course my whole life.", "So have I!"]

    # Trả về tensor PyTorch
    model_inputs = tokenizer(sequences, padding=True, return_tensors="pt")

    # Trả về tensor TensorFlow
    model_inputs = tokenizer(sequences, padding=True, return_tensors="tf")

    # Trả về mảng NumPy
    model_inputs = tokenizer(sequences, padding=True, return_tensors="np")

##
Các token đặc biệt

Nếu chúng ta xem xét các ID đầu vào được trả về bởi tokenizer, chúng ta sẽ thấy chúng hơi khác một chút so với những gì chúng ta đã có trước đó:

    sequence = "I've been waiting for a HuggingFace course my whole life."

    model_inputs = tokenizer(sequence)
    print(model_inputs["input_ids"])

    tokens = tokenizer.tokenize(sequence)
    ids = tokenizer.convert_tokens_to_ids(tokens)
    print(ids)

    [101, 1045, 1005, 2310, 2042, 3403, 2005, 1037, 17662, 12172, 2607, 2026, 2878, 2166, 1012, 102]
    [1045, 1005, 2310, 2042, 3403, 2005, 1037, 17662, 12172, 2607, 2026, 2878, 2166, 1012]

Một token ID đã được thêm vào vị trí đầu và cuối. Hãy giải mã hai chuỗi ID ở trên để xem nó là gì:

    print(tokenizer.decode(model_inputs["input_ids"]))
    print(tokenizer.decode(ids))

    "[CLS] i've been waiting for a huggingface course my whole life. [SEP]"
    "i've been waiting for a huggingface course my whole life."

Tokenizer đã thêm từ đặc biệt `[CLS]` vào đầu và từ đặc biệt `[SEP]` ở cuối. Điều này là do mô hình đã được huấn luyện trước với chúng, vì vậy để có được kết quả tương tự để luận suy, chúng ta cũng cần thêm chúng vào. Lưu ý rằng một số mô hình không thêm các từ đặc biệt hoặc thêm các từ khác; mô hình cũng có thể chỉ thêm những từ đặc biệt này vào đầu hoặc chỉ ở cuối. Trong mọi trường hợp, tokenizer biết cái nào được mong đợi và sẽ giải quyết việc này cho bạn.

##
Tổng kết: Từ tokenizer đến mô hình

Giờ chúng ta đã thấy tất cả các bước riêng lẻ mà `tokenizer` sử dụng khi áp dụng lên văn bản, chúng ta hãy xem lần cuối cách nó có thể xử lý nhiều chuỗi (đệm thêm!), chuỗi rất dài (cắt ngắn!) Và nhiều kiểu tensor với API chính của nó:

    import torch
    from transformers import AutoTokenizer, AutoModelForSequenceClassification

    checkpoint = "distilbert-base-uncased-finetuned-sst-2-english"
    tokenizer = AutoTokenizer.from_pretrained(checkpoint)
    model = AutoModelForSequenceClassification.from_pretrained(checkpoint)
    sequences = ["I've been waiting for a HuggingFace course my whole life.", "So have I!"]

    tokens = tokenizer(sequences, padding=True, truncation=True, return_tensors="pt")
    output = model(**tokens)