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