2016-06-08 1 views
3

Я пытаюсь воспользоваться преимуществами производительности от встроенного API-интерфейсов Sparse Matrix Multiplication от Tensorflow. И keveman рекомендовал, чтобы tf.embedding_lookup_sparse - это правильный путь.Есть ли очевидная причина, что Tensorflow использует формат COO, отличный от CSR, для разреженной матрицы?

Но, похоже, что производительность embedding_lookup_sparse несколько разочарована в my experiments. Хотя он выполняет довольно мелкие матричные умножения, < 1, 3196> и < 3196, 1024>, разреженный матмол с 0,1 разрешающей способностью не может получить плотное умножение матрицы.

Если моя реализация верна, я думаю, что одна из причин заключается в том, что Tensorflow использует формат COO, который сохраняет всю ненулевую пару. Я не эксперт в этом домене, но разве широко известно, что формат CSR более эффективен в таких вычислениях? Есть ли очевидная причина, что Tensorflow внутренне использует формат COO, отличный от CSR, для разреженного представления матрицы?

ответ

2

Как раз для записи, вы говорите матричное умножение, но одна из ваших матриц фактически является вектором (1 x 3196). Таким образом, это сделало бы это преобразование матриц-векторов (другое ядро ​​BLAS). Предположим, вы имеете в виду умножение матричного вектора для моего ответа.

Да, CSR должен теоретически быть быстрее, чем COO для умножения матрицы-вектора; это связано с тем, что размер хранилища в формате CSR равен O(2nnz + n) vs O(3nnzs), а разброс по матричному векторному умножению во многих случаях связан с памятью.

Точная разница в производительности по сравнению с плотным умножением матрицы зависит от размера проблемы, шаблона разреженности, типа данных и реализации. С течением времени сложно сказать, что это должно быть быстрее, потому что в разреженном формате хранения вводится косвенное направление, что потенциально приводит к уменьшению локальности и плохому (а) использованию арифметических единиц (например, без использования векторизации).

В частности, когда размер матрицы и вектора настолько мал, что почти все в кэше, я бы ожидал ограниченных преимуществ производительности. Редкие матричные структуры, как правило, более полезны для действительно больших матриц, начиная от 10 × 10 × 1000 и 1B x 1B, что даже не помещается в основную память с использованием плотного представления. По моему опыту, преимущество хранения по сравнению с плотными форматами обычно отрицается потерей локальности и арифметической эффективностью. В какой-то мере это касается гибридных форматов хранения (таких как Block CSR), которые пытаются использовать лучшее из обоих миров и очень полезны для некоторых приложений (не похоже, что tensorflow поддерживает это).

В tensorflow я бы предположил, что формат COO используется, потому что он более эффективен для других операций, например, он поддерживает O(1) обновления, вставки и удаления из структуры данных. Кажется разумным торговать ~ 50% производительности при разреженном умножении матрицы-вектора для повышения эффективности этих операций.