| 317 | self.assertLess(mx.abs(g1 - g2).max(), 1e-5) |
| 318 | |
| 319 | def test_rope_batch(self): |
| 320 | T = 4 |
| 321 | base = 10000.0 |
| 322 | scale = 1.0 |
| 323 | traditional = True |
| 324 | batch_sizes = [3, 8, 11] |
| 325 | num_heads = [1, 3, 5] |
| 326 | dims = 32 |
| 327 | |
| 328 | x = mx.random.uniform(shape=(8, 4, T, dims)) |
| 329 | |
| 330 | offset = mx.array([1, 2, 3]) |
| 331 | with self.assertRaises(ValueError): |
| 332 | mx.fast.rope( |
| 333 | x, |
| 334 | dims, |
| 335 | traditional=traditional, |
| 336 | base=base, |
| 337 | scale=scale, |
| 338 | offset=offset, |
| 339 | ) |
| 340 | |
| 341 | for batch_size in batch_sizes: |
| 342 | for n_head in num_heads: |
| 343 | x = mx.random.uniform(shape=(batch_size, n_head, T, dims)) |
| 344 | offset = mx.arange(batch_size) |
| 345 | rx = rope_orig(x, dims, traditional, base, scale, offset) |
| 346 | rx_fast = mx.fast.rope( |
| 347 | x, |
| 348 | dims, |
| 349 | traditional=traditional, |
| 350 | base=base, |
| 351 | scale=scale, |
| 352 | offset=offset, |
| 353 | ) |
| 354 | self.assertLess(mx.abs(rx - rx_fast).max(), 1e-5) |
| 355 | x = mx.random.normal(shape=(2, 6, 8, 64)).transpose(0, 2, 1, 3) |
| 356 | dims = 64 |
| 357 | offset = 0 |
| 358 | rx_fast = mx.fast.rope( |
| 359 | x, dims, traditional=traditional, scale=scale, base=base, offset=offset |
| 360 | ) |
| 361 | rx_fast_single = mx.fast.rope( |
| 362 | x[0:1], dims, traditional=traditional, scale=scale, base=base, offset=offset |
| 363 | ) |
| 364 | |
| 365 | rx = rope_orig(x, dims, traditional, base, scale, offset) |
| 366 | self.assertLess(mx.abs(rx - rx_fast).max(), 1e-5) |
| 367 | |
| 368 | def test_rope_with_large_offset(self): |
| 369 | x = mx.random.normal(shape=(1, 1, 1024, 32)) |