text-generation-webui 推理v0.9b模型的bug
使用text-generation-webui 的llama.cpp loader 加载推理 v0.9b Q5_K_M gguf模型时,如果prompt的第一个字符为汉字或者日文,则会报错UnicodeDecodeError: 'utf-8' codec can't decode byte xxxx in position 0: invalid start byte. 使用v0.9模型时无此状况。
llama.cpp server未复现出此问题,同时text-generation-webui不在我们的支持范围内。
p.s. text-generation-webui出现该问题时如果模型可以输出正常的logits,就不是模型的问题。能否提供出现该问题时模型输出的logits?以及可以复现该问题的详细参数。
同时可以对一下hf上的sha256,之前遇到过模型永远退化的情况,发现是模型sha256对不上。
感谢您的回复,我这边找到了原因。text-generation-webui在生成文本前,会先对输入的prompt执行一次tokenizer再detokenizer的操作。而经过此操作之后,原先prompt的第一个字符会被舍去(原因暂时未探明,不清楚是不是Q5_K_M模型独有的问题),此时如果prompt为英文那么第一个字母会消失(e.g Hello --> ello). 而如果为中文,那么大概率会造成解码错误UnicodeDecodeError。此bug对于翻译没有影响,可以忽略。。。
p.s. 复现该问题的脚本如下所示:
import llama_cpp_cuda_tensorcores
#load model
Llama = llama_cpp_cuda_tensorcores.Llama
path = "sakura-13b-lnovel-v0.9b-Q5_K_M.gguf"
params = {
'model_path': str(path),
'n_ctx': 2048,
'n_threads': 0 or None,
'n_threads_batch': 0 or None,
'n_batch': 512,
'use_mmap': True,
'use_mlock': False,
'mul_mat_q': True,
'numa': False,
'n_gpu_layers': 45,
'rope_freq_base': 10000,
'tensor_split': None,
'rope_freq_scale': 1.0 ,
'offload_kqv': True
}
model = Llama(**params,)
def encode(string):
if type(string) is str:
string = string.encode()
return model.tokenize(string)
def decode(ids, **kwargs):
return model.detokenize(ids).decode('utf-8')
#test for bug
prompt = '你好'
tokens = encode(prompt)
try:
print('\n')
print(decode(tokens))
except UnicodeDecodeError as e:
print('\n')
print(e)
感谢您提供的脚本,我看了一下,这个问题的原因是model.tokenize()并未添加add_bos=False参数,增加此参数即可解决。
另外,如要深究此问题,可以看一下llama-cpp-python库老commit的这几行代码
如果不添加add_bos=False,则.tokenize()会给token_ids序列最前面增加bos_token_id=151644(<|im_start|>)。而根据上面提到的代码,如果检测到第一个token_id是bos_token_id的话,会删除第一个字节后返回,导致上面提到的错误。
llama-cpp-python会做出“删除一个字节”这样的操作,是因为旧版的llama.cpp在detokenize user defined类型的特殊token时,会输出空格,而这步的目的就是删除这个空格。如果是control类型的token,在detokenize的时候会直接为空,而本模型的special token均为control类型,因此实际上并没有如llama-cpp-python预期那样在最前面有一个空格,导致了报错。
最新的llama-cpp-python对llama.py进行了一次大改,但我并没有测试是否修复了该问题。
收到,试了下问题已经解决了。。。。。