Wie beschleunigt man Matrix-Multiplikationen in Python?

8

Ich entwickle ein kleines neuronales Netzwerk, dessen Parameter viel Optimierung benötigen, also viel Verarbeitungszeit. Ich habe mein Skript mit cProfile profiliert, und was 80% der Prozessorzeit in Anspruch nimmt, ist die Funktion NumPy dot , der Rest ist Matrixinversion mit der Funktion numpy.linalg.solve . Meine aktuelle Version von numpy verwendet blas oder scheint es zu sein, da numpy.core._dotblas.dot als die Funktion erscheint, die 80% der gesamten Verarbeitungszeit benötigt.

Da es der Kern meines neuronalen Netzwerkes ist und ich viel laufen muss, könnte mir jede kleine Geschwindigkeitssteigerung viel Zeit sparen bei den zahlreichen wiederholten Parameteroptimierungen.

Genauere Angaben: Die Matrixmultiplikation erfolgt auf Matrizen, die eine Form von mindestens 100 * 100 bis 500 * 500 haben. Ich habe einen Computer mit 12 Kernen und benutze sie bis jetzt, um verschiedene neurale Netzwerkparameter parallel laufen zu lassen, aber vielleicht könnte die Matrixmultiplikation parallel gemacht werden?

Danke für Ihre Zeit!

Antwort:

Ich habe einige Tage damit zugebracht, Bibliotheken zu deinstallieren und zu installieren ... Hier ist das Ergebnis dessen, was ich getestet habe: Standardmäßig sind die BLAS-Bibliotheken in meiner Version von Ubuntu (12.04) und in der von Repository installierten Version von Numpy ATLAS-Bibliotheken. Ich habe einige Tests durchgeführt, die die Verbesserung SPEZIELL für die Berechnungen widerspiegeln, an denen ich interessiert bin. Daher dürfen diese Ergebnisse nicht als endgültige Antwort interpretiert werden. Diese Berechnungen beinhalten eine Matrixmultiplikation (Skalarprodukt) in einer 55000 Iterationsschleife mit einer 500 · 500 und 1000 · 1000 Matrix. Ich benutze eine HP Z800 Workstation mit einem Xeon X5675 @ 3.07GHZ mit 12 Kernen. Alle Ergebnisse (Prozent) sind der Vergleich zwischen der beschriebenen Bedingung und der Referenz, die hier die verpackte ATLAS-Bibliothek ist.

  • Scipy.sparse module : Ich weiß nicht, ob ich es richtig einstelle, aber mit einer Spärlichkeit von 10%, die Verwendung dieses Moduls wird nützlich, ausgehend von 1500 * 1500 Matrizen mit OpenBLAS und MKL. Wenn Sie Vorschläge haben, wie Sie sie richtig benutzen können, bin ich interessiert!
  • Mit OpenBlas bekomme ich eine Geschwindigkeitssteigerung von 33% für 500 * 500 Matrizen, aber 160% für 1000 * 1000. Aber mit OpenBLAS funktioniert das scipy.sparse-Modul nicht besser, sondern schlechter.
  • Der große Gewinner sind die MKL-Bibliotheken. Die Beschleunigung beträgt bis zu 230% mit 1000 * 1000 Matrizen aus den ursprünglichen ATLAS-Bibliotheken! Für die 500 * 500-Matrizen ist die Beschleunigung bescheidener (100%), aber immer noch sehr gut. Außerdem können bei der Kompilation mit OpenMP Matrix Multiplikationen auf meinen 12 Prozessoren laufen und hier doppelt so schnell wie auf einem Prozessor mit MKL Bibliotheken. Aber es ist eine Verschwendung von Verarbeitungsleistung, es ist viel effizienter, Multiprocessing-Module zu verwenden, um Skripte / Matrix-Multiplikationen parallel auszuführen.
PierreE 02.09.2012, 19:20
quelle

2 Antworten

7

Wenn Sie es nicht bereits sind, können Sie versuchen, numpy mit einer sehr optimierten BLAS-Bibliothek wie Intel MKL (das ist frei-in-Bier für nicht-kommerzielle Nutzung oder diskontiert für den akademischen Gebrauch , was offensichtlich nicht als nicht kommerziell gilt; Anweisungen von Intel für die Verwendung mit numpy ) oder OpenBLAS (frei in der Sprache). Es gibt auch die Enthought-Python-Distribution , die mit MKL und Free-as-in-Beer für Akademiker verknüpft ist . Das kann Ihre Matrix-Multiplikationen automatisch parallelisieren und kann viel schneller sein als die typische Referenz-BLAS / ATLAS-Installation auf den meisten Linux-Distributionen oder was auch immer Sie verwenden.

Ansonsten wäre das Einzige, was ich davon wissen könnte, ein paar mathematische Tricks, um nicht so viele Multiplikationen / Lösungen berechnen zu müssen. Ohne genau zu wissen, was Sie tun, ist es schwierig, dort irgendwelche Vorschläge zu machen.

Ich nehme an, dass deine Matrizen dicht sind, da sie normalerweise in neuronalen Netzen sind, aber wenn du etwas ungewöhnliches tust, könnte scipy.sparse auch helfen.

    
Dougal 02.09.2012, 19:52
quelle
4

Numpy verwendet sehr schnelle interne Algorithmen und Repräsentationen, die auf Bibliotheken von Drittanbietern basieren (wie BLAS, wie Sie es genannt haben), die unter anderem bereits SSE-Optimierungen verwenden. Da das ursprüngliche BLAS ein wenig langsam ist (weil es eine Referenzimplementierung sein soll, die sich auf Präzision und nicht auf Leistung konzentriert), möchten Sie vielleicht einen anderen auf Leistung ausgerichteten Geschmack verwenden, z. B. OpenBLAS. Um OpenBLAS zu verwenden, müssen Sie entweder ein vordefiniertes OpenBLAS-aktiviertes Numpy-Paket finden oder eine mit OpenBLAS verknüpfte Version neu kompilieren. Sobald Sie eine effiziente BLAS-Implementierung verwenden, werden Sie keine bessere Beschleunigungsoption in reinem Python finden, es sei denn, Sie schreiben eine Bibliothek in C und brauchen viel Zeit, um sie zu optimieren.

Andererseits können Sie überprüfen, ob Ihre Numpy- und BLAS-Bibliothek so effizient wie möglich in Ihrer Architektur kompiliert ist. Wenn Sie beispielsweise die OpenMP-Bibliothek bei der Numpy-Kompilierung aktivieren, können mehrere Kerne mit der Parallelisierung auf Datenebene an Ihrem Problem arbeiten. Dies kann eine wichtige Quelle der Beschleunigung sein, wenn Sie mehrere Kerne auf Ihrem Computer besitzen und Ihre Berechnungen CPU-gebunden sind. Wenn es Ihr Problem erlaubt, können Sie sogar eine aufgabenbasierte parallele Programmierbibliothek verwenden ( SCOOP [Disclaimer: Ich habe es geschrieben], < a href="http://celeryproject.org/"> Sellerie , etc.), um Ihre Arbeit auf mehreren Computern zu verbreiten.

Als letzte Möglichkeit wäre eine andere Möglichkeit, neue Hardware zu kaufen. Es macht Software möglicherweise schneller, ohne eine einzelne Codezeile zu ändern.

    
Soravux 02.09.2012 19:54
quelle