(
self,
input_ids: torch.LongTensor,
next_scores: torch.FloatTensor,
next_tokens: torch.LongTensor,
next_indices: torch.LongTensor,
pad_token_id: Optional[int] = None,
eos_token_id: Optional[int] = None,
mems=None
)
| 205 | return self._done.all() |
| 206 | |
| 207 | def process( |
| 208 | self, |
| 209 | input_ids: torch.LongTensor, |
| 210 | next_scores: torch.FloatTensor, |
| 211 | next_tokens: torch.LongTensor, |
| 212 | next_indices: torch.LongTensor, |
| 213 | pad_token_id: Optional[int] = None, |
| 214 | eos_token_id: Optional[int] = None, |
| 215 | mems=None |
| 216 | ) -> Tuple[torch.Tensor]: |
| 217 | cur_len = input_ids.shape[-1] |
| 218 | batch_size = len(self._beam_hyps) |
| 219 | assert batch_size == (input_ids.shape[0] // self.num_beams) |
| 220 | if isinstance(eos_token_id, int): |
| 221 | eos_token_id = [eos_token_id] |
| 222 | device = next_scores.device |
| 223 | next_beam_scores = torch.zeros((batch_size, self.num_beams), dtype=next_scores.dtype, device=device) |
| 224 | next_beam_tokens = torch.zeros((batch_size, self.num_beams), dtype=next_tokens.dtype, device=device) |
| 225 | next_beam_indices = torch.zeros((batch_size, self.num_beams), dtype=next_indices.dtype, device=device) |
| 226 | |
| 227 | for batch_idx, beam_hyp in enumerate(self._beam_hyps): |
| 228 | if self._done[batch_idx]: |
| 229 | assert ( |
| 230 | len(beam_hyp) >= self.num_beams |
| 231 | ), "Batch can only be done if at least {} beams have been generated".format(self.num_beams) |
| 232 | assert ( |
| 233 | eos_token_id is not None and pad_token_id is not None |
| 234 | ), "generated beams >= num_beams -> eos_token_id and pad_token have to be defined" |
| 235 | # pad the batch |
| 236 | next_beam_scores[batch_idx, :] = 0 |
| 237 | next_beam_tokens[batch_idx, :] = pad_token_id |
| 238 | next_beam_indices[batch_idx, :] = 0 |
| 239 | continue |
| 240 | |
| 241 | # next tokens for this sentence |
| 242 | beam_idx = 0 |
| 243 | for beam_token_rank, (next_token, next_score, next_index) in enumerate( |
| 244 | zip(next_tokens[batch_idx], next_scores[batch_idx], next_indices[batch_idx]) |
| 245 | ): |
| 246 | batch_beam_idx = batch_idx * self.num_beams + next_index |
| 247 | # add to generated hypotheses if end of sentence |
| 248 | if (eos_token_id is not None) and (next_token.item() in eos_token_id): |
| 249 | # if beam_token does not belong to top num_beams tokens, it should not be added |
| 250 | is_beam_token_worse_than_top_num_beams = beam_token_rank >= self.num_beams |
| 251 | if is_beam_token_worse_than_top_num_beams: |
| 252 | continue |
| 253 | beam_hyp.add( |
| 254 | input_ids[batch_beam_idx].clone(), |
| 255 | next_score.item(), |
| 256 | mems=[mem[[next_index.item()]] for mem in mems] if mems else None |
| 257 | ) |
| 258 | else: |
| 259 | # add next predicted token since it is not eos_token |
| 260 | next_beam_scores[batch_idx, beam_idx] = next_score |
| 261 | next_beam_tokens[batch_idx, beam_idx] = next_token |
| 262 | next_beam_indices[batch_idx, beam_idx] = batch_beam_idx |
| 263 | beam_idx += 1 |
| 264 |
no test coverage detected