Vì sao Transformer cần Positional Encoding cho chuỗi thời gian? Hướng dẫn trực quan

05 tháng 9, 2026·14 phút đọc

Bài viết giải thích chi tiết lý do vì sao mô hình Transformer cần cơ chế positional encoding khi xử lý dữ liệu chuỗi thời gian, bắt đầu từ bản chất của self-attention. Tác giả minh họa cách thông tin vị trí được mã hóa và kết hợp để giúp mô hình hiểu được thứ tự và khoảng cách giữa các điểm dữ liệu. Từ đó, bài viết cung cấp nền tảng kiến thức quan trọng để tiếp cận các mô hình nền tảng (foundation models) hiện đại cho chuỗi thời gian.

Vì sao Transformer cần Positional Encoding cho chuỗi thời gian? Hướng dẫn trực quan

Trong quá trình tìm hiểu về các mô hình nền tảng (foundation models) cho chuỗi thời gian, tôi nhận ra rằng mình không thể thực sự hiểu chúng nếu chưa nắm vững về Transformer. Tôi không muốn sử dụng những mô hình này như một "hộp đen", vì vậy tôi bắt đầu truy vết các ý tưởng ngược về nguồn gốc: từ mô hình nền tảng đến Transformer, rồi từ Transformer đến self-attention. Điều khiến quá trình này thú vị là mặc dù Transformer ban đầu được xây dựng cho ngôn ngữ, ý tưởng cốt lõi của nó hoàn toàn phù hợp với chuỗi thời gian. Hai dạng dữ liệu này rất khác nhau nhưng chúng có chung một đặc tính nền tảng: đều là chuỗi tuần tự, và trong cả hai trường hợp, thứ tự đều làm thay đổi ý nghĩa.

Trong ngôn ngữ, "chó cắn người" và "người cắn chó" là hai câu chuyện rất khác nhau. Chuỗi thời gian cũng vậy. Nhiệt độ hôm qua là 30∘ và hôm nay là 20∘ là một câu chuyện hoàn toàn khác so với hôm qua 20∘ và hôm nay 30∘. Giá trị có thể giống nhau, nhưng thứ tự của chúng thay đổi ý nghĩa của toàn bộ chuỗi.

Câu hỏi đặt ra là: nếu self-attention nhìn vào tất cả các quan sát cùng một lúc, làm cách nào Transformer biết được quan sát nào đến trước, quan sát nào đến sau, hoặc khoảng cách giữa hai quan sát là bao xa? Câu hỏi đó đã dẫn tôi đến khái niệm positional encoding (mã hóa vị trí).

Điều khiến tôi bất ngờ nhất là một ý tưởng toán học đơn giản như vậy lại có thể mang lại cho Transformer một "cảm giác" về trật tự. Các kỹ thuật chính xác đã tiến hóa rất nhiều kể từ đó, nhưng bài toán cốt lõi vẫn giữ nguyên. Bài viết này là nỗ lực của tôi nhằm xây dựng trực giác đó từ con số không, bắt đầu với một chuỗi thời gian đơn giản và đi theo con đường từ các quan sát thô đến self-attention và cuối cùng là positional encoding.

Từ các quan sát vô hướng đến biểu diễn vector

Hãy xem xét một chuỗi thời gian đơn giản ghi lại nhiệt độ trong năm ngày làm việc trong tuần.

Ví dụ về chuỗi thời gian: nhiệt độ 5 ngàyVí dụ về chuỗi thời gian: nhiệt độ 5 ngày

Mỗi quan sát x_t chỉ là một giá trị vô hướng. Tuy nhiên, Transformer hoạt động trên các vector có chiều dài cố định là d_model. Do đó, các quan sát vô hướng cần phải được ánh xạ vào không gian biểu diễn đó trước tiên.

Một cách đơn giản để làm điều này là thông qua một phép chiếu tuyến tính có thể học được (learned linear projection), hay còn gọi là embedding:

e_t = W_e * x_t + b_e

Điều này tạo ra một chuỗi các biểu diễn vector: e1, e2, e3, e4, e5.

Embedding là một biểu diễn sâu, trừu tượng của chuỗi dữ liệu dưới dạng một vector số đa chiều, mã hóa các đặc trưng của dữ liệu mà mô hình có thể hiểu được [1].

Mã hóa embedding cho mỗi tokenMã hóa embedding cho mỗi token

