Delegat GPU për LiteRT

Përdorimi i njësive të përpunimit grafik (GPU) për të ekzekutuar modelet tuaja të mësimit të makinerisë (ML) mund të përmirësojë në mënyrë dramatike performancën e modelit tuaj dhe përvojën e përdoruesit të aplikacioneve tuaja të aktivizuara me ML. LiteRT mundëson përdorimin e GPU-ve dhe procesorëve të tjerë të specializuar përmes drejtuesit të harduerit të quajtur delegatë . Aktivizimi i përdorimit të GPU-ve me aplikacionet tuaja LiteRT ML mund të ofrojë përfitimet e mëposhtme:

  • Shpejtësia - GPU-të janë ndërtuar për performancë të lartë të ngarkesave të punës masivisht paralele. Ky dizajn i bën ato të përshtatshme për rrjeta të thella nervore, të cilat përbëhen nga një numër i madh operatorësh, secili duke punuar në tensorë hyrës që mund të përpunohen paralelisht, gjë që zakonisht rezulton në vonesë më të ulët. Në skenarin më të mirë, ekzekutimi i modelit tuaj në një GPU mund të funksionojë mjaft shpejt për të aktivizuar aplikacione në kohë reale që nuk ishin të mundshme më parë.
  • Efikasiteti i energjisë - GPU-të kryejnë llogaritjet ML në një mënyrë shumë efikase dhe të optimizuar, zakonisht duke konsumuar më pak energji dhe duke gjeneruar më pak nxehtësi sesa e njëjta detyrë që ekzekutohet në CPU.

Ky dokument ofron një përmbledhje të mbështetjes së GPU-ve në LiteRT dhe disa përdorime të avancuara për procesorët GPU. Për më shumë informacion specifik në lidhje me zbatimin e mbështetjes GPU në platforma specifike, shihni udhëzuesit e mëposhtëm:

Mbështetje për operacionet GPU ML

Ka disa kufizime për atë se cilat operacione TensorFlow ML, ose ops , mund të përshpejtohen nga delegati i LiteRT GPU. Delegati mbështet funksionet e mëposhtme në precizion float 16-bit dhe 32-bit:

  • ADD
  • AVERAGE_POOL_2D
  • CONCATENATION
  • CONV_2D
  • DEPTHWISE_CONV_2D v1-2
  • EXP
  • FULLY_CONNECTED
  • LOGICAL_AND
  • LOGISTIC
  • LSTM v2 (Basic LSTM only)
  • MAX_POOL_2D
  • MAXIMUM
  • MINIMUM
  • MUL
  • PAD
  • PRELU
  • RELU
  • RELU6
  • RESHAPE
  • RESIZE_BILINEAR v1-3
  • SOFTMAX
  • STRIDED_SLICE
  • SUB
  • TRANSPOSE_CONV

Si parazgjedhje, të gjitha funksionet mbështeten vetëm në versionin 1. Aktivizimi i mbështetjes së kuantizimit mundëson versionet e duhura, për shembull, ADD v2.

Zgjidhja e problemeve Mbështetja e GPU-së

Nëse disa nga opsionet nuk mbështeten nga delegati i GPU-së, korniza do të ekzekutojë vetëm një pjesë të grafikut në GPU dhe pjesën e mbetur në CPU. Për shkak të kostos së lartë të sinkronizimit të CPU/GPU, një mënyrë ekzekutimi e ndarë si kjo shpesh rezulton në performancë më të ngadaltë sesa kur i gjithë rrjeti funksionon vetëm në CPU. Në këtë rast, aplikacioni gjeneron paralajmërime, si p.sh.

WARNING: op code #42 cannot be handled by this delegate.

Nuk ka asnjë thirrje për dështime të këtij lloji, pasi ky nuk është një dështim aktual i kohës së ekzekutimit. Kur testoni ekzekutimin e modelit tuaj me delegatin GPU, duhet të jeni vigjilent për këto paralajmërime. Një numër i madh i këtyre paralajmërimeve mund të tregojë se modeli juaj nuk është më i përshtatshmi për t'u përdorur për përshpejtimin e GPU-së dhe mund të kërkojë rifaktorim të modelit.

Shembuj të modeleve

Modelet e mëposhtme të shembujve janë ndërtuar për të përfituar nga përshpejtimi i GPU-së me LiteRT dhe ofrohen për referencë dhe testim:

Optimizimi për GPU-të

