text-generation-webui 推理v0.9b模型的bug

#1
by GralchemOz - opened

使用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模型时无此状况。

SakuraLLM org
edited Jan 30

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)
GralchemOz changed discussion status to closed
SakuraLLM org

感谢您提供的脚本,我看了一下,这个问题的原因是model.tokenize()并未添加add_bos=False参数,增加此参数即可解决。

SakuraLLM org
edited Jan 31

另外,如要深究此问题,可以看一下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进行了一次大改,但我并没有测试是否修复了该问题。

收到,试了下问题已经解决了。。。。。

Sign up or log in to comment