แนวทางปฏิบัติที่ดีที่สุดในการทดสอบ TensorFlow

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

นี่คือแนวทางปฏิบัติที่แนะนำสำหรับการทดสอบโค้ดในที่ เก็บ TensorFlow

ก่อนที่คุณจะเริ่มต้น

ก่อนที่คุณจะให้ซอร์สโค้ดในโปรเจ็กต์ TensorFlow โปรดตรวจสอบไฟล์ CONTRIBUTING.md ในที่เก็บ GitHub ของโปรเจ็กต์ (ตัวอย่างเช่นดู ไฟล์ CONTRIBUTING.md สำหรับที่เก็บ TensorFlow หลัก ) ผู้ร่วมให้รหัสทั้งหมดจะต้องลงนามใน ข้อตกลงสิทธิ์การใช้งานผู้สนับสนุน (CLA)

หลักการทั่วไป

ขึ้นอยู่กับสิ่งที่คุณใช้ในกฎ BUILD ของคุณเท่านั้น

TensorFlow เป็นไลบรารีขนาดใหญ่และขึ้นอยู่กับแพ็กเกจทั้งหมดเมื่อเขียนการทดสอบหน่วยสำหรับโมดูลย่อยนั้นถือเป็นแนวทางปฏิบัติทั่วไป อย่างไรก็ตามสิ่งนี้จะปิดใช้งานการวิเคราะห์ตามการพึ่งพา bazel ซึ่งหมายความว่าระบบการรวมแบบต่อเนื่องไม่สามารถกำจัดการทดสอบที่ไม่เกี่ยวข้องสำหรับการรัน presubmit / postubmit ได้อย่างชาญฉลาด หากคุณพึ่งพาเฉพาะโมดูลย่อยที่คุณกำลังทดสอบในไฟล์ BUILD ของคุณคุณจะประหยัดเวลาสำหรับนักพัฒนา TensorFlow ทั้งหมดและพลังการคำนวณที่มีค่ามากมาย

อย่างไรก็ตามการแก้ไขการพึ่งพาบิวด์ของคุณเพื่อละเว้นเป้าหมาย TF แบบเต็มทำให้เกิดข้อ จำกัด บางประการสำหรับสิ่งที่คุณสามารถนำเข้าในโค้ด Python ของคุณได้ คุณจะไม่สามารถใช้ import tensorflow as tf คำสั่ง import tensorflow as tf ในการทดสอบหน่วยของคุณได้อีกต่อไป แต่นี่เป็นการแลกเปลี่ยนที่คุ้มค่าเนื่องจากช่วยให้นักพัฒนาทุกคนไม่ต้องทำการทดสอบที่ไม่จำเป็นหลายพันครั้ง

รหัสทั้งหมดควรมีการทดสอบหน่วย

สำหรับโค้ดใด ๆ ที่คุณเขียนคุณควรเขียนการทดสอบหน่วยด้วย หากคุณเขียนไฟล์ foo.py ใหม่คุณควรทำการทดสอบหน่วยใน foo_test.py และส่งภายในการเปลี่ยนแปลงเดียวกัน ตั้งเป้าให้ครอบคลุมการทดสอบที่เพิ่มขึ้น> 90% สำหรับรหัสทั้งหมดของคุณ

หลีกเลี่ยงการใช้กฎการทดสอบ bazel ดั้งเดิมใน TF

