A-A+
Chinese-LLaMA-Alpaca 扩充词表python代码及说明
![Shrimp-虾米-原创文章](/wp-content/themes/Ality/img/007.gif)
【注意:此文章为博主原创文章!转载需注意,请带原文链接,至少也要是txt格式!】
准备工作:词表扩充
由于原版LLaMA对中文的支持非常有限,本项目在原版LLaMA的基础上进一步扩充了中文词表。
- 在通用中文语料上训练了基于sentencepiece的20K中文词表并与原版LLaMA模型的32K词表进行合并
- 排除重复的token后,得到的最终中文LLaMA词表大小为49953
- 需要注意的是,在fine-tune阶段Alpaca比LLaMA多一个pad token,所以中文Alpaca的词表大小为49954
更多关于中文词表扩充的动机,可参考FAQ。
如果欲了解扩充词表的具体方法,或者使用自己的词表对LLaMA tokenizer进行扩充,我们提供了代码merge_tokenizers.py供参考。 该脚本运行方式如下:
python merge_tokenizers.py \
--llama_tokenizer_dir llama_tokenizer_dir \
--chinese_sp_model_file chinese_sp_model_file
其中
llama_tokenizer_dir
:指向存放原版LLaMA tokenizer的目录chinese_sp_model_file
:指向用sentencepiece训练的中文词表文件
我们所使用的在中文通用语料上训练的20K中文词表也一并放出,可以在scripts/chinese_sp.model下载。
其中merge_tokenizers.py的代码介绍为如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | import os # 导入 os 库 os.environ["PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION"]="python" # 设置环境变量 from transformers import LlamaTokenizer # 从 transformers 库中导入 LlamaTokenizer 类 from sentencepiece import sentencepiece_model_pb2 as sp_pb2_model # 从 sentencepiece 库中导入 sentencepiece_model_pb2 模块并重命名为 sp_pb2_model import sentencepiece as spm # 导入 sentencepiece 库并重命名为 spm import argparse # 导入 argparse 库 parser = argparse.ArgumentParser() # 创建一个 ArgumentParser 对象 parser.add_argument('--llama_tokenizer_dir', default=None, 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 # 获取命令行参数的值 chinese_sp_model_file = args.chinese_sp_model_file # 获取命令行参数的值 # load llama_tokenizer = LlamaTokenizer.from_pretrained(llama_tokenizer_dir) # 加载 LLaMA 分词器 chinese_sp_model = spm.SentencePieceProcessor() # 创建一个 SentencePieceProcessor 对象 chinese_sp_model.Load(chinese_sp_model_file) # 加载中文 SentencePiece 分词器 llama_spm = sp_pb2_model.ModelProto() # 创建一个 ModelProto 对象 llama_spm.ParseFromString(llama_tokenizer.sp_model.serialized_model_proto()) # 从 LLaMA 分词器中获取序列化模型并解析它 chinese_spm = sp_pb2_model.ModelProto() # 创建另一个 ModelProto 对象 chinese_spm.ParseFromString(chinese_sp_model.serialized_model_proto()) # 从中文 SentencePiece 分词器中获取序列化模型并解析它 # print number of tokens print(len(llama_tokenizer),len(chinese_sp_model)) # 打印两个分词器的 token 数量 print(llama_tokenizer.all_special_tokens) # 打印 LLaMA 分词器的特殊 token print(llama_tokenizer.all_special_ids) # 打印 LLaMA 分词器的特殊 token 的 ID print(llama_tokenizer.special_tokens_map) # 打印 LLaMA 分词器的特殊 token 映射 ## Add Chinese tokens to LLaMA tokenizer llama_spm_tokens_set=set(p.piece for p in llama_spm.pieces) # 获取 LLaMA 分词器中所有 token 的集合 print(len(llama_spm_tokens_set)) print(f"Before:{len(llama_spm_tokens_set)}") for p in chinese_spm.pieces: piece = p.piece if piece not in llama_spm_tokens_set: new_p = sp_pb2_model.ModelProto().SentencePiece() new_p.piece = piece new_p.score = 0 llama_spm.pieces.append(new_p) print(f"New model pieces: {len(llama_spm.pieces)}") ## Save output_sp_dir = 'merged_tokenizer_sp' output_hf_dir = 'merged_tokenizer_hf' # the path to save Chinese-LLaMA tokenizer os.makedirs(output_sp_dir,exist_ok=True) 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') tokenizer.save_pretrained(output_hf_dir) |
布施恩德可便相知重
微信扫一扫打赏
支付宝扫一扫打赏