Đọc ngày 2026-07-24

Kế hoạch hôm nay

Mục tiêu cần hiểu

  • Hiểu workflow cơ bản của bài toán text classification từ dataset đến model.
  • Biết cách inspect dataset bằng Hugging Face Datasets và kiểm tra phân phối nhãn.
  • Nhận ra vì sao độ dài văn bản ảnh hưởng tokenization, padding, truncation và batch training.
  • Phân biệt character, word và subword tokenization ở mức ý tưởng.

Câu hỏi dẫn đường

  • Text classification gồm những bước nào từ dữ liệu đến dự đoán?
  • Vì sao cần nhìn phân phối nhãn và độ dài văn bản trước khi train?
  • Tokenization ảnh hưởng gì đến input của Transformer?

Ghi chú trong khi đọc

  • Bài toán chính của chapter này là xây một emotion classifier cho tweet. Đây là một dạng Text Classification: input là raw text, output là một nhãn rời rạc như sadness, joy, love, anger, fear, surprise.
  • Workflow tổng quát:
    • Load dataset bằng Hugging Face datasets.
    • Inspect các split như train, validation, test.
    • Kiểm tra schema/cột dữ liệu: text chứa nội dung tweet, label chứa nhãn dạng số.
    • Map nhãn số sang tên nhãn bằng ClassLabel.int2str().
    • Chuyển tạm sang Pandas để nhìn dữ liệu và visualize.
    • Kiểm tra phân phối nhãn để biết dataset có cân bằng không.
    • Kiểm tra độ dài văn bản để biết có rủi ro vượt context size của model không.
    • Tokenize text thành input_idsattention_mask.
    • Dùng dữ liệu đã tokenize làm input cho model Transformer.
  • Hugging Face DatasetDict giống dictionary gồm nhiều split. Mỗi split là một Dataset, có thể truy cập bằng index, slice, hoặc tên cột.
  • Dataset dựa trên Apache Arrow nên lưu dạng columnar, typed, hiệu quả bộ nhớ hơn list/dict Python thông thường.
  • Trong emotion dataset, label không chỉ là positive/negative mà gồm 6 cảm xúc. Điều này làm bài toán giàu hơn sentiment analysis nhị phân.
  • Phân phối nhãn bị lệch: joy và sadness xuất hiện nhiều hơn, love và surprise ít hơn nhiều. Nếu bỏ qua chuyện này, model có thể học thiên về class phổ biến và cho accuracy nhìn có vẻ ổn nhưng thực ra yếu ở class hiếm.
  • Khi class imbalance xuất hiện, cần nghĩ tới metric và training strategy:
    • Không chỉ nhìn accuracy.
    • Có thể cần F1 theo từng class hoặc macro F1.
    • Có thể oversample minority class, undersample majority class, hoặc thu thập thêm dữ liệu cho class thiếu.
    • Không được sampling trước khi chia train/test vì dễ gây data leakage.
  • Độ dài tweet quan trọng vì Transformer có maximum context size. Với DistilBERT là 512 token. Nếu input dài hơn giới hạn thì phải truncate, có thể mất thông tin quan trọng.
  • Ở tập tweet này, phần lớn text khá ngắn, khoảng vài chục từ, nên truncation có vẻ không phải vấn đề lớn.
  • Raw string không thể đưa trực tiếp vào Transformer. Text phải được tokenized và numericalized thành token IDs.
  • Character tokenization:
    • Chia text thành từng ký tự.
    • Ưu điểm: xử lý tốt từ hiếm, typo, biến thể lạ vì ký tự gần như luôn nằm trong vocabulary.
    • Nhược điểm: sequence dài hơn, model phải tự học cấu trúc từ/ngữ nghĩa từ dữ liệu, tốn compute và data.
  • Word tokenization:
    • Chia text theo từ, ví dụ dùng whitespace.
    • Ưu điểm: giữ được cấu trúc từ ngay từ đầu, sequence ngắn hơn character-level.
    • Nhược điểm: vocabulary có thể rất lớn; punctuation, biến thể từ, typo, inflection làm số lượng token tăng mạnh.
    • Nếu giới hạn vocabulary, từ hiếm sẽ bị gom vào [UNK], làm mất thông tin.
  • Subword tokenization là điểm cân bằng:
    • Từ phổ biến được giữ nguyên.
    • Từ hiếm hoặc từ phức tạp được chia thành mảnh nhỏ hơn.
    • Giảm vocabulary size nhưng vẫn giữ khả năng biểu diễn từ mới/từ hiếm tốt hơn word-level.
  • DistilBERT dùng tokenizer tương ứng với checkpoint distilbert-base-uncased. Điều quan trọng là model pretrained phải đi với đúng tokenizer của nó; đổi tokenizer giống như làm xáo trộn vocabulary mà model đã học.
  • AutoTokenizer.from_pretrained() giúp tự tải tokenizer đúng với checkpoint. Đây là pattern hay vì sau này đổi model checkpoint thì code ít phải sửa.
  • Tokenizer trả về:
    • input_ids: ID số của từng token.
    • attention_mask: vị trí nào là token thật, vị trí nào là padding.
  • Special tokens quan trọng:
    • [CLS]: đánh dấu đầu sequence, thường dùng cho representation của toàn câu trong classification.
    • [SEP]: đánh dấu cuối sequence hoặc ranh giới giữa hai sequence.
    • [PAD]: padding để các example trong batch có cùng length.
    • [UNK]: token unknown.
    • [MASK]: dùng trong masked language modeling.
  • Padding giúp các sequence trong cùng batch có shape giống nhau. Attention mask giúp model bỏ qua phần padding khi tính attention.
  • map() trong Hugging Face Datasets là cách chuẩn để apply function tokenize lên toàn bộ dataset/split. Dùng batched=True để xử lý theo batch hiệu quả hơn.