TF มีรายละเอียดปลีกย่อยมากมายเมื่อทำการทดสอบ เราได้พยายามซ่อนความซับซ้อนทั้งหมดนั้นไว้ในมาโครเบเซลของเรา เพื่อหลีกเลี่ยงไม่ให้ต้องจัดการกับสิ่งเหล่านั้นให้ใช้สิ่งต่อไปนี้แทนกฎการทดสอบเนทีฟ โปรดทราบว่าสิ่งเหล่านี้กำหนดไว้ใน tensorflow/tensorflow.bzl สำหรับการทดสอบ CC ให้ใช้ tf_cc_test , tf_gpu_cc_test , tf_gpu_only_cc_test สำหรับการทดสอบ python ให้ใช้ tf_py_test หรือ gpu_py_test หากคุณต้องการบางสิ่งที่ใกล้เคียงกับกฎ py_test ดั้งเดิมโปรดใช้กฎที่กำหนดไว้ใน tensorflow.bzl แทน คุณต้องเพิ่มบรรทัดต่อไปนี้ที่ด้านบนของไฟล์ BUILD: load(“tensorflow/tensorflow.bzl”, “py_test”)

โปรดทราบว่าการทดสอบดำเนินการที่ใด

เมื่อคุณเขียนการทดสอบอินฟาเรดการทดสอบของเราสามารถจัดการการทดสอบของคุณบน CPU, GPU และตัวเร่งความเร็วได้หากคุณเขียนตามนั้น เรามีการทดสอบอัตโนมัติที่ทำงานบน Linux, macos, windows ซึ่งมีระบบที่มีหรือไม่มี GPU คุณเพียงแค่ต้องเลือกหนึ่งในมาโครที่ระบุไว้ด้านบนจากนั้นใช้แท็กเพื่อ จำกัด ตำแหน่งที่จะเรียกใช้งาน

  • แท็ก manual จะยกเว้นการทดสอบของคุณจากการทำงานที่ใดก็ได้ ซึ่งรวมถึงการดำเนินการทดสอบด้วยตนเองที่ใช้รูปแบบเช่น bazel test tensorflow/…

  • no_oss จะยกเว้นการทดสอบของคุณจากการทำงานในโครงสร้างพื้นฐานการทดสอบ TF OSS อย่างเป็นทางการ

  • no_mac หรือ no_windows แท็กสามารถนำมาใช้เพื่อยกเว้นการทดสอบของคุณจากห้องทดสอบระบบปฏิบัติการที่เกี่ยวข้อง

  • สามารถใช้แท็ก no_gpu เพื่อยกเว้นการทดสอบของคุณไม่ให้ทำงานในชุดทดสอบ GPU

ตรวจสอบการทดสอบที่ทำงานในชุดทดสอบที่คาดไว้

TF มีห้องทดสอบค่อนข้างน้อย บางครั้งอาจเกิดความสับสนในการตั้งค่า อาจมีปัญหาที่แตกต่างกันที่ทำให้การทดสอบของคุณถูกละเว้นจากการสร้างแบบต่อเนื่อง ดังนั้นคุณควรตรวจสอบว่าการทดสอบของคุณดำเนินการตามที่คาดไว้ เพื่อทำสิ่งนี้:

  • รอให้การส่งล่วงหน้าของคุณใน Pull Request (PR) ของคุณทำงานจนเสร็จสิ้น
  • เลื่อนไปที่ด้านล่างของ PR เพื่อดูการตรวจสอบสถานะ
  • คลิกลิงก์ "รายละเอียด" ทางด้านขวาของเช็คโคโคโระ
  • ตรวจสอบรายการ "เป้าหมาย" เพื่อค้นหาเป้าหมายที่เพิ่มเข้ามาใหม่

แต่ละชั้น / หน่วยควรมีไฟล์ทดสอบหน่วยของตัวเอง

ชั้นเรียนการทดสอบแยกกันช่วยให้เราแยกความล้มเหลวและทรัพยากรได้ดีขึ้น ซึ่งนำไปสู่ไฟล์ทดสอบที่สั้นและอ่านง่ายกว่ามาก ดังนั้นไฟล์ Python ทั้งหมดของคุณควรมีไฟล์ทดสอบที่เกี่ยวข้องอย่างน้อยหนึ่งไฟล์ (สำหรับ foo.py แต่ละไฟล์ควรมี foo_test.py ) สำหรับการทดสอบที่ละเอียดมากขึ้นเช่นการทดสอบการรวมที่ต้องใช้การตั้งค่าที่แตกต่างกันคุณควรเพิ่มไฟล์ทดสอบเพิ่มเติม

