การดีบักปัญหาเชิงตัวเลขในโปรแกรม TensorFlow โดยใช้ TensorBoard Debugger V2 การดีบักปัญหาเชิงตัวเลขในโปรแกรม TensorFlow โดยใช้ TensorBoard Debugger V2

เหตุการณ์ภัยพิบัติที่เกี่ยวข้องกับ NaN ในบางครั้งอาจเกิดขึ้นระหว่างโปรแกรม TensorFlow ซึ่งทำให้กระบวนการฝึกอบรมแบบจำลองหมดอำนาจ สาเหตุของเหตุการณ์ดังกล่าวมักไม่ชัดเจน โดยเฉพาะอย่างยิ่งสำหรับแบบจำลองที่มีขนาดและความซับซ้อนที่ไม่ซับซ้อน เพื่อให้ง่ายต่อการแก้ไขจุดบกพร่องของโมเดลประเภทนี้ TensorBoard 2.3+ (ร่วมกับ TensorFlow 2.3+) จึงมีแดชบอร์ดพิเศษที่เรียกว่า Debugger V2 ที่นี่ เราสาธิตวิธีใช้เครื่องมือนี้โดยทำงานผ่านจุดบกพร่องจริงที่เกี่ยวข้องกับ NaN ในโครงข่ายประสาทเทียมที่เขียนด้วย TensorFlow

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

การสังเกตจุดบกพร่อง

ซอร์สโค้ดของโปรแกรม TF2 ที่เราจะทำการดีบั๊กมี อยู่ใน GitHub โปรแกรมตัวอย่างยังถูกรวมไว้ในแพ็คเกจ tensorflow pip (เวอร์ชัน 2.3+) และสามารถเรียกใช้ได้โดย:

python -m tensorflow.python.debug.examples.v2.debug_mnist_v2

โปรแกรม TF2 นี้สร้างการรับรู้หลายชั้น (MLP) และฝึกให้จดจำภาพ MNIST ตัวอย่างนี้จงใจใช้ API ระดับต่ำของ TF2 เพื่อกำหนดโครงสร้างเลเยอร์ที่กำหนดเอง ฟังก์ชันการสูญเสีย และลูปการฝึก เนื่องจากโอกาสที่ข้อบกพร่องของ NaN จะสูงขึ้นเมื่อเราใช้ API ที่ยืดหยุ่นกว่าแต่มีโอกาสเกิดข้อผิดพลาดมากกว่าเมื่อเราใช้ API ที่ง่ายกว่านี้ -to-use แต่ API ระดับสูงที่มีความยืดหยุ่นน้อยกว่าเล็กน้อย เช่น tf.keras

โปรแกรมพิมพ์ความถูกต้องของการทดสอบหลังจากแต่ละขั้นตอนการฝึกอบรม เราจะเห็นในคอนโซลว่าความแม่นยำในการทดสอบติดอยู่ที่ระดับโอกาสใกล้ (~0.1) หลังจากขั้นตอนแรก นี่ไม่ใช่อย่างที่คาดหวังไว้สำหรับการฝึกโมเดล: เราคาดว่าความแม่นยำจะค่อยๆ เข้าใกล้ 1.0 (100%) เมื่อขั้นตอนเพิ่มขึ้น

Accuracy at step 0: 0.216
Accuracy at step 1: 0.098
Accuracy at step 2: 0.098
Accuracy at step 3: 0.098
...

การเดาอย่างมีการศึกษาคือปัญหานี้เกิดจากความไม่เสถียรของตัวเลข เช่น NaN หรืออนันต์ อย่างไรก็ตาม เราจะยืนยันได้อย่างไรว่าเป็นกรณีนี้จริงๆ และเราจะค้นหาการดำเนินการ TensorFlow (op) ที่รับผิดชอบในการสร้างความไม่เสถียรของตัวเลขได้อย่างไร เพื่อตอบคำถามเหล่านี้ ให้ใช้เครื่องมือโปรแกรมบั๊กกี้ด้วย Debugger V2

การวัดโค้ด TensorFlow ด้วย Debugger V2

tf.debugging.experimental.enable_dump_debug_info() เป็นจุดเริ่มต้น API ของ Debugger V2 เป็นเครื่องมือในโปรแกรม TF2 ด้วยรหัสบรรทัดเดียว ตัวอย่างเช่น การเพิ่มบรรทัดต่อไปนี้ใกล้กับจุดเริ่มต้นของโปรแกรมจะทำให้ข้อมูลการดีบักถูกเขียนไปยังไดเร็กทอรีบันทึก (logdir) ที่ /tmp/tfdbg2_logdir ข้อมูลการดีบักครอบคลุมแง่มุมต่างๆ ของรันไทม์ TensorFlow ใน TF2 จะรวมประวัติทั้งหมดของการดำเนินการอย่างกระตือรือร้น การสร้างกราฟที่ดำเนินการโดย @tf.function การดำเนินการของกราฟ ค่าเทนเซอร์ที่สร้างโดยเหตุการณ์การดำเนินการ ตลอดจนตำแหน่งโค้ด (การติดตามสแต็ก Python) ของเหตุการณ์เหล่านั้น . ความสมบูรณ์ของข้อมูลการดีบักทำให้ผู้ใช้สามารถจำกัดจุดบกพร่องที่ไม่ชัดเจนได้

tf.debugging.experimental.enable_dump_debug_info(
    "/tmp/tfdbg2_logdir",
    tensor_debug_mode="FULL_HEALTH",
    circular_buffer_size=-1)

อาร์กิวเมนต์ tensor_debug_mode ควบคุมข้อมูลที่ Debugger V2 แยกจากเมตริกซ์กระตือรือร้นหรือในกราฟ “FULL_HEALTH” เป็นโหมดที่รวบรวมข้อมูลต่อไปนี้เกี่ยวกับเทนเซอร์ประเภททศนิยมแต่ละตัว (เช่น float32 ที่มองเห็นได้ทั่วไปและ bfloat16 dtype ทั่วไปน้อยกว่า):

  • DType
  • อันดับ
  • จำนวนองค์ประกอบทั้งหมด
  • การแจกแจงองค์ประกอบประเภทลอยตัวเป็นหมวดหมู่ต่อไปนี้: ค่าจำกัดเชิงลบ ( - ), ศูนย์ ( 0 ), ค่าจำกัดบวก ( + ) ค่าอนันต์เชิงลบ ( -∞ ) ค่าอินฟินิตี้บวก ( +∞ ) และ NaN

