Thanks for tuning in to Google I/O. View all sessions on demandWatch on demand

Praktik terbaik pengujian TensorFlow

Berikut adalah praktik yang direkomendasikan untuk menguji kode di repositori TensorFlow .

Sebelum Anda memulai

Sebelum Anda menyumbangkan kode sumber ke proyek TensorFlow, tinjau file CONTRIBUTING.md di repo GitHub proyek tersebut. (Misalnya, lihat file CONTRIBUTING.md untuk repo TensorFlow inti .) Semua kontributor kode harus menandatangani Perjanjian Lisensi Kontributor (CLA).

Prinsip-prinsip umum

Hanya bergantung pada apa yang Anda gunakan dalam aturan BUILD Anda

TensorFlow adalah library yang besar, dan bergantung pada paket lengkapnya saat menulis pengujian unit untuk submodulnya telah menjadi praktik umum. Namun, ini menonaktifkan analisis berbasis ketergantungan bazel . Ini berarti bahwa sistem integrasi berkelanjutan tidak dapat secara cerdas menghilangkan pengujian yang tidak terkait untuk proses pra-pengiriman / pasca-pengiriman. Jika Anda hanya bergantung pada submodul yang Anda uji dalam file BUILD , Anda akan menghemat waktu untuk semua developer TensorFlow, dan banyak daya komputasi yang berharga.

Namun, mengubah ketergantungan build Anda untuk menghilangkan target TF penuh membawa beberapa batasan untuk apa yang dapat Anda impor dalam kode Python Anda. Anda tidak akan dapat lagi menggunakan import tensorflow as tf pernyataan import tensorflow as tf dalam pengujian unit Anda. Tapi ini adalah pertukaran yang berharga karena menyelamatkan semua pengembang dari menjalankan ribuan tes yang tidak perlu.

Semua kode harus memiliki tes unit

Untuk kode apa pun yang Anda tulis, Anda juga harus menulis pengujian unitnya. Jika Anda menulis file baru foo.py , Anda harus menempatkan pengujian unitnya di foo_test.py dan mengirimkannya dalam perubahan yang sama. Bertujuan untuk cakupan tes tambahan> 90% untuk semua kode Anda.

Hindari menggunakan aturan pengujian bazel asli di TF

TF memiliki banyak kehalusan saat menjalankan tes. Kami telah bekerja untuk menyembunyikan semua kerumitan itu di makro bazel kami. Untuk menghindari keharusan berurusan dengan itu, gunakan yang berikut sebagai ganti aturan pengujian asli. Perhatikan bahwa semua ini didefinisikan di tensorflow/tensorflow.bzl Untuk pengujian CC, gunakan tf_cc_test , tf_gpu_cc_test , tf_gpu_only_cc_test . Untuk pengujian python, gunakan tf_py_test atau gpu_py_test . Jika Anda membutuhkan sesuatu yang sangat dekat dengan aturan py_test asli, gunakan yang ditentukan di tensorflow.bzl sebagai gantinya. Anda hanya perlu menambahkan baris berikut di bagian atas file BUILD: load(“tensorflow/tensorflow.bzl”, “py_test”)

Ketahuilah di mana pengujian dijalankan

Saat Anda menulis pengujian, infra pengujian kami dapat menangani pengujian Anda pada CPU, GPU, dan akselerator jika Anda menulisnya sesuai. Kami memiliki pengujian otomatis yang berjalan di Linux, macOS, windows, yang memiliki sistem dengan atau tanpa GPU. Anda hanya perlu memilih salah satu makro yang tercantum di atas, lalu menggunakan tag untuk membatasi tempat mereka dijalankan.

  • tag manual akan mengecualikan pengujian Anda agar tidak dijalankan di mana pun. Ini termasuk eksekusi uji manual yang menggunakan pola seperti bazel test tensorflow/…

  • no_oss akan mengecualikan pengujian Anda agar tidak berjalan di infrastruktur pengujian TF OSS resmi.

  • no_mac atau no_windows tag dapat digunakan untuk mengecualikan tes dari sistem operasi test suite yang relevan.

  • tag no_gpu dapat digunakan untuk mengecualikan pengujian Anda agar tidak berjalan di rangkaian pengujian GPU.

