Facico / Chinese-Vicuna

Chinese-Vicuna: A Chinese Instruction-following LLaMA-based Model —— 一个中文低资源的llama+lora方案,结构参考alpaca
https://github.com/Facico/Chinese-Vicuna
Apache License 2.0
4.14k stars 421 forks source link

generate和interaction都无法停止,直到达到max_tokens限制才会停止 #59

Open alisyzhu opened 1 year ago

alisyzhu commented 1 year ago

1、执行generate.sh,设置Max new tokens=256,所有问题的结果都会生成至256才停止,即使代码里取消eos的设置,仍然如此

image

2、执行interaction.sh,设置max_new_tokens=128,回答也是如此,代码中并未设置eos信息,

image
Facico commented 1 year ago

你现在仓库的版本是最新版的吗,我看这个UI界面好像没有min_new_tokens

alisyzhu commented 1 year ago

你现在仓库的版本是最新版的吗,我看这个UI界面好像没有min_new_tokens

昨天上午拉取的,我需要重新pull generate的代码吗?

alisyzhu commented 1 year ago

你现在仓库的版本是最新版的吗,我看这个UI界面好像没有min_new_tokens

我这个截取的是interaction的页面,不是generate的,generate是有min_new_tokens选项的;但无论是哪种方式的,预测结果都无法有效停止。

Facico commented 1 year ago

如果使用我们的模型能成功停止吗

alisyzhu commented 1 year ago

还没调起来,一会儿试一下。另外我想问下,之前我通过download脚本下载llama,发现tokenizer有问题,无法正常decode,换成huggingface拉取model,可以decode,但是fine-tune完成后,貌似bos/eos/pad几个符号的处理不一致,导致无法有效停止。但是您反馈你们自己finetune的model是可以正常停止的,请问download和huggingface上的basemodel有什么不同吗?

Facico commented 1 year ago

download和huggingface一个是用的https://agi.gpt4.org/llama/LLaMA/,一个是他们传在huggingface上的,我们之前使用两种方式都是正常的。不清楚第一个链接中后台是否有修改,不过huggingface上的修改是能看到修改记录的

可以加载我们在huggingface上的lora模型看能否正常停止,llama他们的tokenizer后面好像有变过,因为我们finetune中用的是默认的eos,你可以尝试输出一下模型的eos是什么,或者看一下相关配置中eos应该对应哪个

rookiebird commented 1 year ago

之前我在issuse #54 的时候也提过这个问题,刚才又看了下tokenzier_config, 我觉得确实可能是tokenizer_config的问题, 我是下载的 decapoda-research/llama-7b-hf 这个llama 模型,他的tokenizer_config 默认eos_token 和 bos_token 都是空字符,这会导致eos_token_id 和 bos_token_id 都为零。我下huggingface 上默认的tokenizer_config 是这样的

{"bos_token": "", "eos_token": "", "model_max_length": 1000000000000000019884624838656, "tokenizer_class": "LLaMATokenizer", "unk_token": ""}

下面是我tokenizer的测试

image
Facico commented 1 year ago

@rookiebird 我跑了一下确实是和你不一样

print(tokenizer.eos_token_id)
print(tokenizer.bos_token_id)
print(tokenizer._convert_token_to_id(tokenizer.bos_token))
print(tokenizer._convert_token_to_id('<s>'))
print(tokenizer._convert_token_to_id('</s>'))
2
1
0
1
2
rookiebird commented 1 year ago

@Facico 先感谢大佬每次都很及时细心的回复。感觉你的输出也有点奇怪啊,你的tokenizer.bos_token是空字符吧, 所以输出的id 是0, 我怀疑你的tokenizer.eos_token 也是空字符, 但是为啥你的 tokenizer.eos_token_id和tokenizer.bos_token_id却是正确的对上了。。。我理解的顺序是, tokenizer_config.json用到的特殊字符会用来初始化LlamaTokenizer中的特殊字符,然后对应的eos_token_id, bos_token_id 应该是调用 self.convert_tokens_to_ids(special_token) 得到的。 但我也不是非常清楚这个流程。

