- MLX SFT now honours
training.max_grad_norm(#749 by @Srinivasan8888 in #750). The field is forwarded intoTrainingArgumentsby sixteen transformers trainers, so the documented default clips every transformers run at 1.0 — and onbackend: mlxit reached nothing: no MLX file read it,mlx_lm'sTrainingArgshas no such field and its trainer clips nowhere, and theMLX backend ignores:line did not mention it. The same config therefore trained clipped on one backend and unclipped on the other, silently. Gradients are now clipped throughmlx.optimizers.clip_grad_normby an optimizer that clips before delegating, which reaches mlx-lm's singleoptimizer.update(model, grad)call site without forking its training loop;optimizer.stateandoptimizer.learning_ratestill delegate, because upstream reads both off the object it is handed. The norm that ran is recorded inadapter_config.json. Measured on an M1 inside upstream's own compiled-step shape, one step on an ill-conditioned batch moved SGD weights by 388.03 unclipped versus 0.0085 atmax_grad_norm: 1.0; AdamW moves 0.126505 versus 0.126504, because Adam normalises by its second moment — so this rescuesoptimizer: sgd/lionand gradient spikes rather than every MLX run.