Verifikasi pengujian yang dijalankan dalam rangkaian pengujian yang diharapkan

TF memiliki beberapa rangkaian pengujian. Terkadang, penyiapannya mungkin membingungkan. Mungkin ada masalah berbeda yang menyebabkan pengujian Anda dihilangkan dari build berkelanjutan. Jadi, Anda harus memverifikasi pengujian Anda berjalan seperti yang diharapkan. Untuk melakukan ini:

  • Tunggu pra-pengajuan Anda pada Permintaan Tarik (PR) Anda untuk berjalan hingga selesai.
  • Gulir ke bawah PR Anda untuk melihat pemeriksaan status.
  • Klik link "Detail" di sisi kanan cek Kokoro manapun.
  • Periksa daftar "Target" untuk menemukan target yang baru Anda tambahkan.

Setiap kelas / unit harus memiliki file pengujian unitnya sendiri

Kelas pengujian terpisah membantu kami mengisolasi kegagalan dan sumber daya dengan lebih baik. Mereka mengarah ke file pengujian yang jauh lebih pendek dan lebih mudah dibaca. Oleh karena itu, semua file Python Anda harus memiliki setidaknya satu file pengujian yang sesuai (Untuk setiap foo.py , harus memiliki foo_test.py ). Untuk pengujian yang lebih rumit, seperti pengujian integrasi yang memerlukan penyiapan berbeda, Anda dapat menambahkan lebih banyak file pengujian.

Kecepatan dan waktu berjalan

Sharding harus digunakan sesedikit mungkin

Daripada melakukan sharding, harap pertimbangkan:

  • Membuat pengujian Anda lebih kecil
  • Jika hal di atas tidak memungkinkan, bagi tes

Sharding membantu mengurangi latensi keseluruhan suatu pengujian, tetapi hal yang sama dapat dicapai dengan memecah pengujian menjadi target yang lebih kecil. Pengujian pemisahan memberi kami tingkat kontrol yang lebih baik pada setiap pengujian, meminimalkan proses pra-pengiriman yang tidak perlu, dan mengurangi kehilangan cakupan dari buildcop yang menonaktifkan seluruh target karena kasus pengujian yang tidak berfungsi dengan baik. Selain itu, sharding menimbulkan biaya tersembunyi yang tidak begitu jelas, seperti menjalankan semua kode inisialisasi pengujian untuk semua shard. Masalah ini telah dilaporkan kepada kami oleh tim infra sebagai sumber yang menimbulkan beban tambahan.

Tes yang lebih kecil lebih baik

Semakin cepat pengujian Anda dijalankan, semakin besar kemungkinan orang akan menjalankan pengujian Anda. Satu detik ekstra untuk pengujian Anda dapat mengakumulasi hingga berjam-jam waktu ekstra yang dihabiskan untuk menjalankan pengujian Anda oleh pengembang dan infrastruktur kami. Cobalah untuk membuat pengujian Anda berjalan di bawah 30 detik (dalam mode non-opt!), Dan buat pengujian kecil. Hanya tandai pengujian Anda sebagai media sebagai upaya terakhir. Infra tidak menjalankan tes besar apa pun sebagai pra-pengiriman atau pasca-pengiriman! Oleh karena itu, tulislah tes besar hanya jika Anda akan mengatur di mana tes itu akan dijalankan. Beberapa tips agar pengujian berjalan lebih cepat:

  • Jalankan lebih sedikit iterasi pelatihan dalam pengujian Anda
  • Pertimbangkan untuk menggunakan injeksi ketergantungan untuk mengganti ketergantungan berat dari sistem yang diuji dengan pemalsuan sederhana.
  • Pertimbangkan untuk menggunakan data masukan yang lebih kecil dalam pengujian unit
  • Jika tidak ada yang berhasil, coba pisahkan file pengujian Anda.

Waktu pengujian harus menargetkan setengah dari batas waktu ukuran pengujian untuk menghindari serpihan

