ชุดทดสอบตัวเร่งความเร็ว LiteRT (ATS)

ชุดทดสอบตัวเร่ง LiteRT (ATS) เป็นเครื่องมือที่ครอบคลุมซึ่งใช้เพื่อ ตรวจสอบความถูกต้องของฟังก์ชันการทำงานและวัดประสิทธิภาพของ การติดตั้งใช้งานตัวเร่งที่กำหนดเองซึ่งผสานรวมกับเฟรมเวิร์ก LiteRT

ภาพรวมและฟังก์ชันหลัก

ฟังก์ชันหลักของ ATS คือการเรียกใช้โมเดลแมชชีนเลิร์นนิงที่กำหนดไว้ล่วงหน้า กับตัวเร่งเป้าหมาย และเปรียบเทียบผลลัพธ์กับแบ็กเอนด์ CPU มาตรฐานของ LiteRT

  • การตรวจสอบ: ชุดทดสอบจะทำการตรวจสอบตัวเลขโดยการเปรียบเทียบ เทนเซอร์เอาต์พุต (การเปิดใช้งาน) ที่สร้างโดยตัวเร่งกับเทนเซอร์ที่ สร้างโดยแบ็กเอนด์ CPU ที่ทราบว่าใช้งานได้ดี วิธีนี้ช่วยให้การติดตั้งใช้งานตัวเร่งความเร็ว ยังคงมีความแม่นยำและความถูกต้องตามที่กำหนด
  • เมตริกประสิทธิภาพ: ระบบจะบันทึกและบันทึกรายละเอียดประสิทธิภาพที่สำคัญโดยอัตโนมัติ ซึ่งรวมถึงเวลาในการตอบสนองและเมตริกอื่นๆ ที่เกี่ยวข้อง ซึ่งผู้ใช้จะเข้าถึงได้
  • การดำเนินการ: โดยปกติแล้วการทดสอบจะดำเนินการในอุปกรณ์เป้าหมาย (เช่น โทรศัพท์ Android) และได้รับการจัดการโดย Wrapper Shell Script ที่จัดการการโอนไฟล์และการตั้งค่าโดยใช้เครื่องมือ adb (Android Debug Bridge)

ข้อมูลการทดสอบ (โมเดล)

ชุด ATS ใช้คอลเล็กชัน.tfliteโมเดลที่ใช้กันอย่างแพร่หลายเป็นข้อมูลทดสอบ ระบบจะสร้างข้อมูลนำเข้าแบบสุ่มตามประเภทข้อมูล และสามารถเริ่มต้นได้ตามต้องการ

รุ่นที่รวมอยู่

ระบบจะรวมและดาวน์โหลดโมเดลต่อไปนี้โดยอัตโนมัติเพื่อใช้ในการทดสอบ (อาจมีการเปลี่ยนแปลง)

  • hf_all_minilm_l6_v2
  • hf_mobilevit_small
  • qai_hub_midas
  • qai_hub_real_esrgan_x4plus
  • torchvision_mobilenet_v2
  • torchvision_resnet18
  • torchvision_squeezenet1_1
  • u2net_lite
  • whisper_tiny_decoder
  • whisper_tiny_encoder
  • yamnet
  • yolo11n

การดึงข้อมูลโมเดลด้วยตนเอง

แม้ว่าระบบจะดาวน์โหลดโมเดลโดยอัตโนมัติในระหว่างbazel run แต่คุณก็สามารถดึงข้อมูลชุดโมเดลทั้งหมดด้วยตนเองได้โดยใช้wget

wget -p -O <target_file> https://storage.googleapis.com/litert/ats_models.tar.gz

การกำหนดชุด ATS ด้วย Bazel

ใช้มาโคร Bazel litert_define_ats เพื่อกำหนดค่าและกำหนดเป้าหมายการทดสอบ ATS ที่เฉพาะเจาะจงสำหรับตัวเร่ง

มาโครจะสร้างเป้าหมายที่เรียกใช้ได้2 รายการโดยอัตโนมัติ

  1. การทดสอบ JIT ในอุปกรณ์มาตรฐาน (สำหรับการดำเนินการและการตรวจสอบ)
  2. การทดสอบโหมด "คอมไพล์เท่านั้น" ของ AOT โดยเฉพาะ (สำหรับการคอมไพล์โฮสต์)

