|
|
class BatchSizeOptimizer:
|
|
|
def __init__(self, prediction_model, memory_limit_mb=8000):
|
|
|
self.prediction_model = prediction_model
|
|
|
self.memory_limit_mb = memory_limit_mb
|
|
|
|
|
|
def estimate_memory_usage(self, model_features, batch_size):
|
|
|
"""Estimate memory usage for a given batch size"""
|
|
|
|
|
|
base_memory = model_features['model_size_mb']
|
|
|
|
|
|
|
|
|
|
|
|
if model_features['total_parameters'] > 100000000:
|
|
|
|
|
|
activation_memory = base_memory * 0.5 * batch_size
|
|
|
else:
|
|
|
activation_memory = base_memory * 0.3 * batch_size
|
|
|
|
|
|
|
|
|
optimizer_memory = base_memory * 2
|
|
|
|
|
|
|
|
|
total_memory = base_memory + activation_memory + optimizer_memory
|
|
|
|
|
|
return total_memory
|
|
|
|
|
|
def find_optimal_batch_size(self, model_features, min_batch=1, max_batch=32):
|
|
|
"""Find optimal batch size that maximizes throughput within memory constraints"""
|
|
|
valid_batch_sizes = []
|
|
|
throughputs = []
|
|
|
|
|
|
for batch_size in range(min_batch, max_batch + 1):
|
|
|
|
|
|
estimated_memory = self.estimate_memory_usage(model_features, batch_size)
|
|
|
if estimated_memory > self.memory_limit_mb:
|
|
|
continue
|
|
|
|
|
|
|
|
|
features = model_features.copy()
|
|
|
features['batch_size'] = batch_size
|
|
|
|
|
|
|
|
|
exec_time = self.prediction_model.predict(features)
|
|
|
|
|
|
|
|
|
throughput = (batch_size * 1000) / exec_time
|
|
|
|
|
|
valid_batch_sizes.append(batch_size)
|
|
|
throughputs.append(throughput)
|
|
|
|
|
|
if not valid_batch_sizes:
|
|
|
return min_batch
|
|
|
|
|
|
|
|
|
optimal_idx = throughputs.index(max(throughputs))
|
|
|
optimal_batch_size = valid_batch_sizes[optimal_idx]
|
|
|
|
|
|
return optimal_batch_size
|
|
|
|