โหมด “FULL_HEALTH” เหมาะสำหรับการดีบักจุดบกพร่องที่เกี่ยวข้องกับ NaN และอินฟินิตี้ ดูด้านล่างสำหรับ tensor_debug_mode อื่น ๆ ที่รองรับ

อาร์กิวเมนต์ circular_buffer_size ควบคุมจำนวนเหตุการณ์เทนเซอร์ที่บันทึกลงใน logdir ค่าเริ่มต้นคือ 1000 ซึ่งทำให้เฉพาะเทนเซอร์ 1000 ตัวสุดท้ายก่อนสิ้นสุดโปรแกรม TF2 ที่ใช้เครื่องมือวัดเพื่อบันทึกลงในดิสก์ ลักษณะการทำงานเริ่มต้นนี้ช่วยลดโอเวอร์เฮดของดีบักเกอร์โดยเสียสละความสมบูรณ์ของข้อมูลการดีบัก หากต้องการความสมบูรณ์มากกว่า ในกรณีนี้ เราสามารถปิดใช้งานบัฟเฟอร์แบบวงกลมได้โดยการตั้งค่าอาร์กิวเมนต์เป็นค่าลบ (เช่น -1 ที่นี่)

ตัวอย่าง debug_mnist_v2 เรียกใช้ enable_dump_debug_info() โดยส่งแฟล็กบรรทัดคำสั่งไป ในการรันโปรแกรม TF2 ที่มีปัญหาอีกครั้งโดยเปิดใช้งานเครื่องมือการดีบักนี้ ให้ทำดังนี้

python -m tensorflow.python.debug.examples.v2.debug_mnist_v2 \
    --dump_dir /tmp/tfdbg2_logdir --dump_tensor_debug_mode FULL_HEALTH

การเริ่ม Debugger V2 GUI ใน TensorBoard

การรันโปรแกรมด้วยเครื่องมือดีบักเกอร์จะสร้าง logdir ที่ /tmp/tfdbg2_logdir เราสามารถเริ่ม TensorBoard และชี้ไปที่ logdir ด้วย:

tensorboard --logdir /tmp/tfdbg2_logdir

ในเว็บเบราว์เซอร์ ให้ไปที่หน้าของ TensorBoard ที่ http://localhost:6006 ปลั๊กอิน "ดีบักเกอร์ V2" จะไม่ทำงานโดยค่าเริ่มต้น ดังนั้นให้เลือกจากเมนู "ปลั๊กอินที่ไม่ใช้งาน" ที่ด้านบนขวา เมื่อเลือกแล้วควรมีลักษณะดังนี้:

ภาพหน้าจอแบบเต็มของ Debugger V2

ใช้ Debugger V2 GUI เพื่อค้นหาสาเหตุของ NaNs

Debugger V2 GUI ใน TensorBoard แบ่งออกเป็นหกส่วน:

  • การ แจ้งเตือน : ส่วนซ้ายบนนี้ประกอบด้วยรายการของเหตุการณ์ "การแจ้งเตือน" ที่ตรวจพบโดยโปรแกรมแก้ไขข้อบกพร่องในข้อมูลการดีบักจากโปรแกรม TensorFlow ที่ติดตั้งอุปกรณ์ การแจ้งเตือนแต่ละครั้งบ่งบอกถึงความผิดปกติบางอย่างที่ควรให้ความสนใจ ในกรณีของเรา ส่วนนี้เน้นเหตุการณ์ 499 NaN/∞ ที่มีสีชมพู-แดงเด่นชัด สิ่งนี้ยืนยันความสงสัยของเราว่าแบบจำลองล้มเหลวในการเรียนรู้เนื่องจากการมีอยู่ของ NaN และ/หรืออนันต์ในค่าเทนเซอร์ภายใน เราจะเจาะลึกการแจ้งเตือนเหล่านี้ในไม่ช้า
  • Python Execution Timeline : นี่คือครึ่งบนของส่วนบนตรงกลาง นำเสนอประวัติเต็มรูปแบบของการดำเนินการอย่างกระตือรือร้นของ ops และกราฟ แต่ละช่องของไทม์ไลน์จะถูกทำเครื่องหมายด้วยตัวอักษรเริ่มต้นของชื่อ op หรือกราฟ (เช่น "T" สำหรับ "TensorSliceDataset" op, "m" สำหรับ "model" tf.function ) เราสามารถนำทางไทม์ไลน์นี้ได้โดยใช้ปุ่มนำทางและแถบเลื่อนด้านบนไทม์ไลน์
  • การ ดำเนินการกราฟ : ตั้งอยู่ที่มุมบนขวาของ GUI ส่วนนี้จะเป็นศูนย์กลางของงานการดีบักของเรา มันมีประวัติของเมตริกซ์แบบลอยตัวทั้งหมดที่คำนวณภายในกราฟ (เช่น รวบรวมโดย @tf-function s)
  • โครงสร้างกราฟ (ครึ่งล่างของส่วนตรงกลางบน) ซอร์สโค้ด (ส่วนซ้ายล่าง) และ Stack Trace (ส่วนขวาล่าง) จะว่างเปล่าในตอนแรก เนื้อหาของพวกเขาจะถูกเติมเมื่อเราโต้ตอบกับ GUI ทั้งสามส่วนนี้จะมีบทบาทสำคัญในงานการดีบักของเรา

