Deployment dimulai jauh sebelum server menyala: dari memisahkan hasil pelatihan menjadi artefak yang bisa dipindahkan, diaudit, dan dimuat ulang tanpa menjalankan ulang pelatihan. Skrip src/latih_model.py mempraktikkan pemisahan tersebut dengan menulis tiga berkas — bobot (model.pt), konfigurasi (config.json), dan metrik (metrik.json) — ke direktori sementara /tmp/dl_deploy_demo. Konsep pembagian artefak inilah yang dibahas pada chapter Menyimpan Model untuk Produksi
; bobot saja tidak cukup karena arsitektur dan aturan preprocessing harus menyertainya.
Konfigurasi sebagai Kontrak #
Proyek ini tidak menyimpan konstanta penting tersebar di dalam kode; seluruh ketentuan hidup di config/config.json:
{
"nama_model": "mlp-digit-mini",
"versi": "1.0.0",
"arsitektur": {
"fitur": 64,
"sembunyi": [32, 16],
"kelas": 10
},
"preprocessing": {
"normalisasi": 16.0,
"rentang_masukan": [0.0, 16.0]
},
"ambang_keyakinan": 0.9,
"metadata": {
"dataset": "sklearn.datasets.load_digits (1797 gambar 8x8)",
"pelatihan": {
"benih": 42,
"epoch": 40,
"batch": 32,
"optimizer": "Adam",
"learning_rate": 0.001
},
"perangkat": "cpu",
"pembuat": "proyek deployment-model-deep-learning"
}
}Berkas ini menjadi kontrak tiga pihak sekaligus: fungsi bangun_model membangun arsitektur MLP 64-32-16-10 dari blok arsitektur, endpoint API di Bagian 2 memvalidasi masukan memakai rentang_masukan, dan ambang ambang_keyakinan menentukan kapan respons prediksi ditandai kurang meyakinkan. Mengubah satu nilai di konfigurasi otomatis mengubah perilaku seluruh tahap tanpa menyentuh kode — konstanta tidak lagi tersembunyi di dalam logika program, dan itulah sebabnya struktur proyek ini memakai folder config/, bukan data/.
Pelatihan dan Penulisan Artefak #
Sebelum pelatihan, fungsi siapkan_data menyiapkan dataset dengan benih tetap:
def siapkan_data():
"""Dataset digits terbagi latih/validasi dengan benih tetap."""
data = load_digits()
X = data.data.astype("float32") / 16.0 # normalisasi 0..16 -> 0..1
y = data.target.astype("int64")
X_latih, X_val, y_latih, y_val = train_test_split(
X, y, test_size=0.25, random_state=BENIH, stratify=y)
return (X_latih, y_latih), (X_val, y_val)Dua detail menentukan keandalan artefak. Pembagian random_state=42 dengan stratify=y menjaga 450 sampel validasi tetap berimbang sepuluh kelasnya setiap kali skrip dijalankan, sehingga akurasi validasi bisa dibandingkan antar eksekusi. Normalisasi / 16.0 bukan angka bebas — nilainya sama dengan preprocessing.normalisasi di config.json, dan konsistensi ini yang nanti diulang oleh endpoint /predict di Bagian 2; layanan yang preprocessing-nya tidak sama dengan pelatihan akan menghasilkan prediksi meleset.
Fungsi latih_dan_simpan kemudian menjalankan pelatihan standar (Adam, learning rate dari konfigurasi, 40 epoch) lalu menulis ketiga artefak:
model.eval()
metrik = {
"akurasi_latih": round(float(akurasi_latih), 4),
"akurasi_validasi": round(float(akurasi_val), 4),
"jumlah_parameter": sum(p.numel() for p in model.parameters()),
}
direktori.mkdir(parents=True, exist_ok=True)
torch.save(model.state_dict(), direktori / "model.pt")
shutil.copyfile(JALUR_KONFIG, direktori / "config.json")
(direktori / "metrik.json").write_text(
json.dumps(metrik, indent=2) + "\n", encoding="utf-8")Tiga keputusan pada potongan ini patut dibedah. model.eval() dipanggil sebelum evaluasi agar perilaku layer cocok dengan mode inferensi. torch.save(model.state_dict(), ...) hanya menyimpan bobot, bukan seluruh objek — arsitektur dibangun ulang dari config.json oleh pemuat, pola yang direkomendasikan chapter Penyimpanan dan Pemuatan Model
. Terakhir, metrik.json ikut disimpan sehingga endpoint /health nanti bisa melaporkan akurasi validasi tanpa menghitung ulang.
Jalankan dari folder proyek:
python3 src/latih_model.pyOutput yang Dihasilkan:
== pelatihan model digit mini ==
arsitektur : 64 -> 32 -> 16 -> 10 (MLP + ReLU)
data latih : 1347 gambar
data validasi : 450 gambar
epoch / batch : 40 / 32
akurasi latih : 0.9852
akurasi validasi: 0.9511
parameter : 2778
== artefak di /tmp/dl_deploy_demo ==
model.pt : 13757 byte
config.json : 556 byte
metrik.json : 88 byte
config.json disalin dari config/ bundle; versi 1.0.0, ambang keyakinan 0.9Model sederhana 2778 parameter mencapai akurasi validasi 0.9511 (akurasi latih 0.9852 — selisih kecil yang menandakan belum terjadi overfitting berlebih). Angka ini menjadi tolok ukur: layanan yang kita bangun di bagian-bagian berikutnya wajib mempertahankan akurasi yang sama, karena tiap tahap deployment yang benar tidak boleh mengubah perilaku model.
Tiga artefak kini berdiri di /tmp/dl_deploy_demo. Bagian berikutnya memuatnya sekali ke dalam proses server lalu membuka dua endpoint: pemeriksaan kesehatan dan prediksi.