Mỗi e_t nắm giữ thông tin về giá trị quan sát tại thời điểm t, nhưng ở bước này, nó mới chỉ là một biểu diễn của quan sát đó. Từ khóa quan trọng ở đây là "học được" (learned). Mô hình không được cung cấp sẵn một vector biểu diễn cụ thể cho nhiệt độ như 18∘. Các tham số W_e và b_e được học trong quá trình huấn luyện để tạo ra các biểu diễn hữu ích cho nhiệm vụ cuối cùng. Tại thời điểm này, e_t chỉ đại diện cho những gì đã được quan sát, nó chưa cho mô hình biết quan sát đó xảy ra ở vị trí nào trong chuỗi.

Self-attention xây dựng ngữ cảnh bằng cách nào?

Self-attention cho phép mỗi quan sát sử dụng thông tin từ tất cả các quan sát khác trong chuỗi để cập nhật biểu diễn của chính nó.

Giả sử chúng ta muốn cập nhật biểu diễn cho ngày thứ Sáu. Đầu tiên, mô hình tạo ra ba phép chiếu học được (learned projections) từ mỗi e_t:

  • q_t = W_Q * e_t (vector truy vấn - Query)
  • k_t = W_K * e_t (vector khóa - Key)
  • v_t = W_V * e_t (vector giá trị - Value)

Các vector Query, Key, ValueCác vector Query, Key, Value

Các ma trận W_Q, W_K, W_V cũng được học trong quá trình huấn luyện. Mô hình không được chỉ định trước một query, key hay value như thế nào là hữu ích.

Đối với ngày thứ Sáu, query q5 của nó sẽ được so sánh với keys của tất cả các quan sát: k1, k2, k3, k4, k5. Mỗi phép so sánh tạo ra một điểm số chú ý (attention score):

s_{5,j} = (q5^T * k_j) / sqrt(d_k)

Điểm số này đo lường mức độ liên quan của quan sát 'j' khi cập nhật biểu diễn cho ngày thứ Sáu. Hệ số chia sqrt(d_k) giúp ngăn không cho giá trị của phép tính tích vô hướng trở nên quá lớn khi chiều của vector tăng lên.