เมื่อเรามุ่งไปที่องค์กรของ UI แล้ว ให้ทำตามขั้นตอนต่อไปนี้เพื่อทำความเข้าใจว่าทำไม NaN จึงปรากฏขึ้น ขั้นแรก ให้คลิกการแจ้งเตือน NaN/∞ ในส่วนการแจ้งเตือน สิ่งนี้จะเลื่อนรายการเทนเซอร์กราฟ 600 กราฟโดยอัตโนมัติในส่วนการดำเนินการกราฟและเน้นที่ #88 ซึ่งเป็นเมตริกซ์ชื่อ Log:0 ที่สร้างโดย Log (ลอการิทึมธรรมชาติ) สีชมพู-แดงที่เด่นชัดจะเน้นองค์ประกอบ -∞ ท่ามกลาง 1000 องค์ประกอบของเทนเซอร์ 2D float32 นี่เป็นเมตริกซ์แรกในประวัติรันไทม์ของโปรแกรม TF2 ที่มี NaN หรืออินฟินิตี้: เมตริกซ์ที่คำนวณก่อนจะไม่มี NaN หรือ ∞ (ในความเป็นจริง ส่วนใหญ่) เทนเซอร์ที่คำนวณหลังจากนั้นมี NaNs เราสามารถยืนยันได้โดยเลื่อนขึ้นและลงที่รายการ Graph Execution การสังเกตนี้ให้คำใบ้ที่ชัดเจนว่า Log op เป็นที่มาของความไม่แน่นอนของตัวเลขในโปรแกรม TF2 นี้

ดีบักเกอร์ V2: การแจ้งเตือนน่าน / อินฟินิตี้และรายการการดำเนินการกราฟ

เหตุใด Log op นี้จึงคาย -∞ การตอบคำถามนั้นต้องตรวจสอบอินพุตของ op การคลิกที่ชื่อเทนเซอร์ ( Log:0 ) จะแสดงภาพบริเวณใกล้เคียงของ Log op ที่เรียบง่ายแต่ให้ข้อมูลในกราฟ TensorFlow ในส่วนโครงสร้างกราฟ สังเกตทิศทางจากบนลงล่างของการไหลของข้อมูล ตัว op จะแสดงเป็นตัวหนาตรงกลาง เหนือมันทันที เราจะเห็น Placeholder op ให้อินพุตเดียวเท่านั้นใน Log op เทนเซอร์ที่สร้างโดย probs Placeholder ในรายการ Graph Execution อยู่ที่ไหน โดยใช้สีพื้นหลังสีเหลืองเป็นภาพช่วย เราจะเห็นได้ว่า probs:0 เทนเซอร์อยู่เหนือเมตริกซ์ Log:0 สามแถว นั่นคือในแถว 85

ดีบักเกอร์ V2: มุมมองโครงสร้างกราฟและการติดตามไปยังเทนเซอร์อินพุต

การดูรายละเอียดเชิงตัวเลขของเมตริกซ์ probs:0 ในแถวที่ 85 อย่างละเอียดถี่ถ้วนเผยให้เห็นว่าเหตุใด Log:0 ของผู้ใช้จึงสร้าง -∞: ในบรรดาองค์ประกอบ 1,000 องค์ประกอบของ probs:0 องค์ประกอบหนึ่งมีค่าเป็น 0 -∞ คือ ผลลัพธ์ของการคำนวณลอการิทึมธรรมชาติของ 0! หากเราสามารถทำให้แน่ใจว่า Log op สัมผัสกับอินพุตที่เป็นบวกเท่านั้น เราจะสามารถป้องกันไม่ให้ NaN/∞ เกิดขึ้นได้ สิ่งนี้สามารถทำได้โดยการใช้การตัด (เช่น โดยใช้ tf.clip_by_value() ) บนตัวแทนที่ probs เทนเซอร์

เรากำลังเข้าใกล้การแก้ไขข้อผิดพลาด แต่ยังไม่เสร็จสิ้น เพื่อนำการแก้ไขไปใช้ เราจำเป็นต้องทราบที่มาของซอร์สโค้ด Python ที่ Log op และอินพุตตัวยึดตำแหน่ง Debugger V2 ให้การสนับสนุนชั้นหนึ่งสำหรับการติดตาม ops ของกราฟและเหตุการณ์การดำเนินการไปยังแหล่งที่มา เมื่อเราคลิกเมตริกซ์ Log:0 ใน Graph Executions ส่วน Stack Trace จะถูกเติมด้วยสแต็กเทรซดั้งเดิมของการสร้าง Log op การติดตามสแต็กค่อนข้างใหญ่เนื่องจากมีเฟรมจำนวนมากจากโค้ดภายในของ TensorFlow (เช่น gen_math_ops.py และ dumping_callback.py) ซึ่งเราสามารถละเว้นงานการดีบักส่วนใหญ่ได้อย่างปลอดภัย เฟรมเวิร์กที่น่าสนใจคือบรรทัดที่ 216 ของ debug_mnist_v2.py (เช่น ไฟล์ Python ที่เรากำลังพยายามแก้ไข) การคลิก "บรรทัดที่ 216" จะแสดงมุมมองของบรรทัดโค้ดที่เกี่ยวข้องในส่วนซอร์สโค้ด

ดีบักเกอร์ V2: ซอร์สโค้ดและการติดตามสแต็ก

ในที่สุดสิ่งนี้ก็นำเราไปสู่ซอร์สโค้ดที่สร้าง Log op ที่มีปัญหาจาก probs ที่มีปัญหา นี่คือฟังก์ชันการสูญเสียเอนโทรปีแบบแบ่งหมวดหมู่ที่เรากำหนดเองซึ่งตกแต่งด้วย @tf.function และด้วยเหตุนี้จึงแปลงเป็นกราฟ TensorFlow Placeholder op probs สอดคล้องกับอาร์กิวเมนต์อินพุตแรกในฟังก์ชันการสูญเสีย Log op ถูกสร้างขึ้นด้วยการเรียก API tf.math.log()

การแก้ไขค่าสำหรับจุดบกพร่องนี้จะมีลักษณะดังนี้:

  diff = -(labels *
           tf.math.log(tf.clip_by_value(probs), 1e-6, 1.))

จะแก้ไขความไม่แน่นอนของตัวเลขในโปรแกรม TF2 นี้ และทำให้ MLP ฝึกได้สำเร็จ อีกวิธีหนึ่งในการแก้ไขความไม่เสถียรของตัวเลขคือการใช้ tf.keras.losses.CategoricalCrossentropy

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

ความเข้ากันได้ของฮาร์ดแวร์ของดีบักเกอร์ V2

