ResNet50 adalah arsitektur jaringan klasik yang banyak digunakan. Mengoptimalkan model ResNet50 bermanfaat untuk berbagai skenario penerapan inferensi. Topik ini menjelaskan cara mengoptimalkan model ResNet50 berbasis TensorFlow menggunakan Blade.
Informasi latar belakang
Residual Network (ResNet) merupakan jaringan tulang punggung saraf klasik untuk tugas visi komputer dan sering dianggap sebagai "Hello World" bagi model pembelajaran mendalam praktis di ranah citra. ResNet menggunakan lapisan konvolusi untuk mengekstraksi fitur citra. Dengan memperkenalkan struktur blok residual, ResNet mengatasi masalah gradien yang menghilang (vanishing) dan meledak (exploding) yang dapat terjadi saat melatih jaringan saraf dalam. Desain ini secara signifikan meningkatkan performa pelatihan jaringan saraf dalam. Jaringan ResNet khas meliputi ResNet26, ResNet50, dan ResNet101.
Batasan
Lingkungan untuk contoh ini harus memenuhi persyaratan berikut:
-
Lingkungan sistem: Linux dengan Python 3.6 atau versi lebih baru dan Compute Unified Device Architecture (CUDA) 10.0.
-
Framework: TensorFlow 1.15.
-
Tool optimisasi inferensi: Blade 3.17.0 atau versi lebih baru.
Prosedur
Untuk mengoptimalkan model ResNet50 berbasis TensorFlow menggunakan Blade, ikuti langkah-langkah berikut:
-
Instal paket wheel Blade yang mendukung optimisasi TensorRT, lalu unduh model ResNet50 dan data uji.
-
Langkah 2: Optimalkan model menggunakan Blade
Panggil API
blade.optimizeuntuk mengoptimalkan model. -
Langkah 3: Verifikasi performa
Uji kecepatan inferensi sebelum dan sesudah optimisasi untuk memverifikasi informasi dalam laporan optimisasi.
-
Langkah 4: Muat dan jalankan model yang telah dioptimalkan
Integrasikan kit pengembangan perangkat lunak (SDK) Blade untuk memuat model yang telah dioptimalkan guna inferensi.
Langkah 1: Persiapan
Pada contoh ini, optimisasi utama untuk model ResNet50 adalah TensorRT. Oleh karena itu, Anda harus menggunakan Blade 3.17.0 atau versi lebih baru yang mendukung fitur ini.
-
Instal versi Blade yang sesuai dengan TensorFlow 1.15.0 dan CUDA 10.0.
pip3 install pai_blade_gpu==3.17.0 -f https://pai-blade.oss-cn-zhangjiakou.aliyuncs.com/release/repo.html -
Unduh model TensorFlow ResNet50 dan data uji yang sesuai.
wget http://pai-blade.cn-hangzhou.oss.aliyun-inc.com/tutorials/tf_resnet50_v1.5.tar.gz -
Paket tf_resnet50_v1.5.tar.gz yang diunduh berisi file frozen.pb untuk model ResNet50 dan data uji untuk berbagai ukuran batch. Ekstrak paket tersebut secara manual.
tar zxvf tf_resnet50_v1.5.tar.gz
Langkah 2: Optimalkan model dengan Blade
-
Ambil model TensorFlow dan data uji dari paket TAR yang diunduh pada langkah sebelumnya.
import os os.environ["CUDA_VISIBLE_DEVICES"] = "1" import numpy as np import time # import tf to import graphdef model. import tensorflow.compat.v1 as tf import blade from blade.model.tf_model import TfModel def _load_model_and_data(): local_dir = "./tf_resnet50_v1.5/" model_path = os.path.abspath(os.path.join(local_dir, "frozen.pb")) data_path = os.path.abspath(os.path.join(local_dir, "test_bc1.npy")) graph_def = tf.GraphDef() with open(model_path, 'rb') as f: graph_def.ParseFromString(f.read()) test_data = np.load(data_path, allow_pickle=True, encoding='bytes').item() return graph_def, test_data # Let's go! # Load resnet model and test data. graph_def, test_data = _load_model_and_data() print(test_data) -
Gunakan Blade untuk melakukan optimisasi TensorRT.
Optimisasi TensorRT dibagi menjadi dua jenis berikut berdasarkan bentuk input:
-
Optimisasi bentuk statis
Mode ini berlaku ketika bentuk permintaan model bersifat konstan. Misalnya, untuk mengurangi latensi, Anda mungkin membatasi input pada ukuran tertentu. Kode berikut menunjukkan contohnya.
config = blade.Config() config.gpu_config.aicompiler.enable = False config.gpu_config.disable_fp16_accuracy_check = True config.gpu_config.tensorrt.enable = True # TensorRT optimization is enabled by default, you can also use this param to disable if necessary. # Function `optimize` is the entrance to Blade's one-stop optimization. optimized_model_static, opt_spec_static, report = blade.optimize( graph_def, # The original model, here is a TF GraphDef. 'o1', # Optimization level o1 or o2. device_type='gpu', # Target device to run the optimized model. config=config, # The blade.Config with more detailed optimizations configs outputs=['softmax_tensor'], # Name of outputs nodes. You can provide them or blade will guess. test_data=[test_data] ) print(report)Sistem mengembalikan laporan optimisasi yang mirip dengan berikut.
{ "software_context": [ { "software": "tensorflow", "version": "1.15.0" }, { "software": "cuda", "version": "10.0.0" } ], "hardware_context": { "device_type": "gpu", "microarchitecture": "T4" }, "user_config": "", "diagnosis": { "model": "tmp_graph.pbtxt", "test_data_source": "user provided", "shape_variation": "dynamic", "message": "", "test_data_info": "input_tensor:0 shape: (1, 224, 224, 3) data type: float32" }, "optimizations": [ { "name": "Tf2TrtPlus", "status": "effective", "speedup": "3.37", "pre_run": "6.81 ms", "post_run": "2.02 ms" }, { "name": "TfStripUnusedNodes", "status": "effective", "speedup": "na", "pre_run": "na", "post_run": "na" }, { "name": "TfFoldConstants", "status": "effective", "speedup": "na", "pre_run": "na", "post_run": "na" } ], "overall": { "baseline": "6.98 ms", "optimized": "2.11 ms", "speedup": "3.31" }, "model_info": { "input_format": "frozen_pb" }, "compatibility_list": [ { "device_type": "gpu", "microarchitecture": "T4" } ], "model_sdk": {} }Selama optimisasi, optimisasi bentuk statis diaktifkan karena tidak ada opsi optimisasi tambahan yang diberikan. Bentuk
test_datadigunakan untuk optimisasi ini. Laporan optimisasi menunjukkan bahwa optimisasiTf2TrtPlusefektif. Dengan optimisasi bentuk statis, jika bentuk input selama inferensi tidak sesuai dengan bentuk yang digunakan untuk optimisasi, proses akan kembali menjalankan graf TensorFlow asli. Fallback ini secara signifikan mengurangi efisiensi eksekusi.Hasil optimisasi hanya berlaku untuk contoh ini. Hasil aktual Anda mungkin berbeda. Untuk informasi lebih lanjut tentang bidang-bidang dalam laporan optimisasi, lihat Laporan optimisasi.
-
Optimisasi bentuk dinamis
Jika layanan yang Anda terapkan mendukung batching dinamis, server biasanya mengelompokkan permintaan yang diterima dalam suatu jangka waktu tertentu menjadi satu batch. Karena jumlah permintaan yang diterima dalam periode singkat tidak pasti, ukuran batch yang dihasilkan dapat bervariasi. Untuk mendukung optimisasi bentuk yang berubah-ubah ini, Blade mengintegrasikan fitur optimisasi bentuk dinamis TensorRT. Untuk mengaktifkan optimisasi input dinamis, Anda hanya perlu memberikan konfigurasi tambahan dalam TensorRTConfig. Kode berikut menunjukkan contohnya. Untuk informasi lebih lanjut tentang parameter TensorRTConfig, lihat Lampiran: TensorRTConfig.
config_dynamic = blade.Config() config_dynamic.gpu_config.aicompiler.enable = False config_dynamic.gpu_config.disable_fp16_accuracy_check = True config_dynamic.gpu_config.tensorrt.enable = True config_dynamic.gpu_config.tensorrt.dynamic_tuning_shapes = { "min": [1, 224, 224, 3], "opts": [ [1, 224, 224, 3], [2, 224, 224, 3], [4, 224, 224, 3], [8, 224, 224, 3], ], "max": [8, 224, 224, 3], } # Call Blade's one-stop optimization, with a dynamic shapes setting for TensorRT optimization. optimized_model_dynamic, opt_spec_dynamic, report = blade.optimize( graph_def, 'o1', device_type='gpu', config=config_dynamic, outputs=['softmax_tensor'], test_data=[test_data] ) print(report) with tf.gfile.FastGFile('optimized_model_dynamic.pb', mode='wb') as f: f.write(optimized_model_dynamic.SerializeToString())Sistem mengembalikan laporan optimisasi yang mirip dengan berikut.
{ "software_context": [ { "software": "tensorflow", "version": "1.15.0" }, { "software": "cuda", "version": "10.0.0" } ], "hardware_context": { "device_type": "gpu", "microarchitecture": "T4" }, "user_config": "", "diagnosis": { "model": "tmp_graph.pbtxt", "test_data_source": "user provided", "shape_variation": "dynamic", "message": "", "test_data_info": "input_tensor:0 shape: (1, 224, 224, 3) data type: float32" }, "optimizations": [ { "name": "Tf2TrtPlus", "status": "effective", "speedup": "3.96", "pre_run": "7.98 ms", "post_run": "2.02 ms" }, { "name": "TfStripUnusedNodes", "status": "effective", "speedup": "na", "pre_run": "na", "post_run": "na" }, { "name": "TfFoldConstants", "status": "effective", "speedup": "na", "pre_run": "na", "post_run": "na" } ], "overall": { "baseline": "7.87 ms", "optimized": "2.52 ms", "speedup": "3.12" }, "model_info": { "input_format": "frozen_pb" }, "compatibility_list": [ { "device_type": "gpu", "microarchitecture": "T4" } ], "model_sdk": {} }Laporan optimisasi ini mirip dengan laporan untuk optimisasi bentuk statis. Perhatikan bahwa optimisasi TensorRT digunakan selama bentuk input selama inferensi berada dalam rentang
mindanmaxyang diberikan selama optimisasi. Jika bentuk input berada di luar rentang ini, proses akan kembali menjalankan subgraf TensorFlow asli.Hasil optimisasi hanya berlaku untuk contoh ini. Hasil aktual Anda mungkin berbeda. Untuk informasi lebih lanjut tentang bidang-bidang dalam laporan optimisasi, lihat Laporan optimisasi.
-
Langkah 3: Verifikasi performa
Setelah optimisasi selesai, Anda dapat menggunakan skrip Python untuk memverifikasi informasi dalam laporan optimisasi.
import time
with tf.Session(config=TfModel.new_session_config()) as sess, opt_spec_dynamic:
sess.graph.as_default()
tf.import_graph_def(optimized_model_dynamic, name="")
# Warmup!
for i in range(0, 100):
sess.run(['softmax_tensor:0'], test_data)
# Benchmark!
num_runs = 1000
start = time.time()
for i in range(0, num_runs):
sess.run(['softmax_tensor:0'], test_data)
elapsed = time.time() - start
rt_ms = elapsed / num_runs * 1000.0
# Show the result!
print("Latency of optimized model: {:.2f}".format(rt_ms))
Sistem mengembalikan hasil yang mirip dengan berikut.
Latency of optimized model: 2.26
Hasil ini menunjukkan bahwa performa model yang dioptimalkan sebesar 2,26 ms hampir identik dengan nilai "optimized": "2.52 ms" pada bagian "overall" dalam laporan optimisasi. Optimisasi berjalan efektif karena data uji yang digunakan berada dalam rentang optimisasi bentuk dinamis. Hasil optimisasi hanya berlaku untuk contoh ini. Hasil aktual Anda mungkin berbeda.
Langkah 4: Muat dan jalankan model yang telah dioptimalkan
Setelah memverifikasi performa, Anda dapat menerapkan model tersebut. Blade menyediakan SDK runtime Python dan C++ yang dapat Anda integrasikan. Untuk informasi lebih lanjut tentang cara menggunakan SDK C++, lihat Gunakan SDK untuk menerapkan model TensorFlow untuk inferensi. Bagian berikut menjelaskan cara menggunakan SDK Python untuk menerapkan model.
Opsional: Selama masa uji coba, tambahkan pengaturan variabel lingkungan berikut untuk mencegah program berhenti mendadak akibat kegagalan otentikasi:
export BLADE_AUTH_USE_COUNTING=1Lakukan otentikasi untuk menggunakan PAI-Blade.
export BLADE_REGION=<region> export BLADE_TOKEN=<token>Konfigurasikan parameter berikut sesuai kebutuhan bisnis Anda:
<region>: wilayah tempat Anda menggunakan PAI-Blade. Anda dapat bergabung dengan grup DingTalk pengguna PAI-Blade untuk memperoleh daftar wilayah tempat PAI-Blade tersedia. Informasi kode QR grup DingTalk tersedia di Instal PAI-Blade.
<token>: token otentikasi yang diperlukan untuk menggunakan PAI-Blade. Anda dapat bergabung dengan grup DingTalk pengguna PAI-Blade untuk memperoleh token otentikasi tersebut. Informasi kode QR grup DingTalk tersedia di Instal PAI-Blade.
-
Muat dan jalankan model yang telah dioptimalkan.
Untuk mengintegrasikan Blade, Anda hanya perlu menambahkan baris
import blade.runtime.tensorflow. Tidak diperlukan perubahan lain pada kode inferensi asli Anda. Contoh berikut menunjukkan proses ini menggunakan model yang telah dioptimalkan dengan bentuk dinamis.import tensorflow.compat.v1 as tf import blade.runtime.tensorflow infer_data = np.load('./tf_resnet50_v1.5/test_bc1.npy', allow_pickle=True, encoding='bytes').item() # optimized model produced by blade.optimize model_path = './optimized_model_dynamic.pb' graph_def = tf.GraphDef() with open(model_path, 'rb') as f: graph_def.ParseFromString(f.read()) with tf.Session() as sess: sess.graph.as_default() tf.import_graph_def(graph_def, name="") print(sess.run(['softmax_tensor:0'], infer_data))
Lampiran: TensorRTConfig
Karena sifat khusus optimisasi TensorRT, konfigurasi Blade mencakup opsi konfigurasi khusus untuk membantu Anda mengonfigurasi optimisasi TensorRT secara lebih baik sesuai kebutuhan penerapan yang berbeda.
class TensorRTConfig():
def __init__(self) -> None:
self.enable = True
self.dynamic_tuning_shapes: Dict[str, List[List[Any]]] = dict()
......
Parameter utama dalam TensorRTConfig dijelaskan sebagai berikut:
-
enable: Parameter boolean yang mengontrol apakah optimisasi TensorRT diaktifkan. Secara default, optimisasi TensorRT dicoba saat Anda melakukan optimisasi pada perangkat GPU. -
dynamic_tuning_shapes: Permintaan yang dikirim oleh server mungkin berisi input dengan berbagai ukuran. Untuk mencapai hasil optimisasi yang lebih baik untuk ukuran input yang berbeda ini, Blade menyediakan fitur optimisasi bentuk dinamis. Anda dapat mengatur kamusdynamic_tuning_shapessebagai parameter tambahan untuk optimisasi.Kamus
dynamic_tuning_shapesberisi tiga kunci:min,max, danopts. Nilai untukmindanmaxbertipeList[List[int]]dan mewakili serangkaian dimensi minimum dan maksimum untuk input model. Nilai untukoptsbertipeList[List[List[int]]]dan mewakili beberapa set dimensi untuk input model.CatatanBeberapa set dimensi input yang sesuai dengan
optsharus berada di antara dimensi minimum dan maksimum untuk memastikan optimisasi berhasil. Jika tidak, optimisasi TensorRT akan mengembalikan errorDim value in 'opts' is not between min_dim and max_dim.Kode berikut menunjukkan contoh pengaturan optimisasi bentuk dinamis. Beberapa set dimensi yang sesuai dengan
optssemuanya berada dalam rentang dimensi minimum dan maksimum.{ "min": [[1, 3, 224, 224], [1, 50]], # lower bound of the dynamic range of each inputs. "opts": [ [[1, 3, 512, 512], [1, 60]], [[1, 3, 320, 320], [1, 55]], ], # shapes that should be optimized like static shapes "max": [[1, 3, 1024, 1024], [1, 70]] # upper bound of the dynamic range. }