Kunstmatige intelligentie op GPU’s betekent niet noodzakelijkerwijs dure grafische kaarten en een enorm energieverbruik. NVIDIA beweegt zich al een tijdje in de richting van kleinere systemen, zeker ook door de concurrentie van microcontroller-fabrikanten. In dit artikel bekijken we de Jetson Nano en een kleine demotoepassing.

De markt voor AI-versnelling in embedded systemen is in beweging. Bedrijven als Canaan en Maxim Integrated vechten verbitterd om suprematie. ARM waagt zich ook in deze arena met de aankondiging van de Cortex M52. Het doel is om kleine AI-systemen aan te bieden die basale AI-taken uitvoeren op de veelbesproken edge zonder verbinding met het internet. Dit leidt tot een veel stabielere systeemarchitectuur omdat de ML- of AI-taken dan kunnen blijven draaien ook als de verbinding met de bovenliggende server wegvalt. NVIDIA probeert al een tijdje op dit gebied voet aan de grond te krijgen met de Jetson-serie.

Inschrijven
Schrijf u in voor tag alert e-mails over Embedded & AI!

Eerlijkheidshalve moet worden opgemerkt dat maatgesneden boards met deze systemen niet werkelijk haalbaar zijn voor kleinere bedrijven, al was het maar vanwege de extreme bandbreedte die nodig is om toegang te krijgen tot het DDR-RAM. NVIDIA is zich bewust van dit probleem. Het portfolio-overzicht (beschikbaar op ) dat elektronica-ingenieurs een overzicht biedt van het volledige Jetson ecosysteem, bevat daarom ook verschillende ‘compute cards’, zoals de Jetson TX2 die in figuur 1 te zien is.
 

Figuur 1. Het gebruik van deze kant-en-klare module maakt het veel eenvoudiger om de Jetson te integreren in eigen schakelingen.

Er moet ook worden opgemerkt dat door de dominantie van NVIDIA in de GPU-sector, het goed ontwikkelde ecosysteem van derden nu ook het Jetson-productassortiment heeft ontdekt. Een overzicht met verschillende producten van derden is te vinden op , waarvan de integratie in een interne oplossing veel ontwikkelingstijd kan besparen (denk bijvoorbeeld aan het ontwerp van de behuizing en de selectie van camera’s en dergelijke).

De boel aan de praat krijgen

Voor ‘zij-instromers’ biedt NVIDIA de NVIDIA Jetson Nano Developer Kit die je ziet in figuur 2 (naast een Raspberry Pi en een Orange Pi 5+). Bij het ter perse gaan van dit artikel bedroeg de beste OEMSecrets-prijs (zie ) € 155. Hoewel dit iets duurder is dan een Raspberry Pi, is de NVIDIA-technologie beter geïntegreerd in het algemene AI-ecosysteem. Als je de NVIDIA Jetson Nano koopt, is het aan te raden om ook een voedingseenheid te bestellen met een voedingsconnector in de gebruikelijke afmetingen van 5,5/2,1 mm. Hieronder gebruikt de auteur een MeanWell GST25E05-P1J.

 

Figuur 2. De Jetson naast een Raspberry Pi 5 en een OrangePi 5 Plus.

Een zorgvuldige blik op het systeem (zie ook figuur 3) laat zien dat het een tweedelig product is. Naast decarrierprint, die de verschillende interfaces bevat, is er de eigenlijke computermodule met koellichaam. Er moet beslist een microSD-kaart met het besturingssysteem in de computermodule worden geplaatst.

Micro-USB Note

De ingebouwde SoC is een multicore-systeem dat naast de eigenlijke AI-versneller ook vier volwaardige Arm Cortex A57-cores heeft. Dit resulteert in een opstelling die doet denken aan klassieke procescomputers die meestal Embedded Linux draaien. NVIDIA raadt aan om een MicroSD-kaart te gebruiken met minstens 32 GB capaciteit en een minimumsnelheid van UHS1. Het imagebestand is te vinden op , dat je zoals gebruikelijk met een kaartlezer kunt uitpakken op je geheugenkaart.
 

Take developer kit apart
Figuur 3. Als je twee schroeven losdraait, kun je de development kit uit elkaar halen.

Een USB-muis en een USB-toetsenbord zijn ook nodig voor de eerste start; Jetson ondersteunt zowel HDMI als DisplayPort voor schermuitvoer. We gaan ervan uit dat er in de volgende stappen ook een ethernetkabel is aangesloten – eigenlijk is dat vanzelfsprekend.

