ZenML: Bikin Pipeline ML dan LLM yang Portable dan Siap Produksi

# ZenML: Bikin Pipeline ML dan LLM yang Portable dan Siap Produksi Halo temen-temen, ketemu lagi sama aku, Ruby Abdullah. Kali ini aku mau ngajak kalian ngobrol soal salah satu tools yang menurutku w...

By Ruby Abdullah · · tutorial
ZenMLMLOpsMachine LearningML PipelineMLflow

ZenML: Bikin Pipeline ML dan LLM yang Portable dan Siap Produksi

Halo temen-temen, ketemu lagi sama aku, Ruby Abdullah. Kali ini aku mau ngajak kalian ngobrol soal salah satu tools yang menurutku wajib banget dikuasai kalau kalian serius pengen kerja di dunia machine learning atau LLM secara profesional, bukan cuma main-main di notebook doang. Tools itu namanya ZenML.

Jujur ya, dulu waktu aku pertama kali belajar ML, semua proses itu aku tumpuk di satu file notebook. Load data di cell atas, training di tengah, evaluasi di bawah, terus kalau mau deploy tinggal copy-paste sana-sini. Kelihatannya cepet, tapi begitu proyeknya makin gede dan mulai masuk ke produksi, semua jadi berantakan. Susah di-reproduce, susah dilacak, dan kalau ada yang error kita bingung ngulang dari mana. Nah, di sinilah ZenML masuk buat nyelametin hidup kita.

Di artikel ini aku bakal jelasin ZenML dari nol sampai kalian bisa bikin pipeline end-to-end sendiri. Kita bahas instalasi, konsep dasar kayak @step dan @pipeline, konsep stack yang jadi jantungnya ZenML, artifacts dan caching, integrasi ke tools lain kayak MLflow, sampai gimana caranya deploy. Siap? Yuk kita mulai.

Introduction

Sebelum masuk ke kodingan, aku pengen kalian paham dulu ZenML itu sebenernya apa dan kenapa dia penting.

ZenML itu framework MLOps open-source yang tugasnya bikin workflow machine learning kalian jadi terstruktur, bisa diulang (reproducible), dan gampang dipindahin dari laptop ke cloud tanpa harus nulis ulang kode. Jadi bayangin gini, temen-temen. Kalian punya kode training model. Di laptop kalian jalan lokal. Terus bos kalian bilang, "Eh, ini pindahin ke cloud dong, pakai orchestrator Kubernetes, terus tracking-nya pakai MLflow." Kalau tanpa ZenML, kalian harus ngoprek banyak banget kode. Tapi dengan ZenML, kalian cukup ganti konfigurasi stack, dan kode inti kalian tetap sama persis. Keren kan?

Konsep utama ZenML itu ada dua: pipeline dan step. Step itu satu unit kerja, misalnya "load data" atau "train model". Pipeline itu rangkaian step-step yang saling terhubung. Nah, ZenML memisahkan antara logika ML (yang kalian tulis) dengan infrastruktur (tempat kode itu jalan). Pemisahan ini yang bikin kode kalian jadi portable banget.

Kenapa ini penting buat karier kalian? Karena di industri, yang dicari itu bukan cuma orang yang bisa bikin model akurat di notebook. Yang dicari itu orang yang bisa bawa model itu ke produksi, bisa maintain, bisa lacak eksperimen, dan bisa kolaborasi sama tim. ZenML ngajarin kalian mindset MLOps yang bener sejak awal. Jadi menurutku, belajar ZenML itu investasi yang bagus banget buat masa depan kalian.

Satu hal lagi yang aku suka dari ZenML: dia nggak maksa kalian pakai tools tertentu. Kalian mau pakai scikit-learn, PyTorch, TensorFlow, atau bahkan framework LLM kayak LangChain, semua bisa. ZenML itu sifatnya kayak lem yang nyatuin semua komponen kalian jadi satu alur yang rapi.

Instalasi

Oke, sekarang kita masuk ke bagian praktik. Instalasi ZenML itu gampang banget, cukup satu baris perintah aja.

