Я пытаюсь выполнить пакетное умножение матриц с помощью JAX на графическом процессоре и заметил, что умножение фигур (1000, 1000, 3, 35) @ (1000, 1000, 35, 1) происходит примерно в 3 раза быстрее, чем на самом деле. умножить (1000, 1000, 3, 25) @ (1000, 1000, 25, 1) на f64 и ~5x на f32.
Что объясняет эту разницу, учитывая, что на процессоре ни JAX, ни NumPy не показывают такого поведения, а на графическом процессоре CuPy не показывает такого поведения.
Я запускаю это с JAX: 0.4.32 на NVIDIA RTX A5000 (и получаю аналогичные результаты на Tesla T4), код для воспроизведения:
dtype = cp.float64
timings_cp = []
for i in range(5, 55, 5):
a = cp.array(rng.random((1000, 1000, 3, i)), dtype=dtype)
b = cp.array(rng.random((1000, 1000, i, 1)), dtype=dtype)
timings_cp.append(benchmark(lambda a, b: a@b, (a, b), n_repeat=10, n_warmup=10))
dtype = jnp.float64
timings_jax_gpu = []
with jax.default_device(jax.devices('gpu')[0]):
for i in range(5, 55, 5):
a = jnp.array(rng.random((1000, 1000, 3, i)), dtype=dtype)
b = jnp.array(rng.random((1000, 1000, i, 1)), dtype=dtype)
func = jax.jit(lambda a, b: a@b)
timings_jax_gpu.append(benchmark(lambda a, b: func(a, b).block_until_ready(), (a, b), n_repeat=10, n_warmup=10))
plt.figure()
plt.plot(x, [i.gpu_times.mean() for i in timings_cp], label="CuPy")
plt.plot(x, [i.gpu_times.mean() for i in timings_jax_gpu], label="JAX GPU")
plt.legend()
timings_np = []
for i in range(5, 55, 5):
a = rng.random((1000, 1000, 3, i))
b = rng.random((1000, 1000, i, 1))
timings_np.append(benchmark(lambda a, b: a@b, (a, b), n_repeat=10, n_warmup=10))
timings_jax_cpu = []
with jax.default_device(jax.devices('cpu')[0]):
for i in range(5, 55, 5):
a = jnp.array(rng.random((1000, 1000, 3, i)))
b = jnp.array(rng.random((1000, 1000, i, 1)))
func = jax.jit(lambda a, b: a@b)
timings_jax_cpu.append(benchmark(lambda a, b: func(a, b).block_until_ready(), (a, b), n_repeat=10, n_warmup=10))
plt.figure()
plt.plot(x, [i.cpu_times.mean() for i in timings_np], label="NumPy")
plt.plot(x, [i.cpu_times.mean() for i in timings_jax_cpu], label="JAX CPU")
plt.legend()
Я пытаюсь выполнить пакетное умножение матриц с помощью JAX на графическом процессоре и заметил, что умножение фигур (1000, 1000, 3, 35) @ (1000, 1000, 35, 1) происходит примерно в 3 раза быстрее, чем на самом деле. умножить (1000, 1000, 3, 25) @ (1000, 1000, 25, 1) на f64 и ~5x на f32. Что объясняет эту разницу, учитывая, что на процессоре ни JAX, ни NumPy не показывают такого поведения, а на графическом процессоре CuPy не показывает такого поведения. Я запускаю это с JAX: 0.4.32 на NVIDIA RTX A5000 (и получаю аналогичные результаты на Tesla T4), код для воспроизведения: [code]import numpy as np import cupy as cp from cupyx.profiler import benchmark from jax import config config.update("jax_enable_x64", True) import jax import jax.numpy as jnp import matplotlib.pyplot as plt
rng = np.random.default_rng()
x = np.arange(5, 55, 5) [/code] Тайминги графического процессора: [code]dtype = cp.float64 timings_cp = [] for i in range(5, 55, 5): a = cp.array(rng.random((1000, 1000, 3, i)), dtype=dtype) b = cp.array(rng.random((1000, 1000, i, 1)), dtype=dtype) timings_cp.append(benchmark(lambda a, b: a@b, (a, b), n_repeat=10, n_warmup=10))
dtype = jnp.float64 timings_jax_gpu = [] with jax.default_device(jax.devices('gpu')[0]): for i in range(5, 55, 5): a = jnp.array(rng.random((1000, 1000, 3, i)), dtype=dtype) b = jnp.array(rng.random((1000, 1000, i, 1)), dtype=dtype) func = jax.jit(lambda a, b: a@b) timings_jax_gpu.append(benchmark(lambda a, b: func(a, b).block_until_ready(), (a, b), n_repeat=10, n_warmup=10))
plt.figure() plt.plot(x, [i.gpu_times.mean() for i in timings_cp], label="CuPy") plt.plot(x, [i.gpu_times.mean() for i in timings_jax_gpu], label="JAX GPU") plt.legend() [/code] [img]https://i.sstatic.net/YF88454x.png[/img]
Время с этими конкретными фигурами: [code]dtype = jnp.float64 with jax.default_device(jax.devices('gpu')[0]): a = jnp.array(rng.random((1000, 1000, 3, 25)), dtype=dtype) b = jnp.array(rng.random((1000, 1000, 25, 1)), dtype=dtype) func = jax.jit(lambda a, b: a@b) print(benchmark(lambda a, b: func(a, b).block_until_ready(), (a, b), n_repeat=1000, n_warmup=10).gpu_times.mean())
a = jnp.array(rng.random((1000, 1000, 3, 35)), dtype=dtype) b = jnp.array(rng.random((1000, 1000, 35, 1)), dtype=dtype) print(benchmark(lambda a, b: func(a, b).block_until_ready(), (a, b), n_repeat=1000, n_warmup=10).gpu_times.mean()) [/code] Дает [code]f64: 0.01453789699935913 0.004859122595310211
f32:
0.005860503035545349 0.001209742688536644 [/code] Тайминги процессора: [code]timings_np = [] for i in range(5, 55, 5): a = rng.random((1000, 1000, 3, i)) b = rng.random((1000, 1000, i, 1)) timings_np.append(benchmark(lambda a, b: a@b, (a, b), n_repeat=10, n_warmup=10))
timings_jax_cpu = [] with jax.default_device(jax.devices('cpu')[0]): for i in range(5, 55, 5): a = jnp.array(rng.random((1000, 1000, 3, i))) b = jnp.array(rng.random((1000, 1000, i, 1))) func = jax.jit(lambda a, b: a@b) timings_jax_cpu.append(benchmark(lambda a, b: func(a, b).block_until_ready(), (a, b), n_repeat=10, n_warmup=10))
plt.figure() plt.plot(x, [i.cpu_times.mean() for i in timings_np], label="NumPy") plt.plot(x, [i.cpu_times.mean() for i in timings_jax_cpu], label="JAX CPU") plt.legend() [/code] [img]https://i.sstatic.net/kE2R0kpb.png[/img]
Я пытаюсь выполнить пакетное умножение матриц с помощью JAX на графическом процессоре и заметил, что умножение фигур (1000, 1000, 3, 35) @ (1000, 1000, 35, 1) происходит примерно в 3 раза быстрее, чем на самом деле. умножить (1000, 1000, 3, 25) @...
Я пытаюсь выполнить пакетное умножение матриц с помощью JAX на графическом процессоре и заметил, что умножение фигур (1000, 1000, 3, 35) @ (1000, 1000, 35, 1) происходит примерно в 3 раза быстрее, чем на самом деле. умножить (1000, 1000, 3, 25) @...
У меня есть два массива numpy a и b формы и соответственно. И для a, и для b первая запись в форме — это размер пакета. Когда я выполняю опцию умножения матрицы, я получаю массив формы . MWE заключается в следующем.
import numpy as np
Я использую библиотеку MathNet.Numerics в своем приложении C# для выполнения матричных операций.
Однако я заметил, что умножение матриц с использованием этой библиотеки происходит значительно медленнее по сравнению с обычным скалярным умножением или...
Я использую библиотеку MathNet.Numerics в своем приложении C# для выполнения матричных операций.
Однако я заметил, что умножение матриц с использованием этой библиотеки происходит значительно медленнее по сравнению с обычным скалярным умножением или...