Not for clumsy hands - note


Het ontbreken van een camera blijkt problematisch tijdens de installatie. In plaats van een CCD-sensor gebruikt NVIDIA twee van de connectoren die we kennen van Raspberry Pi 4 en dergelijke. Sommige Raspberry Pi-camera’s kunnen rechtstreeks op de Jetson worden aangesloten. In de volgende stappen gebruikt de auteur een Raspberry Pi 2-camera die wordt aangesloten op de CAM0-poort via een FPC-kabel die is gemaakt voor de Raspberry Pi. Er moet beslist worden opgemerkt dat de kabelversie die bedoeld is voor de Raspberry Pi 5 niet compatibel is met de Jetson. Verschillende 3D-modellen voor het positioneren van de camera zijn beschikbaar in ThingiVerse, en het afdrukken ervan zal het leven van de ontwikkelaar een stuk eenvoudiger maken.

Als je de NVIDIA Jetson in gebruik wilt nemen met de eerder genoemde MeanWell-voeding, moet je rekening houden met geniepigheidje waar beginners last van kunnen hebben. De jumper in figuur 4 is bij levering niet geplaatst: de DC connector is dan niet aangesloten op de voeding. Als de voeding is aangesloten, gaat de status-LED niet branden, en dat kan verwarring veroorzaken.
 

Important jumper
Figuur 4. Deze jumper is van cruciaal belang.

Tijdens de eerste keer opstarten schakelt de procescomputer meteen het HDMI-scherm in – de herconfiguratie van de microSD-kaart en enkele andere ‘initiatierituelen’ nemen enige tijd in beslag. Zodra het werk is gedaan, presenteert het systeem een Ubuntu-desktop en vraagt het je om de welkomstwizard te voltooien.

Over het algemeen is dit de gebruikelijke Ubuntu-installatiewizard, maar NVIDIA heeft onder andere een stap toegevoegd om de interne softwarelicenties te accepteren. De wizard voor het selecteren van het voedingsmodel is belangrijk: het is aan te raden om de standaard-optie aan te houden. Dit garandeert dat de Jetson de maximale hoeveelheid stroom krijgt.

Zodra de wizard met succes is voltooid, is het nog even wachten tot het Jetson-board klaar is voor gebruik – er kunnen ook enkele prompts op het bureaublad verschijnen om het systeem opnieuw op te starten.

Inschrijven
Schrijf u in voor tag alert e-mails over Electronics!

Eerste experimenten

NVIDIA vertrouwt op een min of meer volledig standaard-conform Ubuntu 18.04 in de Jetson. De auteur houdt ervan om zulke procescomputers te configureren voor toegang op afstand om zich zo de moeite te besparen om te schakelen tussen de toetsenborden van de PC en de procescomputer.

De Settings-applicatie in Ubuntu is echter ongeschikt voor deze taak, daarom draaien we sudo apt-get update en sudo apt-get upgrade om de package-inventaris bij te werken in de eerste stap. Elke vraag moet worden bevestigd door op Enter te drukken; de herstart van het Docker-systeem moet worden toegestaan. De Jetson moet dan opnieuw worden opgestart. Het invoeren van sudo apt install vino zorgt ervoor dat de VNC-server klaar is voor gebruik.

Tenslotte zijn de onderstaande commando’s nodig om de configuratie in een bruikbare staat te brengen. De string thepassword moet natuurlijk vervangen worden door een wachtwoord dat geschikt is voor jouw installatie.

 

tamhan@tamhan-desktop:~$ mkdir -p ~/.config/autostart

tamhan@tamhan-desktop:~$ cp /usr/share/applications/vino-server.desktop ~/.config/autostart

tamhan@tamhan-desktop:~$ gsettings set org.gnome.Vino prompt-enabled false

tamhan@tamhan-desktop:~$ gsettings set org.gnome.Vino require-encryption false

tamhan@tamhan-desktop:~$ gsettings set org.gnome.Vino authentication-methods "[’vnc’]"

tamhan@tamhan-desktop:~$ gsettings set org.gnome.Vino vnc-password $(echo -n ’thepassword’|base64)

 

Na de volgende herstart is de Jetson toegankelijk met de VNC-client Reminna als een gebruiker is ingelogd. Houd er echter rekening mee dat de applet voor externe toegang in de Settings-applicatie nog steeds niet werkt.

Als volgende stap kun je een eerste test van de cameraverbinding uitvoeren door het volgende commando in te typen:

 

