ผู้มอบสิทธิ์ GPU สำหรับ LiteRT

การใช้หน่วยประมวลผลกราฟิก (GPU) เพื่อเรียกใช้โมเดลแมชชีนเลิร์นนิง (ML) จะช่วยปรับปรุงประสิทธิภาพของโมเดลและประสบการณ์ของผู้ใช้ แอปพลิเคชันที่เปิดใช้ ML ได้อย่างมาก LiteRT ช่วยให้ใช้ GPU และโปรเซสเซอร์เฉพาะทางอื่นๆ ผ่านไดรเวอร์ฮาร์ดแวร์ที่เรียกว่าDelegates ได้ การเปิดใช้ GPU กับแอปพลิเคชัน LiteRT ML จะให้ประโยชน์ต่อไปนี้

  • ความเร็ว - GPU สร้างขึ้นเพื่อปริมาณงานสูงของเวิร์กโหลดแบบคู่ขนานขนาดใหญ่ การออกแบบนี้ทำให้เหมาะกับโครงข่ายประสาทเทียมแบบลึก ซึ่งประกอบด้วยตัวดำเนินการจำนวนมาก โดยแต่ละตัวดำเนินการจะทำงานกับเทนเซอร์อินพุตที่ประมวลผลแบบขนานได้ ซึ่งโดยปกติแล้วจะทำให้เกิดเวลาในการตอบสนองที่ต่ำกว่า ใน สถานการณ์ที่ดีที่สุด การเรียกใช้โมเดลใน GPU อาจทำงานได้เร็วพอที่จะเปิดใช้ แอปพลิเคชันแบบเรียลไทม์ที่ก่อนหน้านี้เป็นไปไม่ได้
  • ประสิทธิภาพด้านพลังงาน - GPU ดำเนินการคำนวณ ML อย่างมีประสิทธิภาพและได้รับการเพิ่มประสิทธิภาพเป็นอย่างมาก โดยปกติแล้วจะใช้พลังงานน้อยลงและสร้างความร้อนน้อยกว่าเมื่อเทียบกับงานเดียวกันที่ทำงานบน CPU

เอกสารนี้ให้ภาพรวมของการรองรับ GPU ใน LiteRT และการใช้งานขั้นสูงบางอย่างสำหรับโปรเซสเซอร์ GPU ดูข้อมูลที่เฉพาะเจาะจงเพิ่มเติมเกี่ยวกับการติดตั้งใช้งานการรองรับ GPU ในแพลตฟอร์มที่เฉพาะเจาะจงได้ที่คู่มือต่อไปนี้

รองรับการดำเนินการ ML ของ GPU

TensorFlow ML Operations หรือ Ops บางอย่างมีข้อจำกัดในการเร่งความเร็วด้วยตัวแทน 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 ไม่รองรับการดำเนินการบางอย่าง เฟรมเวิร์กจะเรียกใช้เฉพาะส่วนหนึ่งของกราฟใน GPU และส่วนที่เหลือใน CPU เนื่องจากค่าใช้จ่ายในการซิงโครไนซ์ CPU/GPU สูง โหมดการดำเนินการแบบแยกส่วนเช่นนี้ มักส่งผลให้ประสิทธิภาพช้ากว่าเมื่อรันทั้งเครือข่ายบน CPU เพียงอย่างเดียว ในกรณีนี้ แอปพลิเคชันจะสร้างคำเตือน เช่น

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

ไม่มีการเรียกกลับสำหรับความล้มเหลวประเภทนี้ เนื่องจากไม่ใช่ความล้มเหลวของรันไทม์จริง เมื่อทดสอบการดำเนินการของโมเดลด้วยตัวแทน GPU คุณควรระวังคำเตือนเหล่านี้ คำเตือนเหล่านี้จำนวนมากอาจ บ่งบอกว่าโมเดลของคุณไม่เหมาะกับการใช้เพื่อการเร่งความเร็ว GPU และ อาจต้องมีการปรับโครงสร้างโมเดล

ตัวอย่างโมเดล

โมเดลตัวอย่างต่อไปนี้สร้างขึ้นเพื่อใช้ประโยชน์จากการเร่งความเร็ว GPU ด้วย LiteRT และมีไว้เพื่อใช้อ้างอิงและทดสอบ

การเพิ่มประสิทธิภาพสำหรับ GPU

เทคนิคต่อไปนี้จะช่วยให้คุณได้รับประสิทธิภาพที่ดีขึ้นเมื่อเรียกใช้โมเดล ในฮาร์ดแวร์ GPU โดยใช้ LiteRT GPU Delegate

  • ปรับรูปร่างการดำเนินการ - การดำเนินการบางอย่างที่รวดเร็วใน CPU อาจมีค่าใช้จ่ายสูงสำหรับ GPU ในอุปกรณ์เคลื่อนที่ การดำเนินการเปลี่ยนรูปร่างมีค่าใช้จ่ายสูงเป็นพิเศษ ซึ่งรวมถึง BATCH_TO_SPACE, SPACE_TO_BATCH, SPACE_TO_DEPTH และอื่นๆ คุณควรตรวจสอบการใช้การดำเนินการเปลี่ยนรูปร่างอย่างละเอียด และพิจารณาว่าอาจมีการใช้การดำเนินการดังกล่าวเพื่อสำรวจข้อมูลเท่านั้น หรือเพื่อการทำซ้ำโมเดลในช่วงแรกๆ การนำออกจะช่วย ปรับปรุงประสิทธิภาพได้อย่างมาก

  • แชแนลข้อมูลรูปภาพ - ใน GPU ระบบจะแบ่งข้อมูลเทนเซอร์ออกเป็น 4 แชแนล และ ดังนั้นการคำนวณในเทนเซอร์ที่มีรูปร่าง [B,H,W,5] จะทำงานได้ เหมือนกับในเทนเซอร์ที่มีรูปร่าง [B,H,W,8] แต่จะแย่กว่า [B,H,W,4] อย่างมาก หากฮาร์ดแวร์กล้องที่คุณใช้รองรับเฟรมรูปภาพใน RGBA การป้อนข้อมูล 4 ช่องจะเร็วกว่ามาก เนื่องจากไม่ต้อง คัดลอกหน่วยความจำจาก RGB 3 ช่องไปยัง RGBX 4 ช่อง

  • โมเดลที่เพิ่มประสิทธิภาพสำหรับอุปกรณ์เคลื่อนที่ - เพื่อให้ได้ประสิทธิภาพที่ดีที่สุด คุณควรพิจารณา ฝึกตัวแยกประเภทอีกครั้งด้วยสถาปัตยกรรมเครือข่ายที่เพิ่มประสิทธิภาพสำหรับอุปกรณ์เคลื่อนที่ การเพิ่มประสิทธิภาพสำหรับการอนุมานในอุปกรณ์ช่วยลดเวลาในการตอบสนองและ การใช้พลังงานได้อย่างมากด้วยการใช้ประโยชน์จากฟีเจอร์ฮาร์ดแวร์ของอุปกรณ์เคลื่อนที่