Debugger V2 รองรับฮาร์ดแวร์การฝึกอบรมหลักรวมถึง CPU และ GPU รองรับการฝึกอบรม Multi-GPU ด้วย tf.distributed.MirroredStrategy การรองรับ TPU ยังอยู่ในช่วงเริ่มต้นและต้องมีการโทร

tf.config.set_soft_device_placement(True)

ก่อนที่จะเรียก enable_dump_debug_info() อาจมีข้อจำกัดอื่นๆ เกี่ยวกับ TPU เช่นกัน หากคุณประสบปัญหาในการใช้ Debugger V2 โปรดรายงานจุดบกพร่องใน หน้าปัญหา GitHub ของเรา

ความเข้ากันได้ของ API ของดีบักเกอร์ V2

Debugger V2 ถูกใช้งานในระดับที่ค่อนข้างต่ำของซอฟต์แวร์ stack ของ TensorFlow และด้วยเหตุนี้จึงเข้ากันได้กับ tf.keras , tf.data และ API อื่นๆ ที่สร้างขึ้นจากระดับที่ต่ำกว่าของ TensorFlow Debugger V2 ยังเข้ากันได้กับ TF1 แม้ว่า Eager Execution Timeline จะว่างเปล่าสำหรับบันทึกการดีบักที่สร้างโดยโปรแกรม TF1

เคล็ดลับการใช้ API

คำถามที่พบบ่อยเกี่ยวกับการดีบัก API นี้คือตำแหน่งใดในโค้ด TensorFlow ควรแทรกการเรียก enable_dump_debug_info() โดยทั่วไปแล้ว ควรเรียก API ให้เร็วที่สุดในโปรแกรม TF2 ของคุณ โดยเฉพาะหลังจากการนำเข้า Python และก่อนเริ่มสร้างกราฟและดำเนินการ วิธีนี้จะช่วยรับประกันความครอบคลุมของ ops และกราฟทั้งหมดที่ขับเคลื่อนโมเดลของคุณและการฝึก

tensor_debug_modes ที่รองรับในปัจจุบัน ได้แก่ NO_TENSOR , CURT_HEALTH , CONCISE_HEALTH , FULL_HEALTH และ SHAPE โดยจะแตกต่างกันไปตามปริมาณข้อมูลที่ดึงมาจากเมตริกซ์แต่ละตัวและค่าใช้จ่ายด้านประสิทธิภาพไปยังโปรแกรมที่แก้ไขข้อบกพร่อง โปรดดู ส่วน args ของเอกสารของ enable_dump_debug_info()

ค่าโสหุ้ยด้านประสิทธิภาพ

API การดีบักจะแนะนำโอเวอร์เฮดด้านประสิทธิภาพให้กับโปรแกรม TensorFlow ที่ติดตั้งเครื่องมือวัด ค่าใช้จ่ายจะแตกต่างกันไปตาม tensor_debug_mode ประเภทของฮาร์ดแวร์ และลักษณะของโปรแกรม TensorFlow ที่ใช้เครื่องมือ ตามจุดอ้างอิง บน GPU โหมด NO_TENSOR เพิ่มโอเวอร์เฮด 15% ระหว่างการฝึก โมเดล Transformer ภายใต้ขนาดแบตช์ 64 เปอร์เซ็นต์โอเวอร์เฮดสำหรับ tensor_debug_modes อื่นๆ จะสูงกว่า: ประมาณ 50% สำหรับ CURT_HEALTH , CONCISE_HEALTH , FULL_HEALTH และ SHAPE โหมด สำหรับซีพียู โอเวอร์เฮดจะต่ำกว่าเล็กน้อย สำหรับ TPU ค่าใช้จ่ายในปัจจุบันสูงขึ้น

ความสัมพันธ์กับ API การดีบัก TensorFlow อื่นๆ

โปรดทราบว่า TensorFlow มีเครื่องมือและ API อื่นๆ สำหรับการดีบัก คุณสามารถเรียกดู API ดังกล่าวได้ภายใต้ เนมสเปซ tf.debugging.* ที่หน้าเอกสาร API ในบรรดา API เหล่านี้ tf.print() ที่ใช้บ่อยที่สุดคือ เมื่อใดควรใช้ Debugger V2 และเมื่อใดควร tf.print() แทน tf.print() จะสะดวกในกรณีที่

  1. เรารู้ดีว่าควรพิมพ์เทนเซอร์ตัวไหน
  2. เราทราบตำแหน่งที่แน่นอนในซอร์สโค้ดที่จะแทรกคำสั่ง tf.print() เหล่านั้น
  3. จำนวนเทนเซอร์ดังกล่าวไม่มากเกินไป

สำหรับกรณีอื่นๆ (เช่น การตรวจสอบค่าเทนเซอร์หลายๆ ค่า การตรวจสอบค่าเทนเซอร์ที่สร้างโดยโค้ดภายในของ TensorFlow และการค้นหาที่มาของความไม่เสถียรของตัวเลขดังที่เราได้แสดงไว้ข้างต้น) Debugger V2 ให้วิธีการดีบักที่เร็วขึ้น นอกจากนี้ Debugger V2 ยังให้แนวทางที่เป็นหนึ่งเดียวในการตรวจสอบการกระตือรือร้นและกราฟเทนเซอร์ นอกจากนี้ยังให้ข้อมูลเกี่ยวกับโครงสร้างกราฟและตำแหน่งของโค้ด ซึ่งเกินความสามารถของ tf.print()

API อื่นที่สามารถใช้ในการดีบักปัญหาที่เกี่ยวข้องกับ ∞ และ NaN ได้คือ tf.debugging.enable_check_numerics() ต่างจาก enable_dump_debug_info() enable_check_numerics() จะไม่บันทึกข้อมูลการดีบักบนดิสก์ แต่จะตรวจสอบ ∞ และ NaN ระหว่างรันไทม์ TensorFlow และเกิดข้อผิดพลาดกับตำแหน่งโค้ดต้นทางทันทีที่ op สร้างค่าตัวเลขที่ไม่ดีดังกล่าว มันมีค่าใช้จ่ายด้านประสิทธิภาพที่ต่ำกว่าเมื่อเปรียบเทียบกับ enable_dump_debug_info() แต่ไม่สามารถติดตามประวัติการดำเนินการของโปรแกรมได้อย่างสมบูรณ์ และไม่มีส่วนต่อประสานกับผู้ใช้แบบกราฟิก เช่น Debugger V2

