大语言模型--Llama3 token结束符问题

2024-07-09 21:12:07 浏览数 (4)

背景

结束符是一个句子(prompt)的结尾标记,再大语言模型中,句子中的每个单词都会被编码成数字才能被模型处理。同样的,结尾标记也会被编码成一个数字。再Meta给的源码中,Llama3的结束符是-1(pad_id=-1,参考llama3/llama/tokenizer.py at main · meta-llama/llama3 (github.com))。transformers中现在是不支持pad_id=-1的,当同时给模型输入了多个句子(batch>1),我们就没法标记单个句子结束的地方。

解决办法

再Llama的源码中,我们看到向分词器(tokenizer模型)中添加了很多special_tokens,并且代码里也有用<|end_of_text|>、<|eot_id|>两个令牌来判断生成的句子是否结束。代码片段如下:

代码语言:txt复制
self.tokenizer.stop_tokens = {
            self.special_tokens["<|end_of_text|>"],
            self.special_tokens["<|eot_id|>"],
        }
    
    
out_tokens, out_logprobs = [], []
for i, toks in enumerate(tokens.tolist()):
    # cut to max gen len
    start = 0 if echo else len(prompt_tokens[i])
    toks = toks[start : len(prompt_tokens[i])   max_gen_len]
    probs = None
    if logprobs:
        probs = token_logprobs[i][start : len(prompt_tokens[i])   max_gen_len]
    # cut to after eos tok if any
    for stop_token in self.tokenizer.stop_tokens:
        try:
            eos_idx = toks.index(stop_token)
            toks = toks[:eos_idx]
            probs = probs[:eos_idx] if logprobs else None
        except ValueError:
            pass
    out_tokens.append(toks)
    out_logprobs.append(probs)

1. 我们可以直接把结束符设置为self.tokenizer.pad_token = "<|eot_id|>"

2. 也可以直接查看stop_tokens的id:

代码语言:txt复制
pad_id = self.tokenizer.convert_tokens_to_ids("<|eot_id|>")
self.tokenizer.pad_token_id = pad_id

1 人点赞