diff --git a/x/models/nn/nn.go b/x/models/nn/nn.go index 9aa333bc..7c7461f0 100644 --- a/x/models/nn/nn.go +++ b/x/models/nn/nn.go @@ -61,6 +61,9 @@ type Linear struct { } func NewLinear(weight *mlx.Array, bias *mlx.Array) *Linear { + if bias != nil && bias.Valid() && bias.DType() != weight.DType() { + bias = bias.AsType(weight.DType()) + } return &Linear{Weight: weight, Bias: bias} } @@ -95,6 +98,9 @@ func NewQuantizedLinear(weight *mlx.Array, bias *mlx.Array, groupSize, bits int, } else { mlx.Eval(qw, scales) } + if bias != nil && bias.Valid() && bias.DType() != weight.DType() { + bias = bias.AsType(weight.DType()) + } return &QuantizedLinear{ Weight: qw, Scales: scales, @@ -107,20 +113,22 @@ func NewQuantizedLinear(weight *mlx.Array, bias *mlx.Array, groupSize, bits int, } func (ql *QuantizedLinear) Forward(x *mlx.Array) *mlx.Array { - var out *mlx.Array + out := mlx.QuantizedMatmul(x, ql.Weight, ql.Scales, ql.QBiases, true, ql.GroupSize, ql.Bits, ql.Mode) if ql.GlobalScale != nil { // Double-scale nvfp4 (e.g., NVIDIA ModelOpt): standard quantized_matmul // followed by global_scale multiply. The global_scale is a per-tensor // F32 scalar (weight_scale_2 in NVIDIA's format). // TODO: switch to a fused double-scale matmul once MLX has kernel // coverage for this path. - out = mlx.QuantizedMatmul(x, ql.Weight, ql.Scales, ql.QBiases, true, ql.GroupSize, ql.Bits, ql.Mode) - out = mlx.Mul(out, ql.GlobalScale) - } else { - out = mlx.QuantizedMatmul(x, ql.Weight, ql.Scales, ql.QBiases, true, ql.GroupSize, ql.Bits, ql.Mode) + outDType := out.DType() + out = mlx.Mul(out, ql.GlobalScale).AsType(outDType) } if ql.Bias != nil && ql.Bias.Valid() { - out = out.Add(ql.Bias) + bias := ql.Bias + if bias.DType() != out.DType() { + bias = bias.AsType(out.DType()) + } + out = out.Add(bias) } return out } @@ -184,7 +192,8 @@ func (qe *QuantizedEmbedding) Forward(indices *mlx.Array) *mlx.Array { } out := mlx.Dequantize(weight, scales, qbiases, qe.GroupSize, qe.Bits, qe.Mode) if qe.GlobalScale != nil { - out = mlx.Mul(out, qe.GlobalScale) + outDType := out.DType() + out = mlx.Mul(out, qe.GlobalScale).AsType(outDType) } return out }