,

เหตุการณ์ภัยพิบัติที่เกี่ยวข้องกับ NaN ในบางครั้งอาจเกิดขึ้นระหว่างโปรแกรม TensorFlow ซึ่งทำให้กระบวนการฝึกอบรมแบบจำลองหมดอำนาจ สาเหตุของเหตุการณ์ดังกล่าวมักไม่ชัดเจน โดยเฉพาะอย่างยิ่งสำหรับแบบจำลองที่มีขนาดและความซับซ้อนที่ไม่ซับซ้อน เพื่อให้ง่ายต่อการแก้ไขจุดบกพร่องของโมเดลประเภทนี้ TensorBoard 2.3+ (ร่วมกับ TensorFlow 2.3+) จึงมีแดชบอร์ดพิเศษที่เรียกว่า Debugger V2 ที่นี่ เราสาธิตวิธีใช้เครื่องมือนี้โดยทำงานผ่านจุดบกพร่องจริงที่เกี่ยวข้องกับ NaN ในโครงข่ายประสาทเทียมที่เขียนด้วย TensorFlow

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

การสังเกตจุดบกพร่อง

ซอร์สโค้ดของโปรแกรม TF2 ที่เราจะทำการดีบั๊กมี อยู่ใน GitHub โปรแกรมตัวอย่างยังถูกรวมไว้ในแพ็คเกจ tensorflow pip (เวอร์ชัน 2.3+) และสามารถเรียกใช้ได้โดย:

python -m tensorflow.python.debug.examples.v2.debug_mnist_v2

โปรแกรม TF2 นี้สร้างการรับรู้หลายชั้น (MLP) และฝึกให้จดจำภาพ MNIST ตัวอย่างนี้จงใจใช้ API ระดับต่ำของ TF2 เพื่อกำหนดโครงสร้างเลเยอร์ที่กำหนดเอง ฟังก์ชันการสูญเสีย และลูปการฝึก เนื่องจากโอกาสที่ข้อบกพร่องของ NaN จะสูงขึ้นเมื่อเราใช้ API ที่ยืดหยุ่นกว่าแต่มีโอกาสเกิดข้อผิดพลาดมากกว่าเมื่อเราใช้ API ที่ง่ายกว่านี้ -to-use แต่ API ระดับสูงที่มีความยืดหยุ่นน้อยกว่าเล็กน้อย เช่น tf.keras

โปรแกรมพิมพ์ความถูกต้องของการทดสอบหลังจากแต่ละขั้นตอนการฝึกอบรม เราจะเห็นในคอนโซลว่าความแม่นยำในการทดสอบติดอยู่ที่ระดับโอกาสใกล้ (~0.1) หลังจากขั้นตอนแรก นี่ไม่ใช่อย่างที่คาดหวังไว้สำหรับการฝึกโมเดล: เราคาดว่าความแม่นยำจะค่อยๆ เข้าใกล้ 1.0 (100%) เมื่อขั้นตอนเพิ่มขึ้น

Accuracy at step 0: 0.216
Accuracy at step 1: 0.098
Accuracy at step 2: 0.098
Accuracy at step 3: 0.098
...

การเดาอย่างมีการศึกษาคือปัญหานี้เกิดจากความไม่เสถียรของตัวเลข เช่น NaN หรืออนันต์ อย่างไรก็ตาม เราจะยืนยันได้อย่างไรว่าเป็นกรณีนี้จริงๆ และเราจะค้นหาการดำเนินการ TensorFlow (op) ที่รับผิดชอบในการสร้างความไม่เสถียรของตัวเลขได้อย่างไร เพื่อตอบคำถามเหล่านี้ ให้ใช้เครื่องมือโปรแกรมบั๊กกี้ด้วย Debugger V2

การวัดโค้ด TensorFlow ด้วย Debugger V2

tf.debugging.experimental.enable_dump_debug_info() เป็นจุดเริ่มต้น API ของ Debugger V2 เป็นเครื่องมือในโปรแกรม TF2 ด้วยรหัสบรรทัดเดียว ตัวอย่างเช่น การเพิ่มบรรทัดต่อไปนี้ใกล้กับจุดเริ่มต้นของโปรแกรมจะทำให้ข้อมูลการดีบักถูกเขียนไปยังไดเร็กทอรีบันทึก (logdir) ที่ /tmp/tfdbg2_logdir ข้อมูลการดีบักครอบคลุมแง่มุมต่างๆ ของรันไทม์ TensorFlow ใน TF2 จะรวมประวัติทั้งหมดของการดำเนินการอย่างกระตือรือร้น การสร้างกราฟที่ดำเนินการโดย @tf.function การดำเนินการของกราฟ ค่าเทนเซอร์ที่สร้างโดยเหตุการณ์การดำเนินการ ตลอดจนตำแหน่งโค้ด (การติดตามสแต็ก Python) ของเหตุการณ์เหล่านั้น . ความสมบูรณ์ของข้อมูลการดีบักทำให้ผู้ใช้สามารถจำกัดจุดบกพร่องที่ไม่ชัดเจนได้

tf.debugging.experimental.enable_dump_debug_info(
    "/tmp/tfdbg2_logdir",
    tensor_debug_mode="FULL_HEALTH",
    circular_buffer_size=-1)

อาร์กิวเมนต์ tensor_debug_mode ควบคุมข้อมูลที่ Debugger V2 แยกจากเมตริกซ์กระตือรือร้นหรือในกราฟ “FULL_HEALTH” เป็นโหมดที่รวบรวมข้อมูลต่อไปนี้เกี่ยวกับเทนเซอร์ประเภททศนิยมแต่ละตัว (เช่น float32 ที่มองเห็นได้ทั่วไปและ bfloat16 dtype ทั่วไปน้อยกว่า):

  • DType
  • อันดับ
  • จำนวนองค์ประกอบทั้งหมด
  • การแจกแจงองค์ประกอบประเภทลอยตัวเป็นหมวดหมู่ต่อไปนี้: ค่าจำกัดเชิงลบ ( - ), ศูนย์ ( 0 ), ค่าจำกัดบวก ( + ) ค่าอนันต์เชิงลบ ( -∞ ) ค่าอินฟินิตี้บวก ( +∞ ) และ NaN