pip install zenml

Kalau kalian mau versi yang lengkap dengan dashboard visual (dan aku saranin banget pakai ini), install versi server-nya:

pip install "zenml[server]"

Aku selalu saranin temen-temen buat pakai virtual environment biar nggak berantakan sama dependency proyek lain. Ini cara aku biasanya setup:

python -m venv zenml-env

source zenml-env/bin/activate # kalau di Windows: zenml-env\Scripts\activate

pip install "zenml[server]" scikit-learn

Setelah kelar install, kita perlu inisialisasi ZenML di dalam folder proyek kita. Ini penting karena ZenML bakal bikin folder tersembunyi .zen yang nyimpen semua konfigurasi dan metadata.

zenml init

Kalian bakal lihat pesan sukses yang bilang repository ZenML udah dibuat. Nah, buat ngecek apakah semuanya udah bener, coba jalanin perintah ini:

zenml status

Kalau kalian pengen lihat dashboard visualnya yang cakep itu, jalanin:

zenml login --local

Perintah ini bakal nge-launch server lokal dan buka browser ke dashboard ZenML. Di sini kalian bisa lihat semua pipeline yang udah kalian jalanin, step-step-nya, artifact yang dihasilkan, dan banyak lagi. Aku pribadi suka banget sama dashboard ini karena bikin debugging jadi jauh lebih gampang. Kita bisa lihat secara visual step mana yang gagal, berapa lama tiap step jalan, dan data apa yang mengalir di antara step.

Oh iya, satu tips dari aku: kalau kalian pakai versi ZenML yang agak lama, perintahnya mungkin zenml up bukan zenml login --local. Jadi kalau ada error, cek dulu versi ZenML kalian dengan zenml version. Aku nulis artikel ini berdasarkan versi ZenML yang cukup baru ya temen-temen.

Basic Usage

Sekarang bagian paling seru, kita mulai nulis kode. Aku bakal jelasin dua decorator paling penting di ZenML: @step dan @pipeline.

Bikin Step Pertama

Step itu ibarat fungsi biasa di Python, tapi kita kasih decorator @step. Decorator ini yang bikin ZenML tahu bahwa fungsi ini adalah satu unit kerja yang bisa dilacak, di-cache, dan dijalanin di infrastruktur tertentu. Coba lihat contoh sederhana ini:

from zenml import step

@step

def loaddata() -> dict:

"""Load data sederhana buat contoh."""

data = {

"features": [[1, 2], [3, 4], [5, 6], [7, 8]],

"labels": [0, 0, 1, 1],

}

return data

Gampang kan? Fungsi ini cuma balikin dictionary. Tapi karena ada decorator @step, ZenML bakal otomatis nyatet output-nya sebagai artifact dan nyimpen ke artifact store. Kita bahas artifact store nanti ya.

Satu hal penting: ZenML sangat menghargai type hints. Perhatiin aku nulis -> dict di fungsi tadi. Type hints ini bukan cuma buat gaya-gayaan, tapi ZenML pakai info ini buat nentuin gimana cara nyimpen dan ngambil artifact. Jadi biasakan selalu kasih type hints di step kalian ya temen-temen.

Bikin Pipeline

Setelah punya step, kita rangkai jadi pipeline pakai decorator @pipeline. Pipeline itu fungsi yang manggil step-step secara berurutan. Contohnya gini:

from zenml import pipeline

@pipeline

def simplepipeline():

data = loaddata()

return data

Terus buat jalaninnya, tinggal panggil aja fungsi pipeline-nya:

if name == "main":

simplepipeline()

Simpan semua kode di atas ke satu file, misalnya run.py, terus jalanin dengan python run.py. ZenML bakal eksekusi pipeline kalian, nyimpen semua artifact, dan nyatet metadata-nya. Kalau kalian buka dashboard, kalian bakal lihat pipeline ini muncul di sana lengkap dengan visualisasi alurnya.

Ngerti Alur Data Antar Step

