/t-bert

Primary LanguagePython

T-BERT

本專案是基於BERT for Pytorch進行延伸開發,包含訓練T-BERT模型之script以及步驟,並且使用國網中心High Performance Computing (HPC)進行多節點高速運算,提供Pytorch的T-BERT模型以及使用方式

T-BERT下載

快速使用T-BERT

T-BERT相容於Huggingface Transformers,可使用Huggingface Transformers進行下游任務的訓練

下載T-BERT-Base, Casedhuggingface_tbert_base目錄

from transformers import BertTokenizer, BertModel

tokenizer = BertTokenizer.from_pretrained("huggingface_tbert_base")
model = BertModel.from_pretrained("huggingface_tbert_base")

Train T-BERT

訓練環境:

國網中心 高速計算服務(TWCC HPC)

Step 1. 準備資料

Pre-training資料的格式必須為一篇文章一行,範例為: bert/data/formatted_one_article_per_line/wikicorpus_zh_one_article_per_line.txt

Pre-training資料下載

t-bert.deepq.ai

使用自己的Pre-training資料

依照Taiwan_corpus步驟產生檔名為wikicorpus_zh_one_article_per_line.txt的Pre-training資料,並將wikicorpus_zh_one_article_per_line.txt移至bert/data/formatted_one_article_per_line

注意:最後檔案名稱一定要取成wikicorpus_zh_one_article_per_line.txt

Step 2. 產生Vocabulary

Vocabulary資料下載

tbert_vocab.txt

使用自己的Pre-training資料產生Vocabulary

依照Generate_TBERT_vocab,並且使用<資料及名稱>_one_article_per_line.txt檔案產生T-BERT所需要的vocabulary。

Step 3. 下載此專案並且設定環境

Clone the repository

git clone https://github.com/DeepqEducation/t-bert.git
cd t-bert

Download the singularity image

Singularity : 類似於docker,利用已經架設好的環境,但是不需要root權限,且能夠讓環境內外的檔案系統更容易互通。

module load singularity
singularity pull docker://nvcr.io/nvidia/pytorch:19.12-py3

Step 4. 從文本生成Pre-training資料

請檢視bert/data/create_Tbert_datasets_from_start.sh,該檔案是從bert/data/create_datasets_from_start.sh進行延伸。
可自行更動:

  • WORKSPACE:為到t-bert repository的路徑(如果在家目錄clone t-bert,則不需要修改).
  • SINGULARITY_PATH:為到singularity image的路徑(依照步驟在t-bert目錄下執行singualrity pull docker,則不需更改)

接續Step 1跟2,可直接執行sbatch bert/data/create_Tbert_datasets_from_start.sh

注意:須自行修改script中accountpartition

create_Tbert_datasets_from_start.sh包含2項前處理:

  1. wikicorpus_zh_one_article_per_line.txt內的文章做斷句,並依照句數,將資料儘量平均分散儲存成多個檔案,再分成train跟test data 檔案格式為:
    一句一行,不同文章之間會再多一行空白行進行區隔,儲存在bert/data/sharded_training_shards_512_test_shards_512_fraction_0.2/wikicorpus_zh/,該資料夾包含切分為512個檔案的pretrain data,train:test比例為8:2。
    train的檔名為:wikicorpus_zh_training_[0-511].txt
    test的檔名為:wikicorpus_zh_test_[0-511].txt

  2. 產生訓練T-BERT的pre-training所需的tensor,對分散儲存的資料做tokenize,將句子的Masked Language Model (MLM)跟Next Sentence Prediction(NSP)的label儲存成HDF5,並儲存在bert/data/hdf5_lower_case_0_seq_len_512_max_pred_80_masked_lm_prob_0.15_random_seed_12345_dupe_factor_5
    train的檔名為:wikicorpus_zh_training_[0-511].hdf5
    test的檔名為:wikicorpus_zh_test_[0-511].hdf5

注意:此步驟耗時,4G的文本資料約需六小時。

解釋bert/data/create_Tbert_datasets_from_start.sh

使BERT For PyTorch的create_datasets_from_start.sh相容於TWCC HPC+Singularity的環境

在BERT For PyTorch中,使用docker將bert這個資料夾放在/workspace/底下,
在此專案中透過singularity -B <t-bert路徑>:/workspace,將t-bert資料夾bind成singularity環境裡的/workspace,之後singularity內的指令下給/workspace等同於下給t-bert

此外BERT For PyTorch有一個環境變數BERT_PREP_WORKING_DIR=/workspace/bert/data,要更改singularity內的環境變數必須設定一個外層的環境變數, SINGULARITYENV_<內部環境變數名稱>=<變數值>,所以我們會在每個singularity指令前加上SINGULARITYENV_BERT_PREP_WORKING_DIR=/workspace/bert/data

create_datasets_from_start.sh在此專案所進行更動:

  • 移除在BERT For PyTorch中會下載squad dataset,google pretrain weight的動作
  • 移除在BERT For PyTorch下載bookcorpus,wikipedia,並對資料做預處理的工作:
  • 移除BERT For PyTorch中的128長度訓練,只採用訓練512長度的訓練方法
  • 產生HDF5的時候可自行更動的參數:
    • vocab檔案路徑 : 本專案將t-bertbind成/workspace,如/workspace/bert/vocab相等於t-bert/bert/vocab
    • do_lower_case 0本專案為中文模型,取消將文字轉為小寫的動作