โหมด “FULL_HEALTH” เหมาะสำหรับการดีบักจุดบกพร่องที่เกี่ยวข้องกับ NaN และอินฟินิตี้ ดูด้านล่างสำหรับ tensor_debug_mode อื่น ๆ ที่รองรับ

อาร์กิวเมนต์ circular_buffer_size ควบคุมจำนวนเหตุการณ์เทนเซอร์ที่บันทึกลงใน logdir ค่าเริ่มต้นคือ 1000 ซึ่งทำให้เฉพาะเทนเซอร์ 1000 ตัวสุดท้ายก่อนสิ้นสุดโปรแกรม TF2 ที่ใช้เครื่องมือวัดเพื่อบันทึกลงในดิสก์ ลักษณะการทำงานเริ่มต้นนี้ช่วยลดโอเวอร์เฮดของดีบักเกอร์โดยเสียสละความสมบูรณ์ของข้อมูลการดีบัก หากต้องการความสมบูรณ์มากกว่า ในกรณีนี้ เราสามารถปิดใช้งานบัฟเฟอร์แบบวงกลมได้โดยการตั้งค่าอาร์กิวเมนต์เป็นค่าลบ (เช่น -1 ที่นี่)

ตัวอย่าง debug_mnist_v2 เรียกใช้ enable_dump_debug_info() โดยส่งแฟล็กบรรทัดคำสั่งไป ในการรันโปรแกรม TF2 ที่มีปัญหาอีกครั้งโดยเปิดใช้งานเครื่องมือการดีบักนี้ ให้ทำดังนี้

python -m tensorflow.python.debug.examples.v2.debug_mnist_v2 \
    --dump_dir /tmp/tfdbg2_logdir --dump_tensor_debug_mode FULL_HEALTH

การเริ่ม Debugger V2 GUI ใน TensorBoard

การรันโปรแกรมด้วยเครื่องมือดีบักเกอร์จะสร้าง logdir ที่ /tmp/tfdbg2_logdir เราสามารถเริ่ม TensorBoard และชี้ไปที่ logdir ด้วย:

tensorboard --logdir /tmp/tfdbg2_logdir

ในเว็บเบราว์เซอร์ ให้ไปที่หน้าของ TensorBoard ที่ http://localhost:6006 ปลั๊กอิน "ดีบักเกอร์ V2" จะไม่ทำงานโดยค่าเริ่มต้น ดังนั้นให้เลือกจากเมนู "ปลั๊กอินที่ไม่ใช้งาน" ที่ด้านบนขวา เมื่อเลือกแล้วควรมีลักษณะดังนี้:

ภาพหน้าจอแบบเต็มของ Debugger V2

ใช้ Debugger V2 GUI เพื่อค้นหาสาเหตุของ NaNs

Debugger V2 GUI ใน TensorBoard แบ่งออกเป็นหกส่วน:

  • การ แจ้งเตือน : ส่วนซ้ายบนนี้ประกอบด้วยรายการของเหตุการณ์ "การแจ้งเตือน" ที่ตรวจพบโดยโปรแกรมแก้ไขข้อบกพร่องในข้อมูลการดีบักจากโปรแกรม TensorFlow ที่ติดตั้งอุปกรณ์ การแจ้งเตือนแต่ละครั้งบ่งบอกถึงความผิดปกติบางอย่างที่ควรให้ความสนใจ ในกรณีของเรา ส่วนนี้เน้นเหตุการณ์ 499 NaN/∞ ที่มีสีชมพู-แดงเด่นชัด สิ่งนี้ยืนยันความสงสัยของเราว่าแบบจำลองล้มเหลวในการเรียนรู้เนื่องจากการมีอยู่ของ NaN และ/หรืออนันต์ในค่าเทนเซอร์ภายใน เราจะเจาะลึกการแจ้งเตือนเหล่านี้ในไม่ช้า
  • Python Execution Timeline : นี่คือครึ่งบนของส่วนบนตรงกลาง นำเสนอประวัติเต็มรูปแบบของการดำเนินการอย่างกระตือรือร้นของ ops และกราฟ แต่ละช่องของไทม์ไลน์จะถูกทำเครื่องหมายด้วยตัวอักษรเริ่มต้นของชื่อ op หรือกราฟ (เช่น "T" สำหรับ "TensorSliceDataset" op, "m" สำหรับ "model" tf.function ) เราสามารถนำทางไทม์ไลน์นี้ได้โดยใช้ปุ่มนำทางและแถบเลื่อนด้านบนไทม์ไลน์
  • การ ดำเนินการกราฟ : ตั้งอยู่ที่มุมบนขวาของ GUI ส่วนนี้จะเป็นศูนย์กลางของงานการดีบักของเรา มันมีประวัติของเมตริกซ์แบบลอยตัวทั้งหมดที่คำนวณภายในกราฟ (เช่น รวบรวมโดย @tf-function s)
  • โครงสร้างกราฟ (ครึ่งล่างของส่วนตรงกลางบน) ซอร์สโค้ด (ส่วนซ้ายล่าง) และ Stack Trace (ส่วนขวาล่าง) จะว่างเปล่าในตอนแรก เนื้อหาของพวกเขาจะถูกเติมเมื่อเราโต้ตอบกับ GUI ทั้งสามส่วนนี้จะมีบทบาทสำคัญในงานการดีบักของเรา

