@@ -1004,13 +1004,15 @@ def _create_completion(
1004
1004
break
1005
1005
1006
1006
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
1014
1016
token_str = self .detokenize ([token ]).decode (
1015
1017
"utf-8" , errors = "ignore"
1016
1018
)
@@ -1043,23 +1045,58 @@ def _create_completion(
1043
1045
"token_logprobs" : [current_logprobs [int (token )]],
1044
1046
"top_logprobs" : [top_logprob ],
1045
1047
}
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
+ }
1063
1100
1064
1101
if len (completion_tokens ) >= max_tokens :
1065
1102
text = self .detokenize (completion_tokens )
0 commit comments