@@ -701,7 +701,7 @@ private void performTextTranslation(final String textToTranslate, final CustomLo
701701 //tokenization
702702 long time = System .currentTimeMillis ();
703703 TokenizerResult input = null ;
704- String correctedSubText = correctText (textSplit .get (i ), inputLanguage .getLocale ());
704+ String correctedSubText = correctText (textSplit .get (i ), inputLanguage .getLocale ()); //input text pre process
705705 input = tokenize (correctedSubText , inputLanguage , outputLanguage );
706706 android .util .Log .i ("performance" , "Tokenization done in: " + (System .currentTimeMillis () - time ) + "ms" );
707707 //encoder execution
@@ -752,9 +752,9 @@ public void onFailure(int[] reasons, long value) {
752752 }
753753 };
754754 if (beamSize > 1 ) { //beam search
755- executeCacheDecoder (textToTranslate , input , encoderResult , completeBeamOutput , beamsOutputsProbabilities , outputLanguage , beamSize , translateListener );
755+ executeCacheDecoder (textToTranslate , input , encoderResult , completeBeamOutput , beamsOutputsProbabilities , inputLanguage , outputLanguage , beamSize , translateListener );
756756 } else if (beamSize == 1 ) { //greedy search (with kv cache)
757- executeCacheDecoder (textToTranslate , input , encoderResult , completeBeamOutput , null , outputLanguage , 1 , translateListener );
757+ executeCacheDecoder (textToTranslate , input , encoderResult , completeBeamOutput , null , inputLanguage , outputLanguage , 1 , translateListener );
758758 }
759759 //we convert the ids of completeBeamOutputs into a string and return it
760760 if (encoderResult != null ) encoderResult .close ();
@@ -1026,7 +1026,7 @@ public void executeCacheDecoderGreedy(String textToTranslate, TokenizerResult in
10261026 }
10271027 }
10281028
1029- public void executeCacheDecoder (String textToTranslate , TokenizerResult input , @ Nullable OnnxTensor encoderResult , ArrayList <Integer >[] completeBeamOutput , @ Nullable double [] beamsOutputsProbabilities , final CustomLocale outputLanguage , int beamSize , @ Nullable final TranslateListener responseListener ) {
1029+ public void executeCacheDecoder (String textToTranslate , TokenizerResult input , @ Nullable OnnxTensor encoderResult , ArrayList <Integer >[] completeBeamOutput , @ Nullable double [] beamsOutputsProbabilities , final CustomLocale inputLanguage , final CustomLocale outputLanguage , int beamSize , @ Nullable final TranslateListener responseListener ) {
10301030 int eos ;
10311031 if (mode == HY_MT ){
10321032 eos = tokenizer .PieceToID ("<|hy_place▁holder▁no▁2|>" );
@@ -1053,6 +1053,7 @@ public void executeCacheDecoder(String textToTranslate, TokenizerResult input, @
10531053 hiddenSizeAttention = 128 ;
10541054 nHeads = 4 ; //nHeads in this case refers only to the number of heads used in kvCache, the real number of heads are 16, but this model uses group query attention, with a group size of 4
10551055 }
1056+ int initialPromptLength = tokenize (" " , inputLanguage , outputLanguage , false ).getInputIDs ().length ;
10561057
10571058 try {
10581059 long initialTime ;
@@ -1272,6 +1273,25 @@ public void executeCacheDecoder(String textToTranslate, TokenizerResult input, @
12721273 partialResults [i ] = tokenizer .decode (completeBeamOutput [i ].stream ().mapToInt (k -> k ).toArray ());
12731274 android .util .Log .i ("result " +i , partialResults [i ]);
12741275 }
1276+
1277+ //early stop if the decoder is generating in loop
1278+ if (input .getInputIDs ().length - initialPromptLength > 30 ){ //if the input is long
1279+ if (j > 3 *input .getInputIDs ().length ) {
1280+ break ;
1281+ }
1282+ }else if (input .getInputIDs ().length - initialPromptLength > 20 ){ //if the input is medium length
1283+ if (j > 4 *input .getInputIDs ().length ){
1284+ break ;
1285+ }
1286+ }else if (input .getInputIDs ().length - initialPromptLength > 10 ){ //if the input is short
1287+ if (j > 5 *input .getInputIDs ().length ){
1288+ break ;
1289+ }
1290+ }else if (input .getInputIDs ().length - initialPromptLength > 5 ){ //if the input is very short
1291+ if (j > 8 *input .getInputIDs ().length ){
1292+ break ;
1293+ }
1294+ }
12751295 }
12761296
12771297 if (result != null ) result .close ();
@@ -1303,17 +1323,23 @@ public long getCurrentResultID(){
13031323 private String correctText (String text , Locale locale ){
13041324 String correctedText = text ;
13051325 String language = locale .getLanguage ();
1326+ correctedText = correctedText .replaceAll ("\\ s+" , " " ); // collapse whitespace
13061327 //we add an eventual period if missing (or in general a terminator symbol)
13071328 if (!language .equals ("th" )) {
13081329 correctedText = correctedText .trim (); //we remove eventual white space from both ends of the text
13091330 if (correctedText .length () >= 2 ) {
1310- if (! Character .isLetterOrDigit (correctedText .charAt (correctedText .length () - 1 ))) {
1311- return correctedText ;
1331+ if (Character .isLetterOrDigit (correctedText .charAt (correctedText .length () - 1 ))) {
1332+ correctedText = correctedText + getSentenceTerminator ( locale ) ;
13121333 }
1313- return correctedText + getSentenceTerminator (locale );
13141334 }
13151335 }
1316- return text ;
1336+ //for Madlad only, we remove all the control characters (like \n), because those will make the model hallucinate
1337+ if (mode == MADLAD || mode == MADLAD_CACHE ){
1338+ correctedText = text .replaceAll ("\\ R" , " " ) // remove all newlines
1339+ .replaceAll ("\\ p{Cntrl}" , "" ) // remove other control chars
1340+ .trim ();
1341+ }
1342+ return correctedText ;
13171343 }
13181344
13191345 private OnnxTensor batchEncoderAttentionMask (int [] attentionMask , int batchSize , boolean log ) throws OrtException {
0 commit comments