Step 5. 開始Pre-training

請檢視bert/run_Tbert.sub,該檔案為bert/run.sub延伸修改。
同步驟4,需要自定義WORKSPACESINGULARITY_PATH變數。
output_dir為儲存model的資料夾名稱,預設為Tbert_base,放在t-bert目錄下
datadir為步驟4產生的資料夾名稱,預設為/workspace/bert/data/hdf5_lower_case_0_seq_len_512_max_pred_80_masked_lm_prob_0.15_random_seed_12345_dupe_factor_5/wikicorpus_zh

自定義/bert/run_pretraining.py預訓練的參數
bert/run_pretraining.py完整參數介紹,可參照bert/README.md中的Advanced/Parameters/Pre-training parameters
如下: max_seq_length: 訓練句子長度
max_steps: 訓練步數(一次gradient更新為一步)
num_steps_per_checkpoint:幾步儲存一個checkpoint
config_file: 指定到Model config的路徑,該config包含Model的架構、層數、vocabulary數量等等,本專案在bert``Tbert_base_config.json以及Tbert_large_config.json,請根據Model架構以及字典大小,修改config。

自定義train_batch_sizelearning_rategradient_accumulation_step以及node個數,在執行指令的環境變數中指定:

在8個node(每個node有8張32GB V100)總共64顆GPU預訓練T-BERT Large

BATCHSIZE=512 LR=4e-3 GRADIENT_STEPS=64 sbatch -N8 --ntasks-per-node=8 bert/run_Tbert.sub

以及 T-BERT Base:
BATCHSIZE=512 LR=4e-3 GRADIENT_STEPS=32 sbatch -N8 --ntasks-per-node=8 bert/run_Tbert.sub

訓練完成的Model將會放至datadir

其中Node數量設定:-N<節點數量>,16個節點為-N16
TWCC的每個節點皆為八顆GPU,因此--ntasks-per-node=8
LR也就是learning rate

剩下設置BATCHSIZE、、GRADIENT_STEPS請參考下列設定教學

使用兩階段長度訓練,請參考bert/README.mdAdvanced/Parameters/Multi-node的訓練指令 script可以參考bert/run_Tbert.subbert/run.sub修改

BATCHSIZEGRADIENT_STEPS 設定教學

注意此處 BATCHSIZE的定義跟其他地方有些不一樣。
定義公式如下:
Effective Batch Size * Gradient Accumulation Steps * Number of GPUs = Global Batch Size
其中參數GRADIENT_STEPS即為上述公式的Gradient Accumulation Steps,代表累加幾次gradient做一次backward pass。
但是本專案中BATCHSIZE定義為Effective Batch Size * Gradient Accumulation Steps

例如:
訓練長度512且Global Batch Size=32768,train在64顆GPU上, 參數BATCHSIZE必須設成32768/64=512
可以調整參數GRADIENT_STEPS來測試Effective Batch Size的極限 GRADIENT_STEPS為64,代表Effective Batch Size=8,表示GPU一次載入8個instance.

在T-BERT中,設定global batch size= 65536 訓練長度128 以及 global batch size= 32768 訓練長度512, train在64顆GPU上,參數BATCHSIZE=32768/64=512。 且經測試後,每個GPU一次只能載入8個instance,因此累加步數GRADIENT_STEPS為512/8=64

Tbert-Large:

  • 句子長度 128, 每個GPU最大可以載入共64個instance:

BATCHSIZE=65536/( <#nodes>*<#GPUs per node> ) = 65536/( Total number of GPUs in the whole cluster )

GRADIENT_STEPS=BATCHSIZE/64

  • 句子長度 512, 每個GPU最大可以載入共8個instance:

BATCHSIZE = 32768/( <#nodes>*<#GPUs per node> ) = 32768/( Total number of GPUs in the whole cluster )

GRADIENT_STEPS=BATCHSIZE/8

T-BERT-Base:

  • 句子長度 512, 每個GPU最大可以載入共16個instance:

BATCHSIZE = 32768/( <#nodes>*<#GPUs per node> ) = 32768/( Total number of GPUs in the whole cluster )

GRADIENT_STEPS = BATCHSIZE / 16

Step 6. 將本專案Model轉換成HuggingFace BERT Model

python convert_nvidia_bert_to_hugginface_bert.py -i <NVIDIA_BERT_checkpoint> -o <output_foldername> -c <BERT_config> -v <vocab.txt>

NVIDIA_BERT_checkpoint本專案所儲存的checkpoint,檔名通常為ckpt_<訓練步數>.pt
output_foldername為要儲存的資料夾名稱
BERT_config步驟5之config,包含Model架構,vocabulary數量等
vocab.txt

訓練Tbert_base的步驟,可用下列指令轉換

python convert_nvidia_bert_to_hugginface_bert.py -i tbert_base/ckpt_10000.pt -o huggingface_tbert_base -c bert/Tbert_base_config.json -v bert/vocab/tbert_vocab.txt

最後產出 T-BERT-Base, Cased

Reference

BERT For PyTorch