3131from . import utils
3232from . import vocab
3333from .beam_search import CandidateScorer , get_search_algorithm , GreedySearch , SearchResult
34- from .data_io import tokens2ids
34+ from .data_io import tokens2ids , get_prepended_token_length
3535from .model import SockeyeModel
3636
3737logger = logging .getLogger (__name__ )
@@ -858,6 +858,10 @@ def num_source_factors(self) -> int:
858858 def num_target_factors (self ) -> int :
859859 return self .models [0 ].num_target_factors
860860
861+ @property
862+ def eop_id (self ) -> int :
863+ return self .models [0 ].eop_id
864+
861865 def translate (self , trans_inputs : List [TranslatorInput ], fill_up_batches : bool = True ) -> List [TranslatorOutput ]:
862866 """
863867 Batch-translates a list of TranslatorInputs, returns a list of TranslatorOutputs.
@@ -1001,13 +1005,14 @@ def _get_inference_input(self,
10011005 optional target prefix, and optional target prefix factors.
10021006 """
10031007 batch_size = len (trans_inputs )
1004- lengths = [len (inp ) for inp in trans_inputs ]
10051008
10061009 max_target_prefix_length = max (inp .num_target_prefix_tokens for inp in trans_inputs )
10071010 max_target_prefix_factors_length = max (inp .num_target_prefix_factors for inp in trans_inputs )
10081011 max_length = max (len (inp ) for inp in trans_inputs )
10091012 # assembling source ids on cpu array (faster) and copy to Translator.device (potentially GPU) in one go below.
10101013 source_np = np .zeros ((batch_size , max_length , self .num_source_factors ), dtype = 'int32' )
1014+ # total token length and prepended token length
1015+ length_np = np .zeros ((batch_size , 2 ), dtype = 'int32' )
10111016
10121017 target_prefix_np = np .zeros ((batch_size , max_target_prefix_length ), dtype = 'int32' ) \
10131018 if max_target_prefix_length > 0 else None
@@ -1019,9 +1024,13 @@ def _get_inference_input(self,
10191024 max_output_lengths = [] # type: List[int]
10201025 for j , trans_input in enumerate (trans_inputs ):
10211026 num_tokens = len (trans_input ) # includes eos
1022- max_output_lengths .append (self ._get_max_output_length (num_tokens ))
1023- source_np [j , :num_tokens , 0 ] = tokens2ids (itertools .chain (trans_input .get_source_prefix_tokens (),
1024- trans_input .tokens ), self .source_vocabs [0 ])
1027+ primary_source_ids = tokens2ids (itertools .chain (trans_input .get_source_prefix_tokens (),
1028+ trans_input .tokens ), self .source_vocabs [0 ])
1029+ source_np [j , :num_tokens , 0 ] = primary_source_ids
1030+ length_np [j , 0 ] = num_tokens
1031+ length_np [j , 1 ] = get_prepended_token_length (primary_source_ids , self .eop_id )
1032+ # the effective source length excludes prepended tokens
1033+ max_output_lengths .append (self ._get_max_output_length (length_np [j , 0 ] - length_np [j , 1 ]))
10251034 if target_prefix_np is not None and trans_input .num_target_prefix_tokens > 0 :
10261035 target_prefix_np [j , :trans_input .num_target_prefix_tokens ] = \
10271036 tokens2ids (trans_input .get_target_prefix_tokens (), self .vocab_targets [0 ])
@@ -1068,7 +1077,7 @@ def _get_inference_input(self,
10681077 "will default to not using a restrict lexicon." )
10691078
10701079 source = pt .tensor (source_np , device = self .device , dtype = pt .int32 )
1071- source_length = pt .tensor (lengths , device = self .device , dtype = pt .int32 ) # shape: (batch_size,)
1080+ source_length = pt .tensor (length_np , device = self .device , dtype = pt .int32 ) # shape: (batch_size, 2 )
10721081 max_out_lengths = pt .tensor (max_output_lengths , device = self .device , dtype = pt .int32 )
10731082 target_prefix = pt .tensor (target_prefix_np , device = self .device , dtype = pt .int32 ) \
10741083 if target_prefix_np is not None else None
0 commit comments