ตัวอย่างlitert_define_atsการใช้งาน

ตัวอย่างนี้กำหนดชุด ATS ชื่อ example_ats สำหรับตัวเร่งที่มีชื่อแบ็กเอนด์ example

# Emits aot-mode and jit-mode test targets, one for running compilation test on host
# and another for running JIT and inference on device
# These targets are named with their respective suffix attribute.
litert_define_ats(
    name = "example_ats",
    backend = "example",
    compile_only_suffix = "_aot",
    do_register = [
        "*mobilenet*",
    ],
    extra_flags = ["--limit=1"],
    jit_suffix = "",
)

การลงมือปฏิบัติ

หากต้องการเรียกใช้การทดสอบมาตรฐานที่กำหนดเป้าหมายสำหรับ Android (ซึ่งจัดการการดำเนินการทั้งหมดของ adb ) ให้ทำดังนี้

# Handles environment setup, and build + push of library and data dependencies to the device,
# executes the suite on the target.
bazel run -c opt --config=android_arm64 :example_ats

วิธีเรียกใช้การทดสอบการคอมไพล์ AOT

# Handle environment setup, and builds library dependencies for host platform.
# Executes the ats compile only flow. The "--compile_mode" flag is already
# bound to the program arguments.
bazel run :example_ats_aot

การดำเนินการ Linux (โฮสต์)

สำหรับการดำเนินการใน Linux ซึ่ง ATS ทำงานในเครื่องเดียวกับที่ใช้สร้าง ผู้ใช้จะต้องใช้ไบนารี :ats โดยตรง

bazel run -c opt :ats

การดำเนินการ IoT

สำหรับการดำเนินการ IoT ผู้ใช้จะต้องสร้างไบนารีในโฮสต์และ ส่งไปยังอุปกรณ์ด้วยตนเอง

Flag บรรทัดคำสั่ง

atsไฟล์ที่เรียกใช้งานได้จะยอมรับแฟล็กหลายรายการเพื่อการควบคุมการทดสอบและการรายงานแบบละเอียด

ธง ประเภท คำอธิบาย
--backend std::string ต้องระบุ แบ็กเอนด์ LiteRT ที่จะใช้เป็นตัวเร่งภายใต้การทดสอบ ("จริง") ตัวเลือกคือ cpu, npu หรือ gpu
--compile_mode bool หากเป็นจริง จะเรียกใช้ขั้นตอนการคอมไพล์ AOT ในเวิร์กสเตชันแทนที่จะเป็นการดำเนินการในอุปกรณ์ หมายเหตุ: ตัวเลือกนี้จะเชื่อมโยงกับเป้าหมายการสร้าง "aot" โดยอัตโนมัติ และไม่จำเป็นต้องตั้งค่าอย่างชัดเจน
--models_out std::string เส้นทางไดเรกทอรีที่บันทึกโมเดลที่ซีเรียลไลซ์ (คอมไพล์) ที่มีผลข้างเคียง เกี่ยวข้องกับการคอมไพล์ AOT หรือ JIT เท่านั้น
--dispatch_dir std::string เส้นทางไปยังไดเรกทอรีที่มีไลบรารีการเรียกใช้ของตัวเร่ง (เกี่ยวข้องกับ NPU)
--plugin_dir std::string เส้นทางไปยังไดเรกทอรีที่มีไลบรารีปลั๊กอินคอมไพเลอร์ของตัวเร่ง (เกี่ยวข้องกับ NPU)
--soc_manufacturer std::string ผู้ผลิต SOC ที่จะกำหนดเป้าหมายสำหรับการคอมไพล์ AOT (เกี่ยวข้องกับการคอมไพล์ NPU)
--soc_model std::string โมเดล SOC ที่จะกำหนดเป้าหมายสำหรับการคอมไพล์ AOT (เกี่ยวข้องกับการคอมไพล์ NPU)
--iters_per_test size_t จำนวนการวนซ้ำที่จะเรียกใช้ต่อการทดสอบ โดยแต่ละครั้งจะมีข้อมูลเทนเซอร์แบบสุ่มที่แตกต่างกัน
--max_ms_per_test int64_t เวลาสูงสุดเป็นมิลลิวินาทีในการเรียกใช้การทดสอบแต่ละครั้งก่อนที่จะหมดเวลา
--fail_on_timeout bool ควรให้การทดสอบล้มเหลวหรือไม่หากการดำเนินการหมดเวลา
--csv std::string เส้นทางไฟล์ที่จะบันทึกรายงานแบบละเอียดในรูปแบบ CSV
--dump_report bool จะทิ้งรายละเอียดรายงานทั้งหมดลงในเอาต์พุตของคอนโซลของผู้ใช้โดยตรงหรือไม่
--data_seed std::optional<int> แหล่งข้อมูลเดียวสำหรับการสร้างข้อมูลทั่วโลก
--do_register std::vector<std::string> นิพจน์ทั่วไปสำหรับการรวมการทดสอบที่เฉพาะเจาะจงอย่างชัดเจน (เช่น *mobilenet*)
--dont_register std::vector<std::string> นิพจน์ทั่วไปเพื่อยกเว้นการทดสอบที่เฉพาะเจาะจง
--extra_models std::vector<std::string> รายการไดเรกทอรีหรือไฟล์โมเดลที่ไม่บังคับเพื่อเพิ่มลงในชุดทดสอบ
--limit int32_t จำกัดจำนวนการทดสอบทั้งหมดที่ลงทะเบียนและเรียกใช้
--quiet bool ลดเอาต์พุตการบันทึกระหว่างการทดสอบ

