更新後的 Transformers 2.0 汲取了 PyTorch 的易用性和 Tensorflow 的工業級生態系統。藉助於更新後的 Transformers 庫,科學家和實踐者可以更方便地在開發同一語言模型的訓練、評估和製作階段選擇不同的框架。
那麼更新後的 Transformers 2.0 具有哪些顯著的特徵呢?對 NLP 研究者和實踐者又會帶來哪些方面的改善呢?機器之心進行了整理。
專案地址:https://github.com/huggingface/transformers
Transformers 2.0 新特性
像 pytorch-transformers 一樣使用方便;
像 Keras 一樣功能強大和簡潔;
在 NLU 和 NLG 任務上實現高效能;
對教育者和實踐者的使用門檻低。
為所有人提供 SOTA 自然語言處理
深度學習研究者;
親身實踐者;
AI/ML/NLP 教師和教育者。
更低的計算開銷和更少的碳排放量
研究者可以共享訓練過的模型,而不用總是重新訓練;
實踐者可以減少計算時間和製作成本;
提供有 8 個架構和 30 多個預訓練模型,一些模型支援 100 多種語言;
為模型使用期限內的每個階段選擇正確的框架
3 行程式碼訓練 SOTA 模型;
實現 TensorFlow 2.0 和 PyTorch 模型的深度互操作;
在 TensorFlow 2.0 和 PyTorch 框架之間隨意移動模型;
為模型的訓練、評估和製作選擇正確的框架。
現已支援的模型
官方提供了一個支援的模型列表,包括各種著名的預訓練語言模型和變體,甚至還有官方實現的一個蒸餾後的 Bert 模型:
1. BERT (https://github.com/google-research/bert)
2. GPT (https://github.com/openai/finetune-transformer-lm)
3. GPT-2 (https://blog.openai.com/better-language-models/)
4. Transformer-XL (https://github.com/kimiyoung/transformer-xl)
5. XLNet (https://github.com/zihangdai/xlnet/)
6. XLM (https://github.com/facebookresearch/XLM/)
7. RoBERTa (https://github.com/pytorch/fairseq/tree/master/examples/roberta)
8. DistilBERT (https://github.com/huggingface/transformers/tree/master/examples/distillation)
快速上手
怎樣使用 Transformers 工具包呢?官方提供了很多程式碼示例,以下為檢視 Transformer 內部模型的程式碼:
import torch from transformers import * #Transformers has a unified API #for 8 transformer architectures and 30 pretrained weights. #Model | Tokenizer | Pretrained weights shortcut MODELS = [(BertModel, BertTokenizer, 'bert-base-uncased'), (OpenAIGPTModel, OpenAIGPTTokenizer, 'openai-gpt'), (GPT2Model, GPT2Tokenizer, 'gpt2'), (TransfoXLModel, TransfoXLTokenizer, 'transfo-xl-wt103'), (XLNetModel, XLNetTokenizer, 'xlnet-base-cased'), (XLMModel, XLMTokenizer, 'xlm-mlm-enfr-1024'), (DistilBertModel, DistilBertTokenizer, 'distilbert-base-uncased'), (RobertaModel, RobertaTokenizer, 'roberta-base')] #To use TensorFlow 2.0 versions of the models, simply prefix the class names with 'TF', e.g. TFRobertaModel is the TF 2.0 counterpart of the PyTorch model RobertaModel #Let's encode some text in a sequence of hidden-states using each model: for model_class, tokenizer_class, pretrained_weights in MODELS: # Load pretrained model/tokenizer tokenizer = tokenizer_class.from_pretrained(pretrained_weights) model = model_class.from_pretrained(pretrained_weights) # Encode text input_ids = torch.tensor([tokenizer.encode("Here is some text to encode", add_special_tokens=True)]) # Add special tokens takes care of adding [CLS], [SEP], <s>... tokens in the right way for each model. with torch.no_grad(): last_hidden_states = model(input_ids)[0] # Models outputs are now tuples #Each architecture is provided with several class for fine-tuning on down-stream tasks, e.g. BERT_MODEL_CLASSES = [BertModel, BertForPreTraining, BertForMaskedLM, BertForNextSentencePrediction, BertForSequenceClassification, BertForMultipleChoice, BertForTokenClassification, BertForQuestionAnswering] #All the classes for an architecture can be initiated from pretrained weights for this architecture #Note that additional weights added for fine-tuning are only initialized
#and need to be trained on the down-stream task
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased') for model_class in BERT_MODEL_CLASSES: # Load pretrained model/tokenizer model = model_class.from_pretrained('bert-base-uncased') #Models can return full list of hidden-states & attentions weights at each layer model = model_class.from_pretrained(pretrained_weights, output_hidden_states=True, output_attentions=True) input_ids = torch.tensor([tokenizer.encode("Let's see all hidden-states and attentions on this text")]) all_hidden_states, all_attentions = model(input_ids)[-2:] #Models are compatible with Torchscript model = model_class.from_pretrained(pretrained_weights, torchscript=True) traced_model = torch.jit.trace(model, (input_ids,)) #Simple serialization for models and tokenizers model.save_pretrained('./directory/to/save/') # save model = model_class.from_pretrained('./directory/to/save/') # re-load tokenizer.save_pretrained('./directory/to/save/') # save tokenizer = tokenizer_class.from_pretrained('./directory/to/save/') # re-load #SOTA examples for GLUE, SQUAD, text generation...
Transformers 同時支援 PyTorch 和 TensorFlow2.0,使用者可以將這些工具放在一起使用。如下為使用 TensorFlow2.0 和 Transformer 的程式碼:
import tensorflow as tf import tensorflow_datasets from transformers import * #Load dataset, tokenizer, model from pretrained model/vocabulary tokenizer = BertTokenizer.from_pretrained('bert-base-cased') model = TFBertForSequenceClassification.from_pretrained('bert-base-cased') data = tensorflow_datasets.load('glue/mrpc') #Prepare dataset for GLUE as a tf.data.Dataset instance train_dataset = glue_convert_examples_to_features(data['train'], tokenizer, max_length=128, task='mrpc') valid_dataset = glue_convert_examples_to_features(data['validation'], tokenizer, max_length=128, task='mrpc') train_dataset = train_dataset.shuffle(100).batch(32).repeat(2) valid_dataset = valid_dataset.batch(64) #Prepare training: Compile tf.keras model with optimizer, loss and learning rate schedule optimizer = tf.keras.optimizers.Adam(learning_rate=3e-5, epsilon=1e-08, clipnorm=1.0) loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True) metric = tf.keras.metrics.SparseCategoricalAccuracy('accuracy') model.compile(optimizer=optimizer, loss=loss, metrics=[metric]) #Train and evaluate using tf.keras.Model.fit() history = model.fit(train_dataset, epochs=2, steps_per_epoch=115, validation_data=valid_dataset, validation_steps=7) #Load the TensorFlow model in PyTorch for inspection model.save_pretrained('./save/') pytorch_model = BertForSequenceClassification.from_pretrained('./save/', from_tf=True) #Quickly test a few predictions - MRPC is a paraphrasing task, let's see if our model learned the task sentence_0 = "This research was consistent with his findings.“
sentence_1 = "His findings were compatible with this research.“
sentence_2 = "His findings were not compatible with this research.“
inputs_1 = tokenizer.encode_plus(sentence_0, sentence_1, add_special_tokens=True, return_tensors='pt')
inputs_2 = tokenizer.encode_plus(sentence_0, sentence_2, add_special_tokens=True, return_tensors='pt') pred_1 = pytorch_model(*inputs_1)[0].argmax().item() pred_2 = pytorch_model(*inputs_2)[0].argmax().item() print("sentence_1 is", "a paraphrase" if pred_1 else "not a paraphrase", "of sentence_0") print("sentence_2 is", "a paraphrase" if pred_2 else "not a paraphrase", "of sentence_0")
使用 py 檔案指令碼進行模型微調
當然,有時候你可能需要使用特定資料集對模型進行微調,Transformer2.0 專案提供了很多可以直接執行的 Python 檔案。例如:
run_glue.py:在九種不同 GLUE 任務上微調 BERT、XLNet 和 XLM 的示例(序列分類);
run_squad.py:在問答資料集 SQuAD 2.0 上微調 BERT、XLNet 和 XLM 的示例(token 級分類);
run_generation.py:使用 GPT、GPT-2、Transformer-XL 和 XLNet 進行條件語言生成;
其他可用於模型的示例程式碼。
GLUE 任務上進行模型微調
如下為在 GLUE 任務進行微調,使模型可以用於序列分類的示例程式碼,使用的檔案是 run_glue.py。
首先下載 GLUE 資料集,並安裝額外依賴:
pip install -r ./examples/requirements.txt
然後可進行微調:
export GLUE_DIR=/path/to/glue
export TASK_NAME=MRPC
python ./examples/run_glue.py \
--model_type bert \
--model_name_or_path bert-base-uncased \
--task_name $TASK_NAME \
--do_train \
--do_eval \
--do_lower_case \
--data_dir $GLUE_DIR/$TASK_NAME \
--max_seq_length 128 \
--per_gpu_eval_batch_size=8 \
--per_gpu_train_batch_size=8 \
--learning_rate 2e-5 \
--num_train_epochs 3.0 \
--output_dir /tmp/$TASK_NAME/
在命令列執行時,可以選擇特定的模型和相關的訓練引數。
使用 SQuAD 資料集微調模型
另外,你還可以試試用 run_squad.py 檔案在 SQuAD 資料集上進行微調。程式碼如下:
python -m torch.distributed.launch --nproc_per_node=8 ./examples/run_squad.py \
--model_type bert \
--model_name_or_path bert-large-uncased-whole-word-masking \
--do_train \
--do_eval \
--do_lower_case \
--train_file $SQUAD_DIR/train-v1.1.json \
--predict_file $SQUAD_DIR/dev-v1.1.json \
--learning_rate 3e-5 \
--num_train_epochs 2 \
--max_seq_length 384 \
--doc_stride 128 \
--output_dir ../models/wwm_uncased_finetuned_squad/ \
--per_gpu_eval_batch_size=3 \
--per_gpu_train_batch_size=3 \
這一程式碼可微調 BERT 全詞 Mask 模型,在 8 個 V100GPU 上微調,使模型的 F1 分數在 SQuAD 資料集上超過 93。
用模型進行文字生成
還可以使用 run_generation.py 讓預訓練語言模型進行文字生成,程式碼如下:
python ./examples/run_generation.py \
--model_type=gpt2 \
--length=20 \
--model_name_or_path=gpt2 \
安裝方法
如此方便的工具怎樣安裝呢?使用者只要保證環境在 Python3.5 以上,PyTorch 版本在 1.0.0 以上或 TensorFlow 版本為 2.0.0-rc1。
然後使用 pip 安裝即可。
pip install transformers
移動端部署很快就到
HuggingFace 在 GitHub 上表示,他們有意將這些模型放到移動裝置上,並提供了一個 repo 的程式碼,將 GPT-2 模型轉換為 CoreML 模型放在移動端。
未來,他們會進一步推進開發工作,使用者可以無縫地將大模型轉換成 CoreML 模型,無需使用額外的程式指令碼。
repo 地址:https://github.com/huggingface/swift-coreml-transformers