rookiebird commented 1 year ago

修改了tokenizer_config文件,训练了1.1 个epoch的结果,看起来效果变好了

61681355957_ pic 101681356330_ pic 111681356384_ pic

71681355972_ pic

xqmmy commented 1 year ago

修改了tokenizer_config文件和add_eos_token这个配置,训练了1.1 个epoch的结果,看起来效果变好了

61681355957_ pic 101681356330_ pic 111681356384_ pic

71681355972_ pic

我也遇到了和你一样的问题,可以发下tokenizer_config文件和add_eos_token这两个配置嘛,谢谢

rookiebird commented 1 year ago

@xqmmy , config 和 generate_config 也要改下,我设置的token_id , bos_token_id 为1, eos_token_id为2 ,pad_token_id 为0 { "add_bos_token": true, "add_eos_token": true, "bos_token": { "__type": "AddedToken", "content": "", "lstrip": false, "normalized": true, "rstrip": false, "single_word": false }, "clean_up_tokenization_spaces": false, "eos_token": { "type": "AddedToken", "content": "", "lstrip": false, "normalized": true, "rstrip": false, "single_word": false }, "model_max_length": 2048, "pad_token": null, "sp_model_kwargs": {}, "tokenizer_class": "LlamaTokenizer", "unk_token": { "type": "AddedToken", "content": "", "lstrip": false, "normalized": true, "rstrip": false, "single_word": false } }

xqmmy commented 1 year ago

@rookiebird 好的,谢谢,我试下

rookiebird commented 1 year ago

我发现finetune的时候作者在加载llamaTokenizer, 已经设置为add_eos为true了, 这个部分好像不用设置了 @xqmmy

Facico commented 1 year ago

@rookiebird 今天的事情比较多,抱歉回复这么晚。可能因为huggingface的tokenizer相关的问题,transformers最新的代码中的llama将他们的tokenzier的路径给修改了,见这里

关于上面的问题,我们的tokenzier_config和你是一样的,bos和eos那里都是空的,如下

{"bos_token": "", "eos_token": "", "model_max_length": 1000000000000000019884624838656, "tokenizer_class": "LLaMATokenizer", "unk_token": ""}

所以我们的tokenizer.bos_token和tokenizer.eos_token都是空的,对应的是0 但上面的tokenizer.eos_token_idtokenizer.bos_token_id这里,它调用的是sentencepiece的接口求的,这个接口导入的是tokenizer.model这个文件,我估计就是这个文件的东西我们不一样。

transformers他们最新的代码好像将tokenizer.model这个换到了新的链接,我还没试过最新的版本,不过可能有所改善。

add_eos设置的是true,add_bos llama代码中默认的是true

rookiebird commented 1 year ago

哈哈哈,那我感觉找到问题的原因了, 似乎旧版本的LlamaTokenizer 是实现了自己的eos_token_id和unk_token_id这两个property函数的,我的这个版本已经删除了,所以默认调用了基类SpecialTokensMixin的函数实现,直接返回的是 self.convert_tokens_to_ids(self.bos_token)

image

OpenSource-fan commented 1 year ago

哈哈哈,那我感觉找到问题的原因了, 似乎旧版本的LlamaTokenizer 是实现了自己的eos_token_id和unk_token_id这两个property函数的,我的这个版本已经删除了,所以默认调用了基类SpecialTokensMixin的函数实现,直接返回的是 self.convert_tokens_to_ids(self.bos_token)

image

👍 这行代码的链接可以share一下吗?

rookiebird commented 1 year ago

@rookiebird 今天的事情比较多,抱歉回复这么晚。可能因为huggingface的tokenizer相关的问题,transformers最新的代码中的llama将他们的tokenzier的路径给修改了,见这里

关于上面的问题,我们的tokenzier_config和你是一样的,bos和eos那里都是空的,如下

