نمایندگان GPU برای LiteRT

استفاده از واحدهای پردازش گرافیکی (GPU) برای اجرای مدل‌های یادگیری ماشینی (ML) می‌تواند عملکرد مدل شما و تجربه کاربری برنامه‌های دارای ML را به طور چشمگیری بهبود بخشد. LiteRT استفاده از GPU و سایر پردازنده های تخصصی را از طریق درایور سخت افزاری به نام delegates امکان پذیر می کند. فعال کردن استفاده از GPU با برنامه های LiteRT ML می تواند مزایای زیر را ارائه دهد:

  • سرعت - پردازنده‌های گرافیکی برای توان عملیاتی بالای بارهای کاری موازی ساخته شده‌اند. این طراحی آن‌ها را برای شبکه‌های عصبی عمیق، که متشکل از تعداد زیادی عملگر هستند، مناسب می‌کند، که هر کدام روی تانسورهای ورودی کار می‌کنند که می‌توانند به‌طور موازی پردازش شوند، که معمولاً منجر به تأخیر کمتری می‌شود. در بهترین سناریو، اجرای مدل شما بر روی یک GPU ممکن است به اندازه کافی سریع اجرا شود تا برنامه های بلادرنگی را فعال کند که قبلا امکان پذیر نبودند.
  • بهره وری انرژی - GPU ها محاسبات ML را به شیوه ای بسیار کارآمد و بهینه انجام می دهند، معمولاً نسبت به همان وظیفه ای که روی CPU اجرا می شود، انرژی کمتری مصرف می کنند و گرمای کمتری تولید می کنند.

این سند یک نمای کلی از پشتیبانی GPU در LiteRT و برخی کاربردهای پیشرفته برای پردازنده‌های GPU ارائه می‌کند. برای اطلاعات بیشتر در مورد اجرای پشتیبانی از GPU در پلتفرم های خاص، به راهنمای زیر مراجعه کنید:

پشتیبانی از عملیات GPU ML

برخی از محدودیت‌ها در مورد عملیات یا عملیات TensorFlow ML وجود دارد که می‌تواند توسط نماینده GPU LiteRT تسریع شود. نماینده عملیات زیر را با دقت شناور 16 بیتی و 32 بیتی پشتیبانی می کند:

  • 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

به‌طور پیش‌فرض، همه عملیات‌ها فقط در نسخه 1 پشتیبانی می‌شوند. فعال کردن پشتیبانی کوانتیزاسیون ، نسخه‌های مناسب را فعال می‌کند، به عنوان مثال، ADD v2.

عیب یابی پشتیبانی از پردازنده گرافیکی

اگر برخی از عملیات توسط نماینده GPU پشتیبانی نشود، چارچوب تنها بخشی از نمودار را روی GPU و قسمت باقیمانده را روی CPU اجرا می کند. به دلیل هزینه بالای همگام سازی CPU/GPU، یک حالت اجرای تقسیم مانند این اغلب منجر به عملکرد کندتر نسبت به زمانی که کل شبکه به تنهایی بر روی CPU اجرا می شود، می شود. در این حالت، برنامه هشدارهایی مانند:

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

هیچ تماسی برای خرابی از این نوع وجود ندارد، زیرا این یک شکست واقعی در زمان اجرا نیست. هنگام آزمایش اجرای مدل خود با نماینده GPU، باید نسبت به این هشدارها هوشیار باشید. تعداد بالای این هشدارها می تواند نشان دهد که مدل شما برای شتاب GPU مناسب نیست و ممکن است نیاز به بازسازی مدل داشته باشد.

مدل های نمونه

مدل‌های نمونه زیر برای استفاده از شتاب GPU با LiteRT ساخته شده‌اند و برای مرجع و آزمایش ارائه شده‌اند:

بهینه سازی برای پردازنده های گرافیکی

