Delegat GPU për LiteRT

Përdorimi i njësive të përpunimit grafik (GPU) për të ekzekutuar modelet tuaja të të mësuarit automatik (ML) mund të përmirësojë ndjeshëm performancën e modelit tuaj dhe përvojën e përdoruesit të aplikacioneve tuaja të aktivizuara nga ML. LiteRT mundëson përdorimin e GPU-ve dhe procesorëve të tjerë të specializuar përmes një drajveri harduerik të quajtur delegatë . Mundësimi 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 rendiment të lartë të ngarkesave të punës masivisht paralele. Ky dizajn i bën ato të përshtatshme për rrjetet nervore të thella, të cilat përbëhen nga një numër i madh operatorësh, secili duke punuar në tenzorë 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ë mjaftueshëm shpejt për të mundësuar aplikacione në kohë reale që nuk ishin të mundura më parë.
  • Efikasiteti i energjisë - GPU-të kryejnë llogaritjet e 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 informacion më specifik rreth zbatimit të mbështetjes së GPU-ve në platforma specifike, shihni udhëzuesit e mëposhtëm:

Mbështetje për operacionet GPU ML

Ekzistojnë disa kufizime në lidhje me operacionet ose operacionet e TensorFlow ML që mund të përshpejtohen nga delegati i GPU-së LiteRT. Delegati mbështet operacionet e mëposhtme me 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 operacionet mbështeten vetëm në versionin 1. Aktivizimi i mbështetjes së kuantizimit aktivizon versionet përkatëse, për shembull, ADD v2.

Zgjidhja e problemeve me mbështetjen e GPU-së

Nëse disa nga operacionet nuk mbështeten nga delegati i GPU-së, kuadri do të ekzekutojë vetëm një pjesë të grafikut në GPU dhe pjesën tjetër në CPU. Për shkak të kostos së lartë të sinkronizimit CPU/GPU, një modalitet ekzekutimi i ndarë si ky shpesh rezulton në performancë më të ngadaltë sesa kur i gjithë rrjeti ekzekutohet vetëm në CPU. Në këtë rast, aplikacioni gjeneron paralajmërim, si p.sh.:

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

Nuk ka rikthim për dështimet e këtij lloji, pasi ky nuk është një dështim real në kohën e ekzekutimit. Kur testoni ekzekutimin e modelit tuaj me delegatin e GPU-së, duhet të jeni të vëmendshëm për këto paralajmërime. Një numër i lartë i këtyre paralajmërimeve mund të tregojë se modeli juaj nuk është më i përshtatshmi për përdorim për përshpejtimin e GPU-së dhe mund të kërkojë rifaktorizim të modelit.

Modele shembullore

Modelet e mëposhtme shembullore 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ë arrini performancë më të mirë kur ekzekutoni modele në harduerin GPU duke përdorur delegatin e GPU-së LiteRT:

  • 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 mobile. Operacionet e riformësimit janë veçanërisht të kushtueshme për t'u ekzekutuar, duke përfshirë BATCH_TO_SPACE , SPACE_TO_BATCH , SPACE_TO_DEPTH e kështu me radhë. Duhet të shqyrtoni nga afër përdorimin e operacioneve të riformësimit dhe të merrni në konsideratë se ato mund të jenë aplikuar vetëm për eksplorimin e të dhënave ose për përsëritje të 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 e tensorit ndahen në 4 kanale, dhe kështu një llogaritje në një tensor me formën [B,H,W,5] kryen pothuajse të njëjtën gjë në një tensor me formën [B,H,W,8] , por dukshëm më keq se [B,H,W,4] . Nëse hardueri i kamerës që po përdorni mbështet korniza imazhi në RGBA, ushqyerja e asaj hyrjeje me 4 kanale është dukshëm më e shpejtë, pasi shmang një kopjim memorieje nga RGB me 3 kanale në RGBX me 4 kanale.

  • Modele të optimizuara për celular - Për performancën më të mirë, duhet të merrni në konsideratë rikualifikimin e klasifikuesit tuaj me një arkitekturë rrjeti të optimizuar për celular. Optimizimi për inferencimin në pajisje mund të zvogëlojë ndjeshëm vonesën dhe konsumin e energjisë duke përfituar nga veçoritë e harduerit celular.

Mbështetje e avancuar e GPU-së

Mund të përdorni teknika shtesë 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 i përshkruajnë këto teknika në detaje të mëtejshme.

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ë tenzorë hyrës dhe dalës me pikë lundruese.

Si funksionon kjo?

Meqenëse backend-i i 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:

  • Tensorët konstantë (si peshat/paragjykimet) dekuantizohen një herë në memorien e GPU-së. Ky operacion ndodh kur delegati është i aktivizuar për LiteRT.

  • Të dhënat hyrëse dhe dalëse në programin GPU, nëse janë 8-bit të kuantizuara, dekuantizohen dhe kuantizohen (respektivisht) për secilin përfundim. Ky operacion kryhet në CPU duke përdorur bërthamat e optimizuara të LiteRT.

  • Simulatorët 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 në lidhje me aktivizimin e kësaj veçorie me delegatin e GPU-së, shihni sa vijon:

Reduktimi i kohës së inicializimit me serializim

Funksioni i delegimit të GPU-së ju lejon të ngarkoni nga kodi i bërthamës i parapërgatitur 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 nisjes deri në 90%. Ky përmirësim arrihet duke shkëmbyer hapësirën e diskut për kursimin e kohës. Mund ta aktivizoni këtë funksion me disa opsione konfigurimi, siç tregohet në shembujt e mëposhtëm të kodit:

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:

  • Ruaj të dhënat e serializimit në një drejtori që nuk është e arritshme për aplikacionet e tjera. Në pajisjet Android, përdor getCodeCacheDir() që tregon në një vendndodhje që është private për aplikacionin aktual.
  • Tokeni i modelit duhet të jetë unik për pajisjen për modelin specifik. Mund të llogaritni një token modeli duke gjeneruar një gjurmë gishtash nga të dhënat e modelit duke përdorur librari të tilla si farmhash::Fingerprint64 .