Inferensi Batch vs Real-Time

Perbandingan pola penyajian inferensi batch dan real-time.

Daftar isi

Model yang sudah tersimpan sebagai artefak masih perlu satu keputusan lagi, yaitu cara prediksinya disajikan. Topik ini membandingkan dua pola penyajian, yaitu inferensi batch yang memproses kumpulan baris sekaligus pada jadwal tertentu, dan inferensi real-time yang merespons satu permintaan segera setelah masuk. Perbandingannya mencakup karakter kedua pola, simulasi pengukuran dengan fungsi Python pada model dataset kanker payudara, serta pertimbangan pemilihan pola pada proyek nyata.

Dua pola penyajian#

Pola batch mengumpulkan baris-baris yang akan dinilai menjadi satu kelompok lalu memprosesnya bersamaan, biasanya terjadwal, misalnya setiap jam atau setiap malam. Tidak ada pihak yang menunggu di depan layar saat pekerjaan itu berjalan, sehingga waktunya boleh mencapai menit hingga jam. Pola ini cocok untuk pekerjaan seperti penilaian kelengkapan arsip dokumen atau pengolahan hasil pencatatan sensor satu hari penuh.

Pola real-time bekerja sebaliknya, yaitu satu permintaan masuk dan satu respons keluar dalam waktu yang singkat, lazimnya di bawah satu detik. Penyajian seperti ini menuntut latensi rendah, yaitu jeda antara permintaan dan respons, karena hasilnya langsung dipakai untuk keputusan yang sedang berlangsung. Contohnya adalah penilaian anomali suhu sensor yang harus tahu hasilnya saat sensor masih mengirim data.

AspekBatchReal-time
Ukuran masukanRatusan hingga jutaan baris per pekerjaanSatu baris per permintaan
Waktu responsBoleh menit hingga jamUmumnya di bawah satu detik
PemicuJadwal atau kedatangan berkasKedatangan permintaan
Contoh kasusPenilaian kelengkapan arsip tiap malamPenilaian anomali suhu sensor
Biaya per prediksiRendah karena dihitung massalLebih tinggi karena biaya tetap per panggilan

Pemilihan pola mengikuti batas waktu kebutuhan pengguna, bukan selera teknis. Apabila hasil boleh menunggu jadwal berikutnya, batch memberi biaya yang lebih hemat karena satu panggilan mengerjakan banyak baris. Apabila keputusan harus lahir saat peristiwa masih berlangsung, biaya tambahan real-time adalah harga untuk jeda yang nyaris nol.

Alur kedua pola#

Diagram berikut menampilkan perbedaan alurnya. Jalur batch melewati antrean tugas dan berakhir pada arsip hasil, sedangkan jalur real-time berhenti pada respons yang dikirim balik kepada peminta.

BatchBerkas dataAntrean tugasPrediksi massalArsip hasilReal-timePermintaan tunggalFungsi penyajiRespons segera
Alur inferensi batch dan real-time

Perbedaan terpenting pada diagram bukanlah jumlah kotaknya, melainkan pemicunya. Jalur batch bergerak karena jadwal, sedangkan jalur real-time bergerak karena permintaan. Karena itu penyaji real-time harus selalu siaga dan memuat modelnya sejak awal, sedangkan pekerjaan batch boleh dibangunkan, menjalankan tugasnya, lalu berhenti.

Perbedaan lain menyentuh nasib hasil prediksinya. Hasil batch keluar sebagai berkas atau tabel yang diperiksa dan digabungkan kembali ke data sumbernya, sehingga kesalahannya dapat ditinjau sebelum dipakai. Hasil real-time langsung dipakai pada saat itu juga dan tidak selalu tersimpan, sehingga pemantauan kualitasnya perlu disiapkan terpisah sebagaimana dibahas pada topik pemantauan drift.

