| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- ## @package embedding_generation_benchmark
- # Module caffe2.python.embedding_generation_benchmark
- from caffe2.proto import caffe2_pb2
- from caffe2.python import workspace, core, utils, model_helper
- import argparse
- import numpy as np
- import time
- import logging
- logging.basicConfig()
- log = logging.getLogger("embedding_generation_benchmark")
- log.setLevel(logging.DEBUG)
- def generate_data(T, batch_size, max_seq_length):
- '''
- Fill a queue with input data
- '''
- log.info("Generating T={} batches".format(T))
- generate_input_init_net = core.Net('generate_input_init')
- queue = generate_input_init_net.CreateBlobsQueue(
- [], "inputqueue", num_blobs=1, capacity=T,
- )
- workspace.RunNetOnce(generate_input_init_net)
- generate_input_net = core.Net('generate_input')
- generate_input_net.EnqueueBlobs([queue, "scratch"], ["scratch"])
- np.random.seed(2603)
- for t in range(T):
- if (t % (max(10, T // 10)) == 0):
- log.info("Generating data {}/{}".format(t, T))
- X = np.tile(np.arange(max_seq_length), [batch_size, 1]).transpose()
- workspace.FeedBlob("scratch", X)
- workspace.RunNetOnce(generate_input_net.Proto())
- log.info("Finished data generation")
- return queue
- def generate_embedding_table(vocab_size, embedding_size):
- log.info("Generating embedding table with dimensions {}"
- .format([vocab_size, embedding_size]))
- generate_table_net = core.Net('generate_table')
- table = generate_table_net.GaussianFill(
- [],
- ['embedding_table'],
- shape=[vocab_size, embedding_size],
- )
- workspace.RunNetOnce(generate_table_net)
- return table
- def create_model(args, queue, embedding_table, embedding_size):
- model = model_helper.ModelHelper(name='embedding_generation_bench')
- input_blob = model.net.DequeueBlobs(queue, 'input_data')
- if args.implementation == 'sinusoid':
- model.net.SinusoidPositionEncoding(
- [input_blob],
- ['output'],
- embedding_size=embedding_size
- )
- else:
- model.net.Gather(
- [embedding_table, input_blob],
- ['output'],
- )
- return model
- def Caffe2EmbeddingGeneration(args):
- T = args.data_size // args.batch_size
- queue = generate_data(T, args.batch_size, args.seq_length)
- embedding_table = None
- if args.implementation == 'table':
- embedding_table = generate_embedding_table(
- args.seq_length,
- args.embedding_size,
- )
- model = create_model(args, queue, embedding_table, args.embedding_size)
- workspace.RunNetOnce(model.param_init_net)
- workspace.CreateNet(model.net)
- start_time = time.time()
- num_iters = T
- total_iters = 0
- # Run the Benchmark
- log.info("------ Warming up ------")
- workspace.RunNet(model.net.Proto().name)
- log.info("------ Starting benchmark ------")
- start_time = time.time()
- last_time = time.time()
- for iteration in range(1, num_iters, args.iters_to_report):
- iters_once = min(args.iters_to_report, num_iters - iteration)
- total_iters += iters_once
- workspace.RunNet(model.net.Proto().name, iters_once)
- new_time = time.time()
- log.info(
- "Iter: {} / {}. Embeddings Generated Per Second: {}k.".format(
- iteration,
- num_iters,
- (iters_once * args.batch_size * args.seq_length) /
- (new_time - last_time) // 100 / 10,
- )
- )
- last_time = new_time
- total_per_sec = (num_iters - 1) * args.batch_size * args.seq_length
- total_per_sec = total_per_sec / (time.time() - start_time) // 100 / 10
- log.info("Done. Total embeddings generated per second " +
- "excluding 1st iteration: {}k".format(total_per_sec))
- return time.time() - start_time
- @utils.debug
- def Benchmark(args):
- return Caffe2EmbeddingGeneration(args)
- def GetArgumentParser():
- parser = argparse.ArgumentParser(
- description="Embedding generation benchmark."
- )
- parser.add_argument(
- "--embedding_size",
- type=int,
- default=512,
- help="Embedding size",
- )
- parser.add_argument(
- "--batch_size",
- type=int,
- default=16,
- help="The batch size."
- )
- parser.add_argument(
- "--data_size",
- type=int,
- default=10000,
- help="Number of sequences to generate"
- )
- parser.add_argument(
- "--seq_length",
- type=int,
- default=128,
- help="Max sequence length"
- )
- parser.add_argument(
- "--iters_to_report",
- type=int,
- default=20,
- help="Number of iterations to report progress"
- )
- parser.add_argument(
- "--implementation",
- type=str,
- default="sinusoid",
- help="'table' or 'sinusoid'",
- )
- return parser
- if __name__ == '__main__':
- args, extra_args = GetArgumentParser().parse_known_args()
- workspace.GlobalInit([
- 'caffe2',
- '--caffe2_log_level=0',
- '--caffe2_print_blob_sizes_at_exit=0'] + extra_args)
- device = core.DeviceOption(caffe2_pb2.CPU)
- with core.DeviceScope(device):
- Benchmark(args)
|