summaryrefslogtreecommitdiff
path: root/Presentation/transcript.md
blob: 513656bd375bda98d15cecdaa5b32c084675b975 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
# EIE: Efficient Inference Engine on Compressed Deep Neural Network

## Vorstellung

- Titel
- Vorstellung der Person

*nächste Folie*

## Inhaltsangabe

- Recap über wichtige Teile der DNN, die für effiziente Inferenz und Kompression wichtig sind
- Motivation: Warum ist effiziente Inferenz wichtig und was heißt überhaupt effizient
- Kompression: Verschiedene Komprimierungsmethoden für neuronale Netze
- Implementation: Eigentliche Implementation der EIE
- Evaluation: Vergleich der EIE mit anderen Hardware-Acceleratoren
- Ausblick: Optmierungsmöglichkeiten und mögliche Implementation anderer Komprimierungsmethoden

*nächste Folie*

## Deep Neural Networks

- Recap
- Beispiel: LeNet
- Convolutional Layer (Faltungsoperationen mit Filtern)
- Fully Connected Layer (Alle Neuronen verbunden, für Klassifizierung)
- FC benötigt in den meisten Netzen 90-95% des Speichers
- Jede Schicht: Input vector $a$, Gewichtsmatrix $W$, Multiplikation und Addition, Aktivierungsfunktion in jedem Neuron, Output vector $b$

*nächste Folie*

- Formal: Berechnung von $b_i = f(\sum\limits_{j=0}^{n} W_{ij} a_j)$ für jedes Element im Output-Vektor
- $W_{ij}$ Eintrag in der Gewichtsmatrix
- $a_j$ Element im Input-Vektor
- Multiplikation und Summation (Multiply-Accumulate MAC) über die Elemente im Input-Vektor bzw. Zeile in der Gewichtsmatrix
- $f$ Aktivierungsfunktion
- Matrix $W$ kann spärlich besetzt sein (englisch: sparse)

*nächste Folie*

## Motivation

- Metriken: Was bedeutet Effizienz?
- Durchsatz (Throughput): Wie viel Daten können pro Zeiteinheit verarbeitet werden?
- Latenz (Latency): Wie lange dauert es, einen einzelnen Datensatz zu verarbeiten?
- Modellgröße: Wie viel Speicher wird zum Speichern des Modells benötigt (hauptsächlich Gewichte, bei komplexeren Modellen auch Parameter für Aktivierungsfunktion)
- Energieverbrauch: Wie viel Energie wird benötigt, um eine bestimmte Anzahl an Daten zu verarbeiten

*nächste Folie*

## Memory access

- Klassischer Aufbau eines Hardware-Accelerators
- Energieverbrauch der einzelnen Speichertypen in der Hierarchie
- Energieverbrauch korrelliert mit Zugriffszeiten und somit mit Latenz und Durchsatz, da so bei Abfragen aus dem Speicher jedes Mal gewartet werden muss
- DRAM ist bei Acceleratoren der Stand der Technik, um große DNN zu speichern (bisher ohne Komprimierung)
- DRAM hat 200x Energieverbrauch im Vergleich zu Registerzugriffen
- DRAM hat 33x Energieverbrauch im Vergleich zu SRAM-Buffer

*nächste Folie*

- Art und Anzahl der Speicherzugriffe variieren je nach Datenfluss-Modell
- Acceleratoren können nicht immer eindeutig einem Modell zugeordnet werden, EIE ist eine Mischung aus a) und b)
- Im Detail werden die einzelnen Modelle nicht vorgestellt

*nächste Folie*

- Hier sind die einzelnen Speicherzugriffe markiert
- Jeder einzelne Speicherzugriff kostet Zeit und Energie, es ist also eines der Hauptmerkmale zur Optimierung

*nächste Folie*

## Komprimierung

- Welche verschiedenen Speicherarten haben wir in einem Accelerator?
- Dynamisch: Eingabedaten
- Statisch: Gewichte, Parameter für Aktivierungsfunktionen

*nächste Folie*

## AlexNet

- Um sich die Größenordnung des benötigten Speichers zu vergegenwärtigen
- Populäres neuronales Netz, benannt nach designer Alex Krizhevsky
- 5 convolutional layers
- 3 fully connected layers
- $\sim 62$ million parameters
- $\sim 240$ MB with 32-bit float representation
- Häufig für Benchmarking von Acceleratoren verwendet

*nächste Folie*

## Basis projection