ความเร็วและเวลาทำงาน

ควรใช้ Sharding ให้น้อยที่สุด

แทนการแยกชิ้นส่วนโปรดพิจารณา:

  • ทำให้การทดสอบของคุณมีขนาดเล็กลง
  • หากไม่สามารถทำได้ข้างต้นให้แยกการทดสอบออก

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

การทดสอบขนาดเล็กจะดีกว่า

ยิ่งการทดสอบของคุณดำเนินไปเร็วเท่าไหร่ผู้คนก็จะมีโอกาสดำเนินการทดสอบของคุณมากขึ้นเท่านั้น หนึ่งวินาทีที่เพิ่มขึ้นสำหรับการทดสอบของคุณสามารถสะสมเป็นชั่วโมงของเวลาเพิ่มเติมที่ใช้ในการทดสอบโดยนักพัฒนาและโครงสร้างพื้นฐาน พยายามทำให้การทดสอบของคุณทำงานภายใน 30 วินาที (ในโหมดไม่เลือก!) และทำให้มีขนาดเล็ก ทำเครื่องหมายการทดสอบของคุณเป็นสื่อเป็นทางเลือกสุดท้ายเท่านั้น อินฟาเรดไม่ทำการทดสอบขนาดใหญ่ใด ๆ ในฐานะการส่งล่วงหน้าหรือโพสต์ส่ง! ดังนั้นให้เขียนเฉพาะการทดสอบขนาดใหญ่หากคุณกำลังจะจัดเรียงว่าจะวิ่งไปที่ใด เคล็ดลับบางประการเพื่อให้การทดสอบทำงานเร็วขึ้น:

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

เวลาทดสอบควรตั้งเป้าไว้ที่ครึ่งหนึ่งของการหมดเวลาของขนาดทดสอบเพื่อหลีกเลี่ยงการเกิดสะเก็ด

ด้วยเป้าหมายการทดสอบ bazel การทดสอบขนาดเล็กจะมีการหมดเวลา 1 นาที หมดเวลาทดสอบปานกลางคือ 5 นาที การทดสอบขนาดใหญ่ไม่ได้ดำเนินการโดย TensorFlow ทดสอบอินฟาเรด อย่างไรก็ตามการทดสอบจำนวนมากไม่ได้กำหนดระยะเวลาที่ใช้ ด้วยเหตุผลหลายประการการทดสอบของคุณอาจใช้เวลานานขึ้นทุกขณะ และหากคุณทำเครื่องหมายการทดสอบที่ทำงานเป็นเวลา 50 วินาทีโดยเฉลี่ยให้มีขนาดเล็กการทดสอบของคุณจะแตกเป็นชิ้นเล็กชิ้นน้อยหากกำหนดเวลาไว้ในเครื่องที่มี CPU เก่า ดังนั้นตั้งเป้าหมายเวลาทำงานโดยเฉลี่ย 30 วินาทีสำหรับการทดสอบขนาดเล็ก ตั้งเป้าเป็นเวลา 2 นาที 30 วินาทีของเวลาวิ่งโดยเฉลี่ยสำหรับการทดสอบระดับกลาง

ลดจำนวนตัวอย่างและเพิ่มความคลาดเคลื่อนในการฝึก

การทดสอบที่ทำงานช้าเป็นอุปสรรคต่อผู้ให้ข้อมูล การฝึกวิ่งในการทดสอบอาจช้ามาก ต้องการความคลาดเคลื่อนที่สูงขึ้นเพื่อให้สามารถใช้ตัวอย่างน้อยลงในการทดสอบของคุณเพื่อให้การทดสอบของคุณเร็วเพียงพอ (สูงสุด 2.5 นาที)

