11#include " infini_train/include/nn/modules/transformer/causal_self_attention.h"
22
33#include < cmath>
4+ #include < limits>
45#include < memory>
56#include < tuple>
67#include < vector>
@@ -43,12 +44,9 @@ CausalSelfAttention::CausalSelfAttention(const TransformerConfig &config) : Clon
4344 /* skip_bias_add=*/ false ,
4445 /* sequence_parallel=*/ nn::parallel::global::GetSequenceParallelEnabled ());
4546
46- // For standard attention (GPT2 style), precompute causal mask
47- if (config_.attention_type == AttentionType::kStandard ) {
48- // causal mask: (1, 1, block_size, block_size)
49- buffers_[kParamBiasName ] = function::Tril (nn::function::Ones ({config_.block_size , config_.block_size }))
50- ->View ({1 , 1 , config_.block_size , config_.block_size });
51- }
47+ // causal mask: (1, 1, block_size, block_size)
48+ buffers_[kParamBiasName ] = function::Tril (nn::function::Ones ({config_.block_size , config_.block_size }))
49+ ->View ({1 , 1 , config_.block_size , config_.block_size });
5250}
5351
5452void CausalSelfAttention::SetupAttention (const TransformerConfig &config) {
@@ -77,88 +75,21 @@ void CausalSelfAttention::SetupAttention(const TransformerConfig &config) {
7775
7876std::vector<std::shared_ptr<infini_train::Tensor>>
7977CausalSelfAttention::Forward (const std::vector<std::shared_ptr<infini_train::Tensor>> &x) {
80- if (config_.attention_type == AttentionType::kRoPE ) {
81- return ForwardWithRoPE (x);
82- } else {
83- return ForwardStandard (x);
84- }
85- }
86-
87- std::vector<std::shared_ptr<infini_train::Tensor>>
88- CausalSelfAttention::ForwardStandard (const std::vector<std::shared_ptr<infini_train::Tensor>> &x) {
89- auto tp_world_size = parallel::global::GetTensorParallelSize ();
90-
91- const auto B = x[0 ]->Dims ()[0 ]; // bs
92- const auto C = x[0 ]->Dims ()[2 ]; // n_embd
93- const int64_t head_dim = n_embd_ / n_head_; // per-head dim (global)
94- const int64_t local_C = n_embd_ / tp_world_size; // per-rank hidden
95-
96- // (B, T, C) -> ColumnParallelLinear(C, 3*C) -> (B, T, 3 * local_C)
97- // -> Split -> (3, B, T, local_C)
98- auto qkv = (*modules_[kCAttnLayerName ])(x)[0 ]->Split (local_C, 2 );
99-
100- // (B, T, local_C)
101- auto q = qkv[0 ];
102- auto k = qkv[1 ];
103- auto v = qkv[2 ];
104-
105- // NOTE(zbl): Acquire full T after AllGather is performed in ColumnParallelLinear
106- const auto T = q->Dims ()[1 ];
107-
108- // View to multi-head: local_n_head * head_dim == local_C
109- // (B, T, local_C) -> (B, T, h_l, Dh) -> (B, h_l, T, Dh)
110- k = k->View ({B, T, local_n_head_, head_dim})->Transpose (1 , 2 );
111- q = q->View ({B, T, local_n_head_, head_dim})->Transpose (1 , 2 );
112- v = v->View ({B, T, local_n_head_, head_dim})->Transpose (1 , 2 );
113-
114- // (B, h_l, T, T)
115- auto att = q->Matmul (k->Transpose (-2 , -1 )) * (1.0 / std::sqrt (head_dim));
116- // (1, 1, T, T)
117- auto mask = buffers_[kParamBiasName ]->Slice ({0 , 0 , 0 , 0 }, {1 , 1 , T, T}, {1 , 1 , 1 , 1 });
118- // (1, 1, T, T) -> eq 0 -> (1, 1, T, T) -> masked_fill -> (B, h_l, T, T)
119- att = att->MaskedFill (mask == 0 , -std::numeric_limits<float >::infinity ());
120- // (B, h_l, T, T)
121- att = nn::function::Softmax (att, -1 );
122- // (B, h_l, T, Dh)
123- auto y = att->Matmul (v);
124- // (B, h_l, T, Dh) -> (B, T, h_l, Dh) -> (B, T, local_C)
125- y = y->Transpose (1 , 2 )->Contiguous ()->View ({B, T, local_C});
126-
127- // Get full tensor
128- // (B, T, local_C) -> RowParallelLinear(n_embd, n_embd) -> (B, T, C)
129- y = (*modules_[kCProjLayerName ])({y})[0 ];
130- // (B, T, C) == (bs, seq_len, n_embd)
131- return {y};
132- }
133-
134- std::shared_ptr<infini_train::Tensor> CausalSelfAttention::RepeatKV (const std::shared_ptr<infini_train::Tensor> &x,
135- int64_t n_rep) {
136- const auto &shape = x->Dims ();
137- const int64_t B = shape[0 ], T = shape[1 ], H = shape[2 ], D = shape[3 ];
138-
139- if (n_rep == 1 ) {
140- return x;
141- }
142-
143- return x->View ({B, T, H, 1 , D})->RepeatInterleave (n_rep, 3 )->Contiguous ()->View ({B, T, H * n_rep, D});
144- }
145-
146- std::vector<std::shared_ptr<infini_train::Tensor>>
147- CausalSelfAttention::ForwardWithRoPE (const std::vector<std::shared_ptr<infini_train::Tensor>> &x) {
14878 const auto B = x[0 ]->Dims ()[0 ]; // bs
14979 const auto C = x[0 ]->Dims ()[2 ]; // n_embd
15080
15181 const auto tp_size = nn::parallel::global::GetTensorParallelSize ();
15282
15383 const auto C_local = C / tp_size;
154- const auto H_local = n_head_ / tp_size ;
84+ const auto H_local = local_n_head_ ;
15585 const auto KV_local = n_kv_head_ / tp_size;
15686 const auto D = head_dim_; // n_embd / n_head
15787
15888 const auto freqs_cis = x.size () > 1 ? x[1 ] : nullptr ;
159- const auto start_pos = x.size () > 2 ? x[2 ] : nullptr ;
16089 const auto mask = x.size () > 3 ? x[3 ] : nullptr ;
161- CHECK (freqs_cis != nullptr ) << " freqs_cis is null." ;
90+ if (config_.position_embedding_type == PositionEmbeddingType::kRoPE ) {
91+ CHECK (freqs_cis != nullptr ) << " freqs_cis is null." ;
92+ }
16293
16394 // (B, T, C) -> (B, T, (H + 2 * n_kv_head) * D)
16495 auto qkv = (*modules_[kCAttnLayerName ])({x[0 ]})[0 ];
@@ -176,10 +107,10 @@ CausalSelfAttention::ForwardWithRoPE(const std::vector<std::shared_ptr<infini_tr
176107 // v: (B, T, KV_local, D)
177108 auto v = qkv->Slice (2 , q_size_local + kv_size_local, q_size_local + 2 * kv_size_local)->View ({B, T, KV_local, D});
178109
179- // -> RoPE on q, k
180- // q: (B, T, H_local, D)
181- // k: (B, T, KV_local, D)
182- std::tie (q, k) = ApplyRotaryEmbedding (q, k, freqs_cis);
110+ if (config_. position_embedding_type == PositionEmbeddingType:: kRoPE ) {
111+ // q: (B, T, H_local, D), k: (B, T, KV_local , D)
112+ std::tie (q, k) = ApplyRotaryEmbedding (q, k, freqs_cis);
113+ }
183114
184115 // TODO(zbl): use kv cache during inference
185116 // if (use_kv_) { ... }
@@ -207,6 +138,10 @@ CausalSelfAttention::ForwardWithRoPE(const std::vector<std::shared_ptr<infini_tr
207138 if (mask) {
208139 // mask: (1, 1, T, T)
209140 att = att->MaskedFill (mask, std::numeric_limits<float >::lowest ());
141+ } else {
142+ // fallback causal mask: (1, 1, T, T)
143+ auto causal_mask = buffers_[kParamBiasName ]->Slice ({0 , 0 , 0 , 0 }, {1 , 1 , T, T}, {1 , 1 , 1 , 1 });
144+ att = att->MaskedFill (causal_mask == 0 , -std::numeric_limits<float >::infinity ());
210145 }
211146 // (B, H_local, T, T)
212147 att = nn::function::Softmax (att, -1 );
@@ -221,4 +156,16 @@ CausalSelfAttention::ForwardWithRoPE(const std::vector<std::shared_ptr<infini_tr
221156 return {y};
222157}
223158
159+ std::shared_ptr<infini_train::Tensor> CausalSelfAttention::RepeatKV (const std::shared_ptr<infini_train::Tensor> &x,
160+ int64_t n_rep) {
161+ const auto &shape = x->Dims ();
162+ const int64_t B = shape[0 ], T = shape[1 ], H = shape[2 ], D = shape[3 ];
163+
164+ if (n_rep == 1 ) {
165+ return x;
166+ }
167+
168+ return x->View ({B, T, H, 1 , D})->RepeatInterleave (n_rep, 3 )->Contiguous ()->View ({B, T, H * n_rep, D});
169+ }
170+
224171} // namespace infini_train::nn
0 commit comments