Các điểm số này được đưa qua hàm softmax để chuyển đổi thành trọng số chú ý (attention weights): α_{5,j} = exp(s_{5,j}) / Σ exp(s_{5,j'})

Cuối cùng, các trọng số này được sử dụng để kết hợp các vector giá trị lại với nhau: z5 = Σ_j α_{5,j} * v_j

Như vậy, e5 là biểu diễn của ngày thứ Sáu trước khi kết hợp thông tin từ phần còn lại của chuỗi, trong khi z5 là biểu diễn có ngữ cảnh của nó sau self-attention.

Nói ngắn gọn: Queries và keys học cách nhận biết các quan sát nào có liên quan đến nhau. Values mang thông tin được kết hợp để tạo ra biểu diễn mới.

Điều gì xảy ra nếu chúng ta xáo trộn chuỗi?

Bây giờ đến câu hỏi quan trọng. Giả sử cùng một năm quan sát nhiệt độ nhưng được sắp xếp lại theo một thứ tự khác. Bản thân các giá trị không hề thay đổi; chỉ có thứ tự của chúng bị đảo lộn. Sau phép chiếu tuyến tính, chúng ta vẫn có cùng một tập hợp các biểu diễn, chỉ là chúng bị sắp xếp lại.

Self-attention vẫn có thể so sánh mỗi biểu diễn với tất cả các biểu diễn khác. Các phép chiếu query, key, value tương tự vẫn được áp dụng, và các mối quan hệ cặp đôi tương tự vẫn có thể được tính toán.

Tuy nhiên, điều đã biến mất là cấu trúc thời gian. Không có gì bên trong e(27∘) cho biết nó ban đầu đến từ thứ Năm. Không có gì bên trong e(18∘) cho biết nó xuất hiện sau e(27∘). Hơn nữa, nếu thứ Tư và thứ Sáu có cùng một giá trị nhiệt độ, phép chiếu sẽ ánh xạ chúng thành cùng một vector embedding. Nếu không có thông tin về vị trí, mô hình không có cách nào để phân biệt embedding nào đến từ thứ Tư và embedding nào đến từ thứ Sáu.

Đây chính là giới hạn cốt lõi: Self-attention có thể học được quan sát nào liên quan đến nhau, nhưng nếu không có tín hiệu vị trí bổ sung, nó không có cách nào cố hữu để biết các quan sát đó nằm ở đâu trong chuỗi.

Thông tin vị trí nên cho mô hình biết điều gì?

Nếu self-attention không biết thứ tự của các quan sát, câu hỏi tiếp theo là loại thông tin vị trí nào sẽ hữu ích? Ở mức tối thiểu, chúng ta muốn mô hình biết được:

  • Vị trí của một quan sát: Vị trí 2 phải có thể phân biệt được với vị trí 20.
  • Thứ tự trước/sau: Mô hình cần phân biệt được t-1 với t+1.
  • Khoảng cách giữa hai quan sát: Trong chuỗi thời gian, sự khác biệt giữa t-1 và t-7 hay thậm chí t-30 có thể rất quan trọng.
  • Các vị trí gần nhau có mối quan hệ có cấu trúc: Vị trí 10 và 11 không nên trông giống như hai mã định danh hoàn toàn không liên quan.
  • Biểu diễn còn hữu dụng trên các chuỗi dài: Lý tưởng nhất là cấu trúc thông tin được cung cấp vẫn có ý nghĩa khi chuỗi tăng lên.

Đối với chuỗi thời gian, tính chất thứ ba đặc biệt hữu ích. Mô hình có thể quan tâm đến một quan sát cách đó 1 bước vì sự phụ thuộc ngắn hạn, hoặc cách đó 7 bước vì mô hình theo mùa trong tuần. Vì vậy, thông tin vị trí không chỉ đơn thuần là gán một nhãn duy nhất cho mỗi bước thời gian, mà nó nên cung cấp một biểu diễn có cấu trúc về thứ tự và khoảng cách tương đối.

Làm thế nào để biểu diễn vị trí?

Một cách đơn giản để biểu diễn vị trí là gán cho mỗi bước thời gian một con số: 1, 2, 3, ... Tuy nhiên, việc đưa trực tiếp vị trí thô này vào mô hình không phải là tối ưu vì các giá trị sẽ tiếp tục tăng theo độ dài chuỗi và một con số duy nhất không thể hiện được các mối quan hệ phong phú.

Một trong những giải pháp ban đầu của Transformer là sử dụng sinusoidal positional encoding (mã hóa vị trí hình sin), trong đó mỗi vị trí được biểu diễn bằng các hàm sin và cosin ở các tần số khác nhau.

Hãy bắt đầu với một ví dụ hai chiều đơn giản nhất: p_t = [sin(t), cos(t)]

Khi t thay đổi, vector vị trí di chuyển một cách mượt mà quanh một vòng tròn, cho phép các vị trí gần nhau có biểu diễn khác nhau nhưng vẫn có mối liên hệ. Quan trọng hơn, việc tiến tới cùng một số bước sẽ tạo ra cùng một kiểu thay đổi trong biểu diễn. Ví dụ, độ lệch 7 vị trí có cùng một mối quan hệ toán học dù chúng ta di chuyển từ vị trí 3 lên 10 hay từ vị trí 20 lên 27.

Việc mở rộng ý tưởng này trên nhiều chiều không gian tạo ra biểu diễn phức tạp hơn. Công thức đầy đủ của sinusoidal positional encoding là:

PE(t, 2i) = sin(t / 10000^(2i / d_model)) PE(t, 2i+1) = cos(t / 10000^(2i / d_model))

Các chiều khác nhau sử dụng các tần số khác nhau. Một số thay đổi nhanh chóng giữa các vị trí gần nhau, trong khi một số khác thay đổi chậm hơn nhiều. Một cách hữu ích để hình dung điều này là như có nhiều chiếc đồng hồ chạy với tốc độ khác nhau, và kết hợp các chỉ số của chúng lại tạo nên một "chữ ký vị trí" có cấu trúc cho mỗi điểm dữ liệu.

Thay vì chỉ đưa cho bước thời gian t một con số, chúng ta đưa cho nó một vector p_t có nhiều chiều chứa thông tin về vị trí của nó và mối quan hệ với các vị trí khác.

Kết hợp giá trị và vị trí

Sau khi thêm thông tin vị trí, mỗi bước thời gian được biểu diễn dưới dạng tổng của hai vector:

h_t = e_t + p_t

Trong đó e_t biểu diễn giá trị quan sát và p_t biểu diễn vị trí của quan sát đó trong chuỗi. Self-attention bây giờ xây dựng queries và keys từ biểu diễn kết hợp này:

Q = H * W_Q, K = H * W_K

Khi mô hình tính điểm số chú ý score(i,j) = q_i^T * k_j, phép so sánh không còn chỉ dựa trên các giá trị quan sát được nữa. Query và key được tạo ra từ các biểu diễn đã chứa thông tin vị trí. Kết quả là, mô hình có thể học các mối quan hệ phụ thuộc vào cả hai yếu tố: người ta quan sát được cái gìcác quan sát đó xảy ra ở đâu trong chuỗi.

Nhờ vậy, mô hình có thể học được rằng một quan sát cách một bước thời gian nên được xử lý khác với một quan sát cách bảy bước thời gian, ngay cả khi giá trị của chúng tương tự nhau. Positional encoding vì thế không "nói" cho mô hình biết rõ ràng lag nào là quan trọng. Nó cung cấp cho self-attention thông tin cần thiết để tự học xem mối quan hệ vị trí nào là quan trọng cho nhiệm vụ.

Tổng kết

Chúng ta đã bắt đầu với một vấn đề đơn giản: self-attention có thể so sánh mọi quan sát với mọi quan sát khác, nhưng bản thân nó không biết thứ tự của các quan sát đó. Giải pháp là làm giàu biểu diễn giá trị e_t bằng một biểu diễn vị trí p_t: h_t = e_t + p_t

Self-attention sau đó xây dựng queries, keys và values từ h_t thay vì chỉ từ biểu diễn giá trị. Điều này có nghĩa là cơ chế chú ý có thể học các mối quan hệ không chỉ dựa trên những gì được quan sát mà còn dựa trên vị trí của quan sát đó trong chuỗi. Đối với các chuỗi thời gian được lấy mẫu đều đặn, điều này giúp mô hình dễ dàng nắm bắt các mối quan hệ như t-1, t-7 hay t-24.

Tuy nhiên, cần lưu ý rằng positional encoding biểu diễn vị trí trong chuỗi, không nhất thiết là thời gian thực. Nếu các quan sát được lấy mẫu không đều, việc cách nhau một vị trí không có nghĩa là cách nhau một giờ hay một ngày. Đây là lúc các kỹ thuật mã hóa thời gian phong phú hơn trở nên quan trọng.

Sinusoidal positional encoding chỉ là một trong những cách đưa trật tự vào Transformer. Các cách tiếp cận khác bao gồm:

  • Learned positional embeddings: các vector vị trí được học trực tiếp trong quá trình huấn luyện.
  • Relative positional encodings: tập trung trực tiếp hơn vào khoảng cách giữa hai quan sát thay vì vị trí tuyệt đối của chúng.

Với chuỗi thời gian, bài toán còn có thể phong phú hơn nữa. Vị trí chuỗi có thể là chưa đủ: mô hình có thể cũng cần biết dấu thời gian thực tế, các hiệu ứng lịch, tính chu kỳ, hay khoảng trống không đều giữa các quan sát. Vì vậy, câu hỏi lớn hơn không chỉ là "Làm thế nào để cho Transformer biết đây là vị trí số 7?" mà còn là "Khái niệm thời gian nào mà mô hình thực sự cần cho nhiệm vụ của nó?"

...Và điều này đưa tôi trở lại điểm khởi đầu của hành trình khám phá: các mô hình nền tảng (foundation models) cho chuỗi thời gian. Các kiến trúc hiện đại có thể sử dụng các phương pháp phức tạp hơn như rotary (xoay vòng) hoặc learned positional representations thay vì công thức hình sin ban đầu. Nhưng việc hiểu được cấu trúc hình sin đơn giản sẽ là nền tảng để chúng ta hiểu lý do vì sao các phương pháp đó tồn tại. Chúng ta đã xây dựng được nền tảng về lý do cần thông tin vị trí, cách nó được biểu diễn và cách self-attention sử dụng nó. Với trực giác này, các kỹ thuật positional encoding tiên tiến hơn sẽ trở nên dễ hiểu hơn nhiều khi chúng ta gặp lại chúng trong tương lai.

Lưu ý: Các hình ảnh minh họa trong bài viết được tác giả phác thảo ý tưởng và tạo ra với sự hỗ trợ của công cụ tạo ảnh AI.

Tài liệu tham khảo: [1] Peixeiro, Marco. Time Series Forecasting Using Foundation Models: How to Build High Accuracy Predictive Models. Manning, 2025. [2] Davidson, Graeme, and Lei Ma. Time Series with PyTorch: Modern Deep Learning Toolkit for Real-World Forecasting Challenges. Packt Publishing, 2026.

Chia sẻ:FacebookX
Nội dung tổng hợp bằng AI, mang tính tham khảo. Xem bài gốc ↗