ขจัดสิ่งที่ไม่ใช่ปัจจัยและเกล็ด

เขียนการทดสอบเชิงกำหนด

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

ควรเพาะแหล่งที่มาของความสุ่มเสี่ยงเสมอ

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

# Python RNG
import random
random.seed(42)

# Numpy RNG
import numpy as np
np.random.seed(42)

# TF RNG
from tensorflow.python.framework import random_seed
random_seed.set_seed(42)

หลีกเลี่ยงการใช้ sleep ในการทดสอบแบบมัลติเธรด

การใช้ฟังก์ชั่นการ sleep การทดสอบอาจเป็นสาเหตุสำคัญของอาการวูบวาบ โดยเฉพาะอย่างยิ่งเมื่อใช้หลายเธรดการใช้สลีปเพื่อรอเธรดอื่นจะไม่ถูกกำหนด เนื่องจากระบบไม่สามารถรับประกันลำดับการดำเนินการของเธรดหรือกระบวนการที่แตกต่างกัน ดังนั้นจึงชอบโครงสร้างการซิงโครไนซ์ที่กำหนดเช่น mutexes

ตรวจสอบว่าการทดสอบเป็นขุยหรือไม่

Flakes ทำให้ buildcops และนักพัฒนาต้องเสียเวลาหลายชั่วโมง ตรวจพบได้ยากและแก้ไขจุดบกพร่องได้ยาก แม้ว่าจะมีระบบอัตโนมัติในการตรวจจับการหลุดลอก แต่ก็จำเป็นต้องสะสมการทดสอบหลายร้อยครั้งก่อนจึงจะสามารถทำการทดสอบ denylist ได้อย่างแม่นยำ แม้ว่าพวกเขาจะตรวจพบพวกเขาปฏิเสธการทดสอบของคุณและการครอบคลุมการทดสอบจะหายไป ดังนั้นผู้ทดสอบควรตรวจสอบว่าการทดสอบของพวกเขามีขุยเมื่อเขียนแบบทดสอบหรือไม่ สามารถทำได้อย่างง่ายดายโดยรันการทดสอบของคุณด้วยแฟ --runs_per_test=1000 : --runs_per_test=1000

ใช้ TensorFlowTestCase

TensorFlowTestCase ใช้มาตรการป้องกันที่จำเป็นเช่นการเพาะเครื่องกำเนิดตัวเลขสุ่มทั้งหมดที่ใช้เพื่อลดความเป็นสะเก็ดให้มากที่สุด ในขณะที่เราค้นพบและแก้ไขแหล่งที่มาของความไม่สมบูรณ์มากขึ้นสิ่งเหล่านี้จะถูกเพิ่มลงใน TensorFlowTestCase ดังนั้นคุณควรใช้ TensorFlowTestCase เมื่อเขียนการทดสอบสำหรับเทนเซอร์โฟลว์ TensorFlowTestCase ถูกกำหนดไว้ที่นี่: tensorflow/python/framework/test_util.py

เขียนการทดสอบแบบปิดผนึก

การทดสอบทางสุญญากาศไม่จำเป็นต้องมีแหล่งข้อมูลภายนอก พวกเขาเต็มไปด้วยทุกสิ่งที่ต้องการและพวกเขาเพิ่งเริ่มบริการปลอม ๆ ที่พวกเขาอาจต้องการ บริการอื่น ๆ นอกเหนือจากการทดสอบของคุณเป็นแหล่งที่มาของการไม่กำหนดปัจจัย แม้ว่าจะมีบริการอื่น ๆ ถึง 99% แต่เครือข่ายก็สามารถหลุดออกได้การตอบสนอง rpc อาจล่าช้าและคุณอาจพบข้อความแสดงข้อผิดพลาดที่อธิบายไม่ได้ บริการภายนอกอาจเป็นได้ แต่ไม่ จำกัด เพียง GCS, S3 หรือเว็บไซต์ใด ๆ