LLaMA模型之中文词表的蜕变

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

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

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

训练数据准备

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

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

词表训练代码

import sentencepiece as spmspm.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 spmsp = 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 spmllama_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.pieceif piece not in llama_spm_tokens_set:new_p = sp_pb2_model.ModelProto().SentencePiece()new_p.piece = piecenew_p.score = 0llama_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 LlamaTokenizerllama_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

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

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

相关文章

mp4视频批量截取!!!

mp4视频批量截取&#xff01;&#xff01;&#xff01; 问题&#xff1a;如果我们想截取一个mp4视频中的多个片段&#xff0c;一个一个截会很麻烦&#xff01; 可以将想要截取的开始时间和结束时间保存到 excel表 中&#xff0c;进行批量截取。 1、对一个视频&#xff0c;记…

bclinux aarch64 ceph 14.2.10 对象存储 http网关 CEPH OBJECT GATEWAY Civetweb

相关内容 bclinux aarch64 ceph 14.2.10 文件存储 Ceph File System, 需要部署mds&#xff1a; ceph-deploy mds-CSDN博客 ceph-deploy bclinux aarch64 ceph 14.2.10【3】vdbench fsd 文件系统测试-CSDN博客 ceph-deploy bclinux aarch64 ceph 14.2.10【2】vdbench rbd 块设…

unity shaderGraph实例-扫描效果

文章目录 效果展示整体结构各区域内容区域1区域2区域3区域4区域5区域6GraphSetttings注意事项使用方法 效果展示 整体结构 各区域内容 区域1 用场景深度减去顶点的View空间的视野深度&#xff08;Z值&#xff09;&#xff0c;这里Z值需要乘-1是因为从相机看到的物体顶点的视野…

大模型的实践应用6-百度文心一言的基础模型ERNIE的详细介绍,与BERT模型的比较说明

大家好,我是微学AI,今天给大家讲一下大模型的实践应用6-百度文心一言的基础模型ERNIE的详细介绍,与BERT模型的比较说明。在大规模语料库上预先训练的BERT等神经语言表示模型可以很好地从纯文本中捕获丰富的语义模式,并通过微调的方式一致地提高各种NLP任务的性能。然而,现…

el-select组件绑定change怎么获取label和value值

组件中change回调只能获取到value,但是有时候需求是要传两个参数&#xff08;elementui 封装的change只能获取到value,我们可以通过原生事件去获取option值&#xff09;。 如果要在element组件上触发原生事件&#xff0c;一律都得加.native修饰符&#xff0c;否则无法触发事件。…

【论文精读】Pose-Free Neural Radiance Fields via Implicit Pose Regularization

今天读的是一篇发表在ICCV 2023上的文章&#xff0c;作者来自NTU。 文章地址&#xff1a;点击前往 文章目录 Abstract1 Intro2 Related Work3 Preliminary4 Proposed Method4.1 Overall Framework4.2 Scene Codebook Construction4.3 Pose-Guided View Reconstruction4.4 Train…

spring中的DI

【知识要点】 控制反转&#xff08;IOC&#xff09;将对象的创建权限交给第三方模块完成&#xff0c;第三方模块需要将创建好的对象&#xff0c;以某种合适的方式交给引用对象去使用&#xff0c;这个过程称为依赖注入&#xff08;DI&#xff09;。如&#xff1a;A对象如果需要…

分类预测 | Matlab实现PSO-LSTM-Attention粒子群算法优化长短期记忆神经网络融合注意力机制多特征分类预测

分类预测 | Matlab实现PSO-LSTM-Attention粒子群算法优化长短期记忆神经网络融合注意力机制多特征分类预测 目录 分类预测 | Matlab实现PSO-LSTM-Attention粒子群算法优化长短期记忆神经网络融合注意力机制多特征分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1…

贪心 455.分发饼干

455.分发饼干 题目&#xff1a; 小朋友胃口值数组g[i]&#xff0c;饼干尺寸数组 s[j]&#xff0c;当饼干尺寸s[j]大于等于g[i]的时候&#xff0c;对应小朋友被满足&#xff0c;小朋友每一个最多一块饼干 &#xff0c;求给定条件下最多被满足的小朋友数量。 思路&#xff1a;…

智慧农业新篇章:拓世法宝AI智能直播一体机助力乡村振兴与农业可持续发展

