How to use Umlaut

Import desired metrics

To use the measurement methods in a pipeline, the desired metrics have to be imported from the Umlaut package.

[33]:
import tensorflow as tf
from umlaut import Benchmark,\
                     ConfusionMatrixTracker,\
                     HyperparameterTracker,\
                     BenchmarkSupervisor,\
                     TimeMetric,\
                     MemoryMetric,\
                     PowerMetric,\
                     EnergyMetric,\
                     ThroughputMetric,\
                     LatencyMetric,\
                     TTATracker,\
                     LossTracker,\
                     CPUMetric
from sklearn.metrics import confusion_matrix
from keras import optimizers

def prep_data():
    fashion_mnist = tf.keras.datasets.fashion_mnist

    (train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
    class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
                   'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']

    train_images = train_images / 255.0
    test_images = test_images / 255.0

    return train_images, test_images, train_labels, test_labels, class_names

Initializing the benchmark object

To start include the measurement functions into the pipeline, a benchmark object has to be created. A benchmark object manages the database entries for the measured metrics. It provides functions to log and access measurement data. The object receives the database file in which the results should be stored and a description as input values.

Two kinds of metrics

The Umlaut framework distinguishes two different kinds of metrics. The supervised metrics and the valued metrics. Both kinds of metrics have to be used different.

Supervised metrics

The supervised metrics include: - throughput - latency - time - memory - power - energy - cpu

[34]:
bm = Benchmark('mnist_db', description="mnist_clothing")

mnist_metrics = {
    "throughput": ThroughputMetric('mnist throughput'),
    "latency": LatencyMetric('mnist latency'),
    "time": TimeMetric('mnist time'),
    "memory": MemoryMetric('mnist memory', interval=0.1),
    "power": PowerMetric('mnist power'),
    "energy": EnergyMetric('mnist energy'),
    "cpu": CPUMetric('mnist' cpu', interval=0.1)
}

To include the measurement of supervised metrics the desired metrics as well as the benchmark object have to be passed to a @BenchmarkSupervisor decorator. The appropriate BenchmarkSupervisor object manages the tracking of all supervised metrics.

Valued metrics

The valued metrics include: - confusion matrix - time to accuracy - loss

To collect measurements for the valued metrics, each one has a track function which has to be called with the corresponding input.

[42]:
@BenchmarkSupervisor(bloat_metrics.values(), bm)
def train(train_images, train_labels):
    model = tf.keras.Sequential([
        tf.keras.layers.Flatten(input_shape=(28, 28)),
        tf.keras.layers.Dense(128, activation='relu'),
        tf.keras.layers.Dense(10)
    ])

    model.compile(optimizer="Adam",
                  loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
                  metrics=['accuracy'])

    history = model.fit(train_images, train_labels, epochs=10, batch_size=256)

    mnist_metrics["throughput"].track(num_entries=len(train_images))
    mnist_metrics["latency"].track(num_entries=len(train_images))

    TTATracker(bm).track(accuracies=history.history["accuracy"],  description="TTA")
    LossTracker(bm).track(loss_values=history.history['loss'], description="loss")

    return model
[ ]:
def test(model, test_images, test_labels, class_names):

    model.evaluate(test_images, test_labels)
    pred_test = model.predict_classes(test_images)
    con_mat = confusion_matrix(test_labels, pred_test)
    ConfusionMatrixTracker(bm).track(con_mat, class_names, "confusion matrix")

    bm.close()

Collect measurements

When all desired metrics are applied to the pipeline it can be executed and measurements are collected during the runtime.

[43]:
train_images, test_images, train_labels, test_labels, class_names = prep_data()
model = train(train_images, train_labels)
test(model, test_images, test_labels, class_names)
2021-07-26 13:40:53.128730: W tensorflow/core/framework/cpu_allocator_impl.cc:80] Allocation of 188160000 exceeds 10% of free system memory.
Epoch 1/10
235/235 [==============================] - 1s 3ms/step - loss: 0.8690 - accuracy: 0.7114
Epoch 2/10
235/235 [==============================] - 1s 3ms/step - loss: 0.4414 - accuracy: 0.8489
Epoch 3/10
235/235 [==============================] - 1s 3ms/step - loss: 0.3959 - accuracy: 0.8628
Epoch 4/10
235/235 [==============================] - 1s 3ms/step - loss: 0.3678 - accuracy: 0.8720
Epoch 5/10
235/235 [==============================] - 1s 3ms/step - loss: 0.3469 - accuracy: 0.8776
Epoch 6/10
235/235 [==============================] - 1s 3ms/step - loss: 0.3349 - accuracy: 0.8809
Epoch 7/10
235/235 [==============================] - 1s 3ms/step - loss: 0.3165 - accuracy: 0.8867
Epoch 8/10
235/235 [==============================] - 1s 3ms/step - loss: 0.3068 - accuracy: 0.8899
Epoch 9/10
235/235 [==============================] - 1s 3ms/step - loss: 0.3026 - accuracy: 0.8914
Epoch 10/10
235/235 [==============================] - 1s 3ms/step - loss: 0.2821 - accuracy: 0.8985

Visualize results

To evaluate the measurement results, Umlaut provides a command line interface as visualization frontend. To use this interface umlaut-cli mnist_db.db has to be executed. The CLI prompts the user to insert a valid combination for the UUID, the measurement type and the measurement description to visualize the corresponding metrics.

Time Memory CPU Energy Latency Loss Power Thrpughput TTA Matrix

Hyperparameter Tracking

Umlaut also includes measuring hyperparameters. Similar to valued metrics, trackers are used to collect hyperparameter measurements. The user can decide which parameters and which values for them to track.

[45]:
def train(train_images, train_labels):
    ht = HyperparameterTracker(bm, "hyper params of sample pipeline", ['lr', 'num_epochs', 'batch_size'],
                               'loss')
    for lr in [0.1, 0.01, 0.001]:
        for num_epochs in [5, 10, 20]:
            for batch_size in [64, 128, 256]:

                model = tf.keras.Sequential([
                    tf.keras.layers.Flatten(input_shape=(28, 28)),
                    tf.keras.layers.Dense(128, activation='relu'),
                    tf.keras.layers.Dense(10)
                ])

                optimizer = optimizers.Adam(lr=lr)

                model.compile(optimizer=optimizer,
                              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
                              metrics=['accuracy'])

                history = model.fit(train_images, train_labels, epochs=num_epochs, batch_size=batch_size)
                ht.track({'lr': lr, 'num_epochs': num_epochs, 'batch_size': batch_size, 'loss': history.history["accuracy"][-1]})
    ht.close()
Hyperparameter

Troubleshooting

PyRAPL (Intel) - No Access

Run sudo chmod -R a+r /sys/class/powercap/intel-rapl