关于LLaMA Tokenizer的一些坑...

2024-02-09 18:20
文章标签 llama tokenizer

本文主要是介绍关于LLaMA Tokenizer的一些坑...,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

import jsonlines
import sentencepiece as spm
from tqdm import tqdmjsonl_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()

从以上代码可以看出,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")

然后遍历 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

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

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

📝 \r 字符是回车符(Carriage Return, CR),在ASCII表中的位置是十进制的13或者十六进制的0x0D。这个字符最初设计用于打字机和早期计算机,指的是将打印头移动到一行的开始位置而不换到下一行,这样新的文本就会覆盖掉同一行上旧的文本。

  • 在Python中使用 print('\r') 时,并不会导致在控制台上换行,因为 \r 只是将光标移回行首,而没有执行换到新行的操作。例如 print('aaa\rbb') 会输出 bba
  • 而在文本文件中写入 \r 字符时,文本编辑器可能会将其解释为换行符,因此会触发换行效果。

接下来,我们就可以找出LLaMA词表中所有可能会导致换行的token了:

tokenizer = spm.SentencePieceProcessor('./tokenizer.model')
vocab_size = tokenizer.GetPieceSize()
for i in range(vocab_size):piece = tokenizer.IdToPiece(i)if '\r' in piece:print(f"{i}: {list(piece)}")

一共有 24 24 24 个:

2104: [';', '\r']
3238: ['>', '\r']
3336: ['▁', '{', '\r']
4970: ['▁', '}', '\r']
6075: [')', ';', '\r']
6756: ['▁', '\r']
8117: ['}', '\r']
8443: [')', '\r']
10175: ['"', '>', '\r']
11167: [',', '\r']
14078: ['(', ')', ';', '\r']
14626: ['{', '\r']
15231: ['"', ',', '\r']
16737: ['%', ';', '\r']
17822: ["'", ')', ';', '\r']
18584: ['"', ')', ';', '\r']
19451: ['"', '\r']
22993: ['.', '\r']
23592: ["'", ',', '\r']
24426: ['▁', '}', ')', ';', '\r']
25982: ['"', ';', '\r']
26471: ['(', ')', '\r']
29722: ['▁', '*', '/', '\r']
30004: ['\r']

可以看出,位于索引 30004 处的token刚好就是 \r,而其他token则均是以 \r 结尾。


很多场景下,我们可能需要保证 jsonltxt 的行数一致才能进行下一步,为此有两种选择方案:

  • 在生成 jsonl 文件的时候做一个预处理,判断其中是否有token包含在上述24个token之一(该方案可保持 jsonl 行数不变)。
  • 对生成的 jsonl 文件按照上述的24个token进行过滤(该方案会导致 jsonl 行数减少)。

无论是哪种方案,都涉及到对是否包含的判断。设24个token构成的列表为 a,某个文档的分词结果为 b,于是问题便归结为判断 a 中是否有元素出现在了 b 中(反之亦然)。根据这篇博客的结论,我们可以用集合法来快速判断。

tokenizer = spm.SentencePieceProcessor('./tokenizer.model')
stop = {2104, 3238, 3336, 4970, 6075, 6756, 8117, 8443, 10175, 11167, 14078, 14626, 15231, 16737, 17822, 18584, 19451, 22993, 23592, 24426, 25982, 26471, 29722, 30004}def valid(ids):return not bool(set(ids).intersection(stop))with jsonlines.open(jsonl_file, mode='r') as r:for idx, line in tqdm(enumerate(r, start=1)):ids = tokenizer.Encode(line['text'])if not valid(ids):print(f"Line {idx} is invalid data!")

这篇关于关于LLaMA Tokenizer的一些坑...的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/694964

相关文章

Python安装llama库出错“metadata-generation-failed”

Python安装llama库出错“metadata-generation-failed” 1. 安装llama库时出错2. 定位问题1. 去官网下载llama包 2.修改配置文件2.1 解压文件2.2 修改配置文件 3. 本地安装文件 1. 安装llama库时出错 2. 定位问题 根据查到的资料,发现时llama包中的execfile函数已经被下线了,需要我们手动修改代码后