การใช้litert_device_scriptเครื่องมือสร้างสำหรับ ATS

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

ฟังก์ชันการทำงานนี้มีให้ใช้งานโดยทั่วไปผ่านยูทิลิตี litert_device_script ซึ่ง ATS สร้างขึ้นเพื่อใช้ในเบื้องหลัง โดยมีกระบวนการลงทะเบียน ที่โปรแกรมเร่งรัดต้องทำเพื่อเข้าถึงฟังก์ชันการสร้างนี้ นอกจากจะรองรับ ats แล้ว ยูทิลิตีเหล่านี้ยังใช้แบบสแตนด์อโลนเพื่อจำลอง cc_binary และ cc_test ที่มีไว้สำหรับเรียกใช้ในอุปกรณ์ที่แตกต่างจากโฮสต์บิลด์ที่ต้องมีการพุชการอ้างอิงได้ด้วย

การลงทะเบียนแบ็กเอนด์

หากต้องการเปิดใช้ตัวเร่งความเร็วใหม่เพื่อใช้กับ litert_device_script (และ ATS) คุณต้องลงทะเบียนไลบรารีที่จำเป็นในไฟล์ litert_device_common.bzl Bazel การลงทะเบียนจะอิงตามชื่อ"แบ็กเอนด์"ที่ไม่ซ้ำกัน ซึ่งแมปกับชุดไลบรารีที่สร้างได้หรือคอมไพล์ล่วงหน้า ที่จำเป็นสำหรับ LiteRT ในการทำงานกับตัวเร่งความเร็วนั้น

ขั้นตอนการจดทะเบียน

  1. กำหนดBackendSpecฟังก์ชัน: สร้างฟังก์ชันที่แสดงผลพจนานุกรมที่มีข้อกำหนดของตัวเร่งความเร็วใหม่

  2. ระบุไลบรารี (libs): นี่คือรายการของ Tuple ที่แสดงรายละเอียดเส้นทางเป้าหมาย Bazel สำหรับไลบรารีที่ใช้ร่วมกันและตัวแปรสภาพแวดล้อม (LD_LIBRARY_PATH) ที่จำเป็นสำหรับ Linker ของอุปกรณ์ในการค้นหา

    • ไลบรารีการเรียกใช้: ต้องใช้สำหรับการดำเนินการรันไทม์
    • ไลบรารีปลั๊กอินคอมไพเลอร์: ต้องใช้สำหรับโหมดการคอมไพล์ AOT
  3. ระบุชื่อไลบรารี (plugin, dispatch): ระบุชื่อไฟล์ของปลั๊กอินและไลบรารีการเรียกใช้

  4. ลงทะเบียน Spec: ผสานรวมฟังก์ชัน Spec ใหม่เข้ากับ_Specsฟังก์ชันหลัก เพื่อให้พร้อมใช้งานตามรหัสแบ็กเอนด์ที่ไม่ซ้ำกัน

