Llama2-Chinese项目:2.2-大语言模型词表扩充

news/发布时间2024/5/17 14:45:37

因为原生LLaMA对中文的支持很弱,一个中文汉子往往被切分成多个token,因此需要对其进行中文词表扩展。思路通常是在中文语料库上训练一个中文tokenizer模型,然后将中文tokenizer与LLaMA原生tokenizer进行合并,最终得到一个扩展后的tokenizer模型。国内Chinese-LLaMA-Alpaca开源项目详细说明了词表扩展[2]。

一.对LLaMA tokenizer扩充自定义的词表
  原版LLaMA模型的词表大小是32K,其主要针对英语进行训练,下面对其扩充20K中文词表,如下所示:

python merge_tokenizers.py \--llama_tokenizer_dir r'L:/20230902_Llama1/llama-7b-hf' \--chinese_sp_model_file r'./chinese_sp.model'
  • llama_tokenizer_dir:指向存放原版LLaMA tokenizer的目录
  • chinese_sp_model_file:指向用sentencepiece训练的中文词表文件

说明:在中文通用语料上训练的20K中文词表下载链接参考[3],如何构建垂直领域的中文词表下次分享。

二.merge_tokenizers.py注释
1.本文环境
本文环境为Windows10,Python3.10,CUDA 11.8,GTX 3090(24G),内存24G。

2.merge_tokenizers.py代码

import os
from transformers import LlamaTokenizer
from sentencepiece import sentencepiece_model_pb2 as sp_pb2_model
import sentencepiece as spm
import argparse
os.environ["PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION"] = "python"# parser = argparse.ArgumentParser() # 创建一个ArgumentParser对象
# parser.add_argument('--llama_tokenizer_dir', default=r'L:/20230902_Llama1/llama-7b-hf', type=str, required=True) # 添加参数
# parser.add_argument('--chinese_sp_model_file', default='./chinese_sp.model', type=str) # 添加参数
# args = parser.parse_args() # 解析参数
# llama_tokenizer_dir = args.llama_tokenizer_dir # 这里是LLaMA tokenizer的路径
# chinese_sp_model_file = args.chinese_sp_model_file # 这里是Chinese tokenizer的路径llama_tokenizer_dir = r'L:/20230902_Llama1/llama-7b-hf'  # 这里是LLaMA tokenizer的路径
chinese_sp_model_file = r'./chinese_sp.model'  # 这里是Chinese tokenizer的路径# 加载tokenizer
llama_tokenizer = LlamaTokenizer.from_pretrained(llama_tokenizer_dir)  # 加载LLaMA tokenizer
chinese_sp_model = spm.SentencePieceProcessor()  # 定义Chinese tokenizer
chinese_sp_model.Load(chinese_sp_model_file)  # 加载Chinese tokenizerllama_spm = sp_pb2_model.ModelProto()  # 定义LLaMA tokenizer的sentencepiece model
llama_spm.ParseFromString(llama_tokenizer.sp_model.serialized_model_proto())  # 从LLaMA tokenizer中加载sentencepiece model
chinese_spm = sp_pb2_model.ModelProto()  # 定义Chinese tokenizer的sentencepiece model
chinese_spm.ParseFromString(chinese_sp_model.serialized_model_proto())  # 从Chinese tokenizer中加载sentencepiece model# 输出tokens的信息
print(len(llama_tokenizer), len(chinese_sp_model))  # 两个tokenizer的词表大小;输出为32000、20000
print(llama_tokenizer.all_special_tokens)  # LLaMA tokenizer的special tokens;输出为['']
print(llama_tokenizer.all_special_ids)  # LLaMA tokenizer的special tokens对应的id;输出为[0]
print(llama_tokenizer.special_tokens_map)  # LLaMA tokenizer的special tokens;输出为{'bos_token': '', 'eos_token': '', 'unk_token': ''}# 将Chinese tokenizer的词表添加到LLaMA tokenizer中(合并过程)
llama_spm_tokens_set = set(p.piece for p in llama_spm.pieces)  # LLaMA tokenizer的词表
print(len(llama_spm_tokens_set))  # LLaMA tokenizer的词表大小;输出为32000
print(f"Before:{len(llama_spm_tokens_set)}")  # LLaMA tokenizer的词表大小;输出为Before:32000
for p in chinese_spm.pieces:  # 遍历Chinese tokenizer的词表piece = p.piece  # Chinese tokenizer的词if piece not in llama_spm_tokens_set:  # 如果Chinese tokenizer的词不在LLaMA tokenizer的词表中new_p = sp_pb2_model.ModelProto().SentencePiece()  # 创建一个新的sentencepiecenew_p.piece = piece  # 设置sentencepiece的词new_p.score = 0  # 设置sentencepiece的scorellama_spm.pieces.append(new_p)  # 将sentencepiece添加到LLaMA tokenizer的词表中
print(f"New model pieces: {len(llama_spm.pieces)}")  # LLaMA tokenizer的词表大小;输出为New model pieces: 49953# 保存LLaMA tokenizer
output_sp_dir = 'merged_tokenizer_sp'  # 这里是保存LLaMA tokenizer的路径
output_hf_dir = 'merged_tokenizer_hf'  # 这里是保存Chinese-LLaMA tokenizer的路径
os.makedirs(output_sp_dir, exist_ok=True)  # 创建保存LLaMA tokenizer的文件夹
with open(output_sp_dir + '/chinese_llama.model', 'wb') as f:f.write(llama_spm.SerializeToString())
tokenizer = LlamaTokenizer(vocab_file=output_sp_dir + '/chinese_llama.model')  # 创建LLaMA tokenizer
tokenizer.save_pretrained(output_hf_dir)  # 保存Chinese-LLaMA tokenizer
print(f"Chinese-LLaMA tokenizer has been saved to {output_hf_dir}")  # 保存Chinese-LLaMA tokenizer# 测试tokenizer
llama_tokenizer = LlamaTokenizer.from_pretrained(llama_tokenizer_dir)  # LLaMA tokenizer
chinese_llama_tokenizer = LlamaTokenizer.from_pretrained(output_hf_dir)  # Chinese-LLaMA tokenizer
print(tokenizer.all_special_tokens)  # LLaMA tokenizer的special tokens;输出为['<s>', '</s>', '<unk>']
print(tokenizer.all_special_ids)  # LLaMA tokenizer的special tokens对应的id;输出为[0, 1, 2]
print(tokenizer.special_tokens_map)  # LLaMA tokenizer的special tokens;输出为{'bos_token': '<s>', 'eos_token': '</s>', 'unk_token': '<unk>'}
text = '''白日依山尽,黄河入海流。欲穷千里目,更上一层楼。
The primary use of LLaMA is research on large language models, including'''
print("Test text:\n", text)  # 测试文本
print(f"Tokenized by LLaMA tokenizer:{llama_tokenizer.tokenize(text)}")  # 测试LLaMA tokenizer
# 输出结果
# Tokenized by LLaMA tokenizer:['▁', '白', '日', '<0xE4>', '<0xBE>', '<0x9D>', '山', '<0xE5>', '<0xB0>', '<0xBD>', ',', '黄', '河', '入', '海', '流', '。', '<0xE6>', '<0xAC>', '<0xB2>', '<0xE7>', '<0xA9>', '<0xB7>', '千', '里', '目', ',', '更', '上', '一', '<0xE5>', '<0xB1>', '<0x82>', '<0xE6>', '<0xA5>', '<0xBC>', '。', '<0x0A>', 'The', '▁primary', '▁use', '▁of', '▁L', 'La', 'MA', '▁is', '▁research', '▁on', '▁large', '▁language', '▁models', ',', '▁including']
print(f"Tokenized by Chinese-LLaMA tokenizer:{chinese_llama_tokenizer.tokenize(text)}")  # 测试Chinese-LLaMA tokenizer
# 输出结果
# Tokenized by Chinese-LLaMA tokenizer:['▁白', '日', '依', '山', '尽', ',', '黄河', '入', '海', '流', '。', '欲', '穷', '千里', '目', ',', '更', '上', '一层', '楼', '。', '<0x0A>', 'The', '▁primary', '▁use', '▁of', '▁L', 'La', 'MA', '▁is', '▁research', '▁on', '▁large', '▁language', '▁models', ',', '▁including']