การสนับสนุน GPU ขั้นสูง

คุณสามารถใช้เทคนิคขั้นสูงเพิ่มเติมกับการประมวลผล GPU เพื่อให้โมเดลมีประสิทธิภาพดียิ่งขึ้น ซึ่งรวมถึงการควอนไทซ์และการซีเรียลไลซ์ ส่วนต่อไปนี้จะอธิบายเทคนิคเหล่านี้โดยละเอียด

การใช้โมเดลที่แปลงเป็นจำนวนเต็ม

ส่วนนี้จะอธิบายวิธีที่ตัวแทน GPU เร่งความเร็วโมเดลที่แปลงเป็นควอนไทซ์ 8 บิต ซึ่งรวมถึงรายการต่อไปนี้

ใช้โมเดลที่มีทั้งอินพุตและเอาต์พุตเทนเซอร์แบบจุดลอยตัวเพื่อเพิ่มประสิทธิภาพ

คุณลักษณะนี้ทำงานอย่างไร

เนื่องจากแบ็กเอนด์ของ GPU รองรับเฉพาะการดำเนินการแบบจุดลอยตัว เราจึงเรียกใช้โมเดลที่ผ่านการวัดปริมาณ โดยให้ "มุมมองแบบจุดลอยตัว" ของโมเดลต้นฉบับ ใน ภาพรวม ขั้นตอนนี้เกี่ยวข้องกับขั้นตอนต่อไปนี้

  • เทนเซอร์ค่าคงที่ (เช่น น้ำหนัก/อคติ) จะได้รับการยกเลิกการวัดปริมาณครั้งเดียวใน หน่วยความจำ GPU การดำเนินการนี้จะเกิดขึ้นเมื่อเปิดใช้ตัวแทนสำหรับ LiteRT

  • อินพุตและเอาต์พุตของโปรแกรม GPU หากมีการวัดปริมาณ 8 บิต จะได้รับการวัดปริมาณย้อนกลับและวัดปริมาณ (ตามลำดับ) สำหรับการอนุมานแต่ละครั้ง การดำเนินการนี้ จะทำใน CPU โดยใช้เคอร์เนลที่เพิ่มประสิทธิภาพของ LiteRT

  • เครื่องจำลองการหาปริมาณจะแทรกอยู่ระหว่างการดำเนินการเพื่อเลียนแบบลักษณะการทำงานที่หาปริมาณแล้ว แนวทางนี้จำเป็นสำหรับโมเดลที่การดำเนินการคาดว่าจะมีการเปิดใช้งาน ตามขอบเขตที่ได้เรียนรู้ระหว่างการควอนไทซ์

ดูข้อมูลเกี่ยวกับการเปิดใช้ฟีเจอร์นี้ด้วยตัวแทน GPU ได้ที่ ต่อไปนี้

ลดเวลาเริ่มต้นด้วยการซีเรียลไลซ์

ฟีเจอร์ตัวแทน GPU ช่วยให้คุณโหลดจากโค้ดเคอร์เนลที่คอมไพล์ไว้ล่วงหน้าและ ข้อมูลโมเดลที่แปลงเป็นอนุกรมและบันทึกไว้ในดิสก์จากการเรียกใช้ก่อนหน้านี้ได้ วิธีนี้ช่วยหลีกเลี่ยง การคอมไพล์ซ้ำและลดเวลาเริ่มต้นได้สูงสุด 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;
      

Java

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

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

เมื่อใช้ฟีเจอร์การเรียงลำดับ โปรดตรวจสอบว่าโค้ดเป็นไปตาม กฎการใช้งานต่อไปนี้

  • จัดเก็บข้อมูลการซีเรียลไลซ์ในไดเรกทอรีที่แอปอื่นๆ เข้าถึงไม่ได้ ในอุปกรณ์ Android ให้ใช้ getCodeCacheDir() ซึ่งชี้ไปยังตำแหน่งที่เป็นส่วนตัวของแอปพลิเคชันปัจจุบัน
  • โทเค็นโมเดลต้องไม่ซ้ำกันสำหรับอุปกรณ์ในโมเดลที่เฉพาะเจาะจง คุณสามารถ คำนวณโทเค็นโมเดลได้โดยการสร้างลายนิ้วมือจากข้อมูลโมเดลโดยใช้ ไลบรารี เช่น farmhash::Fingerprint64