Viết lại bằng lời của tôi

  • Để làm text classification với Transformer, mình không bắt đầu từ model ngay mà phải bắt đầu từ dữ liệu. Trước tiên cần biết dataset có những split nào, mỗi dòng gồm những cột nào, label nghĩa là gì, và các class có cân bằng không. Nếu dữ liệu lệch nhãn, model rất dễ ưu tiên class nhiều mẫu; vì vậy bước inspect class distribution là một phần của modeling chứ không phải bước phụ.
  • Sau đó cần nhìn độ dài văn bản. Transformer không đọc text vô hạn mà có giới hạn context size. Nếu text quá dài, tokenizer phải cắt bớt; nếu phần bị cắt chứa tín hiệu quan trọng thì performance giảm. Với tweet trong emotion dataset, text ngắn nên phù hợp với DistilBERT.
  • Tokenization là cầu nối từ ngôn ngữ tự nhiên sang input số cho model. Character tokenization giữ được mọi ký tự nhưng làm sequence dài và bắt model học quá nhiều từ đầu. Word tokenization giữ nghĩa gần với con người hơn nhưng vocabulary phình lớn và xử lý từ hiếm kém. Subword tokenization nằm giữa hai cực này: giữ nguyên từ thường gặp, chia nhỏ từ hiếm, nên vừa tiết kiệm vocabulary vừa không mất toàn bộ thông tin như [UNK].
  • Với pretrained Transformer, tokenizer không phải chi tiết có thể thay tùy ý. Model đã được pretrain với một vocabulary và cách tách token cụ thể, nên khi fine-tune hay inference phải dùng đúng tokenizer tương ứng với checkpoint. AutoTokenizer giúp giữ coupling này một cách tiện lợi.
  • Sau tokenization, mỗi câu được biến thành input_idsattention_mask. input_ids nói cho model biết token nào xuất hiện; attention_mask nói vị trí nào là nội dung thật và vị trí nào chỉ là padding. Đây là lý do cùng một batch có thể có các câu ngắn/dài khác nhau nhưng vẫn đưa vào model được.
  • Mental model của phần hôm nay: trước khi train classifier, mình đang biến một bài toán “tweet cảm xúc” thành một pipeline có kiểm soát: hiểu dữ liệu, kiểm tra rủi ro imbalance/length, chọn tokenizer đúng với model, rồi chuẩn hóa toàn bộ dataset thành tensor-like features để bước training phía sau có thể chạy ổn định.

Điều chưa rõ

  • Khi dataset bị imbalance, nên chọn macro F1, weighted F1 hay per-class F1 trong trường hợp nào? Accuracy chắc chắn chưa đủ, nhưng cần hiểu trade-off giữa các metric.
  • Khi nào nên dùng oversampling/undersampling, và khi nào nên chỉ đổi loss/metric mà không đụng vào phân phối dữ liệu?
  • Padding toàn bộ dataset tới cùng một độ dài có thể tiện cho feature extraction, nhưng có lãng phí bộ nhớ so với dynamic padding theo batch không?
  • [CLS] token trong DistilBERT/BERT thực sự được dùng như thế nào cho classification head ở phần sau?
  • Subword tokenizer học vocabulary từ corpus bằng thuật toán cụ thể nào, và WordPiece khác BPE/SentencePiece ở đâu?

Việc cần làm

  • Đọc trang 39-57
  • Viết lại workflow text classification bằng lời của tôi
  • Ghi lại 1 concept cần tách sang 04 - Concepts: cập nhật/đào sâu Tokenization, đặc biệt phần subword tokenization.
  • Review lại các câu hỏi về imbalance metrics và dynamic padding vào 2026-07-26.