ตัวอย่างการจดทะเบียน (_ExampleSpec)

โค้ดต่อไปนี้จาก litert_device_common.bzl แสดงวิธีลงทะเบียนตัวเร่งความเร็ว "example"

def _ExampleSpec():
    return {
        # The unique backend ID
        "example": BackendSpec(
            id = "example",
            libs = [
                # Dispatch Library and how to find it on device
                ("//third_party/odml/litert/litert/vendors/examples:libLiteRtDispatch_Example.so", "LD_LIBRARY_PATH"),
                # Compiler Plugin Library
                ("//third_party/odml/litert/litert/vendors/examples:libLiteRtCompilerPlugin_Example.so", "LD_LIBRARY_PATH"),
            ],
            plugin = "libLiteRtCompilerPlugin_Example.so",
            dispatch = "libLiteRtDispatch_Example.so",
        ),
    }

# ... (Other specs are defined here)

def _Specs(name):
    # Your new spec function must be included here
    return (_QualcommSpec() | _GoogleTensorSpec() | _MediatekSpec() | _CpuSpec() | _GpuSpec() | _ExampleSpec())[name]

ใช้ประโยชน์จากการลงทะเบียนกับ litert_device_exec

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

cc_binary(
    name = "example_bin",
    srcs = ["example_bin.cc"],
)

litert_device_exec(
    name = "example_bin_device",
    backend_id = "example",  # Uses the libraries registered under "example"
    data = [
        "//third_party/odml/litert/litert/test:testdata/constant_output_tensor.tflite",
    ],
    target = ":example_bin",
)

การเรียกใช้เป้าหมายนี้ (bazel run ... :example_bin_device) จะมีผลดังนี้

  1. สร้างexample_binไบนารี C++
  2. ส่งไบนารี libLiteRtDispatch_Example.so, libLiteRtCompilerPlugin_Example.so และไฟล์ .tflite ไปยังอุปกรณ์
  3. เรียกใช้ไบนารีโดยใช้ adb shell

หมายเหตุเกี่ยวกับเส้นทางของอุปกรณ์: ตำแหน่งที่แน่นอนของไฟล์ในอุปกรณ์ จะเหมือนกับโครงสร้าง runfile ของ Bazel โดยเฉพาะ /data/local/tmp/runfiles/runfiles_relative_path สคริปต์อุปกรณ์ จะจัดการการตั้งค่าเส้นทางที่เหมาะสมสำหรับตัวลิงก์แบบไดนามิกโดยอัตโนมัติ

โหมดการคอมไพล์ (AOT)

สำหรับตัวเร่งที่รองรับขั้นตอนการคอมไพล์ล่วงหน้า (AOT) สามารถเรียกใช้ ATS ใน"โหมดคอมไพล์"เฉพาะได้

  • วัตถุประสงค์: โหมดนี้ออกแบบมาให้ทำงานบนเวิร์กสเตชัน (เครื่องโฮสต์) ไม่ใช่อุปกรณ์เป้าหมาย โดยจะคอมไพล์โมเดลสำหรับฮาร์ดแวร์เป้าหมายที่ระบุโดยไม่ต้องดำเนินการ
  • เอาต์พุต: โมเดลที่คอมไพล์ทั้งหมดจะส่งออกไปยังไดเรกทอรีที่กำหนดใน เวิร์กสเตชัน
  • การเปิดใช้งาน: มาโครบิลด์ของ ATS จะปล่อยเป้าหมายที่เฉพาะเจาะจงสำหรับ AOT ที่สร้างไลบรารีสำหรับแพลตฟอร์มโฮสต์ คุณเปิดใช้โฟลว์นี้ได้ในไบนารีใดก็ได้ที่มีแฟล็ก --compile_mode แต่จะผูกกับอาร์กิวเมนต์ของการสร้าง AOT โดยอัตโนมัติ

การขยายโปรแกรมในอนาคต

เราวางแผนที่จะขยายชุดเครื่องมือนี้ให้รวมการทดสอบเฉพาะสำหรับการดำเนินการ (Ops) เดียว นอกเหนือจากโมเดลแบบเต็ม