mirror of
https://github.com/hanzo-ml/trainer.git
synced 2026-09-24 00:31:34 +00:00
* fix(examples): Verify TrainJob Completion Signed-off-by: Andrey Velichkevich <[email protected]> * Rename client to TrainerClient() Signed-off-by: Andrey Velichkevich <[email protected]> --------- Signed-off-by: Andrey Velichkevich <[email protected]>
126 KiB
126 KiB
In [ ]:
# !pip install -U kubeflowIn [ ]:
!pip install "mlx>=0.28.0"
!pip install "mlx-data>=0.1.0"
!pip install "matplotlib>=3.10.5"In [1]:
def mlx_train_mnist(bucket: str, model_name: str):
import time
from functools import partial
import mlx.core as mx
import mlx.nn as nn
import mlx.optimizers as optim
from mlx.data.datasets import load_mnist
import boto3
# Define a simple MLP model with MLX.
class MLP(nn.Module):
def __init__(
self, in_dims: int, hidden_dims: int, num_layers: int, out_dims: int
):
super().__init__()
layer_sizes = [in_dims] + [hidden_dims] * num_layers + [out_dims]
self.layers = [
nn.Linear(idim, odim)
for idim, odim in zip(layer_sizes[:-1], layer_sizes[1:])
]
def __call__(self, x):
for layer in self.layers[:-1]:
x = nn.relu(layer(x))
return self.layers[-1](x)
# Initializer MLX distributed backend.
dist = mx.distributed.init(strict=True, backend="mpi")
world_size = dist.size()
rank = dist.rank()
print(f"Start Distributed Training, WORLD_SIZE: {world_size}, RANK: {rank}")
if rank == 0:
print("Download MNIST dataset")
# Load MNIST dataset and partition it.
BATCH_SIZE = 128
train_dataset = load_mnist()
distributed_ds = (
train_dataset.shuffle()
.partition_if(world_size > 1, world_size, rank)
.key_transform("image", lambda x: (x.astype("float32") / 255.0).ravel())
)
# Create the MLP model and SGD optimizer
model = MLP(
in_dims=distributed_ds[0]["image"].shape[-1],
hidden_dims=32,
num_layers=2,
out_dims=10,
)
optimizer = optim.SGD(learning_rate=0.01)
# Define function to calculate loss and accuracy.
def loss_fn(model, x, y):
output = model(x)
loss = mx.mean(nn.losses.cross_entropy(output, y))
acc = mx.mean(mx.argmax(output, axis=1) == y)
return loss, acc
# Define single training step.
@partial(mx.compile, inputs=model.state, outputs=model.state)
def step(x, y):
loss_and_grad_fn = nn.value_and_grad(model, loss_fn)
(loss, acc), grads = loss_and_grad_fn(model, x, y)
# Average grads to aggregate them across distributed nodes.
grads = nn.utils.average_gradients(grads)
optimizer.update(model, grads)
return loss, acc
# Average statistic across distributed nodes.
def average_stats(stats, count):
with mx.stream(mx.cpu):
stats = mx.distributed.all_sum(mx.array(stats))
count = mx.distributed.all_sum(count)
return (stats / count).tolist()
# Start distributed training.
if rank == 0:
print("Start MLX training")
for epoch in range(15):
epoch_start = time.perf_counter()
losses = accuracies = count = 0
for batch_idx, batch_sample in enumerate(distributed_ds.batch(BATCH_SIZE)):
x = mx.array(batch_sample["image"])
y = mx.array(batch_sample["label"])
loss, acc = step(x, y)
mx.eval(loss, acc, model.state)
losses += loss.item()
accuracies += acc.item()
count += 1
# Print the results.
if batch_idx % 10 == 0:
loss, acc = average_stats([losses, accuracies], count)
if rank == 0:
print(
"Epoch: {} [{}/{} ({:.0f}%)] \tTrain loss: {:.3f}, acc: {:.3f}".format(
epoch,
batch_idx * len(x),
len(train_dataset),
100.0 * batch_idx * len(x) / len(train_dataset),
loss,
acc,
)
)
if rank == 0:
print(
"Epoch: {}, time: {:.2f} seconds\n\n".format(
epoch, time.perf_counter() - epoch_start
)
)
# Finally, export model to S3.
if rank == 0:
print("Exporting MNIST model to S3")
model.save_weights(model_name)
boto3.client("s3").upload_file(model_name, bucket, model_name)In [2]:
from kubeflow.trainer import TrainerClient, CustomTrainer
for r in TrainerClient().list_runtimes():
if r.name == "mlx-distributed":
print(f"Name: {r.name}, Framework: {r.trainer.framework}, Trainer Type: {r.trainer.trainer_type.value}\n")
mlx_runtime = rName: mlx-distributed, Framework: mlx, Trainer Type: CustomTrainer
In [4]:
# BUCKET = "Add your S3 bucket"
MODEL = "mnist.npz"In [5]:
args = {"bucket": BUCKET, "model_name": MODEL}
job_id = TrainerClient().train(
trainer=CustomTrainer(
func=mlx_train_mnist,
func_args=args,
num_nodes=3,
packages_to_install=["boto3"],
resources_per_node={
"gpu": 1
},
),
runtime=mlx_runtime,
)In [6]:
# Train API generates a random TrainJob id.
job_idOut [6]:
'vd59b4f8583c'
In [7]:
for job in TrainerClient().list_jobs():
print(f"TrainJob: {job.name}, Status: {job.status}, Created at: {job.creation_timestamp}")TrainJob: vd59b4f8583c, Status: Created, Created at: 2025-10-18 00:21:13+00:00
In [8]:
# We execute mpirun command on node-0, which functions as the MPI Launcher node.
for c in TrainerClient().get_job(name=job_id).steps:
print(f"Step: {c.name}, Status: {c.status}, Devices: {c.device} x {c.device_count}\n")Step: node-0, Status: Running, Devices: gpu x 1 Step: node-1, Status: Running, Devices: gpu x 1 Step: node-2, Status: Running, Devices: gpu x 1
In [9]:
for logline in TrainerClient().get_job_logs(job_id, follow=True):
print(logline)Warning: Permanently added '[vd59b4f8583c-node-0-1.vd59b4f8583c]:2222' (ECDSA) to the list of known hosts. Warning: Permanently added '[vd59b4f8583c-node-0-0.vd59b4f8583c]:2222' (ECDSA) to the list of known hosts. Start Distributed Training, WORLD_SIZE: 3, RANK: 0 Download MNIST dataset Start Distributed Training, WORLD_SIZE: 3, RANK: 1 Start Distributed Training, WORLD_SIZE: 3, RANK: 2 Downloading https://raw.githubusercontent.com/fgnt/mnist/master/train-images-idx3-ubyte.gz |███████████████████████████████████ | 8.2MiB / 9.5MiB (134.8MiB/s) Downloading https://raw.githubusercontent.com/fgnt/mnist/master/train-images-idx3-ubyte.gz 9.5MiB (147.3MiB/s) Downloading https://raw.githubusercontent.com/fgnt/mnist/master/train-images-idx3-ubyte.gz 9.5MiB (119.3MiB/s) Downloading https://raw.githubusercontent.com/fgnt/mnist/master/t10k-images-idx3-ubyte.gz |█ | 32.0KiB / 1.6MiB (3.9MiB/s) Downloading https://raw.githubusercontent.com/fgnt/mnist/master/t10k-images-idx3-ubyte.gz 1.6MiB (35.0MiB/s) Downloading https://raw.githubusercontent.com/fgnt/mnist/master/t10k-images-idx3-ubyte.gz 1.6MiB (35.3MiB/s) Downloading https://raw.githubusercontent.com/fgnt/mnist/master/train-labels-idx1-ubyte.gz 32.0KiB (17.1MiB/s) Downloading https://raw.githubusercontent.com/fgnt/mnist/master/train-labels-idx1-ubyte.gz 32.0KiB (18.4MiB/s) Downloading https://raw.githubusercontent.com/fgnt/mnist/master/t10k-labels-idx1-ubyte.gz 8.0KiB (54.3MiB/s) Downloading https://raw.githubusercontent.com/fgnt/mnist/master/train-labels-idx1-ubyte.gz 32.0KiB (18.5MiB/s) Downloading https://raw.githubusercontent.com/fgnt/mnist/master/t10k-labels-idx1-ubyte.gz 8.0KiB (53.5MiB/s) Downloading https://raw.githubusercontent.com/fgnt/mnist/master/t10k-labels-idx1-ubyte.gz 8.0KiB (56.3MiB/s) Start MLX training Epoch: 0 [0/60000 (0%)] Train loss: 2.310, acc: 0.086 Epoch: 0 [1280/60000 (2%)] Train loss: 2.309, acc: 0.100 Epoch: 0 [2560/60000 (4%)] Train loss: 2.308, acc: 0.100 Epoch: 0 [3840/60000 (6%)] Train loss: 2.310, acc: 0.097 Epoch: 0 [5120/60000 (9%)] Train loss: 2.310, acc: 0.098 Epoch: 0 [6400/60000 (11%)] Train loss: 2.309, acc: 0.098 Epoch: 0 [7680/60000 (13%)] Train loss: 2.309, acc: 0.100 Epoch: 0 [8960/60000 (15%)] Train loss: 2.309, acc: 0.100 Epoch: 0 [10240/60000 (17%)] Train loss: 2.308, acc: 0.102 Epoch: 0 [11520/60000 (19%)] Train loss: 2.308, acc: 0.103 Epoch: 0 [12800/60000 (21%)] Train loss: 2.307, acc: 0.104 Epoch: 0 [14080/60000 (23%)] Train loss: 2.307, acc: 0.105 Epoch: 0 [15360/60000 (26%)] Train loss: 2.307, acc: 0.105 Epoch: 0 [16640/60000 (28%)] Train loss: 2.307, acc: 0.105 Epoch: 0 [17920/60000 (30%)] Train loss: 2.306, acc: 0.106 Epoch: 0 [19200/60000 (32%)] Train loss: 2.306, acc: 0.106 Epoch: 0, time: 29.13 seconds Epoch: 1 [0/60000 (0%)] Train loss: 2.299, acc: 0.115 Epoch: 1 [1280/60000 (2%)] Train loss: 2.298, acc: 0.126 Epoch: 1 [2560/60000 (4%)] Train loss: 2.297, acc: 0.126 Epoch: 1 [3840/60000 (6%)] Train loss: 2.299, acc: 0.122 Epoch: 1 [5120/60000 (9%)] Train loss: 2.299, acc: 0.123 Epoch: 1 [6400/60000 (11%)] Train loss: 2.298, acc: 0.122 Epoch: 1 [7680/60000 (13%)] Train loss: 2.298, acc: 0.124 Epoch: 1 [8960/60000 (15%)] Train loss: 2.298, acc: 0.124 Epoch: 1 [10240/60000 (17%)] Train loss: 2.297, acc: 0.126 Epoch: 1 [11520/60000 (19%)] Train loss: 2.296, acc: 0.127 Epoch: 1 [12800/60000 (21%)] Train loss: 2.296, acc: 0.128 Epoch: 1 [14080/60000 (23%)] Train loss: 2.296, acc: 0.129 Epoch: 1 [15360/60000 (26%)] Train loss: 2.296, acc: 0.128 Epoch: 1 [16640/60000 (28%)] Train loss: 2.295, acc: 0.128 Epoch: 1 [17920/60000 (30%)] Train loss: 2.295, acc: 0.129 Epoch: 1 [19200/60000 (32%)] Train loss: 2.295, acc: 0.130 Epoch: 1, time: 0.48 seconds Epoch: 2 [0/60000 (0%)] Train loss: 2.288, acc: 0.133 Epoch: 2 [1280/60000 (2%)] Train loss: 2.286, acc: 0.144 Epoch: 2 [2560/60000 (4%)] Train loss: 2.286, acc: 0.147 Epoch: 2 [3840/60000 (6%)] Train loss: 2.287, acc: 0.146 Epoch: 2 [5120/60000 (9%)] Train loss: 2.287, acc: 0.148 Epoch: 2 [6400/60000 (11%)] Train loss: 2.286, acc: 0.149 Epoch: 2 [7680/60000 (13%)] Train loss: 2.286, acc: 0.151 Epoch: 2 [8960/60000 (15%)] Train loss: 2.286, acc: 0.153 Epoch: 2 [10240/60000 (17%)] Train loss: 2.285, acc: 0.156 Epoch: 2 [11520/60000 (19%)] Train loss: 2.284, acc: 0.159 Epoch: 2 [12800/60000 (21%)] Train loss: 2.284, acc: 0.161 Epoch: 2 [14080/60000 (23%)] Train loss: 2.284, acc: 0.163 Epoch: 2 [15360/60000 (26%)] Train loss: 2.283, acc: 0.164 Epoch: 2 [16640/60000 (28%)] Train loss: 2.283, acc: 0.165 Epoch: 2 [17920/60000 (30%)] Train loss: 2.282, acc: 0.167 Epoch: 2 [19200/60000 (32%)] Train loss: 2.282, acc: 0.169 Epoch: 2, time: 0.50 seconds Epoch: 3 [0/60000 (0%)] Train loss: 2.274, acc: 0.172 Epoch: 3 [1280/60000 (2%)] Train loss: 2.272, acc: 0.197 Epoch: 3 [2560/60000 (4%)] Train loss: 2.271, acc: 0.199 Epoch: 3 [3840/60000 (6%)] Train loss: 2.272, acc: 0.197 Epoch: 3 [5120/60000 (9%)] Train loss: 2.272, acc: 0.197 Epoch: 3 [6400/60000 (11%)] Train loss: 2.271, acc: 0.197 Epoch: 3 [7680/60000 (13%)] Train loss: 2.270, acc: 0.199 Epoch: 3 [8960/60000 (15%)] Train loss: 2.270, acc: 0.201 Epoch: 3 [10240/60000 (17%)] Train loss: 2.269, acc: 0.204 Epoch: 3 [11520/60000 (19%)] Train loss: 2.268, acc: 0.206 Epoch: 3 [12800/60000 (21%)] Train loss: 2.267, acc: 0.208 Epoch: 3 [14080/60000 (23%)] Train loss: 2.266, acc: 0.210 Epoch: 3 [15360/60000 (26%)] Train loss: 2.266, acc: 0.211 Epoch: 3 [16640/60000 (28%)] Train loss: 2.265, acc: 0.211 Epoch: 3 [17920/60000 (30%)] Train loss: 2.264, acc: 0.214 Epoch: 3 [19200/60000 (32%)] Train loss: 2.264, acc: 0.216 Epoch: 3, time: 0.49 seconds Epoch: 4 [0/60000 (0%)] Train loss: 2.250, acc: 0.219 Epoch: 4 [1280/60000 (2%)] Train loss: 2.247, acc: 0.236 Epoch: 4 [2560/60000 (4%)] Train loss: 2.247, acc: 0.236 Epoch: 4 [3840/60000 (6%)] Train loss: 2.247, acc: 0.238 Epoch: 4 [5120/60000 (9%)] Train loss: 2.247, acc: 0.236 Epoch: 4 [6400/60000 (11%)] Train loss: 2.245, acc: 0.237 Epoch: 4 [7680/60000 (13%)] Train loss: 2.244, acc: 0.238 Epoch: 4 [8960/60000 (15%)] Train loss: 2.244, acc: 0.239 Epoch: 4 [10240/60000 (17%)] Train loss: 2.242, acc: 0.242 Epoch: 4 [11520/60000 (19%)] Train loss: 2.240, acc: 0.244 Epoch: 4 [12800/60000 (21%)] Train loss: 2.239, acc: 0.245 Epoch: 4 [14080/60000 (23%)] Train loss: 2.238, acc: 0.247 Epoch: 4 [15360/60000 (26%)] Train loss: 2.237, acc: 0.246 Epoch: 4 [16640/60000 (28%)] Train loss: 2.236, acc: 0.247 Epoch: 4 [17920/60000 (30%)] Train loss: 2.234, acc: 0.248 Epoch: 4 [19200/60000 (32%)] Train loss: 2.233, acc: 0.249 Epoch: 4, time: 0.49 seconds Epoch: 5 [0/60000 (0%)] Train loss: 2.209, acc: 0.279 Epoch: 5 [1280/60000 (2%)] Train loss: 2.207, acc: 0.270 Epoch: 5 [2560/60000 (4%)] Train loss: 2.206, acc: 0.267 Epoch: 5 [3840/60000 (6%)] Train loss: 2.205, acc: 0.269 Epoch: 5 [5120/60000 (9%)] Train loss: 2.204, acc: 0.268 Epoch: 5 [6400/60000 (11%)] Train loss: 2.202, acc: 0.271 Epoch: 5 [7680/60000 (13%)] Train loss: 2.200, acc: 0.272 Epoch: 5 [8960/60000 (15%)] Train loss: 2.199, acc: 0.275 Epoch: 5 [10240/60000 (17%)] Train loss: 2.196, acc: 0.279 Epoch: 5 [11520/60000 (19%)] Train loss: 2.194, acc: 0.282 Epoch: 5 [12800/60000 (21%)] Train loss: 2.192, acc: 0.284 Epoch: 5 [14080/60000 (23%)] Train loss: 2.189, acc: 0.286 Epoch: 5 [15360/60000 (26%)] Train loss: 2.188, acc: 0.287 Epoch: 5 [16640/60000 (28%)] Train loss: 2.186, acc: 0.288 Epoch: 5 [17920/60000 (30%)] Train loss: 2.183, acc: 0.290 Epoch: 5 [19200/60000 (32%)] Train loss: 2.181, acc: 0.292 Epoch: 5, time: 0.49 seconds Epoch: 6 [0/60000 (0%)] Train loss: 2.138, acc: 0.341 Epoch: 6 [1280/60000 (2%)] Train loss: 2.136, acc: 0.326 Epoch: 6 [2560/60000 (4%)] Train loss: 2.135, acc: 0.323 Epoch: 6 [3840/60000 (6%)] Train loss: 2.131, acc: 0.325 Epoch: 6 [5120/60000 (9%)] Train loss: 2.130, acc: 0.324 Epoch: 6 [6400/60000 (11%)] Train loss: 2.125, acc: 0.327 Epoch: 6 [7680/60000 (13%)] Train loss: 2.123, acc: 0.327 Epoch: 6 [8960/60000 (15%)] Train loss: 2.119, acc: 0.329 Epoch: 6 [10240/60000 (17%)] Train loss: 2.114, acc: 0.332 Epoch: 6 [11520/60000 (19%)] Train loss: 2.111, acc: 0.334 Epoch: 6 [12800/60000 (21%)] Train loss: 2.107, acc: 0.334 Epoch: 6 [14080/60000 (23%)] Train loss: 2.102, acc: 0.334 Epoch: 6 [15360/60000 (26%)] Train loss: 2.099, acc: 0.334 Epoch: 6 [16640/60000 (28%)] Train loss: 2.095, acc: 0.335 Epoch: 6 [17920/60000 (30%)] Train loss: 2.091, acc: 0.336 Epoch: 6 [19200/60000 (32%)] Train loss: 2.086, acc: 0.337 Epoch: 6, time: 0.49 seconds Epoch: 7 [0/60000 (0%)] Train loss: 2.008, acc: 0.372 Epoch: 7 [1280/60000 (2%)] Train loss: 2.004, acc: 0.359 Epoch: 7 [2560/60000 (4%)] Train loss: 2.000, acc: 0.357 Epoch: 7 [3840/60000 (6%)] Train loss: 1.993, acc: 0.362 Epoch: 7 [5120/60000 (9%)] Train loss: 1.989, acc: 0.362 Epoch: 7 [6400/60000 (11%)] Train loss: 1.981, acc: 0.368 Epoch: 7 [7680/60000 (13%)] Train loss: 1.976, acc: 0.368 Epoch: 7 [8960/60000 (15%)] Train loss: 1.970, acc: 0.372 Epoch: 7 [10240/60000 (17%)] Train loss: 1.961, acc: 0.376 Epoch: 7 [11520/60000 (19%)] Train loss: 1.955, acc: 0.380 Epoch: 7 [12800/60000 (21%)] Train loss: 1.948, acc: 0.383 Epoch: 7 [14080/60000 (23%)] Train loss: 1.940, acc: 0.387 Epoch: 7 [15360/60000 (26%)] Train loss: 1.933, acc: 0.390 Epoch: 7 [16640/60000 (28%)] Train loss: 1.927, acc: 0.394 Epoch: 7 [17920/60000 (30%)] Train loss: 1.919, acc: 0.398 Epoch: 7 [19200/60000 (32%)] Train loss: 1.912, acc: 0.402 Epoch: 7, time: 0.49 seconds Epoch: 8 [0/60000 (0%)] Train loss: 1.782, acc: 0.510 Epoch: 8 [1280/60000 (2%)] Train loss: 1.775, acc: 0.464 Epoch: 8 [2560/60000 (4%)] Train loss: 1.768, acc: 0.469 Epoch: 8 [3840/60000 (6%)] Train loss: 1.757, acc: 0.477 Epoch: 8 [5120/60000 (9%)] Train loss: 1.751, acc: 0.479 Epoch: 8 [6400/60000 (11%)] Train loss: 1.739, acc: 0.486 Epoch: 8 [7680/60000 (13%)] Train loss: 1.732, acc: 0.489 Epoch: 8 [8960/60000 (15%)] Train loss: 1.723, acc: 0.494 Epoch: 8 [10240/60000 (17%)] Train loss: 1.712, acc: 0.499 Epoch: 8 [11520/60000 (19%)] Train loss: 1.703, acc: 0.503 Epoch: 8 [12800/60000 (21%)] Train loss: 1.693, acc: 0.508 Epoch: 8 [14080/60000 (23%)] Train loss: 1.682, acc: 0.512 Epoch: 8 [15360/60000 (26%)] Train loss: 1.674, acc: 0.516 Epoch: 8 [16640/60000 (28%)] Train loss: 1.665, acc: 0.520 Epoch: 8 [17920/60000 (30%)] Train loss: 1.655, acc: 0.524 Epoch: 8 [19200/60000 (32%)] Train loss: 1.646, acc: 0.528 Epoch: 8, time: 0.49 seconds Epoch: 9 [0/60000 (0%)] Train loss: 1.483, acc: 0.604 Epoch: 9 [1280/60000 (2%)] Train loss: 1.478, acc: 0.576 Epoch: 9 [2560/60000 (4%)] Train loss: 1.471, acc: 0.584 Epoch: 9 [3840/60000 (6%)] Train loss: 1.458, acc: 0.595 Epoch: 9 [5120/60000 (9%)] Train loss: 1.452, acc: 0.598 Epoch: 9 [6400/60000 (11%)] Train loss: 1.438, acc: 0.605 Epoch: 9 [7680/60000 (13%)] Train loss: 1.431, acc: 0.608 Epoch: 9 [8960/60000 (15%)] Train loss: 1.422, acc: 0.610 Epoch: 9 [10240/60000 (17%)] Train loss: 1.411, acc: 0.614 Epoch: 9 [11520/60000 (19%)] Train loss: 1.402, acc: 0.618 Epoch: 9 [12800/60000 (21%)] Train loss: 1.392, acc: 0.621 Epoch: 9 [14080/60000 (23%)] Train loss: 1.381, acc: 0.624 Epoch: 9 [15360/60000 (26%)] Train loss: 1.373, acc: 0.626 Epoch: 9 [16640/60000 (28%)] Train loss: 1.364, acc: 0.628 Epoch: 9 [17920/60000 (30%)] Train loss: 1.355, acc: 0.631 Epoch: 9 [19200/60000 (32%)] Train loss: 1.347, acc: 0.634 Epoch: 9, time: 0.49 seconds Epoch: 10 [0/60000 (0%)] Train loss: 1.200, acc: 0.677 Epoch: 10 [1280/60000 (2%)] Train loss: 1.196, acc: 0.661 Epoch: 10 [2560/60000 (4%)] Train loss: 1.191, acc: 0.668 Epoch: 10 [3840/60000 (6%)] Train loss: 1.177, acc: 0.679 Epoch: 10 [5120/60000 (9%)] Train loss: 1.173, acc: 0.679 Epoch: 10 [6400/60000 (11%)] Train loss: 1.160, acc: 0.685 Epoch: 10 [7680/60000 (13%)] Train loss: 1.155, acc: 0.686 Epoch: 10 [8960/60000 (15%)] Train loss: 1.148, acc: 0.688 Epoch: 10 [10240/60000 (17%)] Train loss: 1.140, acc: 0.690 Epoch: 10 [11520/60000 (19%)] Train loss: 1.132, acc: 0.693 Epoch: 10 [12800/60000 (21%)] Train loss: 1.125, acc: 0.696 Epoch: 10 [14080/60000 (23%)] Train loss: 1.115, acc: 0.698 Epoch: 10 [15360/60000 (26%)] Train loss: 1.109, acc: 0.699 Epoch: 10 [16640/60000 (28%)] Train loss: 1.103, acc: 0.701 Epoch: 10 [17920/60000 (30%)] Train loss: 1.096, acc: 0.703 Epoch: 10 [19200/60000 (32%)] Train loss: 1.090, acc: 0.704 Epoch: 10, time: 0.49 seconds Epoch: 11 [0/60000 (0%)] Train loss: 0.986, acc: 0.745 Epoch: 11 [1280/60000 (2%)] Train loss: 0.980, acc: 0.727 Epoch: 11 [2560/60000 (4%)] Train loss: 0.980, acc: 0.728 Epoch: 11 [3840/60000 (6%)] Train loss: 0.966, acc: 0.736 Epoch: 11 [5120/60000 (9%)] Train loss: 0.966, acc: 0.734 Epoch: 11 [6400/60000 (11%)] Train loss: 0.955, acc: 0.739 Epoch: 11 [7680/60000 (13%)] Train loss: 0.952, acc: 0.739 Epoch: 11 [8960/60000 (15%)] Train loss: 0.948, acc: 0.739 Epoch: 11 [10240/60000 (17%)] Train loss: 0.943, acc: 0.739 Epoch: 11 [11520/60000 (19%)] Train loss: 0.937, acc: 0.740 Epoch: 11 [12800/60000 (21%)] Train loss: 0.933, acc: 0.742 Epoch: 11 [14080/60000 (23%)] Train loss: 0.925, acc: 0.744 Epoch: 11 [15360/60000 (26%)] Train loss: 0.922, acc: 0.744 Epoch: 11 [16640/60000 (28%)] Train loss: 0.917, acc: 0.745 Epoch: 11 [17920/60000 (30%)] Train loss: 0.913, acc: 0.746 Epoch: 11 [19200/60000 (32%)] Train loss: 0.909, acc: 0.746 Epoch: 11, time: 0.49 seconds Epoch: 12 [0/60000 (0%)] Train loss: 0.847, acc: 0.760 Epoch: 12 [1280/60000 (2%)] Train loss: 0.839, acc: 0.764 Epoch: 12 [2560/60000 (4%)] Train loss: 0.842, acc: 0.763 Epoch: 12 [3840/60000 (6%)] Train loss: 0.830, acc: 0.769 Epoch: 12 [5120/60000 (9%)] Train loss: 0.832, acc: 0.766 Epoch: 12 [6400/60000 (11%)] Train loss: 0.823, acc: 0.769 Epoch: 12 [7680/60000 (13%)] Train loss: 0.821, acc: 0.769 Epoch: 12 [8960/60000 (15%)] Train loss: 0.820, acc: 0.769 Epoch: 12 [10240/60000 (17%)] Train loss: 0.816, acc: 0.769 Epoch: 12 [11520/60000 (19%)] Train loss: 0.812, acc: 0.770 Epoch: 12 [12800/60000 (21%)] Train loss: 0.809, acc: 0.771 Epoch: 12 [14080/60000 (23%)] Train loss: 0.803, acc: 0.772 Epoch: 12 [15360/60000 (26%)] Train loss: 0.801, acc: 0.772 Epoch: 12 [16640/60000 (28%)] Train loss: 0.798, acc: 0.772 Epoch: 12 [17920/60000 (30%)] Train loss: 0.795, acc: 0.773 Epoch: 12 [19200/60000 (32%)] Train loss: 0.793, acc: 0.774 Epoch: 12, time: 0.49 seconds Epoch: 13 [0/60000 (0%)] Train loss: 0.757, acc: 0.786 Epoch: 13 [1280/60000 (2%)] Train loss: 0.746, acc: 0.791 Epoch: 13 [2560/60000 (4%)] Train loss: 0.751, acc: 0.788 Epoch: 13 [3840/60000 (6%)] Train loss: 0.740, acc: 0.793 Epoch: 13 [5120/60000 (9%)] Train loss: 0.743, acc: 0.789 Epoch: 13 [6400/60000 (11%)] Train loss: 0.735, acc: 0.791 Epoch: 13 [7680/60000 (13%)] Train loss: 0.735, acc: 0.791 Epoch: 13 [8960/60000 (15%)] Train loss: 0.734, acc: 0.790 Epoch: 13 [10240/60000 (17%)] Train loss: 0.732, acc: 0.789 Epoch: 13 [11520/60000 (19%)] Train loss: 0.728, acc: 0.790 Epoch: 13 [12800/60000 (21%)] Train loss: 0.726, acc: 0.791 Epoch: 13 [14080/60000 (23%)] Train loss: 0.721, acc: 0.792 Epoch: 13 [15360/60000 (26%)] Train loss: 0.720, acc: 0.792 Epoch: 13 [16640/60000 (28%)] Train loss: 0.718, acc: 0.792 Epoch: 13 [17920/60000 (30%)] Train loss: 0.715, acc: 0.793 Epoch: 13 [19200/60000 (32%)] Train loss: 0.714, acc: 0.793 Epoch: 13, time: 0.49 seconds Epoch: 14 [0/60000 (0%)] Train loss: 0.695, acc: 0.797 Epoch: 14 [1280/60000 (2%)] Train loss: 0.680, acc: 0.808 Epoch: 14 [2560/60000 (4%)] Train loss: 0.685, acc: 0.803 Epoch: 14 [3840/60000 (6%)] Train loss: 0.675, acc: 0.808 Epoch: 14 [5120/60000 (9%)] Train loss: 0.679, acc: 0.805 Epoch: 14 [6400/60000 (11%)] Train loss: 0.671, acc: 0.807 Epoch: 14 [7680/60000 (13%)] Train loss: 0.672, acc: 0.807 Epoch: 14 [8960/60000 (15%)] Train loss: 0.672, acc: 0.806 Epoch: 14 [10240/60000 (17%)] Train loss: 0.670, acc: 0.806 Epoch: 14 [11520/60000 (19%)] Train loss: 0.667, acc: 0.808 Epoch: 14 [12800/60000 (21%)] Train loss: 0.666, acc: 0.808 Epoch: 14 [14080/60000 (23%)] Train loss: 0.661, acc: 0.809 Epoch: 14 [15360/60000 (26%)] Train loss: 0.660, acc: 0.809 Epoch: 14 [16640/60000 (28%)] Train loss: 0.658, acc: 0.809 Epoch: 14 [17920/60000 (30%)] Train loss: 0.657, acc: 0.809 Epoch: 14 [19200/60000 (32%)] Train loss: 0.656, acc: 0.809 Epoch: 14, time: 0.49 seconds Exporting MNIST model to S3
In [ ]:
TrainerClient().wait_for_job_status(name=job_id, timeout=20)In [10]:
import boto3
boto3.client("s3").download_file(BUCKET, MODEL, MODEL)In [12]:
import mlx.core as mx
import mlx.nn as nn
import matplotlib.pyplot as plt
from mlx.data.datasets import load_mnist
# Load test dataset and take the random batch from it.
test_batch = (
load_mnist(train=False)
.key_transform("image", lambda x: (x.astype("float32") / 255.0).ravel())
.batch(20)[mx.random.randint(10, 500)]
)
class MLP(nn.Module):
def __init__(self, in_dims: int, hidden_dims: int, num_layers: int, out_dims: int):
super().__init__()
layer_sizes = [in_dims] + [hidden_dims] * num_layers + [out_dims]
self.layers = [
nn.Linear(idim, odim)
for idim, odim in zip(layer_sizes[:-1], layer_sizes[1:])
]
def __call__(self, x):
for layer in self.layers[:-1]:
x = nn.relu(layer(x))
return self.layers[-1](x)
# Load weights from the trained model.
model = MLP(
in_dims=test_batch["image"][0].shape[-1],
hidden_dims=32,
num_layers=2,
out_dims=10,
).load_weights(MODEL)
# Send test batch to the pre-trained MLP model.
x = mx.array(test_batch["image"])
output = model(x)
fig = plt.figure(figsize=(15, 5))
for i in range(20):
# Format the input image and the model output.
image = test_batch["image"][i].reshape((28, 28))
pred_label = mx.argmax(output[i])
# Add data to the plot.
ax = fig.add_subplot(4, 5, i + 1, xticks=[], yticks=[])
ax.imshow(image, cmap="gray")
if test_batch["label"][i] == pred_label:
ax.set_title(test_batch["label"][i], color="green")
else:
ax.set_title("{} ({})".format(pred_label, test_batch["label"][i]), color="red")
ax.title.set_fontsize(20)
fig.tight_layout()In [ ]:
TrainerClient().delete_job(job_id)