LLaMA模型之中文词表的蜕变

在目前的开源模型中,LLaMA模型无疑是一颗闪亮的⭐️,但是相对于ChatGLM、BaiChuan等国产大模型,其对于中文的支持能力不是很理想。原版LLaMA模型的词表大小是32K,中文所占token是几百个左右,这将会导致中文的编解码效率低。

在将LLaMA系列模型用于中文语言时需要进行中文词表扩充,基于sentencepiece工具训练,产生新的词表,然后与原始词表合并得到一个新词表。

本文将LLaMA模型中文词表扩充分为以下步骤:训练数据准备、词表训练、词表合并、词表测试。

训练数据准备

这里使用MedicalGPT中的天龙八部小说作为训练文本。

数据是txt文件,一行文本作为一条数据。

词表训练代码

import sentencepiece as spm

spm.SentencePieceTrainer.train(
    input='tianlongbabu.txt',
    model_prefix='bpe_llama',
    shuffle_input_sentence=False,
    train_extremely_large_corpus=True,
    max_sentence_length=2048,
    pad_id=3,
    model_type='BPE',
    vocab_size=5000,
    split_digits=True,
    split_by_unicode_script=True,
    byte_fallback=True,
    allow_whitespace_only_pieces=True,
    remove_extra_whitespaces=False,
    normalization_rule_name="nfkc",
)

print('训练完成')

sentencepiece训练参数:
Usage: …/build/src/spm_train [options] files

  • –input(逗号分隔的输入句子列表) 类型:字符串 默认值:“”
  • –input_format(输入格式。支持的格式为texttsv。) 类型:字符串 默认值:“”
  • –model_prefix(输出模型前缀) 类型:字符串 默认值:“”
  • –model_type(模型算法:unigram、bpe、word或char) 类型:字符串 默认值:“unigram”
  • –vocab_size(词汇表大小) 类型:int32 默认值:8000
  • –accept_language(此模型可以接受的语言的逗号分隔列表) 类型:字符串 默认值:“”
  • –self_test_sample_size(自测样本的大小) 类型:int32 默认值:0
  • –character_coverage(用于确定最小符号的字符覆盖率) 类型:double 默认值:0.9995
  • –input_sentence_size(训练器加载的句子的最大大小) 类型:uint64_t 默认值:0
  • –shuffle_input_sentence(提前随机抽样输入句子。当–input_sentence_size > 0时有效) 类型:bool 默认值:true
  • –seed_sentencepiece_size(seed sentencepieces的大小) 类型:int32 默认值:1000000
  • –shrinking_factor(与损失相关的保留顶部shrinking_factor片段) 类型:double 默认值:0.75
  • –num_threads(训练时的线程数) 类型:int32 默认值:16
  • –num_sub_iterations(EM子迭代的数量) 类型:int32 默认值:2
  • –max_sentencepiece_length(sentence piece的最大长度) 类型:int32 默认值:16
  • –max_sentence_length(句子的最大长度(字节)) 类型:int32 默认值:4192
  • –split_by_unicode_script(使用Unicode脚本拆分句子片段) 类型:bool 默认值:true
  • –split_by_number(通过数字(0-9)拆分标记) 类型:bool 默认值:true
  • –split_by_whitespace(使用空格拆分句子片段) 类型:bool 默认值:true
  • –split_digits(将所有数字(0-9)拆分为单独的片段) 类型:bool 默认值:false
  • –treat_whitespace_as_suffix(将空格标记视为后缀而不是前缀。) 类型:bool 默认值:false
  • –allow_whitespace_only_pieces(允许只包含(连续的)空格标记的片段) 类型:bool 默认值:false
  • –control_symbols(控制符号的逗号分隔列表) 类型:字符串 默认值:“”
  • –control_symbols_file(从文件加载控制符号。) 类型:字符串 默认值:“”
  • –user_defined_symbols(用户定义符号的逗号分隔列表) 类型:字符串 默认值:“”
  • –user_defined_symbols_file(从文件加载user_defined_symbols。) 类型:字符串 默认值:“”
  • –required_chars(UTF8字符,无论character_coverage如何,始终在字符集中使用) 类型:字符串 默认值:“”
  • –required_chars_file(从文件加载required_chars。) 类型:字符串 默认值:“”
  • –byte_fallback(将未知片段分解为UTF-8字节片段) 类型:bool 默认值:false
  • –vocabulary_output_piece_score(在vocab文件中定义分数) 类型:bool 默认值:true
  • –normalization_rule_name(规范化规则名称。从nfkc或identity中选择) 类型:字符串 默认值:“nmt_nfkc”
  • –normalization_rule_tsv(规范化规则TSV文件。) 类型:字符串 默认值:“”
  • –denormalization_rule_tsv(反规范化规则TSV文件。) 类型:字符串 默认值:“”
  • –add_dummy_prefix(在文本开头添加虚拟空格) 类型:bool 默认值:true
  • –remove_extra_whitespaces(删除前导、尾随和重复的内部空格) 类型:bool 默认值:true
  • –hard_vocab_limit(如果设置为false,则–vocab_size被视为软限制。) 类型:bool 默认值:true
  • –use_all_vocab(如果设置为true,则使用所有标记作为vocab。对于word/char模型有效。) 类型:bool 默认值:false
  • –unk_id(覆盖UNK(<unk>)id。) 类型:int32 默认值:0
  • –bos_id(覆盖BOS(<s>)id。将-1设置为禁用BOS。) 类型:int32 默认值:1
  • –eos_id(覆盖EOS(</s>)id。将-1设置为禁用EOS。) 类型:int32 默认值:2
  • –pad_id(覆盖PAD(<pad>)id。将-1设置为禁用PAD。) 类型:int32 默认值:-1
  • –unk_piece(覆盖UNK(<unk>)片段。) 类型:字符串 默认值:“<unk>”
  • –bos_piece(覆盖BOS(<s>)片段。) 类型:字符串 默认值:“<s>”
  • –eos_piece(覆盖EOS(</s>)片段。) 类型:字符串 默认值:“</s>”
  • –pad_piece(覆盖PAD(<pad>)片段。) 类型:字符串 默认值:“<pad>”
  • –unk_surface(<unk>的虚拟表面字符串。在解码中,<unk>被解码为unk_surface。) 类型:字符串 默认值:“ ⁇ ”
  • –train_extremely_large_corpus(增加unigram标记化的位深度。) 类型:bool 默认值:false
  • –random_seed(随机生成器的种子值。) 类型:uint32 默认值:4294967295
  • –enable_differential_privacy(是否在训练时添加差分隐私。目前仅UNIGRAM模型支持。) 类型:bool 默认值:false
  • –differential_privacy_noise_level(DP时添加的噪声量) 类型:float 默认值:0
  • –differential_privacy_clipping_threshold(DP时剪切计数的阈值) 类型:uint64_t 默认值:0
  • –help(显示帮助) 类型:bool 默认值:false
  • –version(显示版本) 类型:bool 默认值:false
  • –minloglevel(低于此级别的消息实际上不会被记录在任何地方) 类型:int 默认值:0
  1. 测试