Bentuk pemicunya juga menentukan cara kedua pola gagal. Pekerjaan batch yang gagal pada satu malam dapat diulang pada jadwal berikutnya tanpa dampak yang terasa, sedangkan kegagalan penyaji real-time langsung dirasakan setiap peminta layanan. Karena itu penyaji real-time dilengkapi pengawasan proses dan pemeriksaan kesehatan berkala, sedangkan pekerjaan batch cukup memakai pencatatan log yang memadai.

Simulasi kedua pola dengan scikit-learn#

Penyajian sungguhan memerlukan server yang selalu hidup, sehingga di sandbox kedua pola disimulasikan dengan fungsi Python dan pengukuran waktu sederhana. Fungsi sajikan meniru penyaji real-time, yaitu satu baris masuk dan satu prediksi keluar, sedangkan pola batch dieksekusi dengan satu panggilan predict untuk seluruh data uji. Skrip berikut membandingkan keduanya pada model yang sama.

python bandingkan-batch-realtime.py
"""Membandingkan pola inferensi batch dan real-time pada satu model yang sama."""

import time

import numpy as np
from sklearn.datasets import load_breast_cancer
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler

# satu model terlatih dipakai untuk kedua pola penyajian
data = load_breast_cancer()
X_latih, X_uji, y_latih, y_uji = train_test_split(
    data.data, data.target, test_size=0.25, random_state=42, stratify=data.target
)
model = make_pipeline(StandardScaler(), LogisticRegression(max_iter=5000))
model.fit(X_latih, y_latih)
n_baris = X_uji.shape[0]

# pola batch: seluruh baris dikumpulkan lalu diproses dalam satu panggilan
jumlah_panggilan_batch = 1
prediksi_batch = model.predict(X_uji)

# pola real-time: disimulasikan sebagai fungsi penyaji per permintaan tunggal
def sajikan(satu_baris):
    """Penyaji sederhana: satu permintaan masuk, satu prediksi keluar."""
    return int(model.predict(satu_baris.reshape(1, -1))[0])

prediksi_satuan = [sajikan(X_uji[i]) for i in range(n_baris)]
jumlah_panggilan_satuan = n_baris

# pengukuran waktu sederhana untuk menangkap selisih biaya kedua pola
mulai = time.perf_counter()
model.predict(X_uji)
waktu_batch = time.perf_counter() - mulai

mulai = time.perf_counter()
for i in range(n_baris):
    sajikan(X_uji[i])
waktu_satuan = time.perf_counter() - mulai

print(f"Jumlah baris yang dinilai            : {n_baris}")
print(f"Batch     : {jumlah_panggilan_batch} panggilan predict untuk {n_baris} baris")
print(f"Real-time : {jumlah_panggilan_satuan} panggilan predict untuk {n_baris} baris")
print(f"Hasil prediksi kedua pola identik    : {np.array_equal(prediksi_batch, np.array(prediksi_satuan))}")
print(f"Mode per permintaan lebih berat total: {waktu_satuan > waktu_batch}")
text Keluaran
Jumlah baris yang dinilai            : 143
Batch     : 1 panggilan predict untuk 143 baris
Real-time : 143 panggilan predict untuk 143 baris
Hasil prediksi kedua pola identik    : True
Mode per permintaan lebih berat total: True

Hasil prediksi kedua pola identik karena logika modelnya persis sama, sehingga pemilihan pola tidak mengubah isi keputusan, melainkan cara dan biayanya. Mode per permintaan lebih berat karena setiap panggilan predict membawa biaya tetap untuk menyiapkan pemrosesan satu baris. Biaya itu dibayar 143 kali pada mode per permintaan, sedangkan pola batch membayarnya satu kali untuk seluruh baris. Pada lingkungan pengujian ini selisih total waktunya melebihi seratus kali, sedangkan angka pastinya selalu berubah antar mesin maupun antar percobaan.

Selisih tersebut bukan keanehan scikit-learn, melainkan akibat cara array NumPy bekerja. Satu panggilan predict pada matriks utuh memproses 143 baris sekaligus dalam operasi vektor yang dieksekusi kode tingkat rendah, sedangkan pemanggilan per baris mengulang biaya penyiapan array dan pemanggilan fungsi sebanyak 143 kali. Penyaji produksi menerapkan prinsip yang sama dengan menumpuk permintaan kecil menjadi satu kumpulan sebelum diproses.