เมื่อเรามุ่งไปที่องค์กรของ UI แล้ว ให้ทำตามขั้นตอนต่อไปนี้เพื่อทำความเข้าใจว่าทำไม NaN จึงปรากฏขึ้น ขั้นแรก ให้คลิกการแจ้งเตือน NaN/∞ ในส่วนการแจ้งเตือน สิ่งนี้จะเลื่อนรายการเทนเซอร์กราฟ 600 กราฟโดยอัตโนมัติในส่วนการดำเนินการกราฟและเน้นที่ #88 ซึ่งเป็นเมตริกซ์ชื่อ Log:0 ที่สร้างโดย Log (ลอการิทึมธรรมชาติ) สีชมพู-แดงที่เด่นชัดจะเน้นองค์ประกอบ -∞ ท่ามกลาง 1000 องค์ประกอบของเทนเซอร์ 2D float32 นี่เป็นเมตริกซ์แรกในประวัติรันไทม์ของโปรแกรม TF2 ที่มี NaN หรืออินฟินิตี้: เมตริกซ์ที่คำนวณก่อนจะไม่มี NaN หรือ ∞ (ในความเป็นจริง ส่วนใหญ่) เทนเซอร์ที่คำนวณหลังจากนั้นมี NaNs เราสามารถยืนยันได้โดยเลื่อนขึ้นและลงที่รายการ Graph Execution การสังเกตนี้ให้คำใบ้ที่ชัดเจนว่า Log op เป็นที่มาของความไม่แน่นอนของตัวเลขในโปรแกรม TF2 นี้

ดีบักเกอร์ V2: การแจ้งเตือนน่าน / อินฟินิตี้และรายการการดำเนินการกราฟ

เหตุใด Log op นี้จึงคาย -∞ การตอบคำถามนั้นต้องตรวจสอบอินพุตของ op การคลิกที่ชื่อเทนเซอร์ ( Log:0 ) จะแสดงภาพบริเวณใกล้เคียงของ Log op ที่เรียบง่ายแต่ให้ข้อมูลในกราฟ TensorFlow ในส่วนโครงสร้างกราฟ สังเกตทิศทางจากบนลงล่างของการไหลของข้อมูล ตัว op จะแสดงเป็นตัวหนาตรงกลาง เหนือมันทันที เราจะเห็น Placeholder op ให้อินพุตเดียวเท่านั้นใน Log op เทนเซอร์ที่สร้างโดย probs Placeholder ในรายการ Graph Execution อยู่ที่ไหน โดยใช้สีพื้นหลังสีเหลืองเป็นภาพช่วย เราจะเห็นได้ว่า probs:0 เทนเซอร์อยู่เหนือเมตริกซ์ Log:0 สามแถว นั่นคือในแถว 85

ดีบักเกอร์ V2: มุมมองโครงสร้างกราฟและการติดตามไปยังเทนเซอร์อินพุต

การดูรายละเอียดเชิงตัวเลขของเมตริกซ์ probs:0 ในแถวที่ 85 อย่างละเอียดถี่ถ้วนเผยให้เห็นว่าเหตุใด Log:0 ของผู้ใช้จึงสร้าง -∞: ในบรรดาองค์ประกอบ 1,000 องค์ประกอบของ probs:0 องค์ประกอบหนึ่งมีค่าเป็น 0 -∞ คือ ผลลัพธ์ของการคำนวณลอการิทึมธรรมชาติของ 0! หากเราสามารถทำให้แน่ใจว่า Log op สัมผัสกับอินพุตที่เป็นบวกเท่านั้น เราจะสามารถป้องกันไม่ให้ NaN/∞ เกิดขึ้นได้ สิ่งนี้สามารถทำได้โดยการใช้การตัด (เช่น โดยใช้ tf.clip_by_value() ) บนตัวแทนที่ probs เทนเซอร์

เรากำลังเข้าใกล้การแก้ไขข้อผิดพลาด แต่ยังไม่เสร็จสิ้น เพื่อนำการแก้ไขไปใช้ เราจำเป็นต้องทราบที่มาของซอร์สโค้ด Python ที่ Log op และอินพุตตัวยึดตำแหน่ง Debugger V2 ให้การสนับสนุนชั้นหนึ่งสำหรับการติดตาม ops ของกราฟและเหตุการณ์การดำเนินการไปยังแหล่งที่มา เมื่อเราคลิกเมตริกซ์ Log:0 ใน Graph Executions ส่วน Stack Trace จะถูกเติมด้วยสแต็กเทรซดั้งเดิมของการสร้าง Log op การติดตามสแต็กค่อนข้างใหญ่เนื่องจากมีเฟรมจำนวนมากจากโค้ดภายในของ TensorFlow (เช่น gen_math_ops.py และ dumping_callback.py) ซึ่งเราสามารถละเว้นงานการดีบักส่วนใหญ่ได้อย่างปลอดภัย เฟรมเวิร์กที่น่าสนใจคือบรรทัดที่ 216 ของ debug_mnist_v2.py (เช่น ไฟล์ Python ที่เรากำลังพยายามแก้ไข) การคลิก "บรรทัดที่ 216" จะแสดงมุมมองของบรรทัดโค้ดที่เกี่ยวข้องในส่วนซอร์สโค้ด

ดีบักเกอร์ V2: ซอร์สโค้ดและการติดตามสแต็ก

ในที่สุดสิ่งนี้ก็นำเราไปสู่ซอร์สโค้ดที่สร้าง Log op ที่มีปัญหาจาก probs ที่มีปัญหา นี่คือฟังก์ชันการสูญเสียเอนโทรปีแบบแบ่งหมวดหมู่ที่เรากำหนดเองซึ่งตกแต่งด้วย @tf.function และด้วยเหตุนี้จึงแปลงเป็นกราฟ TensorFlow Placeholder op probs สอดคล้องกับอาร์กิวเมนต์อินพุตแรกในฟังก์ชันการสูญเสีย Log op ถูกสร้างขึ้นด้วยการเรียก API tf.math.log()

การแก้ไขค่าสำหรับจุดบกพร่องนี้จะมีลักษณะดังนี้:

  diff = -(labels *
           tf.math.log(tf.clip_by_value(probs), 1e-6, 1.))

จะแก้ไขความไม่แน่นอนของตัวเลขในโปรแกรม TF2 นี้ และทำให้ MLP ฝึกได้สำเร็จ อีกวิธีหนึ่งในการแก้ไขความไม่เสถียรของตัวเลขคือการใช้ tf.keras.losses.CategoricalCrossentropy

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

ความเข้ากันได้ของฮาร์ดแวร์ของดีบักเกอร์ V2

Debugger V2 รองรับฮาร์ดแวร์การฝึกอบรมหลักรวมถึง CPU และ GPU รองรับการฝึกอบรม Multi-GPU ด้วย tf.distributed.MirroredStrategy การรองรับ TPU ยังอยู่ในช่วงเริ่มต้นและต้องมีการโทร

