该存储库包含代码,以复制我们在“挤满:在单个GPU上训练语言模型”中描述的研究。我们尝试使用有限的计算的Bert型模型进行预处理的语言模型,想知道“真的有多糟糕”?
您可以在此处找到我们的论文:https://arxiv.org/abs/2212.14034,以及下面的摘要:
语言建模的最新趋势集中在通过缩放来提高性能,并导致了大多数研究人员和从业人员无法实现培训语言模型的环境。虽然社区中的大多数人都在问如何突破极端计算的限制,但我们提出了相反的问题:
仅一天,我们就可以使用单个GPU才能获得多远?
我们使用基于变压器的语言模型来研究下游的性能,该模型在单个消费者GPU上进行了一天的胶带模型,该模型完全从头开始训练。除了重新分析此情况预训练管道的几乎所有组件外,并提供了接近BERT的性能的修改管道外,我们研究了为什么缩小缩小是很难的,哪些修改实际上可以改善这种情况下的性能。我们提供的证据表明,即使在这种受到限制的环境中,绩效也会遵循大型设置中观察到的缩放定律。通过缩放法律的镜头,我们对培训和体系结构进行了一系列改进,并讨论了它们在有限的计算设置中的优点和实际适用性(或缺乏)。
您需要Pytorch 2.0来运行新代码。如果您想留在Pytorch 1.**,则可以检查Last1.13release标签。接受新代码库培训的新车型在胶水上的预算相同1-2%。可以在https://huggingface.co/jonasgeiping/crammed-bert上找到该检查点。旧检查点现在为https://huggingface.co/jonasgeiping/crammed-bert-legacy。
此外,数据预处理有所改进,您现在可以直接从huggingface从https:///huggingface.co/datasets/jonasgeiping/the_pile_pile_wordpiecex32768_2EFDB9DB9DB9D060D1AE951AE95FAFFAFFAFFAFFAF952EC1A50F020直接从huggingface流传输数据。
环境:
运行pip install .安装所有依赖项。
torch (至少2.1版)transformers , tokenizers , datasets , evaluatehydra-corepsutil , pynvml , safetensorseinops pip install .安装所有软件包和脚本。curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh ,然后git clone https://github.com/google-research/deduplicate-text-datasets/tree/dev-v1 ,然后运行cargo install --target-dir ../cramming/dedup要验证最小安装,您可以运行
python pretrain.py name=test arch=hf-bert-base train=bert-base data=sanity-check-2 dryrun=True impl.microbatch_size=2
该命令预处理了一个小的理智检查数据集,并运行一个训练步骤。
使用pretrain.py脚本以有限的计算预处理。该存储库使用Hydra(https://hydra.cc/docs/intro/),因此可以在命令行上修改cramming/config中的所有字段。例如,可以通过提供budget=48作为附加参数(运行48小时)来修改budget ,也可以通过train.optim.lr=1e-4修改学习率。查看配置文件夹以查看所有参数。
您的第一步应该是验证已安装的软件包。为此,您可以运行python pretrain.py dryrun=True ,它将运行单个迭代的默认理智检查。从那里,您可以启用其他功能。例如,修改体系结构,例如arch=bert-original和Training Setup train=bert-original 。要真正训练语言模型,您需要从理智检查数据集切换到至少data=pile-readymade 。然后,选择改进的训练设置,例如train=bert-o4 ,以及改进的模型布局,例如arch=crammed-bert 。
数据源将在培训开始并缓存到数据库之前读取,归一化和纠正的data.sources源。具有相同配置的后续调用将重复使用该标记序列的数据库。默认情况下,在此过程中还将构建和保存一个新的令牌。重要的数据选项是data.max_entries_in_raw_dataset ,它定义将加载多少原始数据。例如,对于大型数据源(例如C4),将仅下载一部分原始数据。然后, max_seq_in_tokenized_dataset瓶颈将在数据库中存储多少个处理序列。该数字应大于预期读取的序列数量。
附加说明:
data=pile-readymadepython pretrain.py data=... dryrun=True该= true,它可以干燥训练,但可以运行完整的数据预处理。然后运行可以重新使用缓存的数据。impl.threads 。特别是重复数据删除代码确实需要大量的RAM。bookcorpus-wikipedia进行第一个数据实验,该实验相对较快,然后研究完整的处理和过滤的C4。 作为参考,如果您只对更改培训/体系结构感兴趣,则可以在此处找到一些预处理的数据集:
这些数据源可以流传输。为此,简单的设置data=pile-readymade 。
预处理数据很方便,并且我认为,与培训和体系结构相比,与培训和架构相比,数据处理和过滤的修改仍然不足。与其他调整相比,使用更好的数据可能会带来更多的收益,因此最终您可能需要考虑为完整的数据处理管道设置代码和环境以进行工作。
现在,您可以在the-pile上找到最终版本的检查站。
要评估胶水(或某些胶水任务)上的经过预告片的模型,请使用eval.py该脚本在基本目录中搜索保存的模型。给定上一个运行的名称,默认情况下,此脚本将检索使用此名称保存的最新检查点,然后运行评估。
您可以将日志运行到您的权重和偏见帐户。为此,只需在命令行上或cramming/config/wandb/default.yaml修改wandb.entity和wandb.project 。
要复制论文中讨论的最终食谱,请运行
python pretrain.py name=amp_b8192_cb_o4_final arch=crammed-bert train=bert-o4 data=pile-readymade
预算和
python eval.py eval=GLUE_sane name=amp_b8192_cb_o4_final eval.checkpoint=latest impl.microbatch_size=16 impl.shuffle_in_dataloader=True impl.compile_torch=False
评估模型。论文中称为“挤压伯特”的食谱对应于配置中称为crammed-bert体系结构,并在数据the-pile上接受了训练设置bert-o4训练。
为了获得最佳性能,您需要进行最新的Pytorch夜间,并设置以下电感变量(使用电感器修改torch.compile设置):
max_autotune_gemm: Truemax_autotune_pointwise: Falsetriton.cudagraphs: Truetriton.cudagraph_trees: False 预处理:单个GPU,原始BERT设置:
python pretrain.py name=bert data=bookcorpus-wikipedia arch=bert-original train=bert-original budget=10000000
多GPU,原始BERT设置:
torchrun --nproc_per_node=4 --standalone pretrain.py name=bert4gpu data=bookcorpus-wikipedia arch=bert-original train=bert-original budget=10000000 impl.fullgraph=false impl._inductor_vars.triton.cudagraphs=False
评估拥抱面检查点(在RTE上的此示例中):
python eval.py eval=GLUE_sane eval/tasks=rte name=bert-finetuning eval.checkpoint=hf://bert-base-uncased impl.shuffle_in_dataloader=True impl.compile_torch=False impl.microbatch_size=16
评估本地检查点(禁用汇编,该汇编,该检查点现在期望固定形状):
python eval.py eval=GLUE_sane eval/tasks=rte name=NAME_OF_PRETRAINING_RUN eval.checkpoint=latest impl.shuffle_in_dataloader=True impl.compile_torch=False
理智检查CPU上的分布式代码:
CUDA_VISIBLE_DEVICES= torchrun --nproc_per_node=2 --standalone pretrain.py name=cpu_multi_check dryrun=True data=sanity-check-2 impl.dist_backend=gloo impl.fullgraph=false impl._inductor_vars.triton.cudagraphs=False
食谱的其他示例可以在/scripts文件夹中找到。
以下选项当前是损坏的/有限的/正在进行的工作。由您自己决定使用这些。当然,这里的任何贡献都非常感谢。如果您想调查,您还可以向我发送有关这些观点的更多问题。
Last1.13release标签。如果您有兴趣恢复其中一些选择。随意打开带有新代码库的拉动请求。请随时与我们联系,或在Github上打开问题。