tamhan@tamhan-desktop:~$ gst-launch-1.0 nvarguscamerasrc ! nvoverlaysink

 

De camera-preview die met dit basiscommando kan worden geactiveerd, verschijnt alleen op een monitor die fysiek op de Jetson is aangesloten – het systeem dat via VNC met de computer communiceert, ziet in plaats daarvan de terminaluitvoer. Om het hele proces te beëindigen, is het voldoende om een interrupt te versturen met Control + C.

De feitelijke toegang tot de camera wordt dan – over het algemeen – uitgevoerd met methoden die bekend zijn van de PC of het werkstation. Bijzonder interessant is het bestand , dat de opzet van een Open CV-gebaseerde pijplijn demonstreert.

De volgende commando’s zijn nodig om het lokaal uitvoerbaar te maken:

 

tamhan@tamhan-desktop:~$ git clone https://github.com/JetsonHacksNano/CSI-Camera

tamhan@tamhan-desktop:~$ cd CSI-Camera/

tamhan@tamhan-desktop:~/CSI-Camera$ python3 simple_camera.py

 

Het geopende cameravenster is dan ook zichtbaar via VNC omdat het de informatie niet rechtstreeks naar de framebuffer van de Tegra GPU stuurt.

Als het camerabeeld ondersteboven staat, helpt het om de parameter flip_method in het bestand aan te passen:

 

def show_camera():

    window_title = "CSI Camera"

    print(gstreamer_pipeline(flip_method=2))

    video_capture = cv2.VideoCapture(gstreamer_

      pipeline(flip_method=2), cv2.CAP_GSTREAMER)

    if video_capture.isOpened():

    . . .

Interactie met GPIO-pinnen (via Python)

Kunstmatig intelligente systemen vereisen compleet andere vaardigheden van de ontwikkelaar; over het algemeen is er weinig overlap met klassieke embedded ontwikkeling. In de praktijk is mij gebleken dat mensen van buiten het vakgebied met een achtergrond in traditionele mainframe-computertechnologie AI vaak beter onder de knie krijgen dan embedded ontwikkelaars. De partner van de auteur, die zeer efficiënt in Java programmeert, lost AI-taken sneller op – maar ze heeft weinig kennis van assembler.

Het doel van deze kleine omweg via software-architectuur is om aan te geven dat we in de volgende stappen met opzet GPIO-toegang op de Jetson in Python illustreren. De reden hiervoor is dat het merendeel van de gebruikersgeoriënteerde ontwikkeling van AI-systemen plaatsvindt in Python: als je hier op C vertrouwt, word je uiteindelijk getrakteerd op een onnodige ‘native’ interface.

De standaard-distributie van Python bevat geen package management op de Jetson, daarom moeten de commando’s sudo apt install python-pip en sudo apt install python3-pip worden ingevoerd. De volgende stap is controleren of de GPIO-modules correct zijn geïnstalleerd. Ook hier zijn twee commando’s nodig omdat de Python-omgevingen (uiteraard) niet echt in staat zijn om hun bibliotheekrepository te delen:

 

tamhan@tamhan-desktop:~$ sudo pip install Jetson.GPIO

tamhan@tamhan-desktop:~$ sudo pip3 install Jetson.GPIO

 

We kunnen de Jetson GPIO-API hier niet uitputtend bespreken vanwege ruimtegebrek. Onder vind je een groep kant-en-klare voorbeelden die de API volledig uitleggen.

Het onderstaande programma volstaat voor onze kleine test:

 

import RPi.GPIO as GPIO

import time

 

output_pin = 18  # BCM pin 18, BOARD pin 12

 

def main():

    GPIO.setmode(GPIO.BCM) 

# BCM pin-numbering scheme from Raspberry Pi

    GPIO.setup(output_pin, GPIO.OUT, initial=GPIO.HIGH)

 

    print("Starting demo now! Press CTRL+C to exit")

    try:

        while True:

            GPIO.output(output_pin,  GPIO.HIGH)

            GPIO.output(output_pin,  GPIO.LOW)

            GPIO.output(output_pin,  GPIO.HIGH)

            GPIO.output(output_pin,  GPIO.LOW)

 

    finally:

        GPIO.cleanup()

 

if __name__ == ’__main__’:

    main()

 