import sentencepiece as spm

sp = spm.SentencePieceProcessor()
sp.load("bpe_llama.model")

print(sp.encode_as_pieces("这老者姓左,名叫子穆,是“无量剑”东宗的掌门。那道姑姓辛,道号双清,是“无量剑”西宗掌门。"))
print(sp.encode_as_ids("这老者姓左,名叫子穆,是“无量剑”东宗的掌门。那道姑姓辛,道号双清,是“无量剑”西宗掌门。"))

词表合并代码

import os
os.environ["PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION"]="python"

from transformers import LlamaTokenizer
from sentencepiece import sentencepiece_model_pb2 as sp_pb2_model
import sentencepiece as spm

llama_tokenizer_dir = 'llama-2-7b-bin'
chinese_sp_model_file = 'bpe_llama.model'

# 分词器加载
llama_tokenizer = LlamaTokenizer.from_pretrained(llama_tokenizer_dir)
chinese_sp_model = spm.SentencePieceProcessor()
chinese_sp_model.Load(chinese_sp_model_file)

# 解析
llama_spm = sp_pb2_model.ModelProto()
llama_spm.ParseFromString(llama_tokenizer.sp_model.serialized_model_proto())
chinese_spm = sp_pb2_model.ModelProto()
chinese_spm.ParseFromString(chinese_sp_model.serialized_model_proto())

# 词表长度
print(len(llama_tokenizer),len(chinese_sp_model))

# 添加新token到llama词表
llama_spm_tokens_set=set(p.piece for p in llama_spm.pieces)
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)}")

output_sp_dir = '../merged_tokenizer_sp'
output_hf_dir = '../merged_tokenizer_hf'

vocab_content = ''
for p in llama_spm.pieces:
    vocab_content += f"{p.piece} {p.score}\n"
# 保存词表
with open(output_sp_dir+'/chinese_llama.vocab', "w", encoding="utf-8") as f:
    f.write(vocab_content)
# 保存spm模型
with open(output_sp_dir+'/chinese_llama.model', 'wb') as f:
    f.write(llama_spm.SerializeToString())

# 保存llama新tokenizer
tokenizer = LlamaTokenizer(vocab_file=output_sp_dir+'/chinese_llama.model')
tokenizer.save_pretrained(output_hf_dir)
print(f"Chinese-LLaMA tokenizer has been saved to {output_hf_dir}")

词表文件:

词表测试代码

from transformers import LlamaTokenizer

