| 158 | |
| 159 | template<typename T> |
| 160 | void Decoder<T>::forward(std::vector<Tensor>* output_tensors, |
| 161 | const std::vector<Tensor>* input_tensors, |
| 162 | const std::vector<DecoderLayerWeight<T>>* decoder_layer_weight) |
| 163 | { |
| 164 | // input tensors: |
| 165 | // decoder_input [batch_size, hidden_dimension], |
| 166 | // encoder_output [batch_size, mem_max_seq_len, memory_hidden_dimension], |
| 167 | // encoder_sequence_length [batch_size], |
| 168 | // finished [batch_size], |
| 169 | // step [1] on cpu |
| 170 | // sequence_lengths [batch_size] |
| 171 | // cache_indirection [local_batch_size / beam_width, beam_width, max_seq_len] |
| 172 | // Here, local_batch_size contains the beam_width, so local_batch_size / beam_width |
| 173 | // is real local_batch_size. |
| 174 | |
| 175 | // output tensors: |
| 176 | // decoder_output [batch_size, hidden_dimension], |
| 177 | // key_cache [num_layer, batch, head_num, size_per_head // x, max_seq_len, x] |
| 178 | // value_cache [num_layer, batch, head_num, max_seq_len, size_per_head] |
| 179 | // key_mem_cache [num_layer, batch_size, mem_max_seq_len, hidden_dimension], |
| 180 | // value_mem_cache [num_layer, batch_size, mem_max_seq_len, hidden_dimension] |
| 181 | |
| 182 | FT_CHECK(input_tensors->size() == 7); |
| 183 | FT_CHECK(output_tensors->size() == 5); |
| 184 | isValidBatchSize(input_tensors->at(0).shape[0]); |
| 185 | allocateBuffer(input_tensors->at(0).shape[0]); |
| 186 | |
| 187 | const size_t batch_size = (size_t)input_tensors->at(0).shape[0]; |
| 188 | const size_t mem_max_seq_len = (size_t)input_tensors->at(1).shape[1]; |
| 189 | const DataType data_type = getTensorType<T>(); |
| 190 | |
| 191 | TensorMap cross_attention_input_tensors{ |
| 192 | {"input_query", Tensor{MEMORY_GPU, data_type, {batch_size, hidden_units_}, normed_self_attn_output_}}, |
| 193 | {"encoder_output", input_tensors->at(1)}, |
| 194 | {"encoder_sequence_length", input_tensors->at(2)}, |
| 195 | {"finished", input_tensors->at(3)}, |
| 196 | {"step", input_tensors->at(4)}}; |
| 197 | TensorMap self_attention_input_tensors{ |
| 198 | {"input_query", Tensor{MEMORY_GPU, data_type, {batch_size, hidden_units_}, decoder_normed_input_}}, |
| 199 | {"finished", input_tensors->at(3)}, |
| 200 | {"sequence_lengths", input_tensors->at(5)}, |
| 201 | {"step", input_tensors->at(4)}}; |
| 202 | |
| 203 | TensorMap ffn_input_tensors( |
| 204 | {{"ffn_input", Tensor{MEMORY_GPU, data_type, {batch_size, hidden_units_}, normed_cross_attn_output_}}}); |
| 205 | |
| 206 | for (uint l = 0; l < num_layer_; l++) { |
| 207 | const T* decoder_input = (const T*)((l == 0) ? input_tensors->at(0).getPtr<const T>() : decoder_layer_output_); |
| 208 | T* decoder_output = (T*)((l == num_layer_ - 1) ? output_tensors->at(0).getPtr<T>() : decoder_layer_output_); |
| 209 | |
| 210 | size_t self_key_cache_offset = l; |
| 211 | for (auto t = output_tensors->at(1).shape.begin() + 1; t != output_tensors->at(1).shape.end(); ++t) { |
| 212 | self_key_cache_offset *= (*t); |
| 213 | } |
| 214 | size_t self_value_cache_offset = l; |
| 215 | for (auto t = output_tensors->at(2).shape.begin() + 1; t != output_tensors->at(2).shape.end(); ++t) { |
| 216 | self_value_cache_offset *= (*t); |
| 217 | } |
nothing calls this directly
no test coverage detected