Tentang codelab ini
1. Sebelum memulai
Dalam codelab ini, Anda akan mempelajari cara menjalankan inferensi klasifikasi teks dari aplikasi Flutter dengan TensorFlow Serving melalui REST dan gRPC.
Prasyarat
- Pengetahuan dasar tentang pengembangan Flutter dengan Dart
- Pengetahuan dasar tentang machine learning dengan TensorFlow, seperti pelatihan versus deployment
- Pengetahuan dasar tentang terminal dan Docker
- Codelab Melatih model deteksi spam komentar dengan TensorFlow Lite Model Maker
Yang akan Anda pelajari
- Cara mem-build aplikasi Flutter sederhana dan mengklasifikasikan teks melalui TensorFlow Serving (REST dan gRPC).
- Cara menampilkan hasilnya di UI.
Yang Anda butuhkan
- Flutter SDK
- Penyiapan Android atau iOS untuk Flutter
- Penyiapan Visual Studio Code (VS Code) untuk Flutter dan Dart
- Docker
- Bash
- Compiler buffering protokol dan plugin gRPC Dart untuk compiler protokol (hanya diperlukan jika Anda ingin membuat ulang stub gRPC sendiri)
2. Memulai persiapan
Untuk mendownload kode codelab ini:
- Buka repositori GitHub untuk codelab ini.
- Klik Code > Download zip guna mendownload semua kode untuk codelab ini.
- Ekstrak file zip yang didownload untuk mengekstrak folder root
codelabs-master
dengan semua resource yang Anda butuhkan.
Untuk codelab ini, Anda hanya memerlukan file dalam subdirektori tfserving-flutter/codelab2
di repositori, yang berisi dua folder:
- Folder
starter
berisi kode awal yang Anda buat untuk codelab ini. - Folder
finished
berisi kode yang sudah selesai untuk aplikasi contoh yang telah selesai.
3. Mendownload dependensi untuk project
- Di VS Code, klik File > Open folder, lalu pilih folder
starter
dari kode sumber yang Anda download sebelumnya. - Jika muncul dialog yang meminta Anda mendownload paket yang diperlukan untuk aplikasi awal, klik Get packages.
- Jika Anda tidak melihat dialog ini, buka terminal lalu jalankan perintah
flutter pub get
di folderstarter
.
4. Menjalankan aplikasi awal
- Di VS Code, pastikan Android Emulator atau Simulator iOS disiapkan dengan benar dan muncul di status bar.
Misalnya, berikut adalah tampilan yang Anda lihat saat menggunakan Pixel 5 dengan Android Emulator:
Berikut adalah tampilan yang Anda lihat saat menggunakan iPhone 13 dengan Simulator iOS:
- Klik
Start debugging.
Menjalankan dan menjelajahi aplikasi
Aplikasi akan diluncurkan di Android Emulator atau Simulator iOS. UI-nya cukup sederhana. Ada kolom teks yang dapat digunakan pengguna untuk mengetik teks. Pengguna dapat memilih apakah akan mengirim data ke backend dengan REST atau gRPC. Backend menggunakan model TensorFlow untuk melakukan klasifikasi teks pada input yang telah diproses sebelumnya dan menampilkan hasil klasifikasi ke aplikasi klien, yang kemudian akan mengupdate UI.
Jika Anda mengklik Classify, tidak akan terjadi apa-apa karena komunikasi dengan backend masih belum dapat dilakukan.
5. Men-deploy model klasifikasi teks dengan TensorFlow Serving
Klasifikasi teks adalah tugas machine learning yang sangat umum yang mengklasifikasikan teks ke dalam kategori yang telah ditentukan. Dalam codelab ini, Anda men-deploy model terlatih dari codelab Melatih model deteksi spam komentar dengan TensorFlow Lite Model Maker dengan TensorFlow Serving dan memanggil backend dari frontend Flutter Anda untuk mengklasifikasikan teks input sebagai spam atau bukan spam.
Memulai TensorFlow Serving
- Di terminal Anda, mulai TensorFlow Serving dengan Docker, tetapi ganti placeholder
PATH/TO/SAVEDMODEL
dengan jalur absolut foldermm_spam_savedmodel
di komputer Anda.
docker pull tensorflow/serving docker run -it --rm -p 8500:8500 -p 8501:8501 -v "PATH/TO/SAVEDMODEL:/models/spam-detection" -e MODEL_NAME=spam-detection tensorflow/serving
Docker akan otomatis mendownload image TensorFlow Serving terlebih dahulu, yang memerlukan waktu sebentar. Setelah itu, TensorFlow Serving akan dimulai. Log akan terlihat seperti cuplikan kode berikut:
2022-02-25 06:01:12.513231: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:206] Restoring SavedModel bundle. 2022-02-25 06:01:12.585012: I external/org_tensorflow/tensorflow/core/platform/profile_utils/cpu_utils.cc:114] CPU Frequency: 3000000000 Hz 2022-02-25 06:01:13.395083: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:190] Running initialization op on SavedModel bundle at path: /models/ssd_mobilenet_v2_2/123 2022-02-25 06:01:13.837562: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:277] SavedModel load for tags { serve }; Status: success: OK. Took 1928700 microseconds. 2022-02-25 06:01:13.877848: I tensorflow_serving/servables/tensorflow/saved_model_warmup_util.cc:59] No warmup data file found at /models/ssd_mobilenet_v2_2/123/assets.extra/tf_serving_warmup_requests 2022-02-25 06:01:13.929844: I tensorflow_serving/core/loader_harness.cc:87] Successfully loaded servable version {name: spam-detection version: 123} 2022-02-25 06:01:13.985848: I tensorflow_serving/model_servers/server_core.cc:486] Finished adding/updating models 2022-02-25 06:01:13.985987: I tensorflow_serving/model_servers/server.cc:367] Profiler service is enabled 2022-02-25 06:01:13.988994: I tensorflow_serving/model_servers/server.cc:393] Running gRPC ModelServer at 0.0.0.0:8500 ... [warn] getaddrinfo: address family for nodename not supported 2022-02-25 06:01:14.033872: I tensorflow_serving/model_servers/server.cc:414] Exporting HTTP/REST API at:localhost:8501 ... [evhttp_server.cc : 245] NET_LOG: Entering the event loop ...
6. Membuat token kalimat input
Backend sudah siap, sehingga Anda akan dapat mengirim permintaan klien ke TensorFlow Serving. Namun, Anda perlu membuat token kalimat input terlebih dahulu. Jika Anda memeriksa tensor input model, Anda dapat melihat bahwa tensor meminta daftar 20 bilangan bulat, bukan string mentah. Tokenisasi adalah proses saat Anda memetakan setiap kata yang diketik di aplikasi ke daftar bilangan bulat berdasarkan kamus kosakata sebelum mengirimkannya ke backend untuk tahap klasifikasi. Misalnya, jika Anda mengetik buy book online to learn more
, proses tokenisasi akan memetakannya ke [32, 79, 183, 10, 224, 631, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
. Angka spesifiknya dapat bervariasi berdasarkan kamus kosakata.
- Dalam file
lib/main.dart
, tambahkan kode ini ke metodepredict()
untuk membuat kamus kosakata_vocabMap
.
// Build _vocabMap if empty.
if (_vocabMap.isEmpty) {
final vocabFileString = await rootBundle.loadString(vocabFile);
final lines = vocabFileString.split('\n');
for (final l in lines) {
if (l != "") {
var wordAndIndex = l.split(' ');
(_vocabMap)[wordAndIndex[0]] = int.parse(wordAndIndex[1]);
}
}
}
- Segera setelah cuplikan kode sebelumnya, tambahkan kode ini untuk menerapkan tokenisasi:
// Tokenize the input sentence.
final inputWords = _inputSentenceController.text
.toLowerCase()
.replaceAll(RegExp('[^a-z ]'), '')
.split(' ');
// Initialize with padding token.
_tokenIndices = List.filled(maxSentenceLength, 0);
var i = 0;
for (final w in inputWords) {
if ((_vocabMap).containsKey(w)) {
_tokenIndices[i] = (_vocabMap)[w]!;
i++;
}
// Truncate the string if longer than maxSentenceLength.
if (i >= maxSentenceLength - 1) {
break;
}
}
Kode ini akan membuat string kalimat menggunakan huruf kecil, menghapus karakter non-alfabet, dan memetakan kata ke 20 indeks bilangan bulat berdasarkan tabel kosakata.
7. Menghubungkan aplikasi Flutter dengan TensorFlow Serving melalui REST
Ada dua cara untuk mengirim permintaan ke TensorFlow Serving:
- REST
- gRPC
Mengirim permintaan dan menerima respons melalui REST
Ada tiga langkah sederhana untuk mengirim permintaan dan menerima respons melalui REST:
- Buat permintaan REST.
- Kirim permintaan REST ke TensorFlow Serving.
- Ekstrak hasil prediksi dari respons REST dan render UI-nya.
Anda dapat menyelesaikan langkah-langkah ini di file main.dart
.
Membuat dan mengirim permintaan REST ke TensorFlow Serving
- Saat ini, fungsi
predict()
tidak mengirimkan permintaan REST ke TensorFlow Serving. Anda perlu mengimplementasikan cabang REST untuk membuat permintaan REST:
if (_connectionMode == ConnectionModeType.rest) {
// TODO: Create and send the REST request.
}
- Tambahkan kode ini ke cabang REST:
//Create the REST request.
final response = await http.post(
Uri.parse('http://' +
_server +
':' +
restPort.toString() +
'/v1/models/' +
modelName +
':predict'),
body: jsonEncode(<String, List<List<int>>>{
'instances': [_tokenIndices],
}),
);
Memproses respons REST dari TensorFlow Serving
- Tambahkan kode ini tepat setelah cuplikan kode sebelumnya untuk menangani respons REST:
// Process the REST response.
if (response.statusCode == 200) {
Map<String, dynamic> result = jsonDecode(response.body);
if (result['predictions']![0][1] >= classificationThreshold) {
return 'This sentence is spam. Spam score is ' +
result['predictions']![0][1].toString();
}
return 'This sentence is not spam. Spam score is ' +
result['predictions']![0][1].toString();
} else {
throw Exception('Error response');
}
Kode pascapemrosesan mengekstrak probabilitas bahwa kalimat input adalah pesan spam dari respons dan menampilkan hasil klasifikasi di UI.
Menjalankan aplikasi
- Klik
Start debugging, lalu tunggu aplikasi dimuat.
- Masukkan beberapa teks, lalu pilih REST > Classify.
8. Menghubungkan aplikasi Flutter dengan TensorFlow Serving melalui gRPC
Selain REST, TensorFlow Serving juga mendukung gRPC.
gRPC adalah framework Remote Procedure Call (RPC) modern, open source, dan berperforma tinggi yang dapat berjalan di lingkungan apa pun. Framework ini dapat menghubungkan layanan di dalam dan di seluruh pusat data secara efisien dengan dukungan yang dapat dicocokkan untuk load balancing, tracing, health checking, dan autentikasi. Berdasarkan pengamatan dalam praktiknya, performa gRPC lebih tinggi daripada REST.
Mengirim permintaan dan menerima respons dengan gRPC
Ada empat langkah sederhana untuk mengirim permintaan dan menerima respons dengan gRPC:
- Opsional: Buat kode stub klien gRPC.
- Buat permintaan gRPC.
- Kirim permintaan gRPC ke TensorFlow Serving.
- Ekstrak hasil yang diprediksi dari respons gRPC dan render UI-nya.
Anda dapat menyelesaikan langkah-langkah ini di file main.dart
.
Opsional: Membuat kode stub klien gRPC
Untuk menggunakan gRPC dengan TensorFlow Serving, Anda harus mengikuti alur kerja gRPC. Untuk mempelajari detailnya lebih lanjut, baca dokumentasi gRPC.
TensorFlow Serving dan TensorFlow menentukan file .proto
untuk Anda. Mulai dari TensorFlow dan TensorFlow Serve 2.8, file .proto
berikut adalah file yang diperlukan:
tensorflow/core/example/example.proto
tensorflow/core/example/feature.proto
tensorflow/core/protobuf/struct.proto
tensorflow/core/protobuf/saved_object_graph.proto
tensorflow/core/protobuf/saver.proto
tensorflow/core/protobuf/trackable_object_graph.proto
tensorflow/core/protobuf/meta_graph.proto
tensorflow/core/framework/node_def.proto
tensorflow/core/framework/attr_value.proto
tensorflow/core/framework/function.proto
tensorflow/core/framework/types.proto
tensorflow/core/framework/tensor_shape.proto
tensorflow/core/framework/full_type.proto
tensorflow/core/framework/versions.proto
tensorflow/core/framework/op_def.proto
tensorflow/core/framework/graph.proto
tensorflow/core/framework/tensor.proto
tensorflow/core/framework/resource_handle.proto
tensorflow/core/framework/variable.proto
tensorflow_serving/apis/inference.proto
tensorflow_serving/apis/classification.proto
tensorflow_serving/apis/predict.proto
tensorflow_serving/apis/regression.proto
tensorflow_serving/apis/get_model_metadata.proto
tensorflow_serving/apis/input.proto
tensorflow_serving/apis/prediction_service.proto
tensorflow_serving/apis/model.proto
google/protobuf/any.proto
google/protobuf/wrappers.proto
- Di terminal Anda, buka folder
starter/lib/proto/
dan buat stub:
bash generate_grpc_stub_dart.sh
Membuat permintaan gRPC
Serupa dengan permintaan REST, Anda membuat permintaan gRPC di cabang gRPC.
if (_connectionMode == ConnectionModeType.rest) {
} else {
// TODO: Create and send the gRPC request.
}
- Tambahkan kode ini untuk membuat permintaan gRPC:
//Create the gRPC request.
final channel = ClientChannel(_server,
port: grpcPort,
options:
const ChannelOptions(credentials: ChannelCredentials.insecure()));
_stub = PredictionServiceClient(channel,
options: CallOptions(timeout: const Duration(seconds: 10)));
ModelSpec modelSpec = ModelSpec(
name: 'spam-detection',
signatureName: 'serving_default',
);
TensorShapeProto_Dim batchDim = TensorShapeProto_Dim(size: Int64(1));
TensorShapeProto_Dim inputDim =
TensorShapeProto_Dim(size: Int64(maxSentenceLength));
TensorShapeProto inputTensorShape =
TensorShapeProto(dim: [batchDim, inputDim]);
TensorProto inputTensor = TensorProto(
dtype: DataType.DT_INT32,
tensorShape: inputTensorShape,
intVal: _tokenIndices);
// If you train your own model, update the input and output tensor names.
const inputTensorName = 'input_3';
const outputTensorName = 'dense_5';
PredictRequest request = PredictRequest(
modelSpec: modelSpec, inputs: {inputTensorName: inputTensor});
Catatan: Nama tensor input dan output dapat berbeda dari model ke model, meskipun arsitektur modelnya sama. Pastikan untuk memperbaruinya jika Anda melatih model sendiri.
Mengirim permintaan gRPC ke TensorFlow Serving
- Tambahkan kode ini setelah cuplikan kode sebelumnya untuk mengirim permintaan gRPC ke TensorFlow Serving:
// Send the gRPC request.
PredictResponse response = await _stub.predict(request);
Memproses respons gRPC dari TensorFlow Serving
- Tambahkan kode ini setelah cuplikan kode sebelumnya untuk menerapkan fungsi callback guna menangani respons:
// Process the response.
if (response.outputs.containsKey(outputTensorName)) {
if (response.outputs[outputTensorName]!.floatVal[1] >
classificationThreshold) {
return 'This sentence is spam. Spam score is ' +
response.outputs[outputTensorName]!.floatVal[1].toString();
} else {
return 'This sentence is not spam. Spam score is ' +
response.outputs[outputTensorName]!.floatVal[1].toString();
}
} else {
throw Exception('Error response');
}
Kode pascapemrosesan sekarang akan mengekstrak hasil klasifikasi dari respons dan menampilkannya di UI.
Menjalankan aplikasi
- Klik
Start debugging, lalu tunggu aplikasi dimuat.
- Masukkan beberapa teks, lalu pilih gRPC > Classify.
9. Selamat
Anda telah menggunakan TensorFlow Serving untuk menambahkan kemampuan klasifikasi teks ke aplikasi Anda.
Di codelab berikutnya, Anda akan meningkatkan kualitas model agar dapat mendeteksi pesan spam tertentu yang tidak dapat dideteksi oleh aplikasi saat ini.