Teknikat e mëposhtme mund t'ju ndihmojnë të merrni performancë më të mirë kur përdorni modele në harduerin GPU duke përdorur delegatin LiteRT GPU:

  • Operacionet e riformësimit - Disa operacione që janë të shpejta në një CPU mund të kenë një kosto të lartë për GPU-në në pajisjet celulare. Operacionet e riformësimit janë veçanërisht të shtrenjta për t'u ekzekutuar, duke përfshirë BATCH_TO_SPACE , SPACE_TO_BATCH , SPACE_TO_DEPTH , e kështu me radhë. Duhet të ekzaminoni nga afër përdorimin e operacioneve të riformësimit dhe të konsideroni se mund të jetë aplikuar vetëm për eksplorimin e të dhënave ose për përsëritjet e hershme të modelit tuaj. Heqja e tyre mund të përmirësojë ndjeshëm performancën.

  • Kanalet e të dhënave të imazhit - Në GPU, të dhënat tensori ndahen në 4 kanale, dhe kështu një llogaritje në një tensor me formën [B,H,W,5] funksionon pothuajse të njëjtën gjë në një tensor të formës [B,H,W,8] , por dukshëm më keq se [B,H,W,4] . Nëse pajisja e kamerës që po përdorni mbështet kornizat e imazhit në RGBA, dhënia e asaj hyrjeje me 4 kanale është dukshëm më e shpejtë, pasi shmang një kopje të memories nga RGB me 3 kanale në RGBX me 4 kanale.

  • Modele të optimizuara për celularin - Për performancën më të mirë, duhet të konsideroni ritrajnimin e klasifikuesit tuaj me një arkitekturë rrjeti të optimizuar për celularin. Optimizimi për konkluzionet në pajisje mund të reduktojë në mënyrë dramatike vonesën dhe konsumin e energjisë duke përfituar nga veçoritë e harduerit celular.

Mbështetje e avancuar GPU

Mund të përdorni teknika shtesë dhe të avancuara me përpunimin GPU për të mundësuar performancë edhe më të mirë për modelet tuaja, duke përfshirë kuantizimin dhe serializimin. Seksionet e mëposhtme përshkruajnë këto teknika në më shumë detaje.

Përdorimi i modeleve të kuantizuara

Ky seksion shpjegon se si delegati i GPU-së përshpejton modelet e kuantizuara 8-bit, duke përfshirë sa vijon:

Për të optimizuar performancën, përdorni modele që kanë tensorë hyrje dhe dalje me pikë lundruese.

Si funksionon kjo?

Meqenëse mbështetja e GPU-së mbështet vetëm ekzekutimin me pikë lundruese, ne ekzekutojmë modele të kuantizuara duke i dhënë asaj një 'pamje me pikë lundruese' të modelit origjinal. Në një nivel të lartë, kjo përfshin hapat e mëposhtëm:

  • Tenzorët konstant (të tillë si peshat/paragjykimet) de-kuantizohen një herë në memorien GPU. Ky veprim ndodh kur delegati është i aktivizuar për LiteRT.

  • Hyrjet dhe daljet në programin GPU, nëse kuantizohen 8-bit, de-kuantizohen dhe kuantizohen (përkatësisht) për çdo përfundim. Ky operacion kryhet në CPU duke përdorur kernelet e optimizuara të LiteRT.

  • Simuluesit e kuantizimit futen midis operacioneve për të imituar sjelljen e kuantizuar. Kjo qasje është e nevojshme për modelet ku operacionet presin që aktivizimet të ndjekin kufijtë e mësuar gjatë kuantizimit.

Për informacion rreth aktivizimit të kësaj veçorie me delegatin e GPU-së, shihni sa vijon:

Reduktimi i kohës së inicializimit me serializimin

Funksioni i delegimit të GPU ju lejon të ngarkoni nga kodi i parapërpiluar i kernelit dhe të dhënat e modelit të serializuara dhe të ruajtura në disk nga ekzekutimet e mëparshme. Kjo qasje shmang ripërpilimin dhe mund të zvogëlojë kohën e fillimit deri në 90%. Ky përmirësim arrihet duke shkëmbyer hapësirën në disk për kursimin e kohës. Ju mund ta aktivizoni këtë veçori me disa opsione konfigurimi, siç tregohet në shembujt e kodit të mëposhtëm:

C++

    TfLiteGpuDelegateOptionsV2 options = TfLiteGpuDelegateOptionsV2Default();
    options.experimental_flags |= TFLITE_GPU_EXPERIMENTAL_FLAGS_ENABLE_SERIALIZATION;
    options.serialization_dir = kTmpDir;
    options.model_token = kModelToken;

    auto* delegate = TfLiteGpuDelegateV2Create(options);
    if (interpreter->ModifyGraphWithDelegate(delegate) != kTfLiteOk) return false;
      

Java

    GpuDelegate delegate = new GpuDelegate(
      new GpuDelegate.Options().setSerializationParams(
        /* serializationDir= */ serializationDir,
        /* modelToken= */ modelToken));

    Interpreter.Options options = (new Interpreter.Options()).addDelegate(delegate);
      

Kur përdorni veçorinë e serializimit, sigurohuni që kodi juaj të jetë në përputhje me këto rregulla zbatimi:

  • Ruani të dhënat e serializimit në një direktori që nuk është e aksesueshme nga aplikacionet e tjera. Në pajisjet Android, përdorni getCodeCacheDir() që tregon një vendndodhje që është private për aplikacionin aktual.
  • Shenja e modelit duhet të jetë unik për pajisjen për modelin specifik. Ju mund të llogaritni një shenjë modeli duke gjeneruar një gjurmë gishti nga të dhënat e modelit duke përdorur biblioteka të tilla si farmhash::Fingerprint64 .