Yang bikin ZenML powerful itu cara dia ngatur aliran data antar step. Ketika kalian nulis data = loaddata() terus data itu dipakai di step lain, ZenML otomatis paham bahwa ada dependency antara dua step itu. Dia bakal jalanin dalam urutan yang bener dan otomatis passing artifact dari satu step ke step berikutnya. Kalian nggak perlu ngurus manual gimana caranya data pindah, ZenML yang urus semua di belakang layar.

Ini beda banget sama nulis skrip biasa. Di skrip biasa, kalau ada satu bagian error, kalian harus jalanin ulang dari awal. Di ZenML, karena tiap step outputnya disimpan sebagai artifact, kalian bisa lanjutin dari step yang gagal aja tanpa ngulang dari nol. Ini yang bikin iterasi eksperimen jadi jauh lebih cepet.

Advanced Usage

Nah, sekarang kita naik level. Di bagian ini aku bakal bahas konsep-konsep yang bikin ZenML beneran siap produksi: stack, artifacts, caching, dan integrasi. Terus di akhir aku kasih contoh pipeline end-to-end lengkap.

Konsep Stack

Ini konsep paling penting di ZenML, jadi tolong diperhatiin baik-baik ya temen-temen. Stack itu kumpulan infrastruktur dan tools tempat pipeline kalian jalan. Analoginya kayak gini: kode pipeline kalian itu adalah resep masakan, dan stack itu adalah dapurnya. Resep yang sama bisa dimasak di dapur rumah atau dapur restoran, hasilnya tetap sama tapi skala dan kapasitasnya beda.

Stack terdiri dari beberapa komponen. Yang paling utama ada tiga:

Orchestrator itu yang nentuin di mana dan gimana step-step kalian dijalanin. Default-nya ZenML pakai orchestrator lokal, jadi semua jalan di mesin kalian. Tapi kalian bisa ganti ke Kubernetes, Airflow, Kubeflow, atau cloud orchestrator kayak Vertex AI dan SageMaker. Yang keren, kode kalian nggak berubah sama sekali, cukup ganti orchestrator di stack. Artifact Store itu tempat nyimpen semua output dari step kalian. Default-nya di lokal folder, tapi buat produksi kalian bisa pakai cloud storage kayak Amazon S3, Google Cloud Storage, atau Azure Blob Storage. Semua artifact tersimpan rapi dan bisa diakses ulang kapan aja. Experiment Tracker itu opsional tapi sangat berguna. Ini yang nyatet metrics, parameter, dan hasil eksperimen kalian. Yang paling populer dipakai adalah MLflow, tapi ada juga Weights & Biases dan Neptune.

Buat lihat stack yang lagi aktif, jalanin:

zenml stack describe

Dan buat lihat semua stack yang kalian punya:

zenml stack list

Ketika kalian pertama kali pakai ZenML, kalian otomatis dapet stack default yang isinya orchestrator lokal dan artifact store lokal. Ini udah cukup buat belajar dan development. Nanti kalau mau naik ke produksi, tinggal bikin stack baru.

Artifacts dan Caching

Setiap output dari step di ZenML itu disimpan sebagai artifact. Artifact ini di-version secara otomatis, jadi kalian punya histori lengkap dari semua data dan model yang pernah dihasilkan. Ini penting banget buat reproducibility. Kalau suatu saat ada yang tanya "model versi kemarin itu dilatih pakai data yang mana?", kalian bisa jawab dengan pasti karena semua tercatat.

Nah yang paling aku suka dari sistem artifact ini adalah caching. Ini fitur yang bikin ZenML super efisien. Konsepnya gini: kalau kalian jalanin ulang pipeline dan ada step yang input dan kodenya nggak berubah sama sekali, ZenML nggak bakal jalanin ulang step itu. Dia langsung ambil hasilnya dari cache. Bayangin kalian punya step preprocessing data yang makan waktu 10 menit. Kalau kalian cuma ngubah step training, kalian nggak perlu nunggu 10 menit lagi buat preprocessing, ZenML langsung pakai hasil cache. Hemat waktu banget.

Caching ini aktif secara default. Tapi kalau kalian mau matiin caching buat step tertentu, misalnya step yang ngambil data real-time yang selalu berubah, kalian bisa atur kayak gini:

from zenml import step

@step(enablecache=False)

def fetchrealtimedata() -> dict:

"""Step ini selalu jalan ulang, nggak pakai cache."""

# ambil data terbaru dari API

return {"data": "selalu fresh"}

Kalian juga bisa matiin caching di level pipeline dengan @pipeline(enablecache=False). Fleksibel banget kan.

Integrasi dengan MLflow dan Cloud

ZenML punya puluhan integrasi bawaan. Buat install integrasi, kalian pakai perintah zenml integration install. Misalnya buat MLflow:

zenml integration install mlflow -y

Setelah itu, kalian daftarin experiment tracker MLflow ke ZenML terus masukin ke stack:

zenml experiment-tracker register mlflowtracker --flavor=mlflow

zenml stack register mlflowstack -o default -a default -e mlflowtracker --set

Perintah di atas bikin stack baru bernama mlflowstack yang pakai orchestrator default, artifact store default, dan experiment tracker MLflow. Flag --set langsung ngeaktifin stack ini. Nah setelah itu, di dalam step training kalian tinggal aktifin experiment tracker-nya:

from zenml import step

from zenml.client import Client

experimenttracker = Client().activestack.experimenttracker

@step(experimenttracker=experimenttracker.name)

def trainwithtracking(data: dict) -> float:

import mlflow

mlflow.sklearn.autolog()

# kode training kalian di sini

accuracy = 0.95

mlflow.logmetric("accuracy", accuracy)

return accuracy

Buat cloud, konsepnya sama. Misalnya kalian mau pakai AWS, install integrasi s3 dan aws, daftarin artifact store yang nunjuk ke bucket S3 kalian, terus daftarin orchestrator cloud. Sekali lagi, kode pipeline kalian nggak berubah. Ini kekuatan utama ZenML yang berkali-kali aku tekanin: pisahin logika dari infrastruktur.

Contoh Pipeline End-to-End

Oke temen-temen, sekarang kita gabung semua yang udah kita pelajarin jadi satu pipeline lengkap: load data, train, evaluate. Aku pakai dataset Iris dari scikit-learn biar semua orang bisa langsung coba. Ini kode lengkapnya, tinggal copy dan jalanin:

from zenml import step, pipeline

from typing import Tuple

from typingextensions import Annotated

import pandas as pd

from sklearn.datasets import loadiris

from sklearn.modelselection import traintestsplit

from sklearn.ensemble import RandomForestClassifier

from sklearn.base import ClassifierMixin

@step

def loaddata() -> Tuple[

Annotated[pd.DataFrame, "Xtrain"],

Annotated[pd.DataFrame, "Xtest"],

Annotated[pd.Series, "ytrain"],

Annotated[pd.Series, "ytest"],

]:

"""Load dataset Iris dan split jadi train dan test."""

iris = loadiris(asframe=True)

X = iris.data

y = iris.target

Xtrain, Xtest, ytrain, ytest = traintestsplit(

X, y, testsize=0.2, randomstate=42

)

return Xtrain, Xtest, ytrain, ytest

@step

def trainmodel(

Xtrain: pd.DataFrame, ytrain: pd.Series

) -> ClassifierMixin:

"""Latih model Random Forest."""

model = RandomForestClassifier(nestimators=100, randomstate=42)

model.fit(Xtrain, ytrain)

return model

@step

def evaluatemodel(

model: ClassifierMixin, Xtest: pd.DataFrame, ytest: pd.Series

) -> float:

"""Evaluasi akurasi model di data test."""

accuracy = model.score(Xtest, ytest)

print(f"Akurasi model: {accuracy:.4f}")

return accuracy

@pipeline

def trainingpipeline():

Xtrain, Xtest, ytrain, ytest = loaddata()

model = trainmodel(Xtrain, ytrain)

accuracy = evaluatemodel(model, Xtest, ytest)

return accuracy

if name == "main":

trainingpipeline()

