@@ -1004,13 +1004,15 @@ def _create_completion(
10041004 break
10051005
10061006 token_end_position = 0
1007- for token in remaining_tokens :
1008- token_end_position += len (self .detokenize ([token ]))
1009- # Check if stop sequence is in the token
1010- if token_end_position >= (remaining_length - first_stop_position ):
1011- break
1012- logprobs_or_none : Optional [CompletionLogprobs ] = None
1013- if logprobs is not None :
1007+
1008+ if logprobs is not None :
1009+ # not sure how to handle this branch when dealing
1010+ # with CJK output, so keep it unchanged
1011+ for token in remaining_tokens :
1012+ token_end_position += len (self .detokenize ([token ]))
1013+ # Check if stop sequence is in the token
1014+ if token_end_position > (remaining_length - first_stop_position ):
1015+ break
10141016 token_str = self .detokenize ([token ]).decode (
10151017 "utf-8" , errors = "ignore"
10161018 )
@@ -1043,23 +1045,58 @@ def _create_completion(
10431045 "token_logprobs" : [current_logprobs [int (token )]],
10441046 "top_logprobs" : [top_logprob ],
10451047 }
1046- returned_tokens += 1
1047- yield {
1048- "id" : completion_id ,
1049- "object" : "text_completion" ,
1050- "created" : created ,
1051- "model" : model_name ,
1052- "choices" : [
1053- {
1054- "text" : self .detokenize ([token ]).decode (
1055- "utf-8" , errors = "ignore"
1056- ),
1057- "index" : 0 ,
1058- "logprobs" : logprobs_or_none ,
1059- "finish_reason" : None ,
1060- }
1061- ],
1062- }
1048+ returned_tokens += 1
1049+ yield {
1050+ "id" : completion_id ,
1051+ "object" : "text_completion" ,
1052+ "created" : created ,
1053+ "model" : model_name ,
1054+ "choices" : [
1055+ {
1056+ "text" : self .detokenize ([token ]).decode (
1057+ "utf-8" , errors = "ignore"
1058+ ),
1059+ "index" : 0 ,
1060+ "logprobs" : logprobs_or_none ,
1061+ "finish_reason" : None ,
1062+ }
1063+ ],
1064+ }
1065+ else :
1066+ while len (remaining_tokens ) > 0 :
1067+ decode_success = False
1068+ for i in range (1 , len (remaining_tokens ) + 1 ):
1069+ tokens = remaining_tokens [:i ]
1070+ try :
1071+ bs = self .detokenize (tokens )
1072+ text = bs .decode ('utf-8' )
1073+ decode_success = True
1074+ break
1075+ except UnicodeError :
1076+ pass
1077+ if not decode_success :
1078+ # all remaining tokens cannot be decoded to a UTF-8 character
1079+ break
1080+ token_end_position += len (bs )
1081+ if token_end_position > (remaining_length - first_stop_position ):
1082+ break
1083+ remaining_tokens = remaining_tokens [i :]
1084+ returned_tokens += i
1085+
1086+ yield {
1087+ "id" : completion_id ,
1088+ "object" : "text_completion" ,
1089+ "created" : created ,
1090+ "model" : model_name ,
1091+ "choices" : [
1092+ {
1093+ "text" : text ,
1094+ "index" : 0 ,
1095+ "logprobs" : None ,
1096+ "finish_reason" : None ,
1097+ }
1098+ ],
1099+ }
10631100
10641101 if len (completion_tokens ) >= max_tokens :
10651102 text = self .detokenize (completion_tokens )
0 commit comments