随着乡村振兴战略的深入推进&#xff0c;农业发展日益成为国家关注的焦点。在这一大背景下&#xff0c;助农项目的兴起成为支持乡村振兴的一项重要举措。 乡村振兴战略的实施&#xff0c;得益于《关于推动文化产业赋能乡村振兴的意见》、《关于全面推进乡村振兴加快农业农村现…

0x80070002错误代码要怎么解决?修复0x80070002的方法

0x80070002错误代码&#xff0c;这个系统更新相关的错误&#xff0c;经常在进行系统备份或更新时出现&#xff0c;打乱了我们的步调。为了帮助大家解决问题&#xff0c;本文将探讨该错误0x80070002产生的原因&#xff0c;提供详细的解决步骤&#xff0c;并分享预防措施。 一.0x…

Hive入门--学习笔记

1&#xff0c;Apache Hive概述 定义&#xff1a; Hive是由Facebook开源用于解决海量结构化日志的数据统计&#xff0c;它是基于大数据生态圈Hadoop的一个数据仓库工具。 作用&#xff1a; Hive可以用于将结构化的数据文件【映射】为一张表&#xff0c;并提供类SQL查询功能。 H…

leetcode每日一题-周复盘

前言 该系列文章用于我对一周中leetcode每日一题or其他不会的题的复盘总结。 一方面用于自己加深印象&#xff0c;另一方面也希望能对读者的算法能力有所帮助&#xff0c; 同时也希望能帮助同样坚持刷题的同学加深印象~ 该复盘对我来说比较容易的题我会复盘的比较粗糙&#…

clip4clip:an empirical study of clip for end to end video clip retrieval

广告深度学习计算&#xff1a;阿里妈妈智能创意服务优化使用CPU/GPU分离的多进程架构&#xff0c;加速阿里妈妈智能创意服务。https://mp.weixin.qq.com/s/_pjhXrUZVzFRtiwG2LhnkwCLIP4Clip: CLIP 再下一城&#xff0c;利用CLIP实现视频检索 - 知乎前言&#xff1a; OpenAI 的论…

ios 对话框UIAlertController放 tableview

//强弱引用 #define kWeakSelf(type)__weak typeof(type)weak##type type; -(void) showUIAlertTable {kWeakSelf(self)UIAlertController *alert [UIAlertController alertControllerWithTitle:NSLocalizedString("select_stu", nil) message:nil prefer…

Docker 和 Kubernetes:技术相同和不同之处

Docker和Kubernetes是当今最流行的容器化技术解决方案。本文将探讨Docker和Kubernetes的技术相似之处和不同之处&#xff0c;以帮助读者更好地理解这两种技术。 Docker和Kubernetes&#xff1a;当今最流行的容器化技术解决方案 在当今的IT领域&#xff0c;Docker和Kubernetes无…

ef core code first pgsql

在使用efcode来操作pgsql的时候&#xff0c;总有些基础配置流程项目建立完之后后面就很少用&#xff0c;总是忘掉&#xff0c;写个文档记忆一下吧。基于net 6.0。 1.创建一个mvc项目和一个EF类库 2.在类库里面安装依赖dll Microsoft.EntityFrameworkCore.Design 需要添加的…

ESP32 Arduino实战基础篇-使用中断和定时器

本教程介绍如何使用 PIR 运动传感器通过 ESP32 检测运动。在此示例中,当检测到运动(触发中断)时,ESP32 会启动计时器并打开 LED 并持续预定义的秒数。当计时器倒计时结束时,LED 自动关闭。 通过这个例子,我们还将探讨两个重要的概念:中断和定时器。 中断介绍 要使用 P…

【MySQL】表的增删改查(基础)

一、新增&#xff08;Create&#xff09; 先创建一张表&#xff1a; create table student (id int,sn int comment 学号,name varchar(20),email varchar(20));1.1 单行数据 全列插入 插入两条记录&#xff0c;value_list 数量必须和定义表的列的数量及顺序一致 insert i…

How to design a database storage model for water network information system

How to design a database storage model for water network information system 1、领域划分2、基础域2.1、概述2.2、E-R图2.3、SQL脚本 1、领域划分 序号中文名称英文名称代号备注1基础域basea012资产域assertsa023监测域monitora034水权域quotaa045灌溉域irrigationa056排涝…