Hier is vooral interessant dat NVIDIA de ‘ontluikende’ Jetson-ontwikkelaar verschillende manieren biedt om de pinnen te adresseren – wij gebruiken hier de GPIO.BCM-optie, die gebaseerd is op de pinout van de Raspberry Pi. De beloning voor onze inspanningen is het screenshot van figuur 5 – de frequentiestabiliteit is misschien niet geweldig, maar het is meer dan voldoende voor het triggeren van IoT-gebeurtenissen.
 

NVIDIA Jetson produces square wave signals
Figuur 5. De NVIDIA Jetson produceert blokgolven met Python.

Ook moet worden opgemerkt dat het uitvoeren van GPIO-programmavoorbeelden zonder superuser-rechten soms problemen kan veroorzaken. Zie voor een gedetailleerde bespreking van dit onderwerp.

Inschrijven
Schrijf u in voor tag alert e-mails over python!

Experimenten met de ML-functie

In theorie bevordert de beschikbaarheid van een volwaardig Linux-besturingssysteem en een (zeer snelle) USB3-interface de uitvoering van experimenten. Een mogelijk voorbeeld zou Stable Diffusion zijn: in de praktijk is het mogelijk om de Jetson te gebruiken als beeldgenerator met behulp van een (aangepaste) runner.

In de praktijk is deze aanpak echter niet aan te raden: zowel het relatief kleine grafische geheugen van slechts 4 GB VRAM als het geringe aantal van ‘slechts’ 128 cores zorgen ervoor dat het genereren van afbeeldingen geduld vereist. Op Reddit staan verslagen van ML-experimenteerders die tot 5 uur rekentijd per afbeelding schatten met een clustergrootte van 512×512 pixels.

jump start note

 

Hetzelfde geldt voor de ‘end-to-end’ oplossingen die vaak worden gedemonstreerd – het trainen van een model vereist zoveel rekenkracht en middelen dat NVIDIA in de meeste tutorials aanbeveelt om het uit te besteden aan een desktop of mainframe – de Jetson wordt dan geparametriseerd met de kant-en-klare modelgewichten.

In vind je min of meer gebruiksklare voorbeelden die de prestaties van de Jetson op een inzichtelijke manier illustreren.

Om deze model-‘powershow’ te gebruiken, is het nodig om een NVIDIA-softwarepackage te downloaden en te implementeren. In theorie is het gebruik van een docker-container hier ook mogelijk – voor mensen die niet bekend zijn met containertechnologie is lokaal compileren een alternatief, dat kan worden bereikt door de volgende commando’s in te voeren:

 

sudo apt-get update

sudo apt-get install git cmake libpython3-dev python3-numpy

git clone --recursive --depth=1 https://github.com/dusty-nv/jetson-inference

cd jetson-inference

mkdir build

cd build

cmake ../

make -j$(nproc)

sudo make install

sudo ldconfig

 

Voel je vrij om de vraag over het installeren van de trainingsonderdelen met ja of nee te beantwoorden – de auteur heeft in de volgende stappen No geantwoord om wat geheugen te besparen op zijn microSD-kaart, die slechts 32 GB groot is.

Nadat het compilatieproces met succes is voltooid, kan een relatief complexe projectstructuur worden gevonden in de map ~/jetson-inference/build/aarch64$/bin, die naast verschillende binaire bestanden ook Python-bestanden bevat. Het is interessant om op te merken dat NVIDIA hier zelfs enkele kant-en-klare testvoorbeelden zet.

Als eerste willen we de classifier gebruiken – deze analyseert afbeeldingsbestanden en bepaalt wat er te zien is in de geleverde afbeelding:

 

tamhan@tamhan-desktop:~/jetson-inference/build/aarch64/bin$ ./imagenet.py images/orange_0.jpg images/test/output_0.jpg

 

De eerste maal uitvoeren van deze opdracht neemt iets meer tijd in beslag omdat de meegeleverde modules geoptimaliseerd zijn voor de vereisten van het Jetson-systeem. Daarna zien we de timinginformatie van figuur 6.
 

The demo program supplied with the Jetson
Figuur 6. Het demoprogramma dat bij de Jetson wordt geleverd is niet erg ‘communicatief’ op commandoregel-niveau.

Om de resultaten van het ML-proces te visualiseren, moet je het gegenereerde afbeeldingsbestand bekijken – door het volgende commando in te voeren open je de uitvoermap direct in de file manager van Nautilus:

 

tamhan@tamhan-desktop:~/jetson-inference/build/aarch64/bin$ nautilus images/test/output_0.jpg

