TensorFlow.js berfungsi di browser dan Node.js, dan di kedua platform terdapat banyak konfigurasi berbeda yang tersedia. Setiap platform memiliki serangkaian pertimbangan unik yang akan mempengaruhi cara aplikasi dikembangkan.
Di browser, TensorFlow.js mendukung perangkat seluler dan juga perangkat desktop. Setiap perangkat memiliki serangkaian batasan tertentu, seperti API WebGL yang tersedia, yang secara otomatis ditentukan dan dikonfigurasi untuk Anda.
Di Node.js, TensorFlow.js mendukung pengikatan langsung ke TensorFlow API atau dijalankan dengan implementasi CPU vanilla yang lebih lambat.
Lingkungan
Saat program TensorFlow.js dijalankan, konfigurasi spesifiknya disebut lingkungan. Lingkungan ini terdiri dari satu backend global serta serangkaian tanda yang mengontrol fitur TensorFlow.js yang terperinci.
ujung belakang
TensorFlow.js mendukung beberapa backend berbeda yang mengimplementasikan penyimpanan tensor dan operasi matematika. Pada waktu tertentu, hanya satu backend yang aktif. Seringkali, TensorFlow.js akan secara otomatis memilih backend terbaik untuk Anda berdasarkan lingkungan saat ini. Namun, terkadang penting untuk mengetahui backend mana yang digunakan dan cara mengalihkannya.
Untuk menemukan backend mana yang Anda gunakan:
console.log(tf.getBackend());
Jika Anda ingin mengubah backend secara manual:
tf.setBackend('cpu');
console.log(tf.getBackend());
ujung belakang WebGL
Backend WebGL, 'webgl', saat ini merupakan backend paling kuat untuk browser. Backend ini 100x lebih cepat dibandingkan backend CPU vanilla. Tensor disimpan sebagai tekstur WebGL dan operasi matematika diimplementasikan dalam shader WebGL. Berikut beberapa hal berguna yang perlu diketahui saat menggunakan backend ini: \
Hindari memblokir thread UI
Saat operasi dipanggil, seperti tf.matMul(a, b), tf.Tensor yang dihasilkan dikembalikan secara sinkron, namun penghitungan perkalian matriks mungkin belum siap. Artinya, tf.Tensor yang dikembalikan hanyalah pegangan komputasi. Saat Anda memanggil x.data()
atau x.array()
, nilai akan ditentukan saat komputasi telah benar-benar selesai. Hal ini menjadikannya penting untuk menggunakan metode asynchronous x.data()
dan x.array()
dibandingkan metode sinkronnya x.dataSync()
dan x.arraySync()
untuk menghindari pemblokiran thread UI saat komputasi selesai.
Manajemen memori
Satu peringatan saat menggunakan backend WebGL adalah perlunya manajemen memori eksplisit. WebGLTextures, yang merupakan tempat penyimpanan data Tensor, tidak secara otomatis dikumpulkan oleh browser sebagai sampah.
Untuk menghancurkan memori tf.Tensor
, Anda dapat menggunakan metode dispose()
:
const a = tf.tensor([[1, 2], [3, 4]]);
a.dispose();
Sangat umum untuk menyatukan beberapa operasi dalam satu aplikasi. Menahan referensi ke semua variabel perantara untuk membuangnya dapat mengurangi keterbacaan kode. Untuk mengatasi masalah ini, TensorFlow.js menyediakan metode tf.tidy()
yang membersihkan semua tf.Tensor
yang tidak dikembalikan oleh suatu fungsi setelah menjalankannya, serupa dengan cara variabel lokal dibersihkan ketika suatu fungsi dijalankan:
const a = tf.tensor([[1, 2], [3, 4]]);
const y = tf.tidy(() => {
const result = a.square().log().neg();
return result;
});
Presisi
Pada perangkat seluler, WebGL mungkin hanya mendukung tekstur floating point 16 bit. Namun, sebagian besar model pembelajaran mesin dilatih dengan bobot dan aktivasi floating point 32 bit. Hal ini dapat menyebabkan masalah presisi saat mem-porting model ke perangkat seluler karena angka mengambang 16 bit hanya dapat mewakili angka dalam rentang [0.000000059605, 65504]
. Ini berarti Anda harus berhati-hati agar bobot dan aktivasi pada model Anda tidak melebihi kisaran ini. Untuk memeriksa apakah perangkat mendukung tekstur 32 bit, periksa nilai tf.ENV.getBool('WEBGL_RENDER_FLOAT32_CAPABLE')
, jika ini salah maka perangkat hanya mendukung tekstur floating point 16 bit. Anda dapat menggunakan tf.ENV.getBool('WEBGL_RENDER_FLOAT32_ENABLED')
untuk memeriksa apakah TensorFlow.js saat ini menggunakan tekstur 32 bit.
Kompilasi shader & unggahan tekstur
TensorFlow.js menjalankan operasi pada GPU dengan menjalankan program shader WebGL. Shader ini dirakit dan dikompilasi dengan lambat saat pengguna meminta untuk menjalankan suatu operasi. Kompilasi shader terjadi pada CPU di thread utama dan bisa lambat. TensorFlow.js akan meng-cache shader yang dikompilasi secara otomatis, membuat panggilan kedua ke operasi yang sama dengan tensor input dan output dengan bentuk yang sama menjadi lebih cepat. Biasanya, aplikasi TensorFlow.js akan menggunakan operasi yang sama beberapa kali selama masa pakai aplikasi, sehingga proses melewati model pembelajaran mesin untuk kedua kalinya akan jauh lebih cepat.
TensorFlow.js juga menyimpan data tf.Tensor sebagai WebGLTextures. Saat tf.Tensor
dibuat, kami tidak langsung mengunggah data ke GPU, melainkan menyimpan data tersebut di CPU hingga tf.Tensor
digunakan dalam suatu operasi. Jika tf.Tensor
digunakan untuk kedua kalinya, data sudah ada di GPU sehingga tidak ada biaya upload. Dalam model pembelajaran mesin pada umumnya, ini berarti bobot diunggah selama prediksi pertama melalui model dan prediksi kedua melalui model akan jauh lebih cepat.
Jika Anda peduli dengan performa prediksi pertama melalui model atau kode TensorFlow.js, sebaiknya lakukan pemanasan model dengan meneruskan input Tensor dengan bentuk yang sama sebelum data sebenarnya digunakan.
Misalnya:
const model = await tf.loadLayersModel(modelUrl);
// Warmup the model before using real data.
const warmupResult = model.predict(tf.zeros(inputShape));
warmupResult.dataSync();
warmupResult.dispose();
// The second predict() will be much faster
const result = model.predict(userData);
Bagian belakang TensorFlow Node.js
Di backend TensorFlow Node.js, 'node', TensorFlow C API digunakan untuk mempercepat operasi. Ini akan menggunakan akselerasi perangkat keras mesin yang tersedia, seperti CUDA, jika tersedia.
Di backend ini, sama seperti backend WebGL, operasi mengembalikan tf.Tensor
secara sinkron. Namun, tidak seperti backend WebGL, operasi selesai sebelum Anda mendapatkan tensornya kembali. Artinya panggilan ke tf.matMul(a, b)
akan memblokir thread UI.
Oleh karena itu, jika Anda ingin menggunakannya dalam aplikasi produksi, Anda harus menjalankan TensorFlow.js di thread pekerja agar tidak memblokir thread utama.
Untuk informasi lebih lanjut tentang Node.js, lihat panduan ini.
Bagian belakang WASM
TensorFlow.js menyediakan backend WebAssembly ( wasm
), yang menawarkan akselerasi CPU dan dapat digunakan sebagai alternatif dari backend vanilla JavaScript CPU ( cpu
) dan akselerasi WebGL ( webgl
). Untuk menggunakannya:
// Set the backend to WASM and wait for the module to be ready.
tf.setBackend('wasm');
tf.ready().then(() => {...});
Jika server Anda menyajikan file .wasm
di jalur atau nama berbeda, gunakan setWasmPath
sebelum Anda menginisialisasi backend. Lihat bagian "Menggunakan Bundler" di README untuk info lebih lanjut:
import {setWasmPath} from '@tensorflow/tfjs-backend-wasm';
setWasmPath(yourCustomPath);
tf.setBackend('wasm');
tf.ready().then(() => {...});
Mengapa WASM?
WASM diperkenalkan pada tahun 2015 sebagai format biner berbasis web baru, menyediakan program yang ditulis dalam JavaScript, C, C++, dll. sebagai target kompilasi untuk dijalankan di web. WASM telah didukung oleh Chrome, Safari, Firefox, dan Edge sejak tahun 2017, dan didukung oleh 90% perangkat di seluruh dunia.
Pertunjukan
Backend WASM memanfaatkan perpustakaan XNNPACK untuk implementasi operator jaringan saraf yang optimal.
Versus JavaScript : Biner WASM umumnya jauh lebih cepat daripada bundel JavaScript untuk dimuat, diurai, dan dieksekusi oleh browser. JavaScript diketik secara dinamis dan sampah dikumpulkan, yang dapat menyebabkan pelambatan saat runtime.
Versus WebGL : WebGL lebih cepat daripada WASM untuk sebagian besar model, namun untuk model kecil WASM dapat mengungguli WebGL karena biaya overhead tetap dalam menjalankan shader WebGL. Bagian “Kapan saya harus menggunakan WASM” di bawah membahas heuristik untuk mengambil keputusan ini.
Portabilitas dan Stabilitas
WASM memiliki aritmatika float 32-bit portabel, yang menawarkan paritas presisi di semua perangkat. WebGL, di sisi lain, bersifat spesifik pada perangkat keras dan perangkat yang berbeda dapat memiliki presisi yang berbeda-beda (misalnya fallback ke float 16-bit pada perangkat iOS).
Seperti WebGL, WASM secara resmi didukung oleh semua browser utama. Tidak seperti WebGL, WASM dapat berjalan di Node.js, dan digunakan di sisi server tanpa perlu mengkompilasi perpustakaan asli.
Kapan saya harus menggunakan WASM?
Ukuran model dan permintaan komputasi
Secara umum, WASM adalah pilihan yang baik ketika model lebih kecil atau Anda peduli dengan perangkat kelas bawah yang tidak memiliki dukungan WebGL (ekstensi OES_texture_float
) atau memiliki GPU yang kurang bertenaga. Bagan di bawah menunjukkan waktu inferensi (mulai TensorFlow.js 1.5.2) di Chrome pada MacBook Pro 2018 untuk 5 model yang kami dukung secara resmi di backend WebGL, WASM, dan CPU:
Model yang lebih kecil
Model | WebGL | WASM | CPU | Ingatan |
---|---|---|---|---|
Wajah Blaze | 22,5 ms | 15,6 ms | 315,2 ms | ,4MB |
FaceMesh | 19,3 ms | 19,2 mdtk | 335 ms | 2,8 MB |
Model yang lebih besar
Model | WebGL | WASM | CPU | Ingatan |
---|---|---|---|---|
PoseNet | 42,5 ms | 173,9 mdtk | 1514,7 mdtk | 4,5 MB |
BodyPix | 77 ms | 188,4 mdtk | 2683 mdtk | 4,6 MB |
MobileNet v2 | 37 ms | 94 ms | 923,6 mdtk | 13 MB |
Tabel di atas menunjukkan bahwa WASM 10-30x lebih cepat dibandingkan backend CPU JS biasa di seluruh model, dan bersaing dengan WebGL untuk model yang lebih kecil seperti BlazeFace , yang ringan (400KB), namun memiliki jumlah operasi yang layak (~140). Mengingat program WebGL memiliki biaya overhead tetap per eksekusi operasi, hal ini menjelaskan mengapa model seperti BlazeFace lebih cepat di WASM.
Hasil ini akan bervariasi tergantung pada perangkat Anda. Cara terbaik untuk menentukan apakah WASM tepat untuk aplikasi Anda adalah dengan mengujinya di berbagai backend kami.
Inferensi vs Pelatihan
Untuk mengatasi kasus penggunaan utama penerapan model terlatih, pengembangan backend WASM akan memprioritaskan inferensi dibandingkan dukungan pelatihan . Lihat daftar terbaru operasi yang didukung di WASM dan beri tahu kami jika model Anda memiliki operasi yang tidak didukung. Untuk model pelatihan, sebaiknya gunakan backend Node (TensorFlow C++) atau backend WebGL.
bagian belakang CPU
Backend CPU, 'cpu', adalah backend dengan performa paling rendah, namun paling sederhana. Semua operasi diimplementasikan dalam JavaScript vanilla, sehingga kurang dapat diparalelkan. Mereka juga memblokir thread UI.
Backend ini bisa sangat berguna untuk pengujian, atau pada perangkat yang tidak menyediakan WebGL.
Bendera
TensorFlow.js memiliki serangkaian tanda lingkungan yang secara otomatis dievaluasi dan menentukan konfigurasi terbaik di platform saat ini. Flag ini sebagian besar bersifat internal, namun beberapa flag global dapat dikontrol dengan API publik.
-
tf.enableProdMode():
mengaktifkan mode produksi, yang akan menghapus validasi model, pemeriksaan NaN, dan pemeriksaan kebenaran lainnya yang mendukung kinerja. -
tf.enableDebugMode()
: mengaktifkan mode debug, yang akan mencatat ke konsol setiap operasi yang dijalankan, serta informasi kinerja runtime seperti jejak memori dan total waktu eksekusi kernel. Perhatikan bahwa ini akan sangat memperlambat aplikasi Anda, jangan gunakan ini dalam produksi.