{"bos_token": "", "eos_token": "", "model_max_length": 1000000000000000019884624838656, "tokenizer_class": "LLaMATokenizer", "unk_token": ""}

所以我们的tokenizer.bos_token和tokenizer.eos_token都是空的,对应的是0 但上面的tokenizer.eos_token_idtokenizer.bos_token_id这里,它调用的是sentencepiece的接口求的,这个接口导入的是tokenizer.model这个文件,我估计就是这个文件的东西我们不一样。

transformers他们最新的代码好像将tokenizer.model这个换到了新的链接,我还没试过最新的版本,不过可能有所改善。

add_eos设置的是true,add_bos llama代码中默认的是true

我也是看楼主给的链接才知道这里有修改的,以要旧的代码可以看上面这个链接,但是我觉得直接改配置文件也可以的 @OpenSource-fan

Facico commented 1 year ago

是的,peft和transformers这两个库用的不是release版本,版本迭代的时候太容易有对不齐的问题了。。。

sevenold commented 1 year ago
transformers             4.28.0.dev0
peft                     0.3.0.dev0

config.json

{
  "architectures": [
    "LlamaForCausalLM"
  ],
  "bos_token_id": 1,
  "eos_token_id": 2,
  "hidden_act": "silu",
  "hidden_size": 4096,
  "initializer_range": 0.02,
  "intermediate_size": 11008,
  "model_type": "llama",
  "num_attention_heads": 32,
  "num_hidden_layers": 32,
  "pad_token_id": 0,
  "rms_norm_eps": 1e-06,
  "tie_word_embeddings": false,
  "torch_dtype": "float16",
  "transformers_version": "4.28.0.dev0",
  "use_cache": true,
  "vocab_size": 32000
}

generation_config.json

{
  "_from_model_config": true,
  "bos_token_id": 1,
  "eos_token_id": 2,
  "pad_token_id": 0,
  "transformers_version": "4.28.0.dev0"
}

tokenizer_config.json

{
  "bos_token": "<s>",
  "clean_up_tokenization_spaces": false,
  "eos_token": "</s>",
  "model_max_length": 1000000000000000019884624838656,
  "tokenizer_class": "LlamaTokenizer",
  "unk_token": "<unk>"
}
tokenizer = LlamaTokenizer.from_pretrained(
    args.model_path, add_eos_token=True
)
print(tokenizer.eos_token_id)  
print(tokenizer.bos_token_id)  
print(tokenizer.eos_token)  
print(tokenizer.bos_token)  
print(tokenizer._convert_token_to_id(tokenizer.bos_token))  
print(tokenizer._convert_token_to_id("<s>"))  
print(tokenizer._convert_token_to_id("</s>"))  

2
1
</s>
<s>
1
1
2

我执行finetune后,测试结果

2023-04-20 14:08:18.510 | INFO     | __main__:interaction:129 - tensor([[    1,   450,  1494,   338,   263, 14983,  1546,   385,   319, 29902,
         20255,  2000,  4007, 22137,   322,   263,  5199,  1404,  2000,  4911,
         29889,    13,    13,  2277, 29937,  2799,  4080, 29901,    13, 29871,
         30919, 31076, 29892, 30275, 30356, 30210, 31688, 30769, 30505,   232,
           150,   173, 30755, 30882,    13,    13,  2277, 29937, 13291, 29901,
            13, 30662, 30675, 30392, 30275, 30356, 30210, 31688, 30769, 30267,
            13,    13,  2277, 29937,  2799,  4080, 29901,    13, 31088, 31785,
           235,   178,   140, 30672, 30662, 30675, 30461, 30210, 30888, 30698,
         31495, 30940, 30503, 31704, 30846, 30267,    13,    13,  2277, 29937,
         13291, 29901,    13, 30662, 30675, 30461, 30210, 30888, 30698, 31495,
         30940, 31473,   233,   142,   175, 31969,   232,   177,   174, 30330,
           236,   158,   132, 31831,   232,   182,   179, 30330, 30408, 30670,
         31649, 30214,   231,   192,   137, 30953, 30417,   232,   193,   139,
         30923, 31149, 31221, 30630,   231,   187,   192, 30210, 31495, 30940,
         30214, 31419, 30847,   234,   165,   148, 30853, 30539,   232,   158,
           176, 30330, 31143, 30626, 31184, 30267,    13,    13, 30948, 31516,
         30214, 30662, 30675, 30461, 31994, 30417,   232,   193,   139, 30923,
         31704, 30846, 30214, 31419, 30847, 30429, 30581, 30793]],
       device='cuda:0')

