การวัดปริมาณหลังการฝึกอบรมเป็นเทคนิคการแปลงที่สามารถลดขนาดโมเดลได้ในขณะเดียวกันก็ปรับปรุงเวลาแฝงของ CPU และตัวเร่งความเร็วฮาร์ดแวร์ โดยลดความแม่นยำของโมเดลลงเล็กน้อย คุณสามารถวัดปริมาณโมเดล TensorFlow แบบลอยตัวที่ฝึกไว้แล้วได้เมื่อคุณแปลงเป็นรูปแบบ TensorFlow Lite โดยใช้ TensorFlow Lite Converter
วิธีการเพิ่มประสิทธิภาพ
มีตัวเลือกการวัดปริมาณหลังการฝึกอบรมให้เลือกมากมาย นี่คือตารางสรุปของตัวเลือกและประโยชน์ที่ได้รับ:
เทคนิค | ประโยชน์ | ฮาร์ดแวร์ |
---|---|---|
การวัดช่วงไดนามิก | เล็กลง 4x, เร่งความเร็ว 2x-3x | ซีพียู |
การหาปริมาณจำนวนเต็ม | เล็กลง 4x เร็วขึ้น 3x+ | CPU, Edge TPU, ไมโครคอนโทรลเลอร์ |
การหาปริมาณ float16 | เล็กลง 2 เท่า เร่ง GPU | ซีพียู, จีพียู |
แผนผังการตัดสินใจต่อไปนี้สามารถช่วยตัดสินว่าวิธีการหาปริมาณหลังการฝึกแบบใดดีที่สุดสำหรับกรณีการใช้งานของคุณ:
การวัดช่วงไดนามิก
การวัดปริมาณช่วงไดนามิกเป็นจุดเริ่มต้นที่แนะนำ เนื่องจากช่วยลดการใช้หน่วยความจำและการคำนวณที่เร็วขึ้นโดยที่คุณไม่ต้องจัดเตรียมชุดข้อมูลตัวแทนสำหรับการสอบเทียบ การหาปริมาณประเภทนี้ การหาปริมาณแบบคงที่เฉพาะน้ำหนักจากจุดลอยตัวเป็นจำนวนเต็ม ณ เวลาการแปลง ซึ่งให้ความแม่นยำ 8 บิต:
import tensorflow as tf converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir) converter.optimizations = [tf.lite.Optimize.DEFAULT] tflite_quant_model = converter.convert()
เพื่อลดเวลาแฝงในระหว่างการอนุมาน ตัวดำเนินการ "ช่วงไดนามิก" จะกำหนดปริมาณการเปิดใช้งานแบบไดนามิกตามช่วงเป็น 8 บิต และดำเนินการคำนวณด้วยน้ำหนัก 8 บิตและการเปิดใช้งาน การเพิ่มประสิทธิภาพนี้ให้เวลาแฝงที่ใกล้เคียงกับการอนุมานจุดตายตัวอย่างสมบูรณ์ อย่างไรก็ตาม ผลลัพธ์ยังคงถูกจัดเก็บโดยใช้จุดลอยตัว ดังนั้นความเร็วที่เพิ่มขึ้นของ ops ช่วงไดนามิกจึงน้อยกว่าการคำนวณจุดคงที่แบบเต็ม
การหาปริมาณจำนวนเต็ม
คุณสามารถรับการปรับปรุงเวลาแฝงเพิ่มเติม การลดการใช้หน่วยความจำสูงสุด และความเข้ากันได้กับอุปกรณ์ฮาร์ดแวร์หรือตัวเร่งความเร็วที่เป็นจำนวนเต็มเท่านั้น โดยทำให้แน่ใจว่าคณิตศาสตร์แบบจำลองทั้งหมดเป็นจำนวนเต็มเชิงปริมาณ
สำหรับการวัดปริมาณจำนวนเต็ม คุณต้องปรับเทียบหรือประเมินช่วง เช่น (ต่ำสุด, สูงสุด) ของเมตริกทศนิยมทั้งหมดในแบบจำลอง ไม่เหมือนกับเทนเซอร์คงที่ เช่น น้ำหนักและอคติ เทนเซอร์แปรผัน เช่น อินพุตโมเดล การเปิดใช้งาน (เอาต์พุตของเลเยอร์ระดับกลาง) และเอาต์พุตโมเดลไม่สามารถปรับเทียบได้ เว้นแต่เราจะเรียกใช้การอนุมานสองสามรอบ เป็นผลให้ตัวแปลงต้องการชุดข้อมูลที่เป็นตัวแทนในการสอบเทียบ ชุดข้อมูลนี้สามารถเป็นชุดย่อยขนาดเล็ก (ประมาณ 100-500 ตัวอย่าง) ของข้อมูลการฝึกอบรมหรือการตรวจสอบความถูกต้อง อ้างอิงถึงฟังก์ชัน representative_dataset()
ด้านล่าง
จากเวอร์ชัน TensorFlow 2.7 คุณสามารถระบุชุดข้อมูลตัวแทนผ่าน ลายเซ็นได้ ดังตัวอย่างต่อไปนี้:
def representative_dataset(): for data in dataset: yield { "image": data.image, "bias": data.bias, }
หากมีมากกว่าหนึ่งลายเซ็นในโมเดล TensorFlow ที่ระบุ คุณสามารถระบุชุดข้อมูลหลายชุดได้โดยการระบุคีย์ลายเซ็น:
def representative_dataset(): # Feed data set for the "encode" signature. for data in encode_signature_dataset: yield ( "encode", { "image": data.image, "bias": data.bias, } ) # Feed data set for the "decode" signature. for data in decode_signature_dataset: yield ( "decode", { "image": data.image, "hint": data.hint, }, )
คุณสามารถสร้างชุดข้อมูลตัวแทนได้โดยระบุรายการเทนเซอร์อินพุต:
def representative_dataset(): for data in tf.data.Dataset.from_tensor_slices((images)).batch(1).take(100): yield [tf.dtypes.cast(data, tf.float32)]
ตั้งแต่เวอร์ชัน TensorFlow 2.7 เราขอแนะนำให้ใช้วิธีตามลายเซ็นแทนวิธีตามรายการเทนเซอร์อินพุต เนื่องจากสามารถพลิกลำดับการป้อนเทนเซอร์ได้อย่างง่ายดาย
เพื่อจุดประสงค์ในการทดสอบ คุณสามารถใช้ชุดข้อมูลจำลองได้ดังต่อไปนี้:
def representative_dataset(): for _ in range(100): data = np.random.rand(1, 244, 244, 3) yield [data.astype(np.float32)]
จำนวนเต็มพร้อมโฟลตสำรอง (ใช้อินพุต/เอาต์พุตโฟลตเริ่มต้น)
ในการหาจำนวนเต็มเชิงปริมาณของโมเดล แต่ให้ใช้ตัวดำเนินการทศนิยมเมื่อไม่มีการใช้งานจำนวนเต็ม (เพื่อให้แน่ใจว่าการแปลงเกิดขึ้นอย่างราบรื่น) ให้ใช้ขั้นตอนต่อไปนี้:
import tensorflow as tf converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir) converter.optimizations = [tf.lite.Optimize.DEFAULT] converter.representative_dataset = representative_dataset tflite_quant_model = converter.convert()
จำนวนเต็มเท่านั้น
การสร้างแบบจำลองจำนวนเต็มเท่านั้นเป็นกรณีการใช้งานทั่วไปสำหรับ TensorFlow Lite สำหรับไมโครคอนโทรลเลอร์ และ Coral Edge TPU
นอกจากนี้ เพื่อให้แน่ใจว่าเข้ากันได้กับอุปกรณ์จำนวนเต็มเท่านั้น (เช่น ไมโครคอนโทรลเลอร์ 8 บิต) และตัวเร่งความเร็ว (เช่น Coral Edge TPU) คุณสามารถบังคับใช้การวัดจำนวนเต็มสำหรับ ops ทั้งหมด รวมถึงอินพุตและเอาต์พุต โดยใช้ขั้นตอนต่อไปนี้:
import tensorflow as tf converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir) converter.optimizations = [tf.lite.Optimize.DEFAULT] converter.representative_dataset = representative_dataset converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8] converter.inference_input_type = tf.int8 # or tf.uint8 converter.inference_output_type = tf.int8 # or tf.uint8 tflite_quant_model = converter.convert()
การหาปริมาณ float16
คุณสามารถลดขนาดของโมเดลทศนิยมได้โดยการหาน้ำหนักเป็น float16 ซึ่งเป็นมาตรฐาน IEEE สำหรับตัวเลขทศนิยม 16 บิต หากต้องการเปิดใช้งานการหาปริมาณของน้ำหนัก float16 ให้ใช้ขั้นตอนต่อไปนี้:
import tensorflow as tf converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir) converter.optimizations = [tf.lite.Optimize.DEFAULT] converter.target_spec.supported_types = [tf.float16] tflite_quant_model = converter.convert()
ข้อดีของการวัดปริมาณ float16 มีดังนี้:
- ลดขนาดโมเดลได้ถึงครึ่งหนึ่ง (เนื่องจากน้ำหนักทั้งหมดกลายเป็นครึ่งหนึ่งของขนาดเดิม)
- ทำให้สูญเสียความแม่นยำน้อยที่สุด
- รองรับผู้ร่วมประชุมบางคน (เช่น ผู้ร่วมประชุม GPU) ซึ่งสามารถทำงานโดยตรงกับข้อมูล float16 ทำให้ดำเนินการได้เร็วกว่าการคำนวณ float32
ข้อเสียของการวัดปริมาณ float16 มีดังนี้:
- มันไม่ได้ลดเวลาแฝงมากเท่าการวัดปริมาณเป็นคณิตศาสตร์จุดคงที่
- ตามค่าเริ่มต้น โมเดลเชิงปริมาณ float16 จะ "dequantize" ค่าน้ำหนักเป็น float32 เมื่อรันบน CPU (โปรดทราบว่าผู้แทน GPU จะไม่ดำเนินการ dequantization นี้ เนื่องจากสามารถดำเนินการกับข้อมูล float16 ได้)
จำนวนเต็มเท่านั้น: การเปิดใช้งาน 16 บิตพร้อมน้ำหนัก 8 บิต (ทดลอง)
นี่เป็นแผนการทดลองเชิงปริมาณ มันคล้ายกับโครงร่าง "จำนวนเต็มเท่านั้น" แต่การเปิดใช้งานจะถูกวัดปริมาณตามช่วงเป็น 16 บิต น้ำหนักจะถูกวัดเป็นจำนวนเต็ม 8 บิต และอคติจะถูกวัดเป็นจำนวนเต็ม 64 บิต สิ่งนี้เรียกว่า 16x8 quantization ต่อไป
ข้อได้เปรียบหลักของการวัดปริมาณนี้คือสามารถปรับปรุงความแม่นยำได้อย่างมาก แต่เพิ่มขนาดโมเดลเพียงเล็กน้อยเท่านั้น
import tensorflow as tf converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir) converter.representative_dataset = representative_dataset converter.optimizations = [tf.lite.Optimize.DEFAULT] converter.target_spec.supported_ops = [tf.lite.OpsSet.EXPERIMENTAL_TFLITE_BUILTINS_ACTIVATIONS_INT16_WEIGHTS_INT8] tflite_quant_model = converter.convert()
หากตัวดำเนินการบางตัวในโมเดลไม่รองรับการวัดปริมาณ 16x8 โมเดลยังคงสามารถวัดปริมาณได้ แต่ตัวดำเนินการที่ไม่รองรับจะถูกเก็บไว้แบบลอยตัว ควรเพิ่มตัวเลือกต่อไปนี้ใน target_spec เพื่ออนุญาตสิ่งนี้
import tensorflow as tf converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir) converter.representative_dataset = representative_dataset converter.optimizations = [tf.lite.Optimize.DEFAULT] converter.target_spec.supported_ops = [tf.lite.OpsSet.EXPERIMENTAL_TFLITE_BUILTINS_ACTIVATIONS_INT16_WEIGHTS_INT8, tf.lite.OpsSet.TFLITE_BUILTINS] tflite_quant_model = converter.convert()
ตัวอย่างของกรณีการใช้งานที่มีการปรับปรุงความแม่นยำโดยแผนการวัดปริมาณนี้ ได้แก่:
- ความละเอียดสูงสุด,
- การประมวลผลสัญญาณเสียง เช่น การตัดเสียงรบกวนและการสร้างลำแสง
- ภาพขจัดสัญญาณรบกวน,
- การสร้าง HDR ใหม่จากภาพเดียว
ข้อเสียของการวัดปริมาณนี้คือ:
- ขณะนี้การอนุมานช้ากว่าจำนวนเต็ม 8 บิตอย่างเห็นได้ชัด เนื่องจากขาดการปรับใช้เคอร์เนลที่เหมาะสม
- ขณะนี้ไม่เข้ากันกับผู้รับมอบสิทธิ์ TFLite ที่เร่งด้วยฮาร์ดแวร์ที่มีอยู่
บทช่วยสอนสำหรับโหมดการวัดปริมาณนี้สามารถพบได้ ที่นี่
ความแม่นยำของแบบจำลอง
เนื่องจากน้ำหนักเป็นการวัดปริมาณหลังการฝึกอบรม อาจมีการสูญเสียความแม่นยำ โดยเฉพาะอย่างยิ่งสำหรับเครือข่ายขนาดเล็ก มีโมเดลเชิงปริมาณที่ได้รับการฝึกฝนไว้ล่วงหน้าสำหรับเครือข่ายเฉพาะบน TensorFlow Hub สิ่งสำคัญคือต้องตรวจสอบความถูกต้องของแบบจำลองเชิงปริมาณเพื่อตรวจสอบว่าความแม่นยำที่ลดลงนั้นอยู่ในขอบเขตที่ยอมรับได้ มีเครื่องมือสำหรับประเมิน ความแม่นยำของโมเดล TensorFlow Lite
อีกทางหนึ่ง หากความแม่นยำลดลงสูงเกินไป ให้พิจารณาใช้ การฝึกอบรมที่ทราบปริมาณ อย่างไรก็ตาม การทำเช่นนั้นจำเป็นต้องมีการแก้ไขระหว่างการฝึกโมเดลเพื่อเพิ่มโหนดการวัดปริมาณปลอม ในขณะที่เทคนิคการวัดปริมาณหลังการฝึกในหน้านี้ใช้โมเดลที่ได้รับการฝึกอบรมล่วงหน้าที่มีอยู่
การเป็นตัวแทนของเทนเซอร์เชิงปริมาณ
การวัดปริมาณ 8 บิตจะประมาณค่าทศนิยมโดยใช้สูตรต่อไปนี้
\[real\_value = (int8\_value - zero\_point) \times scale\]
การแสดงมีสองส่วนหลัก:
น้ำหนักต่อแกน (หรือที่เรียกว่าต่อแชนเนล) หรือน้ำหนักต่อเทนเซอร์ที่แสดงโดยค่าเสริมของ int8 two ในช่วง [-127, 127] โดยมีจุดศูนย์เท่ากับ 0
การเปิดใช้งานต่อเทนเซอร์/อินพุตแสดงด้วยค่าเสริมของ int8 two ในช่วง [-128, 127] โดยมีจุดศูนย์อยู่ในช่วง [-128, 127]
สำหรับมุมมองโดยละเอียดของรูปแบบการหาปริมาณของเรา โปรดดู ข้อมูลจำเพาะของการวัดปริมาณ ของเรา ผู้จำหน่ายฮาร์ดแวร์ที่ต้องการเชื่อมต่อกับอินเทอร์เฟซผู้รับมอบสิทธิ์ของ TensorFlow Lite ได้รับการสนับสนุนให้ใช้โครงร่างการวัดปริมาณที่อธิบายไว้ที่นั่น