当前位置:   article > 正文

关于LLaMA Tokenizer的一些坑...

关于LLaMA Tokenizer的一些坑...

使用LLaMA Tokenizerjsonl 文件进行分词,并将分词结果保存到 txt 文件中,分词代码如下:

import jsonlines
import sentencepiece as spm
from tqdm import tqdm

jsonl_file = '/path/to/jsonl_file'
txt_file = '/path/to/txt_file'

tokenizer = spm.SentencePieceProcessor('./tokenizer.model')
w = open(txt_file, mode='w', encoding='utf-8')

with jsonlines.open(jsonl_file, mode='r') as r:
    for line in tqdm(r):
        ids = tokenizer.Encode(line['text'])
        tokenized_text = ' '.join(tokenizer.IdToPiece(i) for i in ids)
        w.write(f"{tokenized_text}\n")

w.close()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

从以上代码可以看出,txt 文件中的每行内容实际上是 jsonl 文件对应行的文档的分词结果,分词之间以空格分隔。理论上,这意味着 txt 文件的行数应与 jsonl 文件的行数相匹配均等同于文档数量。然而,实际情况可能出现 txt 文件的行数显著超过 jsonl 文件的行数。

既然行数对不上,那自然就需要找到第一个出现问题的行。为此,我们重新执行分词过程,并在每行的开头添加该行的索引(从 1 1 1 开始)以便追踪。

with jsonlines.open(jsonl_file, mode='r') as r:
    for idx, line in tqdm(enumerate(r, start=1)):
        ids = tokenizer.Encode(line['text'])
        tokenized_text = ' '.join(tokenizer.IdToPiece(i) for i in ids)
        w.write(f"{idx} {tokenized_text}\n")
  • 1
  • 2
  • 3
  • 4
  • 5

然后遍历 txt 文件,找到第一个出现问题的行:

with open(txt_file, mode='r') as r:
    for cnt, line in tqdm(enumerate(r, start=1)):
        idx = line[:line.index(' ')]
        if str(cnt) != idx:
            print(cnt)
            break
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

打开 txt 文件,发现出现问题的行的开头压根没有数字,这说明分词结果被某种特殊字符换行了。要注意LLaMA词表是没有换行符 \n 的(被映射到 <unk> 了),那还能是什么字符导致换行的呢?

jsonl 文件中对应的行抽取出来,单独对它进行分词,然后将分词结果打印到终端上,发现并没有换行,然而将这个分词结果单独写入到一个新的文件中时,换行出现了。通过对每一个token单独进行分析,发现其中有一个token含有 \r,而这个字符正是导致换行的罪魁祸首!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/81140
推荐阅读
相关标签