大模型面试准备(十一):怎样让英文大语言模型可以很好的支持中文?

节前,我们组织了一场算法岗技术&面试讨论会,邀请了一些互联网大厂朋友、参加社招和校招面试的同学,针对大模型技术趋势、大模型落地项目经验分享、新手如何入门算法岗、该如何备战、面试常考点分享等热门话题进行了深入的讨论。


合集在这里:《大模型面试宝典》(2024版) 正式发布!


如何构建中文tokenization?本篇文章手把手教你:

  1. 使用 sentencepiece 训练一个中文的词表。

  2. 使用 transformers 加载 sentencepiece 模型。

  3. 合并中英文的词表,并使用 transformers 使用合并后的词表。

  4. 在模型中使用新词表。

技术交流群

前沿技术资讯、算法交流、求职内推、算法竞赛、面试交流(校招、社招、实习)等、与 10000+来自港科大、北大、清华、中科院、CMU、腾讯、百度等名校名企开发者互动交流~

我们建了算法岗技术与面试交流群, 想要进交流群、需要源码&资料、提升技术的同学,可以直接加微信号:mlc2040。加的时候备注一下:研究方向 +学校/公司+CSDN,即可。然后就可以拉你进群了。

方式①、微信搜索公众号:机器学习社区,后台回复:加群
方式②、添加微信号:mlc2040,备注:技术交流

用通俗易懂方式讲解系列

  • 《大模型面试宝典》(2024版) 正式发布!
  • 《大模型实战宝典》(2024版)正式发布!
  • 大模型面试准备(一):LLM主流结构和训练目标、构建流程
  • 大模型面试准备(二):LLM容易被忽略的Tokenizer与Embedding
  • 大模型面试准备(三):聊一聊大模型的幻觉问题
  • 大模型面试准备(四):大模型面试必会的位置编码
  • 大模型面试准备(五):图解 Transformer 最关键模块 MHA
  • 大模型面试准备(六):一文讲透生成式预训练模型 GPT、GPT2、GPT3
  • 大模型面试准备(七):ChatGPT 的内核 InstructGPT 详细解读
  • 大模型面试准备(八):一文详解国产大模型导师 LLaMA v1和v2
  • 大模型面试准备(九):简单透彻理解MoE
  • 大模型面试准备(十):大模型数据处理方法及优秀的开源数据介绍

一、为什么需要构建中文tokenization?

大语言模型到目前为止仍呈现百家争鸣趋势,但是从根本来看,主要以基于 llama 家族的模型和基于 glm 家族的模型为主。不过目前大多数 LLMs 还是以基于 llama 家族的模型为主,然而原始基于 llama 家族的模型主要训练语料为英文语料,中文语料占比较少,直接导致基于 llama 家族的模型对于中文的支持不太友好。

那么有什么办法能够解决基于 llama 家族的模型对中文支持不太友好的问题呢?

本文利用《斗破苍穹》作为语料,介绍如何去扩充 vocab 里面的词以对中文进行 token 化

二、如何对原始数据进行预处理?

《斗破苍穹》原始数据样例如下:

    《斗破苍穹》来自: ===上架感言===又一次上架了,这次比上次还激动,甚至激动到了上传了章节却不知道发出来的地步。尴尬,关于新书,上架前成绩好得有些出乎土豆的意料,对于这份厚硕的成绩,土豆心里还真有几分惶恐与忐忑,虽说曾经有人说土豆是刷出来的数据,对于这些留言,我也并未太过在意,别的我不知道,我唯一能知道的,就是人在做,天在看!究竟刷没刷,自己心中有杆秤就能衡量,问心无愧,何惧留言?呵呵,在这里很感谢赐予土豆这种厚硕成绩的诸位书友,真的,很感谢你们。...

上文摘取部分《斗破苍穹》 原始数据,从数据中可以看出,数据中包含大量换行和无效内容,所以需要对《斗破苍穹》原始数据进行预处理,将每一行转化为一句或多句话,同时过滤掉换行和无效内容。

代码讲解

# step 1: 《斗破苍穹》 原始数据 加载
with open("data/《斗破苍穹》.txt", "r", encoding="utf-8") as fp:data = fp.read().strip().split("\n")# step 2: 将每一行转化为一句或多句话,同时过滤掉 换行 和 无效内容
sentences = []
for d in data:d = d.strip()if "===" in d or len(d) == 0 or d == "《斗破苍穹》来自:":continuesentences.append(d)# step 3: 数据写入
with open("data/corpus.txt", "w", encoding="utf-8") as fp:fp.write("\n".join(sentences))

预处理之后得到的 data/corpus.txt 如下所示

    又一次上架了,这次比上次还激动,甚至激动到了上传了章节却不知道发出来的地步。尴尬,关于新书,上架前成绩好得有些出乎土豆的意料,对于这份厚硕的成绩,土豆心里还真有几分惶恐与忐忑,虽说曾经有人说土豆是刷出来的数据,对于这些留言,我也并未太过在意,别的我不知道,我唯一能知道的,就是人在做,天在看!...

三、如何构建中文词库?

得到语料库 corpus.txt 之后,我们需要利用该 corpus.txt 构建中文的词库。这里采用 sentencepiece 训练中文词库。

  1. sentencepiece 安装
pip install sentencepiece
  1. 训练中文词库
  import sentencepiece as spmspm.SentencePieceTrainer.train(input='data/corpus.txt',model_prefix='tokenizer',vocab_size=50000,user_defined_symbols=['foo', 'bar'],character_coverage=1.0,model_type="bpe",)

参数含义介绍:

  • input:指定输入文本文件的路径或者是一个目录,可以指定多个输入文件或目录。其中每一行可以是一句话或者多句话。

  • tokenizer:保存的模型的名称前缀。

  • vocab_size:设置的词表大小。

  • user_defined_symbols:用于指定用户自定义的符号。这些符号将会被视为单独的 Token,不会被拆分成子词。这个参数的作用是将一些用户定义的特殊符号作为一个整体加入到生成的词表中,以便于后续的模型使用。这里我们简单进行了测试。

  • model_type: 指定模型的类型,有三种可选参数:unigram, bpe, char.word。

  • character_coverage: 指定覆盖字符的数量,可以理解为限制字符集的大小。默认值为 1.0,即覆盖全部字符。

  • unk_id: 指定未登录词的 ID 号,即在词表中为未登录词分配一个整数 ID。默认值为 0。

  • bos_id: 指定句子开头符号的 ID 号,即在词表中为句子开头符号分配一个整数 ID。默认值为 1。

  • eos_id: 指定句子结束符号的 ID 号,即在词表中为句子结束符号分配一个整数 ID。默认值为 2。

  • pad_id: 指定填充符号的 ID 号,即在词表中为填充符号分配一个整数 ID。默认值为 -1,即不使用填充符号。

运行后会得到 tokenizer.model 和 tokenizer.vocab 两个文件。

我们来看看词表 tokenizer.vocab 里面都有什么:除了一些特殊符号外,还有我们自定义的 foo 和 bar,其余的一些词是 BPE 训练得到,如下所示:

<unk> 0
<s> 0
</s> 0
foo 0
bar 0
萧炎 -0
.. -1
▁“ -2
也是 -3
便是 -4
了一 -5
。” -6
...

四、如何加载 sentencepiece 模型?

这里我们使用 chinese_bpe.py

import osos.environ["PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION"] = "python"
from transformers import LlamaTokenizer
from sentencepiece import sentencepiece_model_pb2 as sp_pb2_model
import sentencepiece as spm
from tokenization import ChineseTokenizerchinese_sp_model_file = "sentencepisece_tokenizer/tokenizer.model"# load
chinese_sp_model = spm.SentencePieceProcessor()
chinese_sp_model.Load(chinese_sp_model_file)chinese_spm = sp_pb2_model.ModelProto()
chinese_spm.ParseFromString(chinese_sp_model.serialized_model_proto())## Save
output_dir = './transformers_tokenizer/chinese/'
os.makedirs(output_dir, exist_ok=True)
with open(output_dir + 'chinese.model', 'wb') as f:f.write(chinese_spm.SerializeToString())
tokenizer = ChineseTokenizer(vocab_file=output_dir + 'chinese.model')tokenizer.save_pretrained(output_dir)
print(f"Chinese tokenizer has been saved to {output_dir}")# Test
chinese_tokenizer = ChineseTokenizer.from_pretrained(output_dir)
print(tokenizer.all_special_tokens)
print(tokenizer.all_special_ids)
print(tokenizer.special_tokens_map)
text = '''白日依山尽,黄河入海流。欲穷千里目,更上一层楼。
The primary use of LLaMA is research on large language models, including'''
print("Test text:\n", text)
print(f"Tokenized by Chinese tokenizer:{chinese_tokenizer.tokenize(text)}")

执行python chinese_bpe.py后得到如下结果:

Chinese tokenizer has been saved to ./transformers_tokenizer/chinese/
['<s>', '</s>', '<unk>']
[1, 2, 0]
{'bos_token': '<s>', 'eos_token': '</s>', 'unk_token': '<unk>'}
Test text:白日依山尽,黄河入海流。欲穷千里目,更上一层楼。
The primary use of LLaMA is research on large language models, including
Tokenized by Chinese-LLaMA tokenizer:['▁', '白日', '依', '山', '尽', ',', '黄', '河', '入', '海', '流', '。', '欲', '穷', '千里', '目', ',', '更', '上一层', '楼', '。', '▁', 'T', 'h', 'e', '▁', 'p', 'r', 'i', 'm', 'a', 'r', 'y', '▁', 'u', 's', 'e', '▁', 'o', 'f', '▁', 'LL', 'a', 'MA', '▁i', 's', '▁', 'r', 'e', 's', 'e', 'a', 'r', 'ch', '▁', 'o', 'n', '▁', 'l', 'a', 'r', 'g', 'e', '▁', 'l', 'an', 'g', 'u', 'a', 'g', 'e', '▁', 'm', 'o', 'd', 'e', 'l', 's', ',', '▁i', 'n', 'c', 'lu', 'd', 'i', 'ng']

注:其中 ChineseTokenizer 这里参考了 llama 模型里面使用的方法,并稍微做些修改,代码如下所示:

# coding=utf-8
# Copyright 2022 EleutherAI and the HuggingFace Inc. team. All rights reserved.
#
# This code is based on EleutherAI's GPT-NeoX library and the GPT-NeoX
# and OPT implementations in this library. It has been modified from its
# original forms to accommodate minor architectural differences compared
# to GPT-NeoX and OPT used by the Meta AI team that trained the model.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License."""Tokenization classes for LLaMA."""
import os
from shutil import copyfile
from typing import Any, Dict, List, Optional, Tupleimport sentencepiece as spmfrom transformers.tokenization_utils import AddedToken, PreTrainedTokenizer
from transformers.utils import logginglogger = logging.get_logger(__name__)VOCAB_FILES_NAMES = {"vocab_file": "tokenizer.model"}# PRETRAINED_VOCAB_FILES_MAP = {
#     "vocab_file": {
#         "hf-internal-testing/llama-tokenizer": "https://huggingface.co/hf-internal-testing/llama-tokenizer/resolve/main/tokenizer.model",
#     },
#     "tokenizer_file": {
#         "hf-internal-testing/llama-tokenizer": "https://huggingface.co/hf-internal-testing/llama-tokenizer/resolve/main/tokenizer_config.json",
#     },
# }
# PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES = {
#     "hf-internal-testing/llama-tokenizer": 2048,
# }class ChineseTokenizer(PreTrainedTokenizer):"""Construct a Llama tokenizer. Based on byte-level Byte-Pair-Encoding.Args:vocab_file (`str`):Path to the vocabulary file."""vocab_files_names = VOCAB_FILES_NAMES# pretrained_vocab_files_map = PRETRAINED_VOCAB_FILES_MAP# max_model_input_sizes = PRETRAINED_POSITIONAL_EMBEDDINGS_SIZESmodel_input_names = ["input_ids", "attention_mask"]def __init__(self,vocab_file,unk_token="<unk>",bos_token="<s>",eos_token="</s>",pad_token=None,sp_model_kwargs: Optional[Dict[str, Any]] = None,add_bos_token=True,add_eos_token=False,clean_up_tokenization_spaces=False,**kwargs,):self.sp_model_kwargs = {} if sp_model_kwargs is None else sp_model_kwargsbos_token = AddedToken(bos_token, lstrip=False, rstrip=False) if isinstance(bos_token, str) else bos_tokeneos_token = AddedToken(eos_token, lstrip=False, rstrip=False) if isinstance(eos_token, str) else eos_tokenunk_token = AddedToken(unk_token, lstrip=False, rstrip=False) if isinstance(unk_token, str) else unk_tokenpad_token = AddedToken(pad_token, lstrip=False, rstrip=False) if isinstance(pad_token, str) else pad_tokensuper().__init__(bos_token=bos_token,eos_token=eos_token,unk_token=unk_token,pad_token=pad_token,add_bos_token=add_bos_token,add_eos_token=add_eos_token,sp_model_kwargs=self.sp_model_kwargs,clean_up_tokenization_spaces=clean_up_tokenization_spaces,**kwargs,)self.vocab_file = vocab_fileself.add_bos_token = add_bos_tokenself.add_eos_token = add_eos_tokenself.sp_model = spm.SentencePieceProcessor(**self.sp_model_kwargs)self.sp_model.Load(vocab_file)def __getstate__(self):state = self.__dict__.copy()state["sp_model"] = Nonereturn statedef __setstate__(self, d):self.__dict__ = dself.sp_model = spm.SentencePieceProcessor(**self.sp_model_kwargs)self.sp_model.Load(self.vocab_file)@propertydef vocab_size(self):"""Returns vocab size"""return self.sp_model.get_piece_size()def get_vocab(self):"""Returns vocab as a dict"""vocab = {self.convert_ids_to_tokens(i): i for i in range(self.vocab_size)}vocab.update(self.added_tokens_encoder)return vocabdef _tokenize(self, text):"""Returns a tokenized string."""return self.sp_model.encode(text, out_type=str)def _convert_token_to_id(self, token):"""Converts a token (str) in an id using the vocab."""return self.sp_model.piece_to_id(token)def _convert_id_to_token(self, index):"""Converts an index (integer) in a token (str) using the vocab."""token = self.sp_model.IdToPiece(index)return tokendef convert_tokens_to_string(self, tokens):"""Converts a sequence of tokens (string) in a single string."""current_sub_tokens = []out_string = ""prev_is_special = Falsefor i, token in enumerate(tokens):# make sure that special tokens are not decoded using sentencepiece modelif token in self.all_special_tokens:if not prev_is_special and i != 0:out_string += " "out_string += self.sp_model.decode(current_sub_tokens) + tokenprev_is_special = Truecurrent_sub_tokens = []else:current_sub_tokens.append(token)prev_is_special = Falseout_string += self.sp_model.decode(current_sub_tokens)return out_stringdef save_vocabulary(self, save_directory, filename_prefix: Optional[str] = None) -> Tuple[str]:"""Save the vocabulary and special tokens file to a directory.Args:save_directory (`str`):The directory in which to save the vocabulary.Returns:`Tuple(str)`: Paths to the files saved."""if not os.path.isdir(save_directory):logger.error(f"Vocabulary path ({save_directory}) should be a directory")returnout_vocab_file = os.path.join(save_directory, (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["vocab_file"])if os.path.abspath(self.vocab_file) != os.path.abspath(out_vocab_file) and os.path.isfile(self.vocab_file):copyfile(self.vocab_file, out_vocab_file)elif not os.path.isfile(self.vocab_file):with open(out_vocab_file, "wb") as fi:content_spiece_model = self.sp_model.serialized_model_proto()fi.write(content_spiece_model)return (out_vocab_file,)def build_inputs_with_special_tokens(self, token_ids_0, token_ids_1=None):bos_token_id = [self.bos_token_id] if self.add_bos_token else []eos_token_id = [self.eos_token_id] if self.add_eos_token else []output = bos_token_id + token_ids_0 + eos_token_idif token_ids_1 is not None:output = output + bos_token_id + token_ids_1 + eos_token_idreturn outputdef get_special_tokens_mask(self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None, already_has_special_tokens: bool = False) -> List[int]:"""Retrieve sequence ids from a token list that has no special tokens added. This method is called when addingspecial tokens using the tokenizer `prepare_for_model` method.Args:token_ids_0 (`List[int]`):List of IDs.token_ids_1 (`List[int]`, *optional*):Optional second list of IDs for sequence pairs.already_has_special_tokens (`bool`, *optional*, defaults to `False`):Whether or not the token list is already formatted with special tokens for the model.Returns:`List[int]`: A list of integers in the range [0, 1]: 1 for a special token, 0 for a sequence token."""if already_has_special_tokens:return super().get_special_tokens_mask(token_ids_0=token_ids_0, token_ids_1=token_ids_1, already_has_special_tokens=True)bos_token_id = [1] if self.add_bos_token else []eos_token_id = [1] if self.add_eos_token else []if token_ids_1 is None:return bos_token_id + ([0] * len(token_ids_0)) + eos_token_idreturn (bos_token_id+ ([0] * len(token_ids_0))+ eos_token_id+ bos_token_id+ ([0] * len(token_ids_1))+ eos_token_id)def create_token_type_ids_from_sequences(self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None) -> List[int]:"""Creates a mask from the two sequences passed to be used in a sequence-pair classification task. An ALBERTsequence pair mask has the following format:```0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1| first sequence    | second sequence |```if token_ids_1 is None, only returns the first portion of the mask (0s).Args:token_ids_0 (`List[int]`):List of ids.token_ids_1 (`List[int]`, *optional*):Optional second list of IDs for sequence pairs.Returns:`List[int]`: List of [token type IDs](../glossary#token-type-ids) according to the given sequence(s)."""bos_token_id = [self.bos_token_id] if self.add_bos_token else []eos_token_id = [self.eos_token_id] if self.add_eos_token else []output = [0] * len(bos_token_id + token_ids_0 + eos_token_id)if token_ids_1 is not None:output += [1] * len(bos_token_id + token_ids_1 + eos_token_id)return output

不难发现其实里面使用了一些 sentencepiece 里面的函数。

五、如何合并英文词表和中文词表?

这里我们使用 chinese_llama_bpe.py

import osos.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 = "transformers_tokenizer/llama/tokenizer.model"
chinese_sp_model_file = "sentencepisece_tokenizer/tokenizer.model"# load
llama_tokenizer = LlamaTokenizer.from_pretrained(llama_tokenizer_dir)
llama_spm = sp_pb2_model.ModelProto()
llama_spm.ParseFromString(llama_tokenizer.sp_model.serialized_model_proto())
chinese_spm = sp_pb2_model.ModelProto()
chinese_sp_model = spm.SentencePieceProcessor()
chinese_sp_model.Load(chinese_sp_model_file)
chinese_spm.ParseFromString(chinese_sp_model.serialized_model_proto())# print number of tokens
print(len(llama_tokenizer), len(chinese_sp_model))
print(llama_tokenizer.all_special_tokens)
print(llama_tokenizer.all_special_ids)
print(llama_tokenizer.special_tokens_map)## Add Chinese tokens to LLaMA tokenizer
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)}")## Save
output_sp_dir = 'transformers_tokenizer/llama_chinese'
output_hf_dir = 'transformers_tokenizer/llama_chinese'  # 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)
print(f"Chinese-LLaMA tokenizer has been saved to {output_hf_dir}")# Test
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 = '''白日依山尽,黄河入海流。欲穷千里目,更上一层楼。
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)}")
print(f"Tokenized by Chinese-LLaMA tokenizer:{chinese_llama_tokenizer.tokenize(text)}")

上面的代码最核心的是以下这一块,该代码的作用是将原始词表中没有的新词加入词表中。

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)

执行python chinese_llama_bpe.py得到如下结果:

32000 50000
['<s>', '</s>', '<unk>']
[1, 2, 0]
{'bos_token': '<s>', 'eos_token': '</s>', 'unk_token': '<unk>'}
32000
Before:32000
New model pieces: 81163
Chinese-LLaMA tokenizer has been saved to transformers_tokenizer/llama_chinese
['<s>', '</s>', '<unk>']
[1, 2, 0]
{'bos_token': '<s>', 'eos_token': '</s>', 'unk_token': '<unk>'}
Test text:白日依山尽,黄河入海流。欲穷千里目,更上一层楼。
The primary use of LLaMA is research on large language models, including
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']
Tokenized by Chinese-LLaMA tokenizer:['▁白', '日', '依', '山', '尽', ',', '黄', '河', '入', '海', '流', '。', '欲', '穷', '千里', '目', ',', '更', '上一层', '楼', '。', '<0x0A>', 'The', '▁primary', '▁use', '▁of', '▁L', 'La', 'MA', '▁is', '▁research', '▁on', '▁large', '▁language', '▁models', ',', '▁including']

我们会发现再加入了我们定义的词表后确实能够对中文进行分词了。

六、怎么使用修改后的词表?

如果我们重新从头开始训练,那么其实使用起来很简单:

config = AutoConfig.from_pretrained(...)
tokenizer = LlamaTokenizer.from_pretrained(...)
model = LlamaForCausalLM.from_pretrained(..., config=config)
model_vocab_size = model.get_output_embeddings().weight.size(0)
model.resize_token_embeddings(len(tokenizer))

但是如果我们想要保留原始模型 embedding 的参数,那么我们可以这么做:

  1. 找到新词表和旧词表id之间的映射关系。

  2. 将模型里面新词表里面包含的旧词表用原始模型的embedding替换。

  3. 如果新词在旧词表里面没有出现就进行相应的初始化再进行赋值。

比如 transformers 库中的 llama 是这么进行初始化的:

 def _init_weights(self, module):std = self.config.initializer_rangeif isinstance(module, nn.Linear):module.weight.data.normal_(mean=0.0, std=std)if module.bias is not None:module.bias.data.zero_()elif isinstance(module, nn.Embedding):module.weight.data.normal_(mean=0.0, std=std)if module.padding_idx is not None:module.weight.data[module.padding_idx].zero_()

参考

https://github.com/taishan1994/sentencepiece_chinese_bpe

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

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

相关文章

设计模式(11):适配器模式

一.什么使适配器模式&#xff1f; 将一个类的接口转换成客户希望的另外一个接口&#xff0c;Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。 二.模式中的角色 目标角色(Target)&#xff1a; 客气所期待的接口。目标可以是具体的或抽象的类&#…

C++20中的jthread

一、多线程开发 c11以前&#xff0c;是不包含线程库的&#xff0c;开发多线程&#xff0c;必须使用OS系统自带的线程API&#xff0c;这就导致了很多问题&#xff0c;最主要的是&#xff0c;跨平台的开发&#xff0c;一般要保持几个主流应用的库的代码支持&#xff0c;特别是对…

关于缓存的一些问题

关于缓存的一些问题 1、缓存穿透 什么是缓存穿透&#xff1a; 缓存穿透指的是在使用缓存系统的过程中&#xff0c;对于不存在的数据不断地进行查询请求&#xff0c;导致这些请求都无法从缓存中获取到数据&#xff0c;最终达到了绕过缓存的目的&#xff0c;直接访问后端数据源…

C语言-文件操作函数基础+进阶标准输入流输出流

学习的流程 ———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————…

RedisDesktopManager 安装

简介&#xff1a;安装redis可视化工具 一、下载压缩包 Redis 可视化工具 链接&#xff1a;https://pan.baidu.com/s/1P2oZx9UpQbXDsxJ3GPUeOQ 提取码&#xff1a;6rft Redis 命令窗口版本 链接&#xff1a;https://pan.baidu.com/s/1mIuxCEWwD__aoqp1Cx8MFQ 提取码&#xf…

Lucene及概念介绍

Lucene及概念介绍 基础概念倒排索引索引合并分析查询语句的构成 基础概念 Document&#xff1a;我们一次查询或更新的载体&#xff0c;对比于实体类 Field&#xff1a;字段&#xff0c;是key-value格式的数据&#xff0c;对比实体类的字段 Item&#xff1a;一个单词&#xff0…

如何做一个知识博主? 行动

任何事情都需要经过两次创造 提前做一个预演&#xff0c;计划 【以一个计划开始】 你的解决方案究竟将怎样应用? 要根据目标想到所有的关键因素并列出所有的步骤和所有重要的细节。 需要想清楚这个事情成事最核心的胜负手关键因素&#xff1f; 【抓关键】 涨粉&#xff1a…

Decoupled Multimodal Distilling for Emotion Recognition 论文阅读

Decoupled Multimodal Distilling for Emotion Recognition 论文阅读 Abstract1. Introduction2. Related Works2.1. Multimodal emotion recognition2.2. Knowledge distillation3. The Proposed Method3.1. Multimodal feature decoupling3.2. GD with Decoupled Multimodal …

简单易懂的SQL添加数据教程

1. 引言&#xff1a; SQL&#xff08;Structured Query Language&#xff09;是一种处理关系型数据库的标准语言&#xff0c;包括插入&#xff08;INSERT)、更新&#xff08;UPDATE&#xff09;、删除&#xff08;DELETE&#xff09;等操作。在数据库操作中&#xff0c;添加数…

基于muduo网络库实现的集群聊天服务器

目录 项目内容开发环境安装说明技术介绍项目目录数据库设计项目介绍启动服务器启动客户端注册账号登录成功一对一聊天业务创建群聊业务加入群聊业务群聊业务添加好友业务离线消息存储业务 特殊说明 &#xff01;&#xff01;&#xff01;项目是照着腾讯课堂施磊老师的视频学习&…

NC20128 不重复数字

题目描述 给出N个数&#xff0c;要求把其中重复的去掉&#xff0c;只保留第一次出现的数。 例如&#xff0c;给出的数为1 2 18 3 3 19 2 3 6 5 4&#xff0c;其中2和3有重复&#xff0c;去除后的结果为1 2 18 3 19 6 5 4。 输入描述: 输入第一行为正整数T&#xff0c;表示…

04---java面试八股文——spring-----注解-------10题

31、ComponentScan注解的作用 ComponentScan 注解用于指定 Spring 容器在启动时要扫描的基础包路径&#xff0c;以及要扫描的包路径下应该被自动注册为 Spring bean 的类。 具体来说&#xff0c;ComponentScan 注解的作用有以下几个方面&#xff1a; 组件扫描&#xff1a;Comp…

docker部署DOS游戏

下载镜像 docker pull registry.cn-beijing.aliyuncs.com/wuxingge123/dosgame-web-docker:latestdocker-compose部署 vim docker-compose.yml version: 3 services:dosgame:container_name: dosgameimage: registry.cn-beijing.aliyuncs.com/wuxingge123/dosgame-web-docke…

How to install JDK on mac

文章目录 1. Install JDK on mac2. zshenv, zshrc, zprofile3. 查看java环境变量配置 1. Install JDK on mac Installation of the JDK on macOS 2. zshenv, zshrc, zprofile How Do Zsh Configuration Files Work? 3. 查看java环境变量配置 open Terminal&#xff0c;cd…

02-JDK新特性-Lambda表达式

JDK新特性 Lambda表达式 什么是Lambda表达式 Lambda表达式是一个匿名代码块&#xff0c;用于简单的传递一段代码片段。 Lambda表达式标准格式 格式&#xff1a;(形式参数) -> {代码块} 形式参数 如果有多个参数&#xff0c;参数只见用逗号隔开&#xff1b;如果没有&…

普通数据库索引与搜索引擎的索引有何区别

普通数据库索引&#xff0c;如关系型数据库&#xff08;RDBMS&#xff09;中的B树&#xff08;B-tree&#xff09;或哈希索引&#xff0c;与搜索引擎使用的倒排索引&#xff08;Inverted Index&#xff09;之间存在几个关键区别&#xff1a; 数据结构&#xff1a; 普通数据库索…

【Linux 10】环境变量

文章目录 &#x1f308; Ⅰ 命令行参数⭐ 1. main 函数的参数⭐ 2. main 函数参数的意义⭐ 3. 查看 argv 数组的内容⭐ 4. 命令行参数结论⭐ 5. 为什么要有命令行参数⭐ 6. 命令行参数传递由谁执行 &#x1f308; Ⅱ 环境变量基本概念⭐ 1. 常见环境变量 &#x1f308; Ⅲ 查看…

macOS Catalina for mac (macos 10.15系统)v10.15.7正式版

macOS Catalina是苹果公司专为麦金塔电脑推出的桌面操作系统&#xff0c;是macOS的第16个主要版本。它继承了苹果一贯的优雅与高效&#xff0c;不仅引入了分割视图和侧边栏&#xff0c;还带来了全新的音乐和播客应用&#xff0c;极大地提升了用户体验。在隐私保护和安全性方面&…

【Laravel】07 快速套用一个网站模板

【Laravel】07 快速套用一个网站模板 1. 新增post表2.补充 &#xff1a;生成Model、Controller、迁移文件3. 使用php artisan tinker4. 网站模板下载 课程地址 1. 新增post表 在Model中创建Post (base) ➜ example-app php artisan make:model Post Model created successfu…

ubuntu如何升级Cmake

在编译最新版的OBS时提示我cmake版本太老了&#xff1a; CMake Error at CMakeLists.txt:1 (cmake_minimum_required):CMake 3.22 or higher is required. You are running version 3.20.2先看下没升级前的版本&#xff1a; 升级一下cmake 1、下载需要的版本 https://cmake…