Llama 3.1大模型的预训练和后训练范式解析

Meta的Llama大型语言模型每次出新版本,都会是一大事件。前段时间他们不仅发布了3.1的一个超大型的405亿参数模型,还对之前的8亿和70亿参数的模型做了升级,让它们在MMLU测试中的表现更好了。 不同模型在MMLU基准测试中的表现 他们还出了一个92页的技术报告《Llama 3 Herd of Models》(https://arxiv.org/abs/2407.21783),里

llama.cpp demo

git clone https://github.com/ggerganov/llama.cppcd llama.cpp 修改Makefile使能mfma参数     MK_CFLAGS   += -mfma -mf16c -mavx     MK_CXXFLAGS += -mfma -mf16c -mavx 安装python3依赖 cat ./requirements/requirem

llama.cpp本地部署大模型

llama.cpp 是一个C++库,用于简化LLM推理的设置,它使得在本地机器上运行大模型(GGUF格式)成为可能。 官网:https://github.com/ggerganov/llama.cpp 模型库: https://huggingface.co/ HF-Mirror 魔搭社区 安装并且使用llama.cpp 0.安装llama.cpp 官方文档:https://gi

3天把Llama训成Mamba,性能不降,推理更快!

近日,Mamba方面又搞出了有意思的研究:来自康奈尔、普林斯顿等机构的研究人员成功将Llama提炼成了Mamba模型,并且设计了新的推测解码算法,加速了模型的推理。\ 先来看一张其乐融融的图片(一眼AI): 右边的小羊驼代表Llama,而左边的蛇(Mamba)也是我们的老熟人了。 至于到底能不能其乐融融,咱就不管了,之所以有此场景,是因为Mamba方面又搞出了有意思的研究: ——如何把

解决Can‘t load tokenizer for ‘bert-base-chinese‘.问题

报错提示: OSError: Can't load tokenizer for 'bert-base-chinese'. If you were trying to load it from 'https://huggingface.co/models', make sure you don't have a local directory with the same name. Otherwi

LLaMA-Factory仓基础功能架构及NPU/GPU环境实战演练

LLaMA-Factory 基础篇 LLaMA-Factory简介 LLaMA-Factory是一个开源的大规模语言模型微调框架,设计用于简化大模型的训练过程。它提供了一个统一的平台,支持多种大模型的微调,包括LLaMA、BLOOM、Mistral等,旨在帮助用户快速适应和调整这些模型以适应特定的应用场景。LLaMA-Factory通过提供一套完整的工具和接口,使用户能够轻松地对预训练的

The Llama 3 Herd of Models【论文原文下载】

关注B站可以观看更多实战教学视频:hallo128的个人空间 The Llama 3 Herd of Models【论文原文】 点击下载:原文下载链接 摘要 现代人工智能(AI)系统由基础模型驱动。本文介绍了一组新的基础模型,称为 Llama 3。它是一群原生支持多语言、编码、推理和工具使用的语言模型。我们最大的模型是一个密集型 Transformer,具有 405    B {40

lit-llama代码解析

https://github.com/Lightning-AI/lit-llama/blob/main/README.md 下载的时候会报错误,因为网不行,一种方法就是多次尝试,另一种方法是终端连上代理下载 pycharm连接hugging face等网站_hugging face怎么连接-CSDN博客 根据指引下载权重 下载完权重运行:python scripts/convert_h

【AI大模型】近100页的LLaMA 3技术报告:模型结构及影响解析

LLama 3 405B模型效果已经赶上目前最好的闭源模型比如GPT 4o和Claude 3.5,这算是开源届的大事,技术报告接近100页,信息很丰富,粗略看了一下,很有启发。这里就LLaMA 3的模型结构、训练过程做些解读,并对其影响、小模型如何做、合成数据等方面谈点看法。 一、LLaMA 3模型结构 LLaMA 3的模型结构如图1所示,这基本已经形成目前Dense LLM模型的标准结构了,