3.生成的目录


参考文献:
[1]是否有基于Llama-2的增量训练模型:https://github.com/ymcui/Chinese-LLaMA-Alpaca/issues/817
[2]https://github.com/ymcui/Chinese-LLaMA-Alpaca/blob/main/scripts/merge_tokenizer/merge_tokenizers.py
[3]https://github.com/ymcui/Chinese-LLaMA-Alpaca/tree/main/scripts/merge_tokenizer/chinese_sp.model
[4]下载Chinese-LLaMA-Alpaca:git clone https://github.com/ymcui/Chinese-LLaMA-Alpaca.git
[5]下载llama-7b-hf:git lfs clone https://huggingface.co/yahma/llama-7b-hf

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ulsteruni.cn/article/56181835.html

如若内容造成侵权/违法违规/事实不符,请联系编程大学网进行投诉反馈email:xxxxxxxx@qq.com,一经查实,立即删除!

相关文章

Taskflow CGraph

taskflow/taskflow: A General-purpose Parallel and Heterogeneous Task Programming System (github.com)ChunelFeng/CGraph: 【A simple C++ DAG framework】 一个简单好用的、无三方依赖的、跨平台的、收录于awesome-cpp的、基于流图的并行计算框架。欢迎star & fork (…

学习笔记4

知识点总结 第七章 文件操作级别硬件级别fdisk:将硬盘、U盘或SDC盘分区 mkfs:格式化磁盘分区,为系统做好准备 fsck:检 查和维修系统碎片整理:压缩文件系统中的文件操作系统内核中的文件系统函数前缀为k表示内核函数系统调用:用户模式程序使用系统调用来访问内核函数open(…

zabbix6.4+grafana10.1监控可视化

一、安装grafanayum install -y https://dl.grafana.com/enterprise/release/grafana-enterprise-10.1.4-1.x86_64.rpm 二、启动并设为开机自启[root@zabbix-server ~]# systemctl start grafana-server.service [root@zabbix-server ~]# systemctl enable grafana-server.s…

LeetCode 周赛上分之旅 #48 一道简单的树上动态规划问题

⭐️ 本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 和 BaguTree Pro 知识星球提问。 学习数据结构与算法的关键在于掌握问题背后的算法思维框架,你的思考越抽象,它能覆盖的问题域就越广,理解难度也更复杂。在这个专栏里,小彭与你分享每场 LeetCode …

WebKist Inside: CSS 样式表的组成

WebKist Inside: CSS 样式表的组成StyleSheet 一张 StyleSheet 由一系列 Rules 组成,这些 Rules 可以分成 2 大类: Style Rule 和 At-Rule。下面的例子展示了 Style Rule 和 At-Rule:// Style Rule div {background-color: red;font-size: 12px; }// At-Rule @media print {bo…