tf.config.set_soft_device_placement(True)

ก่อนที่จะเรียก enable_dump_debug_info() อาจมีข้อจำกัดอื่นๆ เกี่ยวกับ TPU เช่นกัน หากคุณประสบปัญหาในการใช้ Debugger V2 โปรดรายงานจุดบกพร่องใน หน้าปัญหา GitHub ของเรา

ความเข้ากันได้ของ API ของดีบักเกอร์ V2

Debugger V2 ถูกใช้งานในระดับที่ค่อนข้างต่ำของซอฟต์แวร์ stack ของ TensorFlow และด้วยเหตุนี้จึงเข้ากันได้กับ tf.keras , tf.data และ API อื่นๆ ที่สร้างขึ้นจากระดับที่ต่ำกว่าของ TensorFlow Debugger V2 ยังเข้ากันได้กับ TF1 แม้ว่า Eager Execution Timeline จะว่างเปล่าสำหรับบันทึกการดีบักที่สร้างโดยโปรแกรม TF1

เคล็ดลับการใช้ API

คำถามที่พบบ่อยเกี่ยวกับการดีบัก API นี้คือตำแหน่งใดในโค้ด TensorFlow ควรแทรกการเรียก enable_dump_debug_info() โดยทั่วไปแล้ว ควรเรียก API ให้เร็วที่สุดในโปรแกรม TF2 ของคุณ โดยเฉพาะหลังจากการนำเข้า Python และก่อนเริ่มสร้างกราฟและดำเนินการ วิธีนี้จะช่วยรับประกันความครอบคลุมของ ops และกราฟทั้งหมดที่ขับเคลื่อนโมเดลของคุณและการฝึก

tensor_debug_modes ที่รองรับในปัจจุบัน ได้แก่ NO_TENSOR , CURT_HEALTH , CONCISE_HEALTH , FULL_HEALTH และ SHAPE โดยจะแตกต่างกันไปตามปริมาณข้อมูลที่ดึงมาจากเมตริกซ์แต่ละตัวและค่าใช้จ่ายด้านประสิทธิภาพไปยังโปรแกรมที่แก้ไขข้อบกพร่อง โปรดดู ส่วน args ของเอกสารของ enable_dump_debug_info()

ค่าโสหุ้ยด้านประสิทธิภาพ

API การดีบักจะแนะนำโอเวอร์เฮดด้านประสิทธิภาพให้กับโปรแกรม TensorFlow ที่ติดตั้งเครื่องมือวัด ค่าใช้จ่ายจะแตกต่างกันไปตาม tensor_debug_mode ประเภทของฮาร์ดแวร์ และลักษณะของโปรแกรม TensorFlow ที่ใช้เครื่องมือ ตามจุดอ้างอิง บน GPU โหมด NO_TENSOR เพิ่มโอเวอร์เฮด 15% ระหว่างการฝึก โมเดล Transformer ภายใต้ขนาดแบตช์ 64 เปอร์เซ็นต์โอเวอร์เฮดสำหรับ tensor_debug_modes อื่นๆ จะสูงกว่า: ประมาณ 50% สำหรับ CURT_HEALTH , CONCISE_HEALTH , FULL_HEALTH และ SHAPE โหมด สำหรับซีพียู โอเวอร์เฮดจะต่ำกว่าเล็กน้อย สำหรับ TPU ค่าใช้จ่ายในปัจจุบันสูงขึ้น

ความสัมพันธ์กับ API การดีบัก TensorFlow อื่นๆ

โปรดทราบว่า TensorFlow มีเครื่องมือและ API อื่นๆ สำหรับการดีบัก คุณสามารถเรียกดู API ดังกล่าวได้ภายใต้ เนมสเปซ tf.debugging.* ที่หน้าเอกสาร API ในบรรดา API เหล่านี้ tf.print() ที่ใช้บ่อยที่สุดคือ เมื่อใดควรใช้ Debugger V2 และเมื่อใดควร tf.print() แทน tf.print() จะสะดวกในกรณีที่

  1. เรารู้ดีว่าควรพิมพ์เทนเซอร์ตัวไหน
  2. เราทราบตำแหน่งที่แน่นอนในซอร์สโค้ดที่จะแทรกคำสั่ง tf.print() เหล่านั้น
  3. จำนวนเทนเซอร์ดังกล่าวไม่มากเกินไป

สำหรับกรณีอื่นๆ (เช่น การตรวจสอบค่าเทนเซอร์หลายๆ ค่า การตรวจสอบค่าเทนเซอร์ที่สร้างโดยโค้ดภายในของ TensorFlow และการค้นหาที่มาของความไม่เสถียรของตัวเลขดังที่เราได้แสดงไว้ข้างต้น) Debugger V2 ให้วิธีการดีบักที่เร็วขึ้น นอกจากนี้ Debugger V2 ยังให้แนวทางที่เป็นหนึ่งเดียวในการตรวจสอบการกระตือรือร้นและกราฟเทนเซอร์ นอกจากนี้ยังให้ข้อมูลเกี่ยวกับโครงสร้างกราฟและตำแหน่งของโค้ด ซึ่งเกินความสามารถของ tf.print()

API อื่นที่สามารถใช้ในการดีบักปัญหาที่เกี่ยวข้องกับ ∞ และ NaN ได้คือ tf.debugging.enable_check_numerics() ต่างจาก enable_dump_debug_info() enable_check_numerics() จะไม่บันทึกข้อมูลการดีบักบนดิสก์ แต่จะตรวจสอบ ∞ และ NaN ระหว่างรันไทม์ TensorFlow และเกิดข้อผิดพลาดกับตำแหน่งโค้ดต้นทางทันทีที่ op สร้างค่าตัวเลขที่ไม่ดีดังกล่าว มันมีค่าใช้จ่ายด้านประสิทธิภาพที่ต่ำกว่าเมื่อเปรียบเทียบกับ enable_dump_debug_info() แต่ไม่สามารถติดตามประวัติการดำเนินการของโปรแกรมได้อย่างสมบูรณ์ และไม่มีส่วนต่อประสานกับผู้ใช้แบบกราฟิก เช่น Debugger V2