Penyajian real-time sungguhan#

Penyaji real-time sungguhan membungkus fungsi prediksi dalam endpoint HTTP, yaitu alamat yang dapat dikirim permintaan oleh aplikasi lain. Kerangkanya selalu sama, yaitu model dimuat sekali ketika server hidup, setiap permintaan membawa fitur dalam bentuk JSON, dan server mengembalikan hasil prediksi sebagai respons.

python
# tidak-dijalankan
# kerangka penyaji real-time sungguhan, memerlukan pustaka flask dan jaringan
from flask import Flask, jsonify, request
from joblib import load

app = Flask(__name__)
model = load("model-kanker-v1.joblib")  # dimuat sekali saat server hidup

@app.post("/prediksi")
def prediksi():
    fitur = request.get_json()["fitur"]   # daftar 30 angka dari peminta layanan
    hasil = int(model.predict([fitur])[0])
    return jsonify({"kelas": hasil})

Bentuk kerangka di atas menegaskan peran artefak model dari topik persistensi, yaitu berkas model yang dimuat oleh server saat prosesnya lahir, bukan dilatih ulang di dalamnya. Satu model yang sudah diuji melayani seluruh permintaan, dan pembaruan dilakukan dengan memuat artefak versi baru, bukan dengan menyentuh kode penyajinya.

Masukan dari jaringan tidak sebersih masukan dari data uji. Permintaan dapat membawa daftar dengan jumlah fitur yang salah, nilai bukan angka, atau format JSON yang rusak. Penyaji produksi memeriksa masukan terlebih dahulu dan mengembalikan pesan error yang jelas, alih-alih membiarkan kegagalan menghentikan proses. Respons juga sering diperkaya dengan nomor versi model, sehingga peminta layanan dapat mencocokkan keputusan yang diterima dengan artefak yang menghasilkannya.

Kesalahan umum#

  • Menilai latensi dari permintaan pertama. Panggilan pertama menyertakan penyiapan objek dan pemanasan cache, sehingga angkanya lebih tinggi daripada keadaan stabil. Ukur setelah beberapa permintaan pemanasan.
  • Melatih ulang model di dalam proses penyaji. Penyaji dapat memuat versi yang belum diuji dan kegagalan pelatihan menjatuhkan penyajian. Perbarui model melalui artefak versi baru yang telah lulus evaluasi.
  • Memaksakan real-time untuk kebutuhan yang sebenarnya boleh menunggu. Biaya operasional naik tanpa manfaat apa pun, sedangkan batch pada jadwal berikutnya sudah cukup.
  • Menghitung fitur penyajian dengan kode yang berbeda dari pelatihan. Selisih kecil pada urutan transformasi membuat distribusi masukan penyajian berbeda dari distribusi pelatihan tanpa pesan apa pun. Gunakan pipeline tersimpan yang sama untuk pelatihan dan penyajian sebagaimana dibahas pada topik persistensi model.
  • Membiarkan antrean permintaan tumbuh tanpa batas. Ketika laju permintaan melampaui kapasitas penyaji, jeda respons memanjang dan peminta layanan mengalami kegagalan waktu tunggu. Tetapkan batas antrean pada konfigurasi penyaji, lalu tolak permintaan berlebih dengan pesan yang jelas.

Ringkasan#

  • Batch memproses kumpulan baris dalam satu pekerjaan terjadwal, sedangkan real-time merespons satu permintaan segera setelah masuk.
  • Hasil prediksi kedua pola identik karena logika modelnya sama, sedangkan biayanya berbeda karena mode per permintaan membayar biaya tetap sebanyak jumlah baris.
  • Penyaji real-time sungguhan memuat artefak model sekali saat server hidup, lalu menjawab setiap permintaan melalui endpoint HTTP.
  • Pemilihan pola mengikuti batas waktu respons kebutuhan pengguna, bukan kerumitan teknis.

Referensi#