Teknosys learning library
Self-attention: queries, keys, values, and masks
Self-attention lets each token construct an input-dependent mixture of information from other tokens in the same sequence. “Self” describes the shared source of queries, keys, and values; it does not mean attending only to the current token. For a missing-charger ticket, the representation of “missing” might benefit from information associated with “charger”, but the weights are learned interactions rather than hand-written grammar rules.
Three projections, three roles
A hidden-state matrix X is projected into Q = X W_Q, K = X W_K, and V = X W_V. A query represents what a receiving position uses to match information; a key participates in that match; a value supplies the information to combine. These are useful computational roles, not literal questions, dictionary keys, or human-readable facts.
scores = Q K^T / sqrt(d_k)
weights = softmax(scores + mask)
output = weights V
For one head with T positions:
Q, K: T x d_k
scores: T x T
V: T x d_v
output: T x d_v
The scale factor moderates dot-product magnitude as key width grows. Softmax runs across permitted key positions for each query row. Larger scores receive more weight, and each non-empty row sums to one. The output is a weighted combination of values, not a weighted combination of token IDs.
A numerical example you can run
The following standard-library example uses fabricated already-scaled scores and two-dimensional values. It demonstrates one attention row, not a trained head or a full transformer. Subtracting the largest score before exponentiation improves numerical stability without changing the probabilities.
from math import exp
scores = [2.0, 1.0, 0.0]
values = [(1.0, 0.0), (0.0, 2.0), (3.0, 1.0)]
shift = max(scores)
unnormalized = [exp(score - shift) for score in scores]
weights = [value / sum(unnormalized) for value in unnormalized]
result = [
sum(weight * value[axis] for weight, value in zip(weights, values))
for axis in range(2)
]
print([round(weight, 3) for weight in weights])
print([round(value, 3) for value in result])
# [0.665, 0.245, 0.09]
# [0.935, 0.579]
Masks and multiple heads
A padding mask removes artificial positions. A causal mask prevents a generation position from seeing later target tokens. Masking logits before softmax differs from simply zeroing probabilities afterward: the remaining permitted weights must still be normalized. If a query has no allowed keys, ordinary softmax over all negative-infinity scores is undefined; avoid such rows or use an implementation that handles them explicitly.
Multi-head attention computes several projected views, concatenates their outputs, and applies an output projection. Heads can learn complementary interactions, but a head number does not come with a guaranteed linguistic job. Attention plots can help diagnose masks and patterns; they are not, on their own, causal explanations of a final prediction.
Source: scaled dot-product and multi-head attention in the original paper.
Educational material. Verify examples against current documentation and applicable licenses. Report a correction.