2023-04-20 14:08:18.519 | INFO     | __main__:interaction:131 - ['The following is a conversation between an AI assistant called Assistant and a human user called User.\n\n### Instruction:\n 你好,中国的首都在哪里?\n\n### Response:\n北京是中国的首都。\n\n### Instruction:\n请告诉我北京市的主要景点和活动。\n\n### Response:\n北京市的主要景点包括故宫、雁塔峰、天安门,但也有很多其他美丽的景点,比如碑林公园、长城等。\n\n当然,北京市还有很多活动,比如上海世']

官方提供的权重

2023-04-20 14:28:40.470 | INFO     | __main__:interaction:131 - tensor([[    1,   450,  1494,   338,   263, 14983,  1546,   385,   319, 29902,
         20255,  2000,  4007, 22137,   322,   263,  5199,  1404,  2000,  4911,
         29889,    13,    13,  2277, 29937,  2799,  4080, 29901,    13, 29871,
         30919, 31076, 29892, 30275, 30356, 30210, 31688, 30769, 30505,   232,
           150,   173, 30755, 30882,    13,    13,  2277, 29937, 13291, 29901,
            13, 30919, 31076, 30214, 30275, 30356, 30210, 31688, 30769, 30392,
         30662, 30675, 30267,     2]], device='cuda:0')
2023-04-20 14:28:40.472 | INFO     | __main__:interaction:133 - ['The following is a conversation between an AI assistant called Assistant and a human user called User.\n\n### Instruction:\n 你好,中国的首都在哪里?\n\n### Response:\n你好,中国的首都是北京。']
2023-04-20 14:28:40.473 | INFO     | __main__:interaction:136 - 你好,中国的首都是北京。

代码没有变化只能更改了权重,请两位大佬帮我看看问题出在哪? @rookiebird @Facico

wilson9x1 commented 1 year ago

pip uninstall transformers pip install git+https://github.com/huggingface/transformers@ff20f9cf3615a8638023bc82925573cb9d0f3560

截屏2023-05-07 19 38 51

这个改之后,情况终于和作者一样了。eos_token_id=2!!

可是还是停不下来 直到达到max_tokens限制才会停止。。@Facico 想问问 你有遇到类似情况么?

截屏2023-05-07 19 41 14 截屏2023-05-07 19 46 16

另外如果用提供的web端,也类似情况。而且还输出

### Instruction:
用一句话描述地球为什么是独一无二的 
截屏2023-05-07 19 42 24

和https://github.com/Facico/Chinese-Vicuna/issues/71#issuecomment-1514227087 这个遇到一样情况很类似。

wilson9x1 commented 1 year ago

@sevenold 你的问题解决了么?我发现我的和你遇到问题一模一样

niuhuluzhihao commented 1 year ago

https://github.com/Facico/Chinese-Vicuna/issues/59#issuecomment-1515782229 @sevenold 您好,我遇到的token问题和你一样,请问你解决这个问题了吗?麻烦指导一下

niuhuluzhihao commented 1 year ago

@wilson9x1 @Facico 两位大佬,print(tokenizer._convert_token_to_id(tokenizer.bos_token)) 这个我总是1,不是0,怎么解决呢

wilson9x1 commented 1 year ago

@summer-silence https://github.com/Facico/Chinese-Vicuna/issues/140

这里参考一下看看