Coba perhatiin baik-baik kode di atas. Ada tiga step: loaddata, trainmodel, dan evaluatemodel. Di loaddata aku pakai Annotated buat kasih nama ke tiap output artifact, jadi di dashboard nanti kelihatan jelas mana Xtrain, mana ytest, dan seterusnya. Ini best practice yang bikin pipeline kalian jauh lebih mudah dibaca.

Di pipeline, aku cuma rangkai ketiga step itu. ZenML otomatis paham bahwa trainmodel butuh output dari loaddata, dan evaluatemodel butuh output dari trainmodel dan loaddata. Dia atur urutannya sendiri. Jalanin python run.py, terus buka dashboard, dan kalian bakal lihat DAG (Directed Acyclic Graph) yang cakep nunjukin alur pipeline kalian.

Coba jalanin dua kali. Di run kedua, kalau kalian nggak ngubah apa-apa, perhatiin ZenML bakal bilang step-nya "cached". Itu tadi yang kita bahas soal caching. Sekarang coba ubah nestimators di trainmodel jadi 50, terus jalanin lagi. Kali ini step loaddata tetap cached (karena nggak berubah), tapi trainmodel dan evaluatemodel bakal jalan ulang. Efisien banget kan.

Deploy dan Serving

Setelah model kalian jadi, langkah berikutnya adalah deploy biar bisa dipakai buat prediksi. ZenML punya beberapa cara buat ini. Yang paling umum adalah pakai integrasi model deployer kayak MLflow, Seldon, atau BentoML.

Konsepnya, kalian tambahin step deployment ke pipeline kalian. Step ini bakal ambil model yang udah dilatih terus deploy jadi sebuah endpoint API yang bisa nerima request prediksi. Contoh sederhana pakai MLflow deployer, kalian install dulu integrasinya:

zenml integration install mlflow -y

zenml model-deployer register mlflowdeployer --flavor=mlflow

Terus di pipeline, kalian bisa tambahin step buat deploy model yang lolos threshold akurasi tertentu. Jadi model yang jelek nggak akan ke-deploy. Ini namanya continuous deployment pipeline, salah satu pola MLOps yang paling powerful. Model kalian bakal jadi endpoint yang siap nerima request, dan kalian bisa kirim data baru buat dapet prediksi secara real-time.

Buat produksi beneran, biasanya kalian bakal jalanin pipeline ini secara terjadwal pakai orchestrator kayak Airflow atau Kubeflow, terus deploy ke cluster Kubernetes. Sekali lagi, karena arsitektur ZenML yang pisahin logika dari infrastruktur, transisi dari lokal ke produksi jadi mulus banget.

Best Practices

Setelah aku cukup lama pakai ZenML di berbagai proyek, ada beberapa best practices yang pengen aku bagi ke temen-temen biar kalian nggak ngulang kesalahan yang aku bikin dulu.

Pertama, selalu pakai type hints yang jelas. Aku udah bilang ini di awal tapi aku ulang lagi karena penting. Type hints bukan cuma bikin kode kalian rapi, tapi ZenML pakai info ini buat serialisasi artifact. Kalau type hints kalian salah atau nggak ada, kalian bisa dapet error yang membingungkan. Jadi biasakan nulis type hints yang bener di setiap input dan output step. Kedua, bikin step yang kecil dan fokus. Jangan bikin satu step raksasa yang ngerjain semuanya. Pisahin jadi step-step kecil yang masing-masing punya satu tanggung jawab. Ini bikin caching kalian lebih efektif (karena step yang nggak berubah bisa di-cache), dan bikin debugging lebih gampang (kalau ada error, kalian tahu persis step mana yang bermasalah). Ketiga, manfaatin caching dengan bijak. Caching itu teman kalian, tapi hati-hati sama step yang harusnya selalu fresh, kayak step yang ngambil data dari sumber eksternal yang berubah terus. Buat step kayak gitu, matiin caching dengan enable
cache=False. Sebaliknya, buat step yang berat dan deterministik, biarin caching aktif biar iterasi kalian cepet. Keempat, pisahkan konfigurasi dari kode. Jangan hardcode parameter kayak learning rate atau jumlah epoch langsung di kode. ZenML support file konfigurasi YAML tempat kalian bisa taruh semua parameter. Jadi kalian bisa ubah eksperimen tanpa nyentuh kode sama sekali. Ini bikin kolaborasi tim jauh lebih rapi. Kelima, mulai dari stack lokal, baru naik ke cloud. Jangan langsung setup infrastruktur cloud yang ribet dari awal. Develop dan test dulu di stack lokal sampai pipeline kalian jalan mulus. Baru setelah yakin, kalian pindah ke stack produksi. Karena kode kalian portable, transisi ini nggak akan nyusahin. Keenam, konsisten pakai experiment tracker. Dari awal proyek, biasakan pakai experiment tracker kayak MLflow. Jangan nunggu sampai proyek gede baru mikir soal tracking. Nyatet semua eksperimen dari awal bakal nyelametin kalian ketika perlu bandingin puluhan model buat cari yang terbaik. Ketujuh, kasih nama artifact yang deskriptif. Pakai Annotated buat kasih nama artifact kalian kayak yang aku contohin tadi. Di dashboard, artifact yang punya nama jelas jauh lebih mudah dilacak daripada yang cuma "output0", "output1".