- Standardmäßig sind die kanonischen Einheitsvektoren die Basisvektoren für die Gewichtsmatrizen
- Meistens produzieren jedoch andere Basisvektoren, auf die die Zeilenvektoren der Gewichtsmatrizen projiziert werden, bessere Werte
- Besser = Geringere Werte (ungefähr 0 oder gleich 0)
- Genau das wird hier gemacht
- Gewichte als Linearkombination der Basisvektoren darstellbar
- Beispiel: Von 7% Nullen auf 56% Nullen

*nächste Folie*

## Pruning

- Entferne unwichtige Gewichte, die kaum Einfluss auf die Genauigkeit des neuronalen Netzes haben
- 3-Schritt-Verfahren: Training, Pruning (Gewichte werden auf 0 gesetzt oder ganze Output-Neuronen in einer Schicht weggelassen), Retraining (ohne die entfernten Gewichte)
- Wiederholung so lange, bis je nach Verfahren nichts mehr entfernt werden kann oder ein unterer Grenzwert der Genauigkeit unterschritten worden ist

*nächste Folie*

- Mehrere Pruning-Verfahren möglich
- Betrags-Grenzwert-Verfahren (englisch: magnitude threshold based pruning):  
    Entferne Gewichte, deren Betrag unter einem bestimmten Grenzwert liegen
- Optimal Brain Damage / Optimal Brain Surgeon (ja, so heißen die Verfahren wirklich):  
    - Entfernt Gewichte basierend auf ihrem Einfluss auf die Zielfunktion (Fehlerfunktion, z.B. Quadratische Fehlerfunktion)
    - Gewichte mit geringem Einfluss werden entfernt
    - Optimal Brain Damage berechnet die Sensitivitätswerte basierend auf dem Gradienten, Optimal Brain Surgeon basierend auf der Hesse-Matrix
- Biased weight decay
    - Entfernen von Gewichten durch Hinzufügen eines Terms im Update-Schritt beim Backpropagation-Algorithmus
    - Große Gewichte bleiben länger, kleine Gewichte konvergieren zu Null
    - Während des Trainings, Details außerhalb des Scopes, hier geht es nur um Inferenz, bei der bereits ein vollständig trainiertes NN vorliegt

*nächste Folie*

## Weight quantization

- Gewichtsquantisierung
- Grob: Floating point Gewichte werden als Ganzzahl-Werte kodiert
- Wird durch Clustering gelöst
- Ähnliche Gewichte werden in Clustern gruppiert
- Jeder Cluster hat einen Mittelwert (centroid), durch den dann jedes Gewicht des Clusters ersetzt wird
- Am Ende gespeichert werden nur die Cluster indices und die Mittelwerte der Cluster in einem extra Array, welche mit den indizes indiziert werden
- Durch den Gradienten der Gewichtsmatrix lassen sich die Werte der centroids fine-tunen

*nächste Folie*

- Wie weise ich die Gewichte den Clustern zu?
- Minimierung der Varianz innerhalb aller Cluster
- k-means clustering: 1. Initialisiere k cluster centroids, 2. Für alle Gewichte: Füge Gewicht dem Cluster hinzu, dessen Mittelwert am nächsten dran ist, berechne Mittelwerte aller Cluster neu (weil sich der Mittelwert durch das Hinzufügen ja ändert)

*nächste Folie*

- Die Initialisierung der Mittelwerte macht einen entscheidenden Unterschied bezüglich der Genauigkeit der Quantisierung und damit der Genauigkeit des gesamten NN
- In vielen Anwendungen des k-means clusterings wird die CDF (kumulative Verteilungsfunktion) betrachtet, die Anzahl der Vorkommnisse (y-Achse) äquidistant abgetastet, und die dazugehörigen Werte als Mittelwerte genommen
- Das führt allgemein dazu, dass die durchschnittliche Abweichung von den eigentlichen Werten am geringsten ist
- Im Kontext NN: Höhere Werte haben größere Auswirkung auf Ergebnis als niedrige, sind aber selten und somit im CDF-Verfahren unterrepräsentiert, wodurch hohe Abweichungen in solchen Werten entstehen
- Daher: Lineare Initialisierung

*nächste Folie*

## Huffman encoding

- Zählung und Sortierung der vorkommenden Gewichtswerte
- Erstellen des Huffman-Baumes: Am seltendsten vorkommende Gewichte unten, je häufiger, desto weiter oben am Wurzelknoten
- Binärbaum: Kodierung über Kanten 1 und 0
- Gespeichert werden muss nur der Baum, die Daten können somit z.B. von 1,58 Megabits auf 1,17 Megabits reduziert werden

*nächste Folie*

## HashNets

