update apex fp16 implementation
This commit is contained in:
@@ -1,22 +1,20 @@
|
|||||||
from argparse import ArgumentParser
|
|
||||||
from pathlib import Path
|
|
||||||
import os
|
|
||||||
import torch
|
|
||||||
import logging
|
|
||||||
import json
|
import json
|
||||||
|
import logging
|
||||||
import random
|
import random
|
||||||
import numpy as np
|
from argparse import ArgumentParser
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
from pathlib import Path
|
||||||
from tempfile import TemporaryDirectory
|
from tempfile import TemporaryDirectory
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
import torch
|
||||||
from torch.utils.data import DataLoader, Dataset, RandomSampler
|
from torch.utils.data import DataLoader, Dataset, RandomSampler
|
||||||
from torch.utils.data.distributed import DistributedSampler
|
from torch.utils.data.distributed import DistributedSampler
|
||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
|
|
||||||
from pytorch_transformers import WEIGHTS_NAME, CONFIG_NAME
|
|
||||||
from pytorch_transformers.modeling_bert import BertForPreTraining
|
from pytorch_transformers.modeling_bert import BertForPreTraining
|
||||||
from pytorch_transformers.tokenization_bert import BertTokenizer
|
|
||||||
from pytorch_transformers.optimization import AdamW, WarmupLinearSchedule
|
from pytorch_transformers.optimization import AdamW, WarmupLinearSchedule
|
||||||
|
from pytorch_transformers.tokenization_bert import BertTokenizer
|
||||||
|
|
||||||
InputFeatures = namedtuple("InputFeatures", "input_ids input_mask segment_ids lm_label_ids is_next")
|
InputFeatures = namedtuple("InputFeatures", "input_ids input_mask segment_ids lm_label_ids is_next")
|
||||||
|
|
||||||
@@ -125,7 +123,8 @@ def main():
|
|||||||
parser = ArgumentParser()
|
parser = ArgumentParser()
|
||||||
parser.add_argument('--pregenerated_data', type=Path, required=True)
|
parser.add_argument('--pregenerated_data', type=Path, required=True)
|
||||||
parser.add_argument('--output_dir', type=Path, required=True)
|
parser.add_argument('--output_dir', type=Path, required=True)
|
||||||
parser.add_argument("--bert_model", type=str, required=True, help="Bert pre-trained model selected in the list: bert-base-uncased, "
|
parser.add_argument("--bert_model", type=str, required=True,
|
||||||
|
help="Bert pre-trained model selected in the list: bert-base-uncased, "
|
||||||
"bert-large-uncased, bert-base-cased, bert-base-multilingual, bert-base-chinese.")
|
"bert-large-uncased, bert-base-cased, bert-base-multilingual, bert-base-chinese.")
|
||||||
parser.add_argument("--do_lower_case", action="store_true")
|
parser.add_argument("--do_lower_case", action="store_true")
|
||||||
parser.add_argument("--reduce_memory", action="store_true",
|
parser.add_argument("--reduce_memory", action="store_true",
|
||||||
@@ -235,8 +234,9 @@ def main():
|
|||||||
|
|
||||||
# Prepare model
|
# Prepare model
|
||||||
model = BertForPreTraining.from_pretrained(args.bert_model)
|
model = BertForPreTraining.from_pretrained(args.bert_model)
|
||||||
if args.fp16:
|
# We don't need to manually call model.half() following Apex's recommend
|
||||||
model.half()
|
# if args.fp16:
|
||||||
|
# model.half()
|
||||||
model.to(device)
|
model.to(device)
|
||||||
if args.local_rank != -1:
|
if args.local_rank != -1:
|
||||||
try:
|
try:
|
||||||
@@ -257,25 +257,36 @@ def main():
|
|||||||
{'params': [p for n, p in param_optimizer if any(nd in n for nd in no_decay)], 'weight_decay': 0.0}
|
{'params': [p for n, p in param_optimizer if any(nd in n for nd in no_decay)], 'weight_decay': 0.0}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
optimizer = AdamW(optimizer_grouped_parameters, lr=args.learning_rate, eps=args.adam_epsilon)
|
||||||
|
scheduler = WarmupLinearSchedule(optimizer, warmup_steps=args.warmup_steps,
|
||||||
|
t_total=num_train_optimization_steps)
|
||||||
|
|
||||||
if args.fp16:
|
if args.fp16:
|
||||||
try:
|
try:
|
||||||
from apex.optimizers import FP16_Optimizer
|
# from apex.optimizers import FP16_Optimizer
|
||||||
from apex.optimizers import FusedAdam
|
# from apex.optimizers import FusedAdam
|
||||||
|
from apex import amp
|
||||||
except ImportError:
|
except ImportError:
|
||||||
raise ImportError(
|
raise ImportError(
|
||||||
"Please install apex from https://www.github.com/nvidia/apex to use distributed and fp16 training.")
|
"Please install apex from https://www.github.com/nvidia/apex to use distributed and fp16 training.")
|
||||||
|
|
||||||
optimizer = FusedAdam(optimizer_grouped_parameters,
|
# This below line of code is the main upgrade of Apex Fp16 implementation. I chose opt_leve="01"
|
||||||
lr=args.learning_rate,
|
# because it's recommended for typical use by Apex. We can make it configured
|
||||||
bias_correction=False,
|
model, optimizer = amp.initialize(model, optimizer, opt_level="O1")
|
||||||
max_grad_norm=1.0)
|
|
||||||
if args.loss_scale == 0:
|
# We don't need to use FP16_Optimizer wrapping over FusedAdam as well. Now Apex supports all Pytorch Optimizer
|
||||||
optimizer = FP16_Optimizer(optimizer, dynamic_loss_scale=True)
|
|
||||||
else:
|
# optimizer = FusedAdam(optimizer_grouped_parameters,
|
||||||
optimizer = FP16_Optimizer(optimizer, static_loss_scale=args.loss_scale)
|
# lr=args.learning_rate,
|
||||||
else:
|
# bias_correction=False,
|
||||||
optimizer = AdamW(optimizer_grouped_parameters, lr=args.learning_rate, eps=args.adam_epsilon)
|
# max_grad_norm=1.0)
|
||||||
scheduler = WarmupLinearSchedule(optimizer, warmup_steps=args.warmup_steps, t_total=num_train_optimization_steps)
|
# if args.loss_scale == 0:
|
||||||
|
# optimizer = FP16_Optimizer(optimizer, dynamic_loss_scale=True)
|
||||||
|
# else:
|
||||||
|
# optimizer = FP16_Optimizer(optimizer, static_loss_scale=args.loss_scale)
|
||||||
|
# else:
|
||||||
|
# optimizer = AdamW(optimizer_grouped_parameters, lr=args.learning_rate, eps=args.adam_epsilon)
|
||||||
|
# scheduler = WarmupLinearSchedule(optimizer, warmup_steps=args.warmup_steps, t_total=num_train_optimization_steps)
|
||||||
|
|
||||||
global_step = 0
|
global_step = 0
|
||||||
logging.info("***** Running training *****")
|
logging.info("***** Running training *****")
|
||||||
@@ -304,7 +315,10 @@ def main():
|
|||||||
if args.gradient_accumulation_steps > 1:
|
if args.gradient_accumulation_steps > 1:
|
||||||
loss = loss / args.gradient_accumulation_steps
|
loss = loss / args.gradient_accumulation_steps
|
||||||
if args.fp16:
|
if args.fp16:
|
||||||
optimizer.backward(loss)
|
# I depricate FP16_Optimizer's backward func and replace as Apex document
|
||||||
|
# optimizer.backward(loss)
|
||||||
|
with amp.scale_loss(loss, optimizer) as scaled_loss:
|
||||||
|
scaled_loss.backward()
|
||||||
else:
|
else:
|
||||||
loss.backward()
|
loss.backward()
|
||||||
tr_loss += loss.item()
|
tr_loss += loss.item()
|
||||||
@@ -322,7 +336,8 @@ def main():
|
|||||||
# Save a trained model
|
# Save a trained model
|
||||||
if args.local_rank == -1 or torch.distributed.get_rank() == 0:
|
if args.local_rank == -1 or torch.distributed.get_rank() == 0:
|
||||||
logging.info("** ** * Saving fine-tuned model ** ** * ")
|
logging.info("** ** * Saving fine-tuned model ** ** * ")
|
||||||
model_to_save = model.module if hasattr(model, 'module') else model # Take care of distributed/parallel training
|
model_to_save = model.module if hasattr(model,
|
||||||
|
'module') else model # Take care of distributed/parallel training
|
||||||
model_to_save.save_pretrained(args.output_dir)
|
model_to_save.save_pretrained(args.output_dir)
|
||||||
tokenizer.save_pretrained(args.output_dir)
|
tokenizer.save_pretrained(args.output_dir)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user