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

llama2,chinese,项目,语言,模型,词表,扩充 · 浏览次数 : 109

小编点评

生成内容时需要带简单的排版,以便便于生成器理解排版要求。例如,需要在文本中加上简单的排版符号,以便生成器识别排版要求。例如,需要在文本中加上简单的排版符号,以便生成器识别排版要求: **白日依山尽,黄河入海流。** **欲穷千里目,更上一层楼。** **The primary use of LLaMA is research on large language models, including**

正文

  因为原生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 tokenizer

llama_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()  # 创建一个新的sentencepiece
        new_p.piece = piece  # 设置sentencepiece的词
        new_p.score = 0  # 设置sentencepiece的score
        llama_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

与Llama2-Chinese项目:2.2-大语言模型词表扩充相似的内容:

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

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

Llama2-Chinese项目:2.1-Atom-7B预训练

虽然Llama2的预训练数据相对于第一代LLaMA扩大了一倍,但是中文预训练数据的比例依然非常少,仅占0.13%,这也导致了原始Llama2的中文能力较弱。为了能够提升模型的中文能力,可以采用微调和预训练两种路径,其中: 微调需要的算力资源少,能够快速实现一个中文Llama的雏形。但缺点也显而易见,

Llama2-Chinese项目:2.3-预训练使用QA还是Text数据集?

Llama2-Chinese项目给出pretrain的data为QA数据格式,可能会有疑问pretrain不应该是Text数据格式吗?而在Chinese-LLaMA-Alpaca-2和open-llama2预训练使用的LoRA技术,给出pretrain的data为Text数据格式。所以推测应该pre

Llama2-Chinese项目:3.2-LoRA微调和模型量化

提供LoRA微调和全量参数微调代码,训练数据为data/train_sft.csv,验证数据为data/dev_sft.csv,数据格式为"Human: "+问题+"\nAssistant: "+答案。本文主要介绍Llama-2-7b模型LoRA微调以及4bit量化的实践过程。

Llama2-Chinese项目:4-量化模型

一.量化模型调用方式 下面是一个调用FlagAlpha/Llama2-Chinese-13b-Chat[1]的4bit压缩版本FlagAlpha/Llama2-Chinese-13b-Chat-4bit[2]的例子: from transformers import AutoTokenizerfro

Llama2-Chinese项目:7-外延能力LangChain集成

本文介绍了Llama2模型集成LangChain框架的具体实现,这样可更方便地基于Llama2开发文档检索、问答机器人和智能体应用等。 1.调用Llama2类 针对LangChain[1]框架封装的Llama2 LLM类见examples/llama2_for_langchain.py,调用代码如下

Llama2-Chinese项目:1-项目介绍和模型推理

Atom-7B与Llama2间的关系:Atom-7B是基于Llama2进行中文预训练的开源大模型。为什么叫原子呢?因为原子生万物,Llama中文社区希望原子大模型未来可以成为构建AI世界的基础单位。目前社区发布了6个模型,如下所示: FlagAlpha/Atom-7BFlagAlpha/Llama2

Llama2-Chinese项目:5-推理加速

随着大模型参数规模的不断增长,在有限的算力资源下,提升模型的推理速度逐渐变为一个重要的研究方向。常用的推理加速框架包含lmdeploy、FasterTransformer和vLLM等。 一.lmdeploy推理部署 lmdeploy由上海人工智能实验室开发,推理使用C++/CUDA,对外提供pyth

Llama2-Chinese项目:6-模型评测

测试问题筛选自AtomBulb[1],共95个测试问题,包含:通用知识、语言理解、创作能力、逻辑推理、代码编程、工作技能、使用工具、人格特征八个大的类别。 1.测试中的Prompt 例如对于问题"列出5种可以改善睡眠质量的方法",如下所示: [INST] <>You are a helpf

Llama2-Chinese项目:8-TRL资料整理

TRL(Transformer Reinforcement Learning)是一个使用强化学习来训练Transformer语言模型和Stable Diffusion模型的Python类库工具集,听上去很抽象,但如果说主要是做SFT(Supervised Fine-tuning)、RM(Reward