- in
- [B batch, T positions, 768 d]
- out
- [B batch, 12 heads, T positions, 64 d_h] [B batch, 12 heads, T positions, 64 d_h] [B batch, 12 heads, T positions, 64 d_h]
- parameters
- 1,771,776 · × 12 blocks = 21,261,312
Parameters
1,771,776 parameters per block, across its learned components
| Component | Calculation | Parameters |
|---|---|---|
| Fused Q, K, V projection | 1,771,776 | |
| Reshape into attention heads | — | 0 |
| Per-instance total | 1,771,776 | |
Across 12 independent blocks: parameters.
The group references these owners; it adds no weights of its own.
Explanation
One learned projection produces the fused field of 2,304 features: . Splitting it gives , and of 768 features each, and each is reshaped into 12 heads of 64 features. Only the projection owns parameters; splitting and reshaping reorganize values without changing them.
- Intermediate states
- Query field · Key field · Value field
Codemodel.py 50–103 · modeling_gpt2.py 185–191
def conv1d(x, scope, nf, *, w_init_stdev=0.02):
with tf.variable_scope(scope):
*start, nx = shape_list(x)
w = tf.get_variable('w', [1, nx, nf], initializer=tf.random_normal_initializer(stddev=w_init_stdev))
b = tf.get_variable('b', [nf], initializer=tf.constant_initializer(0))
c = tf.reshape(tf.matmul(tf.reshape(x, [-1, nx]), tf.reshape(w, [-1, nf]))+b, start+[nf])
return c c = conv1d(x, 'c_attn', n_state*3)
q, k, v = map(split_heads, tf.split(c, 3, axis=2)) query_states, key_states, value_states = self.c_attn(hidden_states).split(self.split_size, dim=2)
shape_kv = (*key_states.shape[:-1], -1, self.head_dim)
key_states = key_states.view(shape_kv).transpose(1, 2)
value_states = value_states.view(shape_kv).transpose(1, 2)
shape_q = (*query_states.shape[:-1], -1, self.head_dim)
query_states = query_states.view(shape_q).transpose(1, 2) def split_heads(x): return tf.transpose(split_states(x, hparams.n_head), [0, 2, 1, 3]) q, k, v = map(split_heads, tf.split(c, 3, axis=2))Sources4
Evidence for the operations this group contains. The group itself is a presentation and has no implementation of its own.
Contextual evidence from Fused Q, K, V projection
The released projection helper owns a learned matrix and output bias and applies them to the last feature axis.
linear-operation · openai/gpt-2 / src/model.py
Pinned revision 9b63575ef427 ↗ · lines 50–56
Read code excerpt
def conv1d(x, scope, nf, *, w_init_stdev=0.02):
with tf.variable_scope(scope):
*start, nx = shape_list(x)
w = tf.get_variable('w', [1, nx, nf], initializer=tf.random_normal_initializer(stddev=w_init_stdev))
b = tf.get_variable('b', [nf], initializer=tf.constant_initializer(0))
c = tf.reshape(tf.matmul(tf.reshape(x, [-1, nx]), tf.reshape(w, [-1, nf]))+b, start+[nf])
return cContextual evidence from Fused Q, K, V projection
The released attention module creates one 3× projection and splits it into Q, K, and V head fields.
openai · openai/gpt-2 / src/model.py
Pinned revision 9b63575ef427 ↗ · lines 101–104
Read code excerpt
c = conv1d(x, 'c_attn', n_state*3)
q, k, v = map(split_heads, tf.split(c, 3, axis=2))Contextual evidence from Fused Q, K, V projection
The maintained implementation applies c_attn once, splits the three fields, and reshapes each to heads.
transformers · huggingface/transformers / src/transformers/models/gpt2/modeling_gpt2.py
Pinned revision 71c6f699ac9b ↗ · lines 185–191
Read code excerpt
query_states, key_states, value_states = self.c_attn(hidden_states).split(self.split_size, dim=2)
shape_kv = (*key_states.shape[:-1], -1, self.head_dim)
key_states = key_states.view(shape_kv).transpose(1, 2)
value_states = value_states.view(shape_kv).transpose(1, 2)
shape_q = (*query_states.shape[:-1], -1, self.head_dim)
query_states = query_states.view(shape_q).transpose(1, 2)Contextual evidence from Q, K, V split
The fused field is split three ways and each result is reshaped into the head axis.
openai · openai/gpt-2 / src/model.py
Pinned revision 9b63575ef427 ↗ · lines 75–103
Read code excerpt
def split_heads(x):… lines 76–76 omitted …
return tf.transpose(split_states(x, hparams.n_head), [0, 2, 1, 3])… lines 78–102 omitted …
q, k, v = map(split_heads, tf.split(c, 3, axis=2))Contextual evidence from Reshape into attention heads
The released split_heads function introduces a head axis and moves it before the position axis.
openai · openai/gpt-2 / src/model.py
Pinned revision 9b63575ef427 ↗ · lines 75–79
Read code excerpt
def split_heads(x):… lines 76–76 omitted …
return tf.transpose(split_states(x, hparams.n_head), [0, 2, 1, 3])