llama_tokenizer = LlamaTokenizer.from_pretrained(llama_tokenizer_dir)
chinese_llama_tokenizer = LlamaTokenizer.from_pretrained(output_hf_dir)
print(tokenizer.all_special_tokens)
print(tokenizer.all_special_ids)
print(tokenizer.special_tokens_map)
text='''白日依山尽,黄河入海流。欲穷千里目,更上一层楼。'''
text='''大模型是指具有非常大的参数数量的人工神经网络模型。 在深度学习领域,大模型通常是指具有数亿到数万亿参数的模型。'''
print("Test text:\n",text)
print(f"Tokenized by LLaMA tokenizer:{len(llama_tokenizer.tokenize(text))},{llama_tokenizer.tokenize(text)}")
print(f"Tokenized by GoGPT-LLaMA tokenizer:{len(chinese_llama_tokenizer.tokenize(text))},{chinese_llama_tokenizer.tokenize(text)}")

从结果可以看到,中文分词后长度显著减小,英文分词没有产生影响。

注:在对中文词表扩展后的LLaMA模型做增量预训练时,需要调整嵌入层的大小(model.resize_token_embeddings(len(tokenizer))),因为词表大小发生变化。

参考

[1] https://github.com/shibing624/MedicalGPT/tree/main

[2] https://github.com/yanqiangmiffy/how-to-train-tokenizer/tree/main

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

全国各区县平均降水月数据!多时间版本可查询

本周给大家推荐一些环境监测数据~ 今天分享的是全国平均降水数据~ 全国平均降水是指全国各个地区降水的平均值。这个值是通过收集和统计全国各地的降雨和降雪数据得出的。由于各地的气候条件和地形不同&#xff0c;因此全国平均降水并不是简单的平均数&#xff0c;而是根据各…

设计模式之原型模式(Prototype)

原型模式 如果已经有一个对象了&#xff0c;你想创建一个对象&#xff0c;而且对象里面的属性和已经存在的对象的属性差不多&#xff0c;就可以使用clone方法 克隆一个出来 实现原型模式需要实现标记型接口Cloneable -->标记型接口 : 里面没有需要实现的方法(空接口) 一般…

SQL学习之增删改查

文章目录 数据库数据类型建表create table插入数据insert into查询数据select from修改数据update set删除数据delete from备份ctas结果插入iis截断表 truncate table修改表结构alter table添加注释 注&#xff1a;本文的SQL语法是基于Oracle数据库操作的&#xff0c;但是基本的…

猫罐头如何选择?最受欢迎的5款猫罐头推荐!新手养猫速看!

对于一个刚入门的养猫新手来说&#xff0c;面对市面上琳琅满目的猫罐头选择确实让人头大。我们总想选到营养价值高的罐头&#xff0c;但又怕猫咪不喜欢吃&#xff0c;还担心选到不安全的产品。 作为家里有5只猫猫的铲屎官来说&#xff0c;养猫的这几年可以说是血泪史了&#x…

保姆级vue-pdf的使用过程

第一步 引入vue-pdf npm install --save vue-pdf 第二步 按照需求我们慢慢进行 01.给你一个pdf文件的url&#xff0c;需要在页面渲染 代码 <template><div><pdfref"pdf":src"url"></pdf></div> </template> <…

scDrug:从scRNA-seq到药物反应预测

scRNA-seq技术允许在转录组水平上对数千个细胞进行测量。scRNA-seq正在成为研究肿瘤微环境中细胞成分及其相互作用的重要工具。scRNA-seq也被用于揭示肿瘤微环境模式与临床结果之间的关联&#xff0c;并在复杂组织中剖析药物治疗的细胞特异性效应。scRNA-seq的最新进展推动了疾…

postswigger 靶场(CSRF)攻略-- 3.令牌验证

靶场地址&#xff1a; https://portswigger.net/web-security/csrf 令牌(token) 验证取决于令牌(token) 的存在 题目中已告知易受攻击的是电子邮件的更改功能&#xff0c;而目标是利用 csrf 漏洞更改受害者的电子邮件地址&#xff0c;最后给出了登录凭据&#xff1a;wiener:pet…

SaaS 电商设计 (三) 如何做大促压测

一.背景&目标 1.1 常见的压测场景 电商大促:一众各大厂的促销活动场景,如:淘宝率先推出的天猫双11,而后京东拉出的京东 618 .还是后续陆陆续续的一些年货节, 3.8 女神节等等.都属于一些常规的电商大促 票务抢购:常见的如承载咱们 80,90 青春回忆的 Jay 的演唱会,还有普罗…

LLM 大模型向量数据库技术架构浅析