- Idee: Es müssen keine Indexwerte in der Matrix gespeichert werden
- Stattdessen: Es existiert eine sog. Hashfunktion $h^{\ell}(i, j)$: Einweg-Funktion, welche den Matrix-Koordinaten $(i,j)$ einen Indexwert für das Lookup-Array $w^{\ell}$ zuweist
- Somit existiert keine tatsächliche Matrix, sondern sie ist nur virtuell, gespeichert werden muss nur die größe der Matrix, die Hashfunktion und das Lookup-Array

*nächste Folie*

## Speicherformat

- Etabliert hat sich das Compressed Sparse Column (CSC) / Compressed Sparse Row (CSR) Format
- Je nach dem, ob man PEs des Accelerators nach Spalten oder Zeilen segmentieren und input oder output lokal bleiben möchte
- EIE nutzt das CSC Format
- Jede Spalte wird als Vektoren $v$ und $z$ kodiert
- $v$ enthält alle Gewichte, die nicht null sind
- $z$ enthält die Anzahl der Nullen vor dem jeweiligen Eintrag in $v$
- Beispiel: $W_j = [0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3]$ wird zu $v = [1, 2, 0, 3]$, $z = [2, 0, 15, 2]$
- EIE: $v$'s und $z$'s aller Spalten werden zusammen als ein großes Array-Paar gespeichert, zusammen mit Vektor $p$, wobei $p_j$ ein Zeiger auf das erste Element der Spalte $W_j$ ist

*nächste Folie*

## EIE Implementation

- Ziel: Annäherung der Formel für jede Aktivierung $b_i = f(\sum\limits_{j=0}^{n-1} W_{ij} a_j) \overset{!}{=} \text{ReLU}(\sum\limits_{j \in X_i \cap Y} S[I_{ij}] a_j)$ möglichst effizient
- $X_i$ Menge an Spalten, wobei 0-Einträge ausgelassen werden
- $Y$ Menge an Einträgen im Inputvektor $a$, die nicht null sind
- $I_{ij}$ 4-bit Index für die Lookup-Tabelle
- $S$ Lookup-Tabelle

*nächste Folie*

- Segmentierung der Eingabematrix auf die verschiedenen processing elements
- Auf dem SRAM-Block in jedem PE ist der für das PE vorgesehene Teil der Spalte $W_j$ gespeichert, jeweils in CSC-Format, mit Zeigern auf das erste Element der jeweiligen Spalte
- Beispiel: In PE0 sind von Spalte $W_0$ die Elemente $w_{0,0}$, $w_{8,0}$, $w_{12,0}$ in $v$ gespeichert, die Nullen dazwischen für alle Elemente in PE0 in $z$, und die Zeiger die Spaltenanfänge
- Farbliche Darstellung von $a$ nur Momentaufnahme, geht durchgehend weiter, $a_j$ werden gebroadcastet
- Jedes PE multipliziert $a_j$ mit den Elementen seiner Zeile und schreibt das Ergebnis in Akkumulator-Register, worin die $b_i$'s gecached und in den SRAM geschrieben werden

*nächste Folie*

- HW Aufbau bestehend aus einem Knoten, der Nullen im Eingabevektor erkennt, und dem eigentlichen Processing Element
- PEs sind jeweils in 4er-Gruppen aufgeteilt, wobei sich alle 4 PEs eine LNZD-Einheit teilen
- PE besteht aus Pointer-Read-Unit (Für die Zeiger auf die Spalten), Sparse-Matrix-Access-Unit (Zum Lesen der Gewichtswerte aus der Matrix), Arithmetic Unit (Zur Multiplikation und Addition), und Read/Write-Unit (Puffern und Schreiben der Output-Werte)

*nächste Folie*

- LNZD-Unit
- Die LNZD-Unit erkennt Nullen im Eingabevektor und überspringt diese
- Bei nicht-null Werten werden diese zusammen mit dem Index an alle PEs gesendet

*nächste Folie*

- Pointer-Read-Unit
- Lesen der Zeiger auf Start-Elemente der Spalten $W_j$
- Elemente sind abwechselnd in zwei verschiedenen SRAM-Banken gespeichert
- Somit können sie gleichzeitig ausgelesen werden

*nächste Folie*

- Sparse-Matrix-Read-Unit
- Liest $v$ und $z$ Vektoren für die betreffende Spalte aus, auf Basis der Zeiger
- Es werden nur 64-Bit Worte gleichzeitig ausgelesen, somit 8 Einträge pro Wort (4 bit Wert, 4 bit Index)

*nächste Folie*

