-
Introdução ao MLX para Apple Silicon
O MLX é um framework de matriz flexível e eficiente para computação numérica e aprendizado de máquina em processadores Apple Silicon. Vamos explorar os recursos essenciais, incluindo memória unificada, computação preguiçosa e transformações de função. Também analisaremos técnicas mais avançadas para criar e acelerar modelos de aprendizado de máquina nas plataformas Apple usando APIs em Swift e Python.
Capítulos
- 0:00 - Introdução
- 1:15 - Visão geral do MLX
- 4:21 - Principais recursos
- 10:15 - Acelerar o MLX
- 17:30 - MLX Swift
Recursos
- MLX Swift Examples
- MLX Examples
- MLX Swift
- MLX LM - Python API
- MLX Explore - Python API
- MLX Framework
- MLX Llama Inference
- MLX
Vídeos relacionados
WWDC25
-
Buscar neste vídeo...
-
-
3:48 - Basics
import mlx.core as mx # Make an array a = mx.array([1, 2, 3]) # Make another array b = mx.array([4, 5, 6]) # Do an operation c = a + b # Access information about the array shape = c.shape dtype = c.dtype print(f"Result c: {c}") print(f"Shape: {shape}") print(f"Data type: {dtype}") -
5:31 - Unified memory
import mlx.core as mx a = mx.array([1, 2, 3]) b = mx.array([4, 5, 6]) c = mx.add(a, b, stream=mx.gpu) d = mx.multiply(a, b, stream=mx.cpu) print(f"c computed on the GPU: {c}") print(f"d computed on the CPU: {d}") -
6:20 - Lazy computation
import mlx.core as mx # Make an array a = mx.array([1, 2, 3]) # Make another array b = mx.array([4, 5, 6]) # Do an operation c = a + b # Evaluates c before printing it print(c) # Also evaluates c c_list = c.tolist() # Also evaluates c mx.eval(c) print(f"Evaluate c by converting to list: {c_list}") print(f"Evaluate c using print: {c}") print(f"Evaluate c using mx.eval(): {c}") -
7:32 - Function transformation
import mlx.core as mx def sin(x): return mx.sin(x) dfdx = mx.grad(sin) def sin(x): return mx.sin(x) d2fdx2 = mx.grad(mx.grad(mx.sin)) # Computes the second derivative of sine at 1.0 d2fdx2(mx.array(1.0)) -
9:16 - Neural Networks in MLX
import mlx.core as mx import mlx.nn as nn import mlx.optimizers as optim class MLP(nn.Module): """A simple MLP.""" def __init__(self, dim, h_dim): super().__init__() self.linear1 = nn.Linear(dim, h_dim) self.linear2 = nn.Linear(h_dim, dim) def __call__(self, x): x = self.linear1(x) x = nn.relu(x) x = self.linear2(x) return x -
9:57 - MLX and PyTorch
# MLX version import mlx.core as mx import mlx.nn as nn import mlx.optimizers as optim class MLP(nn.Module): """A simple MLP.""" def __init__(self, dim, h_dim): super().__init__() self.linear1 = nn.Linear(dim, h_dim) self.linear2 = nn.Linear(h_dim, dim) def __call__(self, x): x = self.linear1(x) x = nn.relu(x) x = self.linear2(x) return x # PyTorch version import torch import torch.nn as nn import torch.optim as optim class MLP(nn.Module): """A simple MLP.""" def __init__(self, dim, h_dim): super().__init__() self.linear1 = nn.Linear(dim, h_dim) self.linear2 = nn.Linear(h_dim, dim) def forward(self, x): x = self.linear1(x) x = x.relu() x = self.linear2(x) return x -
11:35 - Compiling MLX functions
import mlx.core as mx import math def gelu(x): return x * (1 + mx.erf(x / math.sqrt(2))) / 2 @mx.compile def compiled_gelu(x): return x * (1 + mx.erf(x / math.sqrt(2))) / 2 x = mx.random.normal(shape=(4,)) out = gelu(x) compiled_out = compiled_gelu(x) print(f"gelu: {out}") print(f"compiled gelu: {compiled_out}") -
12:32 - MLX Fast package
import mlx.core as mx import time def rms_norm(x, weight, eps=1e-5): y = x.astype(mx.float32) y = y * mx.rsqrt(mx.mean( mx.square(y), axis=-1, keepdims=True, ) + eps) return (weight * y).astype(x.dtype) batch_size = 8192 feature_dim = 4096 iterations = 1000 x = mx.random.normal([batch_size, feature_dim]) weight = mx.ones(feature_dim) bias = mx.zeros(feature_dim) start_time = time.perf_counter() for _ in range(iterations): y = rms_norm(x, weight, eps=1e-5) mx.eval(y) rms_norm_time = time.perf_counter() - start_time print(f"rms_norm execution: {gelu_time:0.4f} sec") start_time = time.perf_counter() for _ in range(iterations): mx.eval(mx.fast.rms_norm(x, weight, eps=1e-5)) fast_rms_norm_time = time.perf_counter() - start_time print(f"mx.fast.rms_norm execution: {compiled_gelu_time:0.4f} sec") print(f"mx.fast.rms_norm speedup: {rms_norm_time/fast_rms_norm_time:0.2f}x") -
13:30 - Custom Metal kernel
import mlx.core as mx # Build the kernel source = """ uint elem = thread_position_in_grid.x; out[elem] = metal::exp(inp[elem]); """ kernel = mx.fast.metal_kernel( name="myexp", input_names=["inp"], output_names=["out"], source=source, ) # Call the kernel on a sample input x = mx.array([1.0, 2.0, 3.0]) out = kernel( inputs=[x], grid=(x.size, 1, 1), threadgroup=(256, 1, 1), output_shapes=[x.shape], output_dtypes=[x.dtype], )[0] print(out) -
14:41 - Quantization
import mlx.core as mx x = mx.random.normal([1024]) weight = mx.random.normal([1024, 1024]) quantized_weight, scales, biases = mx.quantize( weight, bits=4, group_size=32, ) y = mx.quantized_matmul( x, quantized_weight, scales=scales, biases=biases, bits=4, group_size=32, ) w_orig = mx.dequantize( quantized_weight, scales=scales, biases=biases, bits=4, group_size=32, ) -
15:23 - Quantized models
import mlx.nn as nn model = nn.Sequential( nn.Embedding(100, 32), nn.Linear(32, 32), nn.Linear(32, 32), nn.Linear(32, 1), ) print(model) nn.quantize( model, bits=4, group_size=32, ) print(model) -
16:50 - Distributed
import mlx.core as mx group = mx.distributed.init() world_size = group.size() rank = group.rank() x = mx.array([1.0]) x_sum = mx.distributed.all_sum(x) print(x_sum) -
17:20 - Distributed launcher
mlx.launch --hosts ip1, ip2, ip3, ip4 my_script.py -
18:20 - MLX Swift
// Swift import MLX // Make an array let a = MLXArray([1, 2, 3]) // Make another array let b = MLXArray([1, 2, 3]) // Do an operation let c = a + b // Access information about the array let shape = c.shape let dtype = c.dtype // Print results print("a: \(a)") print("b: \(b)") print("c = a + b: \(c)") print("shape: \(shape)") print("dtype: \(dtype)")
-
-
- 0:00 - Introdução
O MLX é um framework de matriz de código aberto desenvolvido especificamente para o Apple Silicon. Ele permite tarefas eficientes de aprendizado de máquina e possibilita a execução de LLMs (grandes modelos de linguagem) diretamente no dispositivo usando Python e Swift.
- 1:15 - Visão geral do MLX
Esse framework de aprendizado de máquina de alto desempenho é otimizado para o Apple Silicon, permitindo tarefas de computação numérica rápida e aprendizado de máquina na CPU e GPU. Ele tem uma API de núcleo semelhante ao NumPy, e a API de nível superior é semelhante ao PyTorch e JAX. Use-o em apps como o LM Studio para geração de texto no dispositivo com Lams (grandes modelos de linguagem). O MLX também tem APIs no Python, Swift, C++ e C. O MLX está em código aberto sob licença do MIT e tem uma comunidade ativa no Hugging Face.
- 4:21 - Principais recursos
O MLX é incrivelmente eficiente porque foi feito sob medida para o Apple Silicon, aproveitando sua arquitetura de memória unificada. O compartilhamento de memória entre a CPU e a GPU elimina a necessidade de cópia de dados. As operações simplesmente especificam o dispositivo desejado. Em vez de executar imediatamente uma computação, o MLX cria gráficos de computação que são executados somente quando um resultado é necessário. Com as transformações de funções, o MLX pode receber funções como entrada e retornar novas funções, facilitando a diferenciação automática e outras otimizações. O MLX inclui pacotes de nível superior para construir e treinar redes neurais, bem como operações comuns de aprendizado de máquina. Esses pacotes são modulares e projetados para serem semelhantes a frameworks populares como o PyTorch, facilitando a alternância de desenvolvedores.
- 10:15 - Acelerar o MLX
As compilações de função com 'mx.compile' fundem várias inicializações de kernel da GPU em um único kernel, reduzindo a largura de banda da memória e a sobrecarga de execução. Para operações mais complexas, o subpacote 'mx.fast' fornece implementações altamente ajustadas e especializadas de operações comuns de aprendizado de máquina, como a norma RMS e mecanismos de atenção. O MLX permite quantização para inferência mais rápida e eficiente com menos sobrecarga de memória, reduzindo a precisão sem afetar excessivamente a qualidade. As computações em larga escala podem usar o subpacote 'mx.distributed' para distribuir tarefas em várias máquinas.
- 17:30 - MLX Swift
O MLX também oferece uma API do Swift que oferece a mesma melhoria em eficiência, para um desenvolvimento integrado em plataformas da Apple no Xcode. Visite o site do MLX ou baixe os repositórios de exemplo para saber mais.