تکنیک‌های زیر می‌توانند به شما کمک کنند هنگام اجرای مدل‌ها بر روی سخت‌افزار GPU با استفاده از نماینده LiteRT GPU عملکرد بهتری داشته باشید:

  • عملیات تغییر شکل - برخی از عملیاتی که در یک CPU سریع هستند ممکن است هزینه بالایی برای GPU در دستگاه های تلفن همراه داشته باشند. اجرای عملیات تغییر شکل بسیار گران است، از جمله BATCH_TO_SPACE ، SPACE_TO_BATCH ، SPACE_TO_DEPTH ، و غیره. شما باید استفاده از عملیات تغییر شکل را به دقت بررسی کنید و در نظر بگیرید که ممکن است فقط برای کاوش داده ها یا برای تکرارهای اولیه مدل شما اعمال شده باشد. حذف آنها می تواند به طور قابل توجهی عملکرد را بهبود بخشد.

  • کانال‌های داده تصویر - در GPU، داده‌های تانسور به 4 کانال تقسیم می‌شوند و بنابراین محاسبه روی یک تانسور با شکل [B,H,W,5] روی تانسور شکل [B,H,W,8] تقریباً یکسان عمل می‌کند. [B,H,W,8] ، اما به طور قابل توجهی بدتر از [B,H,W,4] . اگر سخت‌افزار دوربینی که استفاده می‌کنید از فریم‌های تصویر در RGBA پشتیبانی می‌کند، تغذیه آن ورودی 4 کانال به طور قابل توجهی سریع‌تر است، زیرا از کپی حافظه از RGB 3 کانال به RGBX 4 کانال جلوگیری می‌کند.

  • مدل‌های بهینه‌سازی شده برای موبایل - برای بهترین عملکرد، باید طبقه‌بندی‌کننده خود را با معماری شبکه بهینه‌سازی شده برای تلفن همراه بازآموزی کنید. بهینه‌سازی برای استنباط روی دستگاه می‌تواند با بهره‌گیری از ویژگی‌های سخت‌افزاری موبایل، تأخیر و مصرف انرژی را به‌طور چشمگیری کاهش دهد.

پشتیبانی از GPU پیشرفته

می‌توانید از تکنیک‌های پیشرفته و اضافی با پردازش GPU استفاده کنید تا عملکرد بهتری را برای مدل‌های خود فراهم کنید، از جمله کوانتیزاسیون و سریال‌سازی. بخش های بعدی این تکنیک ها را با جزئیات بیشتر توضیح می دهند.

استفاده از مدل های کوانتیزه

این بخش توضیح می‌دهد که چگونه نماینده GPU به مدل‌های کوانتیزه ۸ بیتی شتاب می‌دهد، از جمله موارد زیر:

برای بهینه سازی عملکرد، از مدل هایی استفاده کنید که دارای هر دو تانسور ورودی و خروجی ممیز شناور هستند.

این چگونه کار می کند؟

از آنجایی که باطن GPU فقط از اجرای ممیز شناور پشتیبانی می‌کند، ما مدل‌های کوانتیزه‌شده را با دادن «نمای ممیز شناور» از مدل اصلی اجرا می‌کنیم. در سطح بالا، این شامل مراحل زیر است:

  • تانسورهای ثابت (مانند وزن ها/بایاس ها) یک بار در حافظه GPU کوانتیزه می شوند. این عملیات زمانی اتفاق می افتد که نماینده برای LiteRT فعال باشد.

  • ورودی ها و خروجی های برنامه GPU، اگر 8 بیتی کوانتیزه شوند، برای هر استنتاج، کوانتیزه و کوانتیزه می شوند (به ترتیب). این عملیات بر روی CPU با استفاده از هسته های بهینه LiteRT انجام می شود.

  • شبیه سازهای کوانتیزاسیون بین عملیات برای تقلید رفتار کوانتیزه شده قرار می گیرند. این رویکرد برای مدل‌هایی ضروری است که عملیات‌ها انتظار دارند فعال‌سازی‌ها از محدوده‌های آموخته‌شده در طول کوانتیزاسیون پیروی کنند.

برای اطلاعات در مورد فعال کردن این ویژگی با نماینده GPU، به موارد زیر مراجعه کنید:

کاهش زمان اولیه سازی با سریال سازی

ویژگی GPU delegate به شما این امکان را می دهد که از کد هسته از پیش کامپایل شده بارگیری کنید و داده ها را به صورت سریالی و ذخیره شده روی دیسک از اجراهای قبلی مدل کنید. این رویکرد از کامپایل مجدد جلوگیری می کند و می تواند زمان راه اندازی را تا 90٪ کاهش دهد. این بهبود با تبادل فضای دیسک برای صرفه جویی در زمان به دست می آید. همانطور که در نمونه کد زیر نشان داده شده است، می توانید این ویژگی را با چند گزینه پیکربندی فعال کنید:

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;
      

جاوا

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

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

هنگام استفاده از ویژگی سریال سازی، مطمئن شوید که کد شما با این قوانین پیاده سازی مطابقت دارد:

  • داده های سریال سازی را در دایرکتوری ذخیره کنید که برای سایر برنامه ها قابل دسترسی نیست. در دستگاه‌های Android، از getCodeCacheDir() استفاده کنید که به مکانی اشاره می‌کند که برای برنامه فعلی خصوصی است.
  • نشانه مدل باید منحصر به فرد برای دستگاه برای مدل خاص باشد. می‌توانید با ایجاد اثر انگشت از داده‌های مدل با استفاده از کتابخانه‌هایی مانند farmhash::Fingerprint64 ، یک نشانه مدل را محاسبه کنید.