MinT: 最简Transformer库和教程
从头开始实现常见的极简Transformer!
Colabs
一系列关于从头构建常见Transformer模型的教程。每个教程都基于前一个教程,因此应按顺序完成。
这里的代码也被整理为一个Python包,方便在教程之外使用。
因为这是为了解释建模和训练方法而编写的教程,目前我们依赖HuggingFace的tokenizers库来实现子词标记。我选择它是因为它快速且被广泛使用。还有其他不错的快速库(如BlingFire)覆盖了多种子词方法,但这个库目前不支持它们。
基于零基础的极简Transformer库
常见Transformer架构的极简PyTorch实现。目前实现了以下内容:
预训练
目前有一些示例程序展示如何从零预训练(或继续在预训练模型上进行预训练)
小数据集的内存训练
有两个预训练示例,一个是适合像Wikitext-2这样的小数据集的玩具示例。加载器预处理数据并将张量读入TensorDataset中。它使用SimpleTrainer
进行多轮训练。因为数据集小且是Map风格的数据集,训练整个epoch然后评估整个测试数据集是合理的。对于大数据集,我不推荐这种方法。
大数据集的内存外训练
第二个示例使用无限IterableDataset来读取多个文件(分片)并在飞行中将它们转换为张量。这个程序是语言模型更实际的一个示例。
大数据集中预处理的分片
该库也支持完全预处理的数据集,但目前没有这方面的示例。
维基百科
要使用此程序在英文维基百科上进行预训练,您将需要一个XML维基百科转储。这通常命名为enwiki-latest-pages-articles.xml.bz2
,可以在维基百科转储站点找到。例如,这应该用于下载:
wget https://dumps.wikimedia.org/enwiki/latest/enwiki-latest-pages-articles.xml.bz2
您还需要使用这个存储库:
git clone https://github.com/attardi/wikiextractor
cd wikiextractor
git checkout 16186e290d9eb0eb3a3784c6c0635a9ed7e855c3
以下是我运行的示例:
python WikiExtractor.py ${INPUT}/enwiki-latest-pages-articles.xml.bz2 \
-q --json \
--processes 7 \
--output ${OUTPUT}/enwiki-extracted \
--bytes 100M \
--compress \
--links \
--discard_elements gallery,timeline,noinclude \
--min_text_length 0 \
--filter_disambig_pages
关于以上的命令行,如果你的系统上有bzip2并且你的Python可以导入bz2模块,仅使用--compress
在每个生成的目标(例如AA,AB,AC)中,我们将添加一个前缀(例如AA)进行重命名:
for file in *.bz2; do mv "$file" "AA_$file"; done;
然后我们可以将这些文件复制到一个目录,或者按我们希望的方式将其拆分为训练和测试数据集。
以下是如何使用DistributedDataParallel在多个工作者上进行训练:
CUDA_VISIBLE_DEVICES=2,3,4,5,6,7,8,9 python -m torch.distributed.launch \
--node=1 \
--nproc_per_node=8 \
--node_rank=0 \
--master_port=$PORT \
pretrain_bert_wiki.py \
--vocab_file /data/k8s/hf-models/bert-base-uncased/vocab.txt \
--lowercase \
--train_file "/path/to/enwiki-extracted/train/" \
--valid_file "/path/to/enwiki-extracted/valid/" \
--num_train_workers 4 \
--num_valid_workers 1 --batch_size $B --num_steps $N --saves_per_cycle 1 \
--train_cycle_size 10000 \
--eval_cycle_size 500 \
--distributed
微调
tune_bert_for_cls程序是一个简单的示例,展示了如何从零微调我们的BERT实现。
完整器REPL
bert_completer程序允许你输入掩码字符串并查看BERT将如何补全它们。当它启动时,你可以传递--sample
以从输出中进行采样,否则它会使用最可能的值。你可以在运行时在两种模式之间切换:
BERT>> :sample
或
BERT>> :max
这个示例使用prompt_toolkit
,它不是一个核心依赖项,但你可以这样安装它:
pip install .[examples]