Conclusion

Oke temen-temen, kita udah sampai di penghujung artikel. Kita udah bahas banyak banget hal soal ZenML. Kita mulai dari instalasi dan inisialisasi, terus masuk ke konsep dasar @step dan @pipeline. Lanjut ke konsep yang lebih dalam kayak stack dengan tiga komponen utamanya (orchestrator, artifact store, experiment tracker), sistem artifact dan caching yang super efisien, integrasi ke MLflow dan cloud, sampai contoh pipeline end-to-end lengkap dari load data, train, sampai evaluate. Kita juga udah ngebahas gimana caranya deploy model dan sekumpulan best practices dari pengalamanku.

Kalau aku boleh rangkum satu pelajaran paling penting dari ZenML, itu adalah pisahin logika ML dari infrastruktur. Ini prinsip yang bikin kode kalian portable, reproducible, dan siap produksi. Dengan ZenML, kalian bisa fokus ke bagian yang bener-bener penting, yaitu bikin model yang bagus, tanpa harus pusing mikirin gimana caranya kode itu jalan di infrastruktur yang berbeda-beda.

Buat kalian yang serius pengen berkarier di dunia machine learning dan LLM, aku sangat menyarankan buat mendalami ZenML. Skill MLOps kayak gini yang bakal ngebedain kalian dari kebanyakan orang yang cuma bisa main di notebook. Mulai dari proyek kecil, coba bikin pipeline sederhana kayak yang aku contohin tadi, terus pelan-pelan naikin kompleksitasnya. Nanti kalian bakal ngerasain sendiri betapa nyamannya kerja dengan workflow yang terstruktur.

Sekian dari aku. Semoga artikel ini bermanfaat dan bikin kalian makin semangat belajar. Kalau ada pertanyaan, jangan ragu buat cari aku ya. Selamat ngoding, dan sampai ketemu di artikel berikutnya. Semangat terus temen-temen.

Artikel Terkait

MLflow vs Neptune.ai: Panduan Lengkap Experiment Tracking untuk MLOps

MLflow vs Neptune.ai: Panduan Lengkap Experiment Tracking untuk MLOps Experiment tracking adalah komponen krusial dalam ...

Tutorial Lengkap MLflow: Dari Setup hingga Production

Pendahuluan MLflow adalah platform open-source untuk mengelola end-to-end machine learning lifecycle. Dikembangkan oleh ...

Tutorial Lengkap Replicate: Menjalankan dan Deploy Model ML via API

Tutorial Lengkap Replicate: Menjalankan dan Deploy Model ML via API Replicate adalah platform cloud yang memungkinkan An...

Tutorial Lengkap Comet ML: Platform MLOps untuk Experiment Tracking dan Model Management

Tutorial Lengkap Comet ML: Platform MLOps untuk Experiment Tracking dan Model Management Dalam dunia machine learning mo...