Semua bab sebelumnya berdiri di atas satu asumsi tersirat: deployment berhasil dan model baru memang lebih baik. Bab ini membahas saat asumsi itu gagal — model versi baru di-deploy, metrik produksi merosot, dan setiap menit berarti keputusan yang salah terus dibuat. Kemampuan membatalkan rilis dengan cepat dan terkendali bukan tanda kegagalan tim; ia adalah ukuran kematangan operasional. Pete Hodgson, praktisi continuous delivery, merangkumnya dalam satu kalimat yang sering dikutip: tim yang baik bukan yang tidak pernah gagal, melainkan yang bisa membatalkan kegagalannya dalam hitungan menit. Chapter penutup section ini mensimulasikan siklus lengkap update — deploy, deteksi, rollback — lalu merangkum keseluruhan MLOps.
Strategi Update #
| Strategi | Cara kerja | Saat cocok |
|---|---|---|
| big-bang | versi baru langsung melayani seluruh traffic | perubahan kecil, risiko rendah, sistem non-kritis |
| gradual (canary/berperingkat) | versi baru diuji pada sebagian traffic dulu | perubahan perilaku signifikan, pengguna banyak |
| rollback siap | versi lama tetap termuat; alihkan rute saat bermasalah | prasyarat kedua strategi di atas |
Pembahasan lengkap jalur bertahap ada di chapter Continuous Deployment . Di sini fokusnya adalah sisi yang jarang dibahas: apa yang membuat rollback cepat. Jawabannya satu frasa — warm standby: versi lama tetap termuat di memori (atau siap dimuat dalam hitungan detik), sehingga rollback hanya mengubah rute traffic, bukan memuat ulang model. Kontras dengan cold standby: berkas versi lama ada di penyimpanan tetapi tidak termuat — rollback berarti menunggu proses memuat, validasi, dan pemanasan ulang, dan selama itu sistem terus melayani dengan model yang bermasalah.
Alur keputusan pasca-deploy membentuk lingkar berikut:
Data Migration dan Komunikasi #
Rollback model jarang berdiri sendiri. Dua hal biasanya ikut dipertaruhkan. Pertama, data migration: bila v2 menyimpan prediksi dengan skema baru atau format output berbeda, rollback ke v1 bisa menemukan data yang tidak lagi cocok skema pembacanya. Praktik amannya dua arah: skema baru harus kompatibel mundur (v1 membaca tetapi mengabaikan field baru), dan data selama masa v2 disimpan sedemikian rupa agar bisa dibaca ulang. Kedua, komunikasi perubahan: pengguna internal dan eksternal perlu tahu bahwa perilaku sistem berubah — dan saat rollback terjadi, bahwa ia berubah kembali. Catatan perubahan (changelog) per versi dan notifikasi pemangku kepentingan adalah bagian operasional yang sama pentingnya dengan kode.
Contoh Teruji: Update dengan Rollback Otomatis #
Berkas update_rollback.py menyiapkan v1 yang sehat dan v2 yang dilatih pada data bergeser. v2 di-deploy penuh, monitoring mengukur akurasi nyata per jendela pada arus data produksi, dan dua pelanggaran berturut-turut memicu rollback otomatis ke v1 yang tetap termuat:
"""Simulasi update model dengan rollback otomatis.
v2 dilatih pada data yang bergeser dan di-deploy menggantikan v1.
Monitoring per jendela mengukur akurasi nyata dari prediksi v2 pada
arus data produksi. Dua jendela berturut-turut di bawah ambang
memicu rollback otomatis ke v1 yang tetap siap sebagai warm standby.
"""
import numpy as np
AMBANG_AKURASI = 0.85
PELANGGARAN_PERLU = 2
N_PER_JENDELA = 300
def buat_data(seed, geser=0.0):
"""Dua gumpalan Gaussian; geser memindahkan distribusi data latih."""
rng = np.random.default_rng(seed)
kelas0 = rng.normal(loc=[-1.0 + geser, 0.0], scale=0.7, size=(120, 2))
kelas1 = rng.normal(loc=[1.0 + geser, 0.4], scale=0.7, size=(120, 2))
X = np.vstack([kelas0, kelas1])
y = np.array([0] * 120 + [1] * 120)
urut = rng.permutation(len(y))
return X[urut], y[urut]
def latih(X, y, epoch=300):
w = np.zeros(3)
for _ in range(epoch):
skor = np.clip(X @ w[1:] + w[0], -30, 30)
p = 1.0 / (1.0 + np.exp(-skor))
galat = p - y
w[1:] -= (X.T @ galat) / len(y)
w[0] -= galat.mean()
return w
def akurasi(w, X, y):
return float((((X @ w[1:] + w[0] >= 0).astype(int)) == y).mean())
def main():
# arus data produksi: distribusi seperti saat v1 dilatih
X_prod, y_prod = buat_data(seed=99)
# v1: data normal; v2: data latih bergeser (update yang buruk)
v1 = latih(*buat_data(seed=42), epoch=300)
v2 = latih(*buat_data(seed=44, geser=1.5), epoch=300)
print("== pra-deploy: evaluasi kedua versi ==")
print(f" v1 akurasi pada data produksi : {akurasi(v1, X_prod, y_prod):.3f}")
print(f" v2 akurasi pada data produksi : {akurasi(v2, X_prod, y_prod):.3f}")
print(f" ambang rollback : {AMBANG_AKURASI}")
print(" v2 di-deploy penuh; v1 tetap dimuat (warm standby)\n")
rng = np.random.default_rng(7)
model_aktif, nama_aktif = v2, "v2"
pelanggaran = 0
print("== monitoring pasca-deploy ==")
for t in range(1, 6):
idx = rng.choice(len(y_prod), size=N_PER_JENDELA, replace=True)
ak = akurasi(model_aktif, X_prod[idx], y_prod[idx])
if ak >= AMBANG_AKURASI:
pelanggaran = 0
print(f" jendela {t} [{nama_aktif}]: akurasi {ak:.3f} — OK")
else:
pelanggaran += 1
print(f" jendela {t} [{nama_aktif}]: akurasi {ak:.3f} — "
f"DI BAWAH AMBANG (pelanggaran {pelanggaran})")
if (pelanggaran >= PELANGGARAN_PERLU
and model_aktif is v2):
model_aktif, nama_aktif = v1, "v1"
pelanggaran = 0
print(f" -> ROLLBACK OTOMATIS: traffic dialihkan ke v1 "
f"(warm standby, tanpa pelatihan ulang)")
print("\n== status akhir ==")
print(f"model aktif : {nama_aktif}")
print(f"v2 dicabut dari serving; penyebabnya perlu diperiksa "
"sebelum update berikutnya")
if __name__ == "__main__":
main()Output yang Dihasilkan:
== pra-deploy: evaluasi kedua versi ==
v1 akurasi pada data produksi : 0.921
v2 akurasi pada data produksi : 0.629
ambang rollback : 0.85
v2 di-deploy penuh; v1 tetap dimuat (warm standby)
== monitoring pasca-deploy ==
jendela 1 [v2]: akurasi 0.647 — DI BAWAH AMBANG (pelanggaran 1)
jendela 2 [v2]: akurasi 0.640 — DI BAWAH AMBANG (pelanggaran 2)
-> ROLLBACK OTOMATIS: traffic dialihkan ke v1 (warm standby, tanpa pelatihan ulang)
jendela 3 [v1]: akurasi 0.917 — OK
jendela 4 [v1]: akurasi 0.937 — OK
jendela 5 [v1]: akurasi 0.903 — OK
== status akhir ==
model aktif : v1
v2 dicabut dari serving; penyebabnya perlu diperiksa sebelum update berikutnyaMari kita telaah kode di atas baris per baris:
- Baris 44-47 (v1 dan v2): kedua model dilatih dan keduanya tetap di memori — v1 sebagai warm standby, v2 sebagai kandidat. Baris inilah perbedaan teknis konkret antara warm dan cold standby: tidak ada pemanggilan
muat_versidi tengah insiden. - Baris 49-53 (pra-deploy): kedua versi dievaluasi pada data produksi sebelum deploy. Angka v2 (0.629) sebenarnya sudah memberi peringatan — dalam praktik, angka seperti ini menahan v2 di gerbang registry dari chapter Model Registry dan deployment tidak boleh terjadi; simulasi ini sengaja meloloskannya untuk memperlihatkan jalur pemulihan.
- Baris 59-61 (monitoring): setiap jendela mengambil 300 sampel dari arus produksi dengan
rng.choice(replace=True)— request nyata bisa berulang, jadi sampling dengan pengembalian lebih mirip kenyataan. Akurasi dihitung dari prediksi model yang sedang aktif. - Baris 62-75 (keputusan per jendela): pelanggaran dihitung beruntun; dua pelanggaran berturut-turut pada v2 memicu pengalihan
model_aktifke v1 — satu baris penugasan, karena v1 sudah termuat. Jendela 3-5 setelahnya dievaluasi dengan v1 dan kembali sehat: 0.917, 0.937, 0.903. - Baris 76-79 (status akhir): penutup mencatat v2 dicabut dan penyebabnya perlu diperiksa — rollback memulihkan layanan, tetapi tidak menghapus kewajiban memahami kegagalan. Data latih v2 yang bergeser (masalah drift dari chapter Data dan Model Drift ) tetap harus ditelusuri sebelum update berikutnya.
Kronologi keluaran memperlihatkan bentuk kurva insiden yang sehat: dua jendela bermasalah (0.647, 0.640), rollback, lalu pemulihan. Total jendela waktu pengguna menerima prediksi buruk: dua dari lima — dan pada sistem nyata dengan ambang serta monitoring yang sama, angka itu adalah selisih antara insiden sepuluh menit dan insiden semalam.
Sintesis: Siklus MLOps #
Sepuluh chapter section ini kini membentuk satu lingkaran utuh. Experiment Management mencatat setiap percobaan; Model Versioning memberi artifact identitas permanen; Model Registry menjadi sumber kebenaran status versi; Pipeline Training Otomatis menjalankan semuanya tanpa menunggu manusia; Continuous Integration menguji setiap perubahan; Continuous Deployment merilisnya dengan eksposur terkendali; Data dan Model Drift dan Monitoring Kinerja Model mengawasi dunia yang terus berubah; Reproducibility dan Audit menjaga jejak yang bisa diverifikasi; dan rollback menutup lingkaran dengan jaminan bahwa kegagalan bisa dibatalkan cepat. Model produksi yang dikelola siklus ini bukan lagi artefak sekali jadi — ia menjadi sistem yang terus belajar, terukur, dan bisa dipulihkan.
Dengan fondasi operasional selesai, Course bergerak ke wilayah yang semakin menekan: keamanan, etika, dan keandalan — tempat model berhadapan dengan penyalahgunaan, privasi, dan konsekuensi sosial dari keputusannya.