การมอบสิทธิ์ GPU สำหรับ TensorFlow Lite

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

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

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

การสนับสนุนการดำเนินการ GPU ML

การดำเนินการหรือ ops ของ TensorFlow ML ที่เร่งได้ด้วยการมอบสิทธิ์ GPU ของ TensorFlow Lite ยังมีข้อจำกัดบางประการ ผู้รับมอบสิทธิ์รองรับการดำเนินการต่อไปนี้ด้วยความแม่นยำแบบลอยแบบ 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 ด้วย TensorFlow Lite และมีไว้เพื่ออ้างอิงและการทดสอบ

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

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

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

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

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

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

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

การใช้โมเดลที่เล็กลง

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

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

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

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

  • Tensor คงที่ (เช่น น้ำหนัก/อคติ) จะมีการลดค่าเชิงปริมาณลงในหน่วยความจำ GPU การดำเนินการนี้จะเกิดขึ้นเมื่อเปิดใช้ผู้รับมอบสิทธิ์สำหรับ TensorFlow Lite

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

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

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

การลดเวลาเริ่มต้นด้วยการเรียงลำดับ

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

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