▼最近直播超级多&#xff0c;预约保你有收获 近期直播&#xff1a;《LLM 大模型向量数据库技术架构剖析和应用案例实战》 —1— AI 智能时代&#xff0c;开发者需要一个真正的向量数据库吗&#xff1f; 答案很简单&#xff0c;这取决于开发者的应用场景。举个例子&#xff0c;…

内网穿透的应用-如何使用CFImagehost搭建简洁易用的私人图床并公网访问

文章目录 1.前言2. CFImagehost网站搭建2.1 CFImagehost下载和安装2.2 CFImagehost网页测试2.3 cpolar的安装和注册 3.本地网页发布3.1 Cpolar临时数据隧道3.2 Cpolar稳定隧道&#xff08;云端设置&#xff09;3.3.Cpolar稳定隧道&#xff08;本地设置&#xff09; 4.公网访问测…

pdf增强插件 Enfocus PitStop Pro 2022 mac中文版功能介绍

Enfocus PitStop Pro mac是一款 Acrobat 插件&#xff0c;主要用于 PDF 预检和编辑。这个软件可以帮助用户检查和修复 PDF 文件中的错误&#xff0c;例如字体问题、颜色设置、图像分辨率等。同时&#xff0c;Enfocus PitStop Pro 还提供了丰富的编辑工具&#xff0c;可以让用户…

响应式工作范文作文学习参考资料网站模板源码

模板信息&#xff1a; 模板编号&#xff1a;29083 模板编码&#xff1a;UTF8 模板分类&#xff1a;博客、文章、资讯、其他 适合行业&#xff1a;工作范文类企业 模板介绍&#xff1a; 本模板自带eyoucms内核&#xff0c;无需再下载eyou系统&#xff0c;原创设计、手工书写DIVC…

docker小技能

文章目录 I 预备知识Docker组成命名空间 (进程隔离)II 常用命令2.1 案例:流水线docker 部署2.2 删除没有使用的镜像2.3 shell 不打印错误输出2.4 阿里云流水线/jenkins忽略shell步骤中的报错https://www.runoob.com/docker/docker-architecture.html I 预备知识 Docker组成…

【vue】0到1的常规vue3项目起步

创建项目并整理目录 npm init vuelatestjsconfig.json配置别名路径 配置别名路径可以在写代码时联想提示路径 {"compilerOptions" : {"baseUrl" : "./","paths" : {"/*":["src/*"]}} }elementPlus引入 1. 安装e…

openGauss学习笔记-122 openGauss 数据库管理-设置密态等值查询-密态支持函数/存储过程

文章目录 openGauss学习笔记-122 openGauss 数据库管理-设置密态等值查询-密态支持函数/存储过程122.1 创建并执行涉及加密列的函数/存储过程 openGauss学习笔记-122 openGauss 数据库管理-设置密态等值查询-密态支持函数/存储过程 密态支持函数/存储过程当前版本只支持sql和P…

【工程实践】Docker使用记录

前言 服务上线经常需要将服务搬到指定的服务器上&#xff0c;经常需要用到docker&#xff0c;记录工作中使用过dcoker指令。 1.写Dockerfile 1.1 全新镜像 FROM nvidia/cuda:11.7.1-devel-ubuntu22.04ENV WORKDIR/data/Qwen-14B-Chat WORKDIR $WORKDIR ADD . $WORKDIR/RUN ap…

【数组方法reduce】reduce细讲以及模拟重写其他数组扩展方法

学习关键语句: Array.reduce Array.prototype.reduce reduce方法 重写 reduce 方法 1. 写在前面 很多同学 ( 指我自己 ) 在学习其他数组扩展方法时都没那么困难 , 但是到了 reduce 方法时就会显得蠢蠢的 , 所以今天就赶紧将这个方法讲个明白 其实所有的数组扩展方法本质上都…

数据结构 顺序表和链表

1.线性表 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元素的有限序列 线性表是一种在实际中广泛使用的数据结构&#xff0c;常见的线性表&#xff1a;顺序表、链表、栈、队列、字符串.. 线性表在逻辑上是线性结构&#xff0c;也就说是连续的一条直线…

2023年【汽车驾驶员(高级)】证考试及汽车驾驶员(高级)实操考试视频

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 汽车驾驶员&#xff08;高级&#xff09;证考试考前必练&#xff01;安全生产模拟考试一点通每个月更新汽车驾驶员&#xff08;高级&#xff09;实操考试视频题目及答案&#xff01;多做几遍&#xff0c;其实通过汽车…

【备忘】在Nginx服务器安装SSL证书

您可以在Nginx或Tengine服务器上安装SSL证书&#xff0c;实现通过HTTPS安全访问Web服务器。本文介绍如何为Nginx或Tengine服务器安装SSL证书。 重要 本文以CentOS 8.0 64位操作系统、Nginx 1.14.2为例介绍。不同版本的操作系统或Web服务器&#xff0c;部署操作可能有所差异&a…