Text-to-Image
MLX
MiniMax H3
Safetensors
English
apple-silicon
macos
image-to-image
image-editing
image-generation
Instructions to use devin-lai/MiniMax-H3-Image-mlx with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- MLX
How to use devin-lai/MiniMax-H3-Image-mlx with MLX:
# Download the model from the Hub pip install huggingface_hub[hf_xet] hf download devin-lai/MiniMax-H3-Image-mlx --local-dir MiniMax-H3-Image-mlx
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- LM Studio
- Atomic Chat
Download experiments/r3/fusions.py from devin-lai/MiniMax-H3-Image-mlx: direct link, hf CLI and curl.
- Browser
- Download file 5.7 kB
-
https://huggingface.co/devin-lai/MiniMax-H3-Image-mlx/resolve/main/experiments/r3/fusions.py
- Command line
-
hf download hf://devin-lai/MiniMax-H3-Image-mlx/experiments/r3/fusions.py
-
curl -L -o fusions.py https://huggingface.co/devin-lai/MiniMax-H3-Image-mlx/resolve/main/experiments/r3/fusions.py
5.7 kB
| """Research kernels. No default dispatch until full-output validation.""" | |
| from functools import lru_cache | |
| import mlx.core as mx | |
| from experiments.v2_mpp import gemm | |
| class TunedFC2: | |
| def __init__(self, layer): | |
| self.original = layer | |
| self.bias = layer.bias | |
| self.weight = layer.weight | |
| self.zero = mx.zeros(self.weight.shape[0], self.weight.dtype) | |
| def nbytes(self): | |
| return self.original.nbytes | |
| def __call__(self, x): | |
| if x.ndim != 2 or x.dtype != mx.bfloat16 or self.weight.shape != (5376, 14336): | |
| return self.original(x) | |
| return gemm( | |
| x, | |
| self.weight, | |
| self.zero if self.bias is None else self.bias, | |
| 64, | |
| 128, | |
| 512, | |
| 4, | |
| 8, | |
| ) | |
| def _qk(): | |
| return mx.fast.metal_kernel( | |
| name="h3_r3_qk_native_reduce", | |
| input_names=["qkv", "qw", "kw", "cosine", "sine", "epsilon"], | |
| output_names=["qout", "kout"], | |
| source=r""" | |
| uint lane = thread_position_in_threadgroup.x; | |
| uint row = threadgroup_position_in_grid.y; | |
| uint heads = qkv_shape[2], dim = qkv_shape[3]; | |
| uint token = row / heads, head = row % heads; | |
| uint qb = token * 3 * heads * dim + head * dim; | |
| uint kb = qb + heads * dim; | |
| uint rot = cosine_shape[1]; | |
| float qsum = 0, ksum = 0; | |
| #pragma unroll | |
| for (uint j = 0; j < 4; ++j) { | |
| uint c = lane * 4 + j; | |
| float q = float(qkv[qb+c]), k = float(qkv[kb+c]); | |
| qsum += q*q; ksum += k*k; | |
| } | |
| float qi = metal::precise::rsqrt(simd_sum(qsum)/float(dim)+epsilon[0]); | |
| float ki = metal::precise::rsqrt(simd_sum(ksum)/float(dim)+epsilon[0]); | |
| #pragma unroll | |
| for (uint j = 0; j < 4; ++j) { | |
| uint c = lane * 4 + j; | |
| T qn = T(float(qw[c])*(float(qkv[qb+c])*qi)); | |
| T kn = T(float(kw[c])*(float(qkv[kb+c])*ki)); | |
| if (c < rot) { | |
| uint partner = (c+rot/2)%rot; | |
| T qother = T(float(qw[partner])*(float(qkv[qb+partner])*qi)); | |
| T kother = T(float(kw[partner])*(float(qkv[kb+partner])*ki)); | |
| if (c < rot/2) { qother = -qother; kother = -kother; } | |
| T qcos = T(qn*cosine[token*rot+c]); | |
| T kcos = T(kn*cosine[token*rot+c]); | |
| T qsin = T(qother*sine[token*rot+c]); | |
| T ksin = T(kother*sine[token*rot+c]); | |
| qn = T(qcos+qsin); kn = T(kcos+ksin); | |
| } | |
| uint offset = HEAD_MAJOR ? (head*qkv_shape[0]+token)*dim+c : row*dim+c; | |
| qout[offset] = qn; kout[offset] = kn; | |
| } | |
| """, | |
| ) | |
| def qk_native_reduce(qkv, qw, kw, cos, sin, eps=1e-5, *, head_major=False): | |
| n, _, heads, dim = qkv.shape | |
| if dim != 128: | |
| raise ValueError("Research kernel only supports D128") | |
| shape = (1, heads, n, dim) if head_major else (1, n, heads, dim) | |
| return _qk()( | |
| inputs=[ | |
| qkv, | |
| qw, | |
| kw, | |
| cos.reshape(n, -1), | |
| sin.reshape(n, -1), | |
| mx.array([eps], mx.float32), | |
| ], | |
| template=[("T", qkv.dtype), ("HEAD_MAJOR", head_major)], | |
| grid=(32, n * heads, 1), | |
| threadgroup=(32, 1, 1), | |
| output_shapes=[shape, shape], | |
| output_dtypes=[qkv.dtype, qkv.dtype], | |
| ) | |
| def _norm(): | |
| return mx.fast.metal_kernel( | |
| name="h3_r3_norm_mod_native_reduce", | |
| input_names=["x", "weight", "shift", "scale", "indices", "epsilon"], | |
| output_names=["out"], | |
| source=r""" | |
| uint tid = thread_position_in_threadgroup.x; | |
| uint row = threadgroup_position_in_grid.y; | |
| uint width = x_shape[1]; | |
| float sum = 0; | |
| for (uint r = 0; r < width; r += TG*4) { | |
| #pragma unroll | |
| for (uint j = 0; j < 4; ++j) { | |
| uint c = r + tid*4+j; | |
| if (c < width) { float a = float(x[row*width+c]); sum += a*a; } | |
| } | |
| } | |
| sum = simd_sum(sum); | |
| threadgroup float partial[32]; | |
| uint lane = tid % 32, warp = tid / 32; | |
| if (warp == 0) partial[lane] = 0; | |
| threadgroup_barrier(mem_flags::mem_threadgroup); | |
| if (lane == 0) partial[warp] = sum; | |
| threadgroup_barrier(mem_flags::mem_threadgroup); | |
| threadgroup float inverse; | |
| if (warp == 0) { | |
| float s = simd_sum(partial[lane]); | |
| if (lane == 0) inverse = metal::precise::rsqrt(s/float(width)+epsilon[0]); | |
| } | |
| threadgroup_barrier(mem_flags::mem_threadgroup); | |
| uint index = indices[row]*width; | |
| for (uint r = 0; r < width; r += TG*4) { | |
| #pragma unroll | |
| for (uint j = 0; j < 4; ++j) { | |
| uint c = r+tid*4+j; | |
| if (c < width) { | |
| T affine = T(float(weight[c])*(float(x[row*width+c])*inverse)); | |
| T factor = T(T(1)+scale[index+c]); | |
| T product = T(affine*factor); | |
| out[row*width+c] = T(product+shift[index+c]); | |
| } | |
| } | |
| } | |
| """, | |
| ) | |
| def norm_native_reduce(x, weight, shift, scale, indices, eps=1e-5, threads=1024): | |
| return _norm()( | |
| inputs=[ | |
| x, | |
| weight, | |
| shift, | |
| scale, | |
| indices.astype(mx.uint32), | |
| mx.array([eps], mx.float32), | |
| ], | |
| template=[("T", x.dtype), ("TG", threads)], | |
| grid=(threads, x.shape[0], 1), | |
| threadgroup=(threads, 1, 1), | |
| output_shapes=[x.shape], | |
| output_dtypes=[x.dtype], | |
| )[0] | |