Le chemin a finalement été long et les préparatifs sont terminés. Déplaçons le circuit de convolution conçu avec la carte Ultra96V2!
Le fichier suivant a été créé la dernière fois (AI Edge Contest (Implementation Contest) Tutorial [9: HW Synthesis to Generate Bitstream]) doit.
Ces fichiers sont renvoyés au 3e (AI Edge Contest (Implementation Contest) Tutorial [3: Inference Execution on Ultra96 Board CPU]) Placez-le dans / home / xylinx / pynq / overlays / base
sur la carte Ultra96 V2.
Aussi, le banc d'essai que j'ai utilisé jusqu'à présent
Placez dans / home / xylinx / data
.
Bloc-notes pour le contrôle du matériel est un référentiel de didacticiels (https://github/master/Inference_PYNQ_1/ultra96v2_pynq_convolution_layer0.ipynb) est un référentiel de didacticiels (
https://FPGA_2019_2019_AI_HirokiNaka. Il se trouve dans blob / master / Inference_PYNQ_1). Veuillez le cloner et le placer dans votre maison Ultra96 V2
/ home / xylinx`. Plus tard, je le chargerai avec le notebook Jupyter Ultra96 V2.
Connectez-vous au notebook Jupyter Ultra96 V2 depuis votre navigateur. Veuillez vous référer à la partie 3. Cliquez sur Télécharger pour charger et exécuter le notebook (ʻultra96v2_pynq_convolution_layer0.ipynb`). Après cela, si vous exécutez à partir du haut, la préparation, l'exécution de l'inférence (mais lente) et l'inférence sur le processeur pour la comparaison seront effectuées respectivement.
Ci-dessous, je me concentrerai sur les principaux points.
ultra96v2_pynq_convolution_layer0.ipynb
from pynq import Overlay
import pynq
overlay = Overlay('/home/xilinx/pynq/overlays/base/pynq_ultra96_conv_l0_r1.bit')
dir(overlay)
PYNQ fait abstraction du matériel avec le concept de superposition. Comme vous pouvez le voir en l'affichant, je pense que certains noms de noyau (kernel_0 ou axi_dma_0) utilisés dans la connexion IP précédente sont affichés. Accédez-y et effectuez des opérations.
ultra96v2_pynq_convolution_layer0.ipynb
registers = overlay.kernel_0.register_map
Par exemple, vous pouvez contrôler votre noyau IP avec Python en accédant à register_map. Cette fois, le flux AXI est spécifié par le pragma, de sorte que l'opération est facile! C'est génial (pour tous ceux qui ont écrit des bus AXI en RTL).
Bien qu'il s'agisse d'un paramètre DMA,
ultra96v2_pynq_convolution_layer0.ipynb
import pynq.lib.dma
dma = overlay.axi_dma_0
Et accéder à la superposition
ultra96v2_pynq_convolution_layer0.ipynb
from pynq import Xlnk
inimg_size = 416*11*3
outfmap_size = 102*64+1
xlnk = Xlnk()
send_buf = xlnk.cma_array(shape=(inimg_size),dtype=np.int32)
recv_buf = xlnk.cma_array(shape=(outfmap_size),dtype=np.int32)
Et Xlnk ()
(un wrapper pour le middleware de contrôle DMA conçu par Xilinx), j'ai sécurisé le tableau. Victoire facile.
Transfert et réception de données matérielles
ultra96v2_pynq_convolution_layer0.ipynb
%%time
for line in range(102):
# load input image
for i in range(11):
inimg_buf[i] = inimg[i+line*4]
tmp = inimg_buf.copy().transpose((2,0,1)).reshape(-1,) # CH,Y,X
send_buf[0:inimg_size] = tmp[0:inimg_size]
# activate DMA
registers.CTRL.AP_START = 1
# DMA access
dma.sendchannel.transfer(send_buf)
dma.recvchannel.transfer(recv_buf)
# wait DMA
dma.sendchannel.wait()
dma.recvchannel.wait()
# store output buffer
tmp2 = recv_buf[0:outfmap_size - 1]
tmp2 = tmp2.reshape((64,102)) # CH, X
outfmap_buf[line] = tmp2
Passez le tableau numpy (inimg dans ce cas) et définissez le registre de début de transfert sur ON (ʻAP_START`). Après cela, passez le tampon à "transfer" et attendez que le transfert (c'est-à-dire, le traitement de l'opération de convolution) soit terminé ("wait"). Après cela, transmettez les données correspondantes au tableau numpy et vous avez terminé. Répétez cette opération pour la ligne de sortie.
J'ai mesuré le temps avec «%% time». C'est un moyen d'appeler une commande externe dans Jupyter Notebook. Et lequel
CPU times: user 22.5 s, sys: 6.85 ms, total: 22.5 s
Wall time: 22.5 s
Lent. .. .. Après tout, l'estimation de 22 secondes et HLS était exacte. .. .. Nous vérifions également après cela. Veuillez le déplacer et vérifier que le matériel fonctionne correctement.
Au fait, vous devriez avoir Pytorch installé, alors vérifions le temps d'inférence du processeur.
ultra96v2_pynq_convolution_layer0.ipynb
import torch
x = torch.randn(1,3,416,416)
conv = torch.nn.Conv2d(in_channels=3, out_channels=64, kernel_size=11,stride=4,bias=False)
y = conv(x)
CPU times: user 259 ms, sys: 7.96 ms, total: 267 ms
Wall time: 93.2 ms
Eh, environ 100 fois plus vite. .. .. C'est Dosun. (C'est assez courant> conception FPGA)
J'ai donc essayé toutes les étapes de l'apprentissage de Pytorch → conception de logiciels → conception de matériel → travaillant réellement avec FPGA, mais le résultat était décevant. .. Je pense que vous pouvez comprendre à quel point les obstacles à la conception matérielle sont élevés, sans parler de l'apprentissage en profondeur.
À ce rythme, ce n'est pas assez bon, alors faisons de notre mieux pour le rendre plus rapide. Donc ça va continuer pendant un moment.
Recommended Posts