欢迎来到池州三陆五信息科技有限公司- 未来科技

微信
手机版
网站地图

BERT1美元训练,教我如何青梅谷歌tpu羊毛

2023-04-17 09:39:12 栏目 : 移动互联 围观 : 0次

BERT是谷歌去年发售的NLP模型,发售后在各种各样的测试中压倒了竞争对手。BERT是开源。只是可惜训练BERT的价格很高,让人望而生畏。

到目前为止,我花了4天时间训练了64个TPU,在“谷歌”中,我用并行计算优化了1个多小时就可以完成,但所需的TPU数量一下子增加了,达到了1024个,令人惊异。

那么,总共多少钱呢谷歌云TPU的使用价格是每小时6.5美元,但是到训练完成为止要花将近4万美元,所以是破格的。

现在有一只羊毛告诉我了。有人在培养基上找到了拔谷歌羊毛的方法。只需1美元就可以训练BERT。模型留在你的谷歌云盘以后可以用。

准备好了

为了拔出谷歌的毛,Google云存储是必要的。按照“Google”云TPU快速入门指南创建“Google”云平台和“Google”云存储帐户。全新谷歌为云平台用户提供300美元的免费服务

GoogleColab并不是为了执行长时间的工作而设计的,而是每8小时中断一次。对于不间断训练,试着考虑一下收费不间断地使用TPUv2的方法怎么样。

也就是说,如果使用Colab TPU,可以以1美元的价格在克劳德磁盘上保存模型和数据,以几乎可以忽略的成本从一开始就可以对BERT模型进行事前训练。

以下代码在Colab Jupyter环境中运行

首先,安装培训模型所需的软件包。Jupyter可以使用直接从笔记本电脑运行的bash命令#8216。是!#8217。:来修改标记元素的显示属性。

来修改标记元素的显示属性!pip install sentencepiece!git clone https://github.com/Google-调查/BERT

导入包并允许在“谷歌”云中:

import sysimport jsonimport nltkimport randomiport loggingimport tensorflow astfimport sentencepiece asspmfromglob import glob glob[Google]。colab import auth,drivefrom tensorflow.keras.utils import progbarsys.path.append ([BERT])from [BERT] import modeling, optimization,tokenizationfrom[BERT]。run_pretraining import input_f _builder,模型_f _builderauth.authenticate_用户()#configure logginglog=。loging.getlogger('tensorflow')log.setlevel(loging.info)#create formatter and add it to the handlersformatter=loging.formatter('%(asctime)s:%(message)s')sh=loging.streamhandler()sh.setlevel(loging.info)sh.setformatter(formatter)log.handlers=[LAsh]COB_TPU_ADDR'in os.environ:log.info(Using TPU runtime)you_TPU = True TPU_ address='grpc://'+os.environ['COLAB_TPU_ADDR']withtf.session(TPU_ADDRESS)as Session:log.info('TPU address is'+TPU_address)#Upload credentials to TPU。with open('/content/adc.json', 'r') as f:auth_info = json . load (f) tf . contrib.为.configure_gcs (session credentials = auth_info)、else:log.warning('Not connected to TPU runtime') you _TPU=False。

然后从网页获取文本数据的语料库。在实验中,我们使用了包含65种语言的数据集“OpenSubtitles”。

与一般的文本数据集(如维基百科)不同,它不需要复杂的预处理。