Dengan target pengujian bazel , pengujian kecil memiliki batas waktu 1 menit. Batas waktu pengujian sedang adalah 5 menit. Pengujian besar tidak dijalankan oleh infra pengujian TensorFlow. Namun, banyak tes yang tidak menentukan lamanya waktu yang dibutuhkan. Untuk berbagai alasan pengujian Anda mungkin membutuhkan lebih banyak waktu sesekali. Dan, jika Anda menandai pengujian yang berjalan rata-rata selama 50 detik sebagai kecil, pengujian Anda akan gagal jika dijadwalkan pada mesin dengan CPU lama. Oleh karena itu, targetkan waktu berjalan rata-rata 30 detik untuk pengujian kecil. Targetkan rata-rata waktu berjalan 2 menit 30 detik untuk pengujian sedang.

Kurangi jumlah sampel dan tingkatkan toleransi untuk pelatihan

Tes yang berjalan lambat menghalangi kontributor. Menjalankan pelatihan dalam ujian bisa sangat lambat. Lebih suka toleransi yang lebih tinggi agar dapat menggunakan lebih sedikit sampel dalam pengujian Anda untuk menjaga pengujian Anda cukup cepat (maks 2,5 menit).

Singkirkan non-determinisme dan serpihan

Tulis tes deterministik

Tes unit harus selalu bersifat deterministik. Semua pengujian yang dijalankan pada TAP dan gitar harus dijalankan dengan cara yang sama setiap saat, jika tidak ada perubahan kode yang memengaruhi mereka. Untuk memastikannya, di bawah ini adalah beberapa hal yang perlu diperhatikan.

Selalu benih sumber stokastisitas apa pun

Penghasil bilangan acak apa pun, atau sumber stokastisitas lainnya dapat menyebabkan serpihan. Oleh karena itu, masing-masing harus diunggulkan. Selain membuat pengujian tidak terlalu rapuh, ini membuat semua pengujian dapat direproduksi. Berbagai cara untuk mengatur beberapa seed yang mungkin perlu Anda atur dalam tes TF adalah:

# 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)

Hindari menggunakan mode sleep dalam pengujian multithread

Menggunakan fungsi sleep dalam tes bisa menjadi penyebab utama kulit mengelupas. Terutama saat menggunakan banyak utas, menggunakan tidur untuk menunggu utas lain tidak akan pernah menjadi determistik. Ini karena sistem tidak dapat menjamin urutan eksekusi utas atau proses yang berbeda. Oleh karena itu, lebih suka konstruksi sinkronisasi deterministik seperti mutex.

Periksa apakah tesnya tidak stabil

Serpihan menyebabkan buildcops dan pengembang kehilangan waktu berjam-jam. Mereka sulit dideteksi, dan sulit untuk di-debug. Meskipun ada sistem otomatis untuk mendeteksi kelemahan, sistem tersebut perlu mengakumulasikan ratusan uji coba sebelum dapat menolak uji daftar secara akurat. Bahkan ketika mereka mendeteksi, mereka menolak daftar tes Anda dan cakupan tes hilang. Oleh karena itu, penulis tes harus memeriksa apakah tes mereka tidak stabil saat menulis tes. Ini dapat dengan mudah dilakukan dengan menjalankan pengujian Anda dengan flag: --runs_per_test=1000

Gunakan TensorFlowTestCase

TensorFlowTestCase melakukan tindakan pencegahan yang diperlukan seperti melakukan seeding semua generator nomor acak yang digunakan untuk mengurangi flakiness sebanyak mungkin. Saat kami menemukan dan memperbaiki lebih banyak sumber kelemahan, ini semua akan ditambahkan ke TensorFlowTestCase. Oleh karena itu, Anda harus menggunakan TensorFlowTestCase saat menulis pengujian untuk tensorflow. TensorFlowTestCase didefinisikan di sini: tensorflow/python/framework/test_util.py

Tulis tes kedap udara

Tes hermetik tidak membutuhkan sumber daya dari luar. Mereka dikemas dengan semua yang mereka butuhkan, dan mereka hanya memulai layanan palsu yang mungkin mereka butuhkan. Layanan apa pun selain pengujian Anda adalah sumber non determinisme. Bahkan dengan 99% ketersediaan layanan lain, jaringan dapat gagal, respons rpc dapat ditunda, dan Anda mungkin akan mendapatkan pesan kesalahan yang tidak dapat dijelaskan. Layanan luar mungkin, tetapi tidak terbatas pada, GCS, S3 atau situs web apa pun.