- Arithmetic unit
- Erhält Vektor $v$ und absoluten Zielregister-Index $x$
- Berechnet $b_x = b_x + v \cdot a_j$
- Akkumuliert Index $x$ und berechnet die tatsächliche Zieladresse

*nächste Folie*

- Beinhaltet Input und Output-Werte
- Puffer für Input- und Output-Werte tauschen Rollen nach jeder Schicht (Output-Werte einer Schicht sind die Input-Werte der nächsten Schicht)
- Puffer schreibt und liest nach Bedarf in den SRAM

*nächste Folie*

- ReLU und LNZD-Unit
- Wendet die ReLU-Funktion auf die Output-Werte an
- Führt lokale LNZD durch, und sendet das Ergebnis an die LNZD-Unit der Gruppe

*nächste Folie*

## Evaluation

*obere Grafik*

- Vergleich der Geschwindigkeit bei Berechnung verschiedener Schichten von verschiedenen Modellen
- Standardverfahren
- Alex steht für AlexNet, VGG für VGG-Net (Visual Geometry Group), NT für NeuralTalk
- Als Datensatz zum testen wird ImageNet benutzt, als Framework das Caffe deep learning framework
- Maß der Geschwindigkeit: Größe des Datensatzes geteilt durch den höchsten gemessenen Durchsatz, $[\text{Frames}/\text{s}]$
- Immer nur ein Datensatz (Batch-Size 1), da das System zur Verwendung in Echtzeitszenarien ausgelegt ist
- 1x ist CPU unkomprimiert
- EIE ist 189x (Intel Core i7 5930k), 13x (NVIDIA GeForce GTX Titan X), 307x (NVIDIA Tegra K1) so schnell wie CPU, GPU and mGPU für komprimierte DNN
- Markant ist: Kaum Verbesserung durch Komprimierung auf nicht-dedizierter Hardware (steht in keinem Verhältnis zur EIE, logarithmische Skala)
- Durchsatz: 102 GOP/s unkomprimiert entsprechen 3 TOP/s komprimiert

*untere Grafik*

- Maß für Energieverbrauch: Durchschnittliche Leistungsaufnahme mal Dauer pro Datensatz, $[\text{Frames}/\text{J}]$
- 1x ist wieder CPU unkomprimiert
- EIE ist 24.000x, 3.400x, 2.700x energieeffizienter als CPU, GPU and mGPU
- Auch hier: Kaum Verbesserung durch Komprimierung auf nicht-dedizierter Hardware
- Gründe für hohe Effizienz: Zugriff auf SRAM anstatt DRAM, Kompressionsalgorithmus und Architektur reduziert Anzahl der Speicherzugriffe, Kodierung der spärlichen Matrix durch CSC

*nächste Folie*

- Vergleich der EIE mit verschiedenen Hardware-Acceleratoren
- Modellgröße bei General Purpose Plattformen wie GPUs sehr groß, dafür in allen Effizienz-Parametern unterlegen
- Auch im Vergleich zu anderen ASIC- und FPGA-Architekturen überlegen
- A-Eye (FPGA) nutzt DDR3-DRAM für Speicherzugriffe
- TrueNorth nutzt auch SRAM, aber keine dedizierte Architektur, um komprimierte DNN zu behandeln
- Da-DianNao ist ASIC mit eingebettetem DRAM (also auf dem selben Chip)
- Dafür: Unkomprimierte Implementation, nur kleine DNNs mit 18M Parametern
- EIE besonders in 28nm Strukturbreite mit 256 PEs immer noch 3x so schnell vom Durchsatz und hat bessere Effizienz

*nächste Folie*

## Ausblick

- EIE basiert hauptsächlich auf Algorithmen für die Verarbeitung von komprimierten DNNs, die vorher auf General Purpose Hardware implementiert wurden (GPUs), nur eben als Hardware-Architektur
- Verschiedene Arten der Optimierung: Komprimierung, Kombination mit anderen (orthogonalen) Optimierungsmethoden, Optimierungen an der Hardware
- Komprimierung: Huffman-Kodierung (35-49x Komprimierungsfaktor mit Pruning, Quantisierung, Huffman), HashNets (variable Komprimierungsrate bis zu 64x, je nach Anforderung an Präzision)
- Kombination mit anderen Optimierungsmethoden: In-Memory computation (Berechnung ohne ALU direkt im Speicher), Approximierende Schaltungen (Berechnung mit Aufgabe der Exaktheit)
- Hardware-Optimierungen: Neue Speichertechnologien (z.B. Memristoren)

*nächste Folie*

Literatur

*Ende*