Alles wird smarter. Künstliche Intelligenz ist nicht nur eine Anwendung für Rechenzentren, sondern wird in allen Arten von eingebetteten Systemen eingesetzt, mit denen wir täglich interagieren. Wir erwarten, dass wir mit ihnen über Sprache und Gesten kommunizieren können, dass sie uns erkennen und verstehen und dass sie zumindest ein wenig gesunden Menschenverstand zeigen. Diese Intelligenz macht solche Systeme nicht nur funktionaler und einfacher zu bedienen, sondern auch sicherer und zuverlässiger.
Und sie ist das Ergebnis von Fortschritten bei tiefen neuronalen Netzwerken. Eine der größten Herausforderungen neuronaler Netzwerke besteht in ihrer Rechenkomplexität. Bereits kleine neuronale Netzwerke können Millionen von Multiply Accumulate Operations (MACs) erfordern, um ein Ergebnis zu liefern. Für größere geht es in die Milliarden. Bei großen Sprachmodellen und vergleichbaren komplexen Netzwerken handelt es sich um mehrere Billionen MACs. Dieses Rechenleistung geht über das hinaus, was eingebettete Prozessoren liefern können.
Schnelle Berechnungen gefordert
In einigen Fällen können die Berechnungen über ein Netzwerk an ein Rechenzentrum abgegeben werden. Immer mehr Geräte verfügen über schnelle und zuverlässige Netzwerkverbindungen – so ist dies für viele Systeme eine praktikable Option. Es gibt jedoch auch zahlreiche Systeme mit strengen Echtzeitanforderungen, die selbst die schnellsten und zuverlässigsten Netzwerke nicht erfüllen können. Zum Beispiel muss jedes autonome Mobilitätssystem – selbstfahrende Autos oder selbststeuernde Drohnen – Entscheidungen schneller treffen, als dies über ein externes Rechenzentrum möglich wäre.
Zudem gibt es Systeme, in denen sensible Daten verarbeitet werden, die nicht über Netzwerke verschickt werden sollten. Denn alles, was über ein Netzwerk läuft, bietet eine zusätzliche Angriffsfläche für Hacker. Aus diesen genannten Gründen – Leistung, Datenschutz und Sicherheit – müssen bestimmte Berechnungen Inferenzen ausschließlich in eingebetteten
Systemen erfolgen.
Bei sehr einfachen Netzwerken übernehmen eingebettete CPUs die Aufgabe. Selbst ein Raspberry Pi kann einen einfachen Algorithmus zur Objekterkennung einsetzen. Für komplexere Aufgaben gibt es eingebettete GPUs sowie neuronale Verarbeitungseinheiten (NPUs) speziell für eingebettete Systeme, die eine größere Rechenleistung liefern können. Wenn es allerdings um Hochleistung und höchste Effizienz geht, kann ein maßgeschneiderter KI (Künstliche Intelligenz)-Beschleuniger Anwendungen möglich machen, die andernfalls
unmöglich wären.
Maßgeschneiderte Beschleuniger
Die Entwicklung einer neuen Hardware ist eine gewaltige Aufgabe, egal ob für ASIC oder FPGA. Andererseits ermöglicht es Entwicklern, ein Leistungs- und Effizienzniveau zu erreichen, das mit Standardkomponenten nicht machbar ist. Aber wie kann das durchschnittliche Entwicklungsteam einen besseren Beschleuniger für maschinelles Lernen entwickeln als die Designer führender kommerzieller KI-Beschleuniger, die auf mehrere Generationen an Erfahrung zurückblicken? Durch eine hochspezifische Anpassung der Implementierung an die durchzuführende Inferenz kann diese Implementierung eine Größenordnung besser sein als allgemeinere beziehungsweise herkömmliche Lösungen.
Ein klassischer Entwickler von KI-Beschleunigern wird eine NPU erzeugen, die jedes erdenkliche neuronale Netzwerk unterstützt. Das Ziel sind Tausende von Design-Ins, also muss das Design so allgemein wie möglich gestaltet werden. Nicht nur das, diese Entwickler streben auch danach, ein gewisses Maß an „Zukunftssicherheit“ in ihre Designs zu integrieren. Sie wollen in der Lage sein, auch für mehrere Jahre in die Zukunft jedes Netzwerk zu unterstützen, das sich vorstellen lässt. Keine leichte Aufgabe in einer Technologiebranche, die sich so rasant weiterentwickelt.
Ein maßgeschneiderter Beschleuniger hingegen muss nur ein oder mehrere verwendete Netzwerke unterstützen. Diese Freiheit ermöglicht es, viele programmierbare Elemente bei der Implementierung des Beschleunigers in der Hardware zu fixieren. So erhält man Hardware, die sowohl kleiner als auch schneller ist als Allzwecklösungen. Beispielsweise kann ein spezieller Beschleuniger für Faltung mit fester Bild- und Filtergröße bis zu zehnmal schneller sein als ein gut konzipierter Universal-TPU.
Beschleuniger von der Stange
Universalbeschleuniger verwenden in der Regel Gleitkommazahlen. Das liegt daran, dass praktisch alle neuronalen Netzwerke auf Mehrzweckcomputern in Python unter Nutzung von Gleitkommazahlen entwickelt werden. Um die korrekte Unterstützung dieser neuronalen Netzwerke zu gewährleisten, muss der Beschleuniger natürlich Gleitkommazahlen unterstützen.
Die meisten neuronalen Netzwerke verwenden jedoch Zahlen nahe 0 und erfordern in diesem Bereich höchste Präzision. Und Gleitkomma-Multiplikatoren sind riesig.
Werden sie nicht benötigt, spart man durch ihren Verzicht viel Fläche und zusätzlich Strom.
Einige NPUs unterstützen die Darstellung ganzer Zahlen, manchmal in verschiedenen Größen. Die Unterstützung mehrerer numerischer Darstellungsformate führt jedoch zu Schaltungen, die Strom verbrauchen und die Laufzeit verzögern. Die Entscheidung für nur eine Darstellungsform und deren ausschließliche Verwendung ermöglicht eine kleinere und schnellere Implementierung.
Speicherbedarf im Fokus
Beim Bau eines maßgeschneiderten Beschleunigers ist man nicht auf 8 Bit oder 16 Bit begrenzt. Es kann jede Größe verwendet werden. Durch die Auswahl der geeigneten numerischen Darstellung oder „Quantifizierung“ eines neuronalen Netzwerks können die Daten und die Operatoren optimal dimensioniert werden. Die Quantifizierung kann die Datenmenge, die gespeichert, verschoben und verarbeitet werden muss, erheblich reduzieren.
Die Reduzierung des Speicherplatzes für eine schlanke Datenbank und die Verkleinerung der Multiplikatoren können die Fläche und Leistung eines Designs deutlich verbessern. Beispielsweise ist ein 10-Bit-Festpunktmultiplikator etwa 20 Mal kleiner als ein 32-Bit-Gleitkommamultiplikator und verbraucht entsprechend etwa 1/20 der Leistung. Das bedeutet, dass das Design entweder durch die Verwendung des kleineren Multiplikators viel kleiner und energieeffizienter sein kann. Oder der Designer nutzt die Fläche und setzt 20 Multiplikatoren ein, die parallel arbeiten und mit denselben Ressourcen eine wesentlich höhere Leistung erzielen.
Herausforderungen der HLS
Eine der größten Herausforderungen beim Aufbau eines maßgeschneiderten Beschleunigers für maschinelles Lernen besteht darin, dass die Datenwissenschaftler, die das neuronale Netzwerk entwickelt haben, in der Regel nichts vom Hardware-Design verstehen, und die Hardware-Designer nichts von Datenwissenschaft. In einem traditionellen Design-Flow würden sie „Meetings“ und „Spezifikationen“ nutzen, um Wissen zu übertragen und Ideen auszutauschen. Aber ehrlich gesagt mag niemand Meetings oder Spezifikationen. Außerdem eignen sie sich nicht besonders gut für einen fließenden Informationsaustausch.
Die High-Level-Synthese (HLS) ermöglicht es, eine von den Datenwissenschaftlern erstellte Implementierung nicht nur als ausführbare Referenz, sondern auch als maschinenlesbare Eingabe für den Hardware-Designprozess zu verwenden. Dadurch entfällt die manuelle Neuinterpretation des Algorithmus im Designablauf, die langsam und extrem fehleranfällig ist. HLS synthetisiert eine RTL-Implementierung aus einer algorithmischen Beschreibung. In der Regel wird der Algorithmus in C++ oder SystemC beschrieben, aber eine Reihe von Design-Flows wie HLS4ML ermöglichen es HLS-Tools, neuronale Netzwerkbeschreibungen direkt aus Frameworks für maschinelles Lernen zu entnehmen.
Fazit
Die HLS erlaubt eine praktische Erforschung der Quantifizierung auf eine Art und Weise, die für maschinelles Lernen noch nicht praktikabel ist. Um die Auswirkungen der Quantifizierung vollständig zu verstehen, ist eine bitgenaue Implementierung des Algorithmus erforderlich, einschließlich der Charakterisierung der Auswirkungen von Überlauf, Sättigung und Rundung. Heutzutage ist dies nur in Hardware-Beschreibungssprachen (HDLs) oder HLS-bitgenauen Datentypen (https://hlslibs.org) machbar.
Da maschinelles Lernen zunehmend in allen Bereichen Einzug hält, müssen immer mehr eingebettete Systeme Inferenzbeschleuniger einsetzen. Die HLS ist eine praktische und bewährte Möglichkeit, maßgeschneiderte Beschleuniger zu entwickeln, die für eine ganz bestimmte Anwendung optimiert sind und eine höhere Leistung und Effizienz bieten als NPUs für allgemeine Zwecke.