The NVIDIA sample program
Figuur 7. Het NVIDIA-voorbeeldprogramma blijkt een voorbeeldige fruitdetector te zijn.

De beloning voor je inspanningen is het scherm van figuur 7.

Analyse van het Python-bestand

Nu werpen we een snelle blik op het voorbeeldprogramma dat we zojuist hebben gebruikt. De broncode kan worden geopend door de volgende opdrachtregel in te voeren:

 

tamhan@tamhan-desktop:~/jetson-inference/build/aarch64/bin$ gedit imagenet.py

 

Al op het eerste gezicht is het duidelijk dat de hier gebruikte bibliotheek verwant is aan het klassieke ImageNet – NVIDIA verpakt verschillende veelgebruikte kunstmatige intelligentie-systemen in de Jetson-starterkit.
 

Classification

De kern van het programmavoorbeeld is een eindeloze lus die een afbeelding opneemt uit de invoerstroom, deze doorsluist naar het ML-model en uiteindelijk de ‘berekende’ informatie toont (listing 1). De initialisatie van de gegevensstromen en het te gebruiken model wordt daarvoor uitgevoerd volgens het volgende schema:
 

net = imageNet(args.network, sys.argv)

input = videoSource(args.input, argv=sys.argv)

output = videoOutput(args.output, argv=sys.argv)

font = cudaFont()

 

Een ander interessant aspect is het verkrijgen of het invullen van de network-parameter, die de naam van het te verwerken model levert. Hier vertrouwt NVIDIA op de klasse ArgParser, die – normaal gesproken – gespecialiseerd is in het verwerken van parameters die via de commandoregel worden aangeleverd.

In het geval van deze declaratie wordt een standaardwaarde ingevoerd die normaal gesproken het GoogLeNet activeert en laadt:

 

parser.add_argument("--network", type=str, default="googlenet", help="pre-trained model to load (see below for options)")

 

Terzijde: ‘begeleide’ online-training inclusief certificering

Het succes van de voormalige Sovjet-Unie in verschillende Arabische en Afrikaanse landen kan deels worden toegeschreven aan het hechte trainingspartnerschap – wat de leerling leert, gebruikt hij later in zijn werk. NVIDIA is zich duidelijk bewust van deze situatie en daarom is Jetson AI Certification – zoals te zien in figuur 8 – een volledig gratis tweedelige ML-cursus. Ook moet worden benadrukt dat het succesvol afronden van de cursus door NVIDIA wordt beloond met een certificaat.

Als je geïnteresseerd bent, raden we je aan om te bezoeken. Daar vind je meer informatie over hoe je je deelname aan de NVIDIA-training zo efficiënt mogelijk kunt organiseren.
 

Two-track education
Figuur 8. Tweesporen-onderwijs in NVIDIA-stijl (bron: NVIDIA)

Voordelen dankzij Linux

Met de Jetson stuurt NVIDIA een hybride in de race die wat kunstmatige intelligentie betreft vlees noch vis is. Aan de ene kant hebben speciale low-power microcontrollers zoals de Maxim MAX78000 een aanzienlijk lager energieverbruik. Aan de andere kant lijden dergelijke controllers onder het feit dat ze geen ondersteuning bieden voor CUDA: een model dat op een PC of mainframecomputer kan draaien, moet dus worden aangepast voordat het met deze chips in IoT-applicaties kan worden gebruikt.

Aan de andere kant is de NVIDIA Jetson geen volwaardige GPU: zowel qua energieverbruik als qua ondersteunde CUDA-variant (CUDA 11 werkt niet) is de module geen volwaardige vervanger voor een RTX 4000.

Het komt erop neer dat een implementatie loont als een model dat probleemloos werkt op een computer of mainframe met weinig moeite moet worden gemobiliseerd en het voldoende heeft de middelen die Jetson biedt. De beschikbaarheid van een Linux-besturingssysteem betekent dat er relatief weinig conversiewerk nodig is voor een datawetenschapper – vertrouwd raken met de ingebedde API’s die Maxim en consorten gebruiken vereist aanzienlijk meer inspanning. De hogere kosten van de hardware kunnen dus snel en efficiënt worden afgeschreven, vooral bij kleinere series.


Dit artikel (230740-03) is verschenen in Elektor maart/april 2024


Vragen of opmerkingen?

Hebt u vragen of opmerkingen naar aanleiding van dit artikel? Stuur een e-mail naar de auteur via tamhan@tamoggemon.com of naar de redactie van Elektor via redactie@elektor.com.