available = { ' af '、 ' ar '、 ' bg '、 ' bn '、 ' br / '、 ' bs '、 ' ca '、 ' cs '、 ' da '、' de '、 ' el '、 ' en '、 ' eo '、 ' es '、 ' et '、 ' eu '、 ' fa '、 ' fi '、 ' fr '、 '【',*he','高','hr','hu','hy','id','is','it','ja','ka 32','kk','ko','lt',':','mk使役','ml','ms','nl','no','pl','pt','pt_br','ro','ru','si','sk',','sl','s','sq','sq'“ta”、“te”、“th原始”、“tl '、 ' tr '、 ' lig '、 ' ur '、' / '、 ' ze_en '、 ' ze_zh '、 ' zh '、 ' zh_cn '、'z _en','z _tw','z _zh'}朗格_code=en#@param{type:string}assert朗格_是Code in AVAILABLE,Invalid language code selected!wget http://opus.nlpl.eu/download.phpf=opensubtitles/v2016/mono/opensubtitles.raw. ' $ lang_code'.动画-o dataset。rmvb.动画!我是gzip-d dataset.txt.gz!tail dataset.txt

你可以从设置代码中选择你喜欢的语言。默认情况下,代码仅使用整个语料库的一部分进行演示。在实际训练模型时,请务必去掉demomode复选框,使用大100倍的数据集。

当然,100M的数据是相当的BERT基本模型的训练。

if demomode: CORPUS_SIZE = 1000000else: CORPUS_SIZE=100000#@param{type:integer!(head-n$CORPUS_SIZE dataset.txt)gt。subdataset.txt!mvsubdataset.txt

下载的原始文本数据包含标点符号、大写字母和非UTF符号,但在继续下一步之前将其删除。在推论期间将相同的过程应用于新数据

如果需要不同的预处理(例如,在推理过程中可能会出现大写字母或标点符号),请修改以下代码:。

regex_tokenizer = nltk.RegexpTokenizer("\w+")def normalize_text(text): # lowercase text text = str(text).lower() # remove non-UTF text = text.encode("utf-8", "ignore").decode() # remove punktuation symbols text = " ".join(regex_tokenizer.tokenize(text) return textdef count_lines(filename): count = 0 with open(filename) as fi: for line in fi: count += 1 return count

在此预处理整个数据集。

RAW_DATA_FPATH = "dataset.txt" #@param {type: "string"}PRC_DATA_FPATH = "proc_dataset.txt" #@param {type: "string"}# apply normalization to the dataset# this will take a minute or twototal_lines = count_lines(RAW_DATA_FPATH)bar = Progbar(total_lines)with open(RAW_DATA_FPATH,encoding="utf-8") as fi: with open(PRC_DATA_FPATH, "w",encoding="utf-8") as fo: for l in fi: fo.write(normalize_text(l)+"\n") bar.add(1、

接下来,我们将训练模型来学习代表我们数据集的新词汇表。

BERT文件使用WordPiece分词器,不能在开源中使用。在单字模式下使用SentencePiece分词器。虽然与BERT不直接兼容,但是可以用小的处理方法进行动作。

由于SentencePiece需要相当多的执行内存,因此在Colab中执行完整的数据集会导致内核崩溃。

为了避免这种情况,对数据集的一部分进行随机子采样,构建词汇表。另一个选择是使用内存更大的计算机执行此步骤。

此外,SentencePiece默认将BOS和EOS控制符号添加到词汇表中。将索引设置为-1以将其禁用。

VOC_SIZE的典型值为32000到12800。如果要更新词汇表并在预训练阶段结束后调整模型,则NUM_PLACEHOLDERS个令牌。

MODEL_PREFIX = "tokenizer" #@param {type: "string"}VOC_SIZE = 32000 #@param {type:"integer"}SUBSAMPLE_SIZE = 12800000 #@param {type:"integer"}NUM_PLACEHOLDERS = 256 #@param {type:"integer"}SPM_COMMAND = ('--input={} --model_prefix={} ' '--vocab_size={} --input_sentence_size={} ' '--shuffle_input_sentence=true ' '--bos_id=-1 --eos_id=-1').format(PRC_DATA_FPATH, MODEL_PREFIX, VOC_SIZE - NUM_PLACEHOLDERS, SUBSAMPLE_SIZE)spm.SentencePieceTrainer.Train(SPM_COMMAND)

接下来,让我们来看看如何在“BERT”模型中运行SentencePiece。

以下是使用了来自正式的事前训练英语BERT的基础模型的WordPiece词汇表表记的语句。

gt;gt;gt; wordpiece.tokenize("Colorless geothermal substations are generating furiously")['color', '##less', 'geo', '##thermal', 'sub', '##station', '##s', 'are', 'generating', 'furiously']

WordPiece标记预设了出现在“##”单词中间的子字。出现在单词开头的子字不变。如果子字显示在单词的开头和中间,则两个版本(带和非带)都将添加到词汇表中。

SentencePiece创建了两个文件:tokenizer.model和tokenizer.vocab看看学过的词:

def read_sentencepiece_vocab(filepath): voc = [] with open(filepath, encoding='utf-8') as fi: for line in fi: voc.append(line.split("\t")[0]) # skip the first lt;unkgt; token voc = voc[1:] return vocsnt_vocab = read_sentencepiece_vocab("{}.vocab".format(MODEL_PREFIX)print("Learnt vocab size: {}".format(len(snt_vocab))print("Sample tokens: {}".format(random.sample(snt_vocab, 10))

执行结果:

Learnt vocab size: 31743 Sample tokens: ['▁cafe', '▁slippery', 'xious', '▁resonate', '▁terrier', '▁feat', '▁frequencies', 'ainty', '▁punning', 'modern']

从文档中可以看出,SentencePiece和WordPiece的执行结果完全相反:SentencePiece首先使用原符号“_”将空格转换为空格,如下:

Hello_World。

然后将文本拆分为小块。

[Hello] [_Wor] [ld] [.]

在空格后面出现的子字(也是许多数词开头的子字)前面加上“_”,但其他子字不变。这将排除仅出现在语句开头的子字,而不是其他位置。但这些事件应该非常罕见。

因此,为了获得与WordPiece相似的词汇表,必须从包含该词汇表的标记中删除“_”,并执行向不包含“##”的标记中添加的简单转换。

我们还添加了一些BERT架构所需的特殊控制符号。按照惯例,我们把它们放在词汇的开头。

您还为词汇表添加了占位符标记。

如果希望使用用于特定任务的新令牌更新预先训练的模型,这些方法非常有用。

在这种情况下,占位符标志将替换为新标记,以重新生成预训练数据并调整新数据。

def parse_sentencepiece_token(token): if token.startswith("▁"): return token[1:] else: return "##" + tokenBERT_vocab = list(map(parse_sentencepiece_token, snt_vocab)ctrl_symbols = ["[PAD]

最后,将检索到的词汇表写入文件。

VOC_FNAME = "vocab.txt" #@param {type:"string"}with open(VOC_FNAME, "w") as fo: for token in BERT_vocab: fo.write(token+"\n")

接下来,我们来看看新词实际上是如何运作的。

gt;gt;gt; testcase = "Colorless geothermal substations are generating furiously"gt;gt;gt; BERT_tokenizer = tokenization.FullTokenizer(VOC_FNAME)gt;gt;gt; BERT_tokenizer.tokenize(testcase)['color', '##less', 'geo', '##ther', '##mal', 'sub', '##station', '##s', 'are', 'generat', '##ing', 'furious', '##ly']

通过手头的词汇集,可以为BERT模型生成预训练数据。

我们的数据集可能非常大,所以我们将其碎片化。

mkdir ./shardssplit -a 4 -l 256000 -d $PRC_DATA_FPATH ./shards/shard_

现在,对于各部分,从BERT仓库向create_pretraining_需要使用data.py脚本和xargs的命令。

在开始生成之前,必须设置要传递给脚本的参数。您可以从自述文件中找到有关其含义的详细信息。

MAX_SEQ_LENGTH = 128 #@param {type:"integer"}MASKED_LM_PROB = 0.15 #@paramMAX_PREDICTIONS = 20 #@param {type:"integer"}DO_LOWER_CASE = True #@param {type:"boolean"}PRETRAINING_DIR = "pretraining_data" #@param {type:"string"}# controls how many parallel processes xargs can createPROCESSES = 2 #@param {type:"integer"}

执行此操作可能需要相当长的时间,具体取决于数据集的大小。

XARGS_CMD = ("ls ./shards/ | " "xargs -n 1 -P {} -I{} " "python3 BERT/create_pretraining_data.py " "--input_file=./shards/{} " "--output_file={}/{}.tfrecord " "--vocab_file={} " "--do_lower_case={} " "--max_predictions_per_seq={} " "--max_seq_length={} " "-

展开剩余内容

分享到:

猜你喜欢

  • b2b网站策划书_b2b策划案

    b2b网站策划书_b2b策划案大家好,今天我来给大家讲解一下关于b2b网站策划书的问题。为了让大家更好地理解这个问题,我将相关资料进行了整理,现在就让我们一起来看看吧。文章目录...

    2024-10-22 企业 网站
  • 浙江高端网站_浙江高端网站有哪些

    浙江高端网站_浙江高端网站有哪些好久不见了,今天我想和大家探讨一下关于“浙江高端网站”的话题。如果你对这个领域还不太了解,那么这篇文章就是为你准备的,让我们一看看吧。文章目录列...

    2024-10-22 网站 浙江
  • 做酒的网站_做酒的网站有哪些

    做酒的网站_做酒的网站有哪些希望我能够回答您有关做酒的网站的问题。我将根据我的知识库和研究成果回答您的问题。文章目录列表:1.酒仙网CEO郝鸿峰的电商百亿梦想2.有没有关于介绍...

    2024-10-22 中国 酒类 酒仙 网站
  • 索尼手机软件_索尼手机软件商店

    索尼手机软件_索尼手机软件商店下面,我将为大家展开关于索尼手机软件的讨论,希望我的回答能够解决大家的疑问。现在,让我们开始聊一聊索尼手机软件的问题。文章目录列表:1.索尼的手机...

    2024-10-22 手机 索尼
热门标签