Veri bilimi ve makine öğrenimi projeleri, geliştirme, test ve dağıtım süreçlerinde karmaşıklıklarla doludur. Bulut tabanlı çözümler cazip görünse de, lokal bir ortamda “bulut benzeri” bir deneyim sunarak maliyetleri düşürmek, performansı artırmak ve veri gizliliğini sağlamak mümkün mü? Evet, Docker Compose ile bu hedefe ulaşabilir, MLOps süreçlerinizi yerel makinenizde bile verimli bir şekilde yönetebilirsiniz.
Makine Öğrenimi Operasyonları (MLOps), makine öğrenimi modellerini geliştirme, dağıtma ve yönetme süreçlerini otomatikleştiren ve standartlaştıran bir kültürel ve mühendislik yaklaşımıdır. Geliştirme, test ve üretim arasındaki boşluğu kapatmayı hedefler. Temelde, bir modelin fikirden üretime kadar olan tüm yaşam döngüsünü kapsar. Bu süreç; veri hazırlığı, model eğitimi, model sürümleme, model dağıtımı, model izleme ve sürekli yeniden eğitim gibi adımları içerir.
Özellikle veri bilimcileri için, farklı bağımlılıklarla çalışan birden fazla proje üzerinde çalışmak oldukça yaygın bir durumdur. Bir projenin Python 3.8’e ihtiyacı varken, diğeri yalnızca Python 3.10 ile uyumlu olabilir. Bu tür senaryolar, geliştirme ortamı yönetimini bir kabusa dönüştürebilir. İşte tam da bu noktada konteynerizasyon devreye giriyor. Konteynerler, bir uygulamanın ve tüm bağımlılıklarının izole edilmiş, taşınabilir bir ortamda paketlenmesini sağlar. Bu sayede, uygulamanızın farklı ortamlarda (yerel makine, test sunucusu, bulut) aynı şekilde çalışacağından emin olabilirsiniz.
Docker, konteyner teknolojisinin en popüler uygulayıcılarından biridir. Docker ile uygulamalarınızı hafif, taşınabilir ve kendi bağımlılıklarını içeren “Docker imajları” haline getirirsiniz. Bu imajlar, çalıştırıldığında konteyner adı verilen izole edilmiş ortamlar oluşturur. Her konteyner, kendi işletim sistemi katmanına sahip gibi davranır, ancak temel işletim sistemi çekirdeğini paylaşır. Bu durum, sanal makinelerden (VM) çok daha verimli olmalarını sağlar, çünkü VM’ler her biri kendi tam işletim sistemi kopyasını çalıştırır.
Peki ya birden fazla servisin (örneğin, bir veritabanı, bir web uygulaması ve bir MLflow izleme sunucusu) bir arada çalışması gerekiyorsa? İşte burada Docker Compose devreye girer. Docker Compose, birden fazla Docker konteynerini içeren uygulamaları tanımlamak ve çalıştırmak için bir araçtır. Tek bir YAML dosyası kullanarak, uygulamanızın tüm servislerini, ağlarını ve depolama birimlerini yapılandırabilirsiniz. Bu, karmaşık çoklu hizmet mimarilerini tek bir komutla kolayca ayağa kaldırmanıza olanak tanır. Böylece, veri bilimi projeleriniz için gereken tüm bileşenleri, tıpkı bulutta olduğu gibi, tek bir orkestrasyon mekanizmasıyla yönetebilirsiniz.
Özetle, MLOps, bir modelin yaşam döngüsünü yönetmek için bir çerçeve sunarken, Docker ve Docker Compose bu çerçeveyi pratikte uygulamanıza olanak tanıyan güçlü araçlardır. Geliştirme ortamınızın taşınabilirliğini, tekrarlanabilirliğini ve ölçeklenebilirliğini artırarak, veri bilimcilerin daha verimli çalışmasını sağlarlar. Özellikle yerel makinenizde bulut benzeri bir geliştirme ve test ortamı kurmak istediğinizde, bu üçlünün gücünü göz ardı etmek büyük bir hata olur.
Neden Lokal MLOps Çözümlerine İhtiyaç Duyuyoruz? Bulutun Ötesindeki Avantajlar Nelerdir?
Günümüz veri bilimi projelerinde bulut bilişim platformları (AWS, Google Cloud, Azure vb.) yaygın olarak kullanılsa da, bu platformların getirdiği bazı zorluklar ve sınırlamalar da mevcuttur. İşte tam da bu noktada, lokal MLOps çözümlerine duyulan ihtiyaç belirginleşir. Bulutun sunduğu kolaylıkların yanı sıra, lokal bir kurulumun getirdiği eşsiz avantajlar, birçok veri bilimci ve kuruluş için kritik öneme sahiptir.
Öncelikle, maliyet faktörü çoğu zaman en büyük itici güçtür. Bulut servisleri, özellikle büyük ölçekli veri setleri ve yoğun hesaplama gerektiren modellerle çalışırken, önemli maliyetler yaratabilir. Geliştirme aşamasında bile, sürekli açıp kapanan sanal makineler, depolama alanları ve özel servisler, faturaların hızla yükselmesine neden olabilir. Lokal bir kurulumda ise, mevcut donanım kaynaklarınızı kullanarak bu maliyetleri büyük ölçüde düşürebilirsiniz. Özellikle prototipleme ve deney aşamalarında, bulut maliyetlerini düşünmeden sınırsız deneme yapma özgürlüğü, inovasyonu hızlandırır.
İkinci olarak, veri gizliliği ve güvenliği giderek daha hassas bir konu haline gelmektedir. Özellikle kişisel veriler veya hassas kurumsal bilgilerle çalışırken, verilerin bulut ortamına taşınması yasal düzenlemeler (GDPR, KVKK gibi) veya şirket politikaları nedeniyle mümkün olmayabilir veya ek güvenlik önlemleri gerektirebilir. Lokal bir MLOps ortamı, verilerinizin şirket ağınız içinde kalmasını sağlayarak bu tür endişeleri ortadan kaldırır. Bu, özellikle sağlık, finans ve kamu sektöründeki kuruluşlar için hayati bir avantajdır.
Üçüncüsü, geliştirme hızı ve tekrarlanabilirlik. Lokal bir ortamda, bağımlılıkları yönetmek ve farklı servisleri entegre etmek, genellikle bulut platformlarının karmaşık yapılandırmalarından daha hızlıdır. Docker Compose sayesinde, tek bir komutla tüm geliştirme ortamınızı ayağa kaldırabilir, hızlıca değişiklikler yapıp test edebilir ve aynı ortamı ekip üyeleri arasında kolayca paylaşabilirsiniz. Bu, “benim makinemde çalışıyordu” sendromunu ortadan kaldırır ve ekip içinde tutarlı bir geliştirme deneyimi sağlar. Ayrıca, internet bağlantısına bağımlı olmadan çalışabilme yeteneği, saha çalışmalarında veya bağlantının zayıf olduğu durumlarda büyük bir esneklik sunar.
Dördüncü bir avantaj, vendor lock-in’den (satıcıya bağımlılık) kaçınmaktır. Bulut platformları genellikle kendi ekosistemlerine özgü servisler ve API’ler sunar. Bir kez bu ekosisteme entegre olduğunuzda, başka bir bulut sağlayıcıya veya on-premise çözümlere geçiş yapmak zaman alıcı ve maliyetli olabilir. Lokal MLOps çözümleri, açık kaynaklı araçları (MLflow, Jupyter, PostgreSQL vb.) Docker konteynerlerinde kullanarak bu bağımlılığı azaltır. Böylece, gelecekteki teknoloji değişikliklerine veya iş ihtiyaçlarına daha kolay adapte olabilirsiniz.
Son olarak, performans ve düşük gecikme süresi bazı senaryolarda kritik olabilir. Büyük veri kümeleriyle çalışırken veya gerçek zamanlı çıkarım (real-time inference) gerektiren uygulamalar geliştirirken, verilerin ağ üzerinden buluta gidip gelmesi ek gecikmeler yaratabilir. Lokal bir kurulumda, verileriniz ve hesaplama kaynaklarınız fiziksel olarak birbirine yakın olduğu için, bu gecikmeler en aza indirilir ve daha yüksek performans elde edilebilir. Tüm bu nedenler göz önüne alındığında, lokal MLOps çözümleri, bulutun vazgeçilmez bir alternatifi olmaktan ziyade, onu tamamlayan güçlü bir strateji olarak öne çıkmaktadır.
Docker Compose ile Bulut Benzeri Bir Geliştirme Ortamı Nasıl Kurulur? Adım Adım Rehber
Veri bilimi projelerinde, tekrarlanabilir, izole edilmiş ve kolayca kurulabilen bir geliştirme ortamı hayati önem taşır. Docker Compose, bu ihtiyacı karşılamak için mükemmel bir araçtır. Gelin, bir veri bilimi projesi için temel bileşenleri (JupyterLab, bir veritabanı ve MLflow) içeren bulut benzeri bir lokal ortamı nasıl kuracağımızı adım adım inceleyelim.
Adım 1: Docker’ı Kurun ve Temel Yapıyı Oluşturun
Öncelikle, sisteminizde Docker Desktop’ın (Windows/macOS için) veya Docker Engine’in (Linux için) kurulu olduğundan emin olun. Kurulum talimatları için Docker’ın resmi web sitesini ziyaret edebilirsiniz. Kurulumdan sonra, projeniz için yeni bir dizin oluşturun ve içine girin:
mkdir my_mlops_project
cd my_mlops_project
Bu dizinde, Docker Compose yapılandırma dosyamızı, yani docker-compose.yml dosyasını oluşturacağız. Bu dosya, tüm servislerimizi, ağlarımızı ve depolama birimlerimizi tanımlayacağımız merkezi yerdir.
Adım 2: docker-compose.yml Dosyasını Yapılandırın
Şimdi, docker-compose.yml dosyasını oluşturup aşağıdaki içeriği ekleyelim. Bu örnek, JupyterLab tabanlı bir geliştirme ortamı, PostgreSQL veritabanı ve MLflow izleme sunucusu içeriyor.
version: '3.8'
services:
jupyter:
image: jupyter/scipy-notebook:latest # Ya da kendi özel Docker imajınız
ports:
- "8888:8888" # Jupyter Lab erişimi
volumes:
- ./notebooks:/home/jovyan/work # Notebook'ları kalıcı depolama
- ./data:/home/jovyan/data # Veri dosyalarını kalıcı depolama
environment:
JUPYTER_ENABLE_LAB: "yes"
GRANT_SUDO: "yes"
user: root # Gerekirse dosya izinleri için
depends_on:
- postgres
- mlflow_server
networks:
- mlops_network
postgres:
image: postgres:13 # İstediğiniz PostgreSQL sürümü
environment:
POSTGRES_DB: mlops_db
POSTGRES_USER: user
POSTGRES_PASSWORD: password
volumes:
- postgres_data:/var/lib/postgresql/data # Veritabanı verileri için kalıcı depolama
networks:
- mlops_network
mlflow_server:
image: ghcr.io/mlflow/mlflow:latest # MLflow'un resmi Docker imajı
environment:
MLFLOW_TRACKING_URI: http://mlflow_server:5000
MLFLOW_BACKEND_STORE_URI: postgresql://user:password@postgres:5432/mlops_db
MLFLOW_DEFAULT_ARTIFACT_ROOT: s3://mlflow-artifacts # S3 gibi bir yer belirtilmeli, lokal için dosya sistemi kullanılabilir
command: mlflow server --host 0.0.0.0 --port 5000 --backend-store-uri postgresql://user:password@postgres:5432/mlops_db --artifacts-destination ./mlruns
ports:
- "5000:5000" # MLflow UI erişimi
volumes:
- ./mlruns:/mlruns # MLflow artifact'ları için kalıcı depolama
depends_on:
- postgres
networks:
- mlops_network
volumes:
postgres_data: # PostgreSQL verileri için özel bir volume
networks:
mlops_network:
driver: bridge # Tüm servisler için ortak bir ağ
Bu yapılandırma dosyasında dikkat edilmesi gereken önemli noktalar:
version: '3.8': Docker Compose dosyasının versiyonunu belirtir.services: Çalıştırılacak konteynerleri tanımlar. Her servis bir uygulamayı veya bir bileşeni temsil eder.image: Konteynerin temelini oluşturan Docker imajını belirtir (örn.jupyter/scipy-notebook:latest).ports: Yerel makineniz ile konteyner arasındaki port eşleştirmelerini yapar (örn.8888:8888).volumes: Verilerinizi konteyner yeniden başlatıldığında bile kaybetmemenizi sağlayan kalıcı depolama birimleridir../notebooks:/home/jovyan/workifadesi, yerelnotebooksdizininizi Jupyter konteynerindeki/home/jovyan/workdiziniyle eşleştirir.postgres_datagibi isimlendirilmiş bir volume ise, Docker tarafından yönetilen kalıcı bir depolama alanıdır.environment: Konteyner içinde ayarlanacak ortam değişkenlerini tanımlar.depends_on: Servisler arasındaki bağımlılıkları belirtir. Örneğin, Jupyter'ın başlaması için PostgreSQL ve MLflow'un hazır olması gerekir.networks: Konteynerlerin birbirleriyle iletişim kurmasını sağlayan ağları tanımlar. Tüm servislermlops_networkağına bağlı olduğu için birbirlerini isimleriyle çağırabilirler (örn.postgres:5432).command: Konteyner başlatıldığında çalışacak komutu belirtir (MLflow sunucusu için).
Adım 3: Dizinsel Yapıyı Hazırlayın
docker-compose.yml dosyasında belirtilen kalıcı depolama birimleri (volumes) için yerel dizinleri oluşturmanız gerekir:
mkdir notebooks
mkdir data
mkdir mlruns
Bu dizinler, Jupyter notebook'larınız, veri setleriniz ve MLflow log'larınız için kullanılacaktır.
Adım 4: Ortamı Başlatın
Tüm yapılandırmaları tamamladıktan sonra, projenizin ana dizininde (docker-compose.yml dosyasının bulunduğu yer) aşağıdaki komutu çalıştırarak tüm servisleri başlatabilirsiniz:
docker compose up -d
-d parametresi, konteynerleri arka planda (detached mode) çalıştırmanızı sağlar, böylece terminalinizi serbest bırakabilirsiniz. Konteyner imajları ilk çalıştırmada indirileceği için bu işlem biraz zaman alabilir.
Adım 5: Servislere Erişim
Konteynerleriniz çalışmaya başladıktan sonra, aşağıdaki adreslerden servislere erişebilirsiniz:
- JupyterLab: Tarayıcınızda http://localhost:8888 adresine gidin. Terminalinizde görüntülenen token ile giriş yapmanız istenebilir.
- MLflow UI: Tarayıcınızda http://localhost:5000 adresine gidin. Burada MLflow denemelerinizi, modellerinizi ve kayıtlarınızı görebilirsiniz.
- PostgreSQL: Veritabanına doğrudan tarayıcı üzerinden erişim yoktur, ancak Jupyter'dan veya başka bir PostgreSQL istemcisinden
localhost:5432üzerinden bağlanabilirsiniz (kullanıcı:user, şifre:password, veritabanı:mlops_db).
Adım 6: Ortamı Durdurun ve Temizleyin
İşiniz bittiğinde, tüm servisleri durdurmak için:
docker compose down
Eğer tüm konteynerleri, ağları ve isimlendirilmiş volume'leri (bu örnekte postgres_data) tamamen kaldırmak isterseniz:
docker compose down --volumes
Bu adımları takip ederek, veri bilimi projeleriniz için bulut benzeri, izole ve tekrarlanabilir bir lokal geliştirme ortamını kolayca kurabilir ve yönetebilirsiniz. Bu sayede, farklı projeler arasında geçiş yaparken bağımlılık çakışmalarıyla uğraşmak zorunda kalmaz ve geliştirme süreçlerinizi standardize edersiniz.
Uçtan Uca Bir ML Projesi: Veri Hazırlığından Model Dağıtımına Yerel Akış Nasıl Oluşturulur?
Lokal MLOps ortamımızı Docker Compose ile kurduktan sonra, bu ortamda bir makine öğrenimi projesinin tüm adımlarını nasıl gerçekleştireceğimizi keşfedelim. Bu yaklaşım, gerçek bir üretim ortamının basitleştirilmiş bir modelini sunarak, veri bilimcilerin ve ML mühendislerinin iş akışlarını daha verimli hale getirmelerine olanak tanır. Amacımız, veri alımından modelin dağıtımına kadar her aşamayı lokal konteynerlerimiz içinde yönetmek.
1. Veri Hazırlığı ve Keşifsel Veri Analizi (EDA)
İlk adım, projenin veri ihtiyacını karşılamak ve veriyi analiz etmektir. my_mlops_project/data dizininize bir CSV dosyası (örneğin iris.csv) koyduğunuzu varsayalım. JupyterLab konteyneriniz bu dosyaya /home/jovyan/data/iris.csv yolundan erişebilir. JupyterLab ortamında bir notebook açarak, pandas gibi kütüphanelerle veriyi yükleyebilir, temizleyebilir ve keşfedebilirsiniz.
import pandas as pd
# Data klasöründeki veriye erişim
df = pd.read_csv('/home/jovyan/data/iris.csv')
print(df.head())
print(df.info())
# Veri temizleme ve ön işleme adımları burada gerçekleştirilir
Bu aşamada veriler üzerinde yapılan değişiklikler, data klasörünüze kaydedilerek kalıcı hale getirilebilir. Örneğin, temizlenmiş veriyi /home/jovyan/data/cleaned_iris.csv olarak kaydedebilirsiniz.
2. Model Eğitimi ve Deneme Takibi (MLflow ile)
Veri hazırlığı tamamlandıktan sonra, modeli eğitmeye geçebiliriz. Burada, MLflow'u devreye sokarak denemelerimizi takip edeceğiz. Jupyter notebook'unuz içinde MLflow'u nasıl kullanacağınızı gösteren bir örnek:
import mlflow
import mlflow.sklearn
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
# MLflow izleme sunucusunun adresi (docker-compose'daki servis adı)
mlflow.set_tracking_uri("http://mlflow_server:5000")
mlflow.set_experiment("Iris_Classification_Experiment")
with mlflow.start_run():
# Veriyi yükle ve hazırla
df = pd.read_csv('/home/jovyan/data/cleaned_iris.csv') # Temizlenmiş veri
X = df.drop('species', axis=1)
y = df['species']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Modeli eğit
n_estimators = 100
max_depth = 5
model = RandomForestClassifier(n_estimators=n_estimators, max_depth=max_depth, random_state=42)
model.fit(X_train, y_train)
# Tahmin yap ve performansı değerlendir
y_pred = model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
# MLflow ile parametreleri ve metrikleri logla
mlflow.log_param("n_estimators", n_estimators)
mlflow.log_param("max_depth", max_depth)
mlflow.log_metric("accuracy", accuracy)
# Modeli kaydet
mlflow.sklearn.log_model(model, "random_forest_model")
print(f"Model Accuracy: {accuracy}")
Bu kod bloğu çalıştıktan sonra, MLflow UI'a (http://localhost:5000) gittiğinizde, yeni bir denemenin kaydedildiğini, parametreleri, metrikleri ve eğitilmiş modelin artifact olarak depolandığını göreceksiniz. Model, MLflow'un artifact deposuna (bu örnekte ./mlruns dizinine) kaydedilir.
3. Model Sürümleme ve Kayıt
MLflow'un model kayıt (Model Registry) özelliği ile en iyi modeli sürümleyebilir ve bir sonraki aşama olan dağıtıma hazırlayabilirsiniz. Modelinizi eğittikten ve MLflow'a kaydettikten sonra, MLflow UI üzerinden veya programatik olarak modelinizi register edebilirsiniz:
# Önceki çalıştırmanın run_id'sini almanız veya MLflow UI'dan kopyalamanız gerekir
# run_id = "..." # MLflow UI'dan alın
# model_uri = f"runs:/{run_id}/random_forest_model"
# mlflow.register_model(model_uri=model_uri, name="IrisClassifier")
# Ya da MLflow UI üzerinden manuel kayıt
Modelinizi bir isimle kaydettikten sonra, farklı versiyonlarını yönetebilir, sahne (Staging, Production) atamaları yapabilirsiniz.
4. Model Dağıtımı (Basit Bir Flask Uygulaması ile Simülasyon)
Model dağıtımı, lokal ortamda genelde bir web servisi olarak simüle edilir. Eğittiğimiz modeli yükleyecek ve tahminler yapacak basit bir Flask API oluşturabiliriz. Bu Flask uygulamasını da Docker Compose'a yeni bir servis olarak ekleyebiliriz.
Öncelikle, projenizin ana dizininde model_serving adında bir dizin oluşturun ve içine app.py ile Dockerfile dosyalarını ekleyin:
model_serving/app.py:
import mlflow
import pandas as pd
from flask import Flask, request, jsonify
# MLflow izleme sunucusunun adresi
mlflow.set_tracking_uri("http://mlflow_server:5000")
# Kayıtlı modeli yükle
# Eğer modeliniz MLflow Registry'de ise, adıyla yükleyebilirsiniz:
# model = mlflow.pyfunc.load_model("models:/IrisClassifier/Production")
# Eğer sadece artifact olarak kaydedildiyse, artifact URI'si ile:
model = mlflow.pyfunc.load_model("./mlruns/0//artifacts/random_forest_model") # run_id'yi kendi run_id'nizle değiştirin
app = Flask(__name__)
@app.route('/predict', methods=['POST'])
def predict():
data = request.get_json(force=True)
df_input = pd.DataFrame(data)
predictions = model.predict(df_input).tolist()
return jsonify(predictions)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5001)
model_serving/Dockerfile:
FROM python:3.9-slim-buster
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY app.py .
EXPOSE 5001
CMD ["python", "app.py"]
model_serving/requirements.txt:
flask
mlflow
scikit-learn
pandas
Şimdi docker-compose.yml dosyanıza yeni bir servis ekleyin:
model_api:
build: ./model_serving # Dockerfile'ı buradan inşa et
ports:
- "5001:5001" # API erişimi
volumes:
- ./mlruns:/app/mlruns # MLflow artifact'larına erişim için
depends_on:
- mlflow_server
networks:
- mlops_network
docker compose up -d --build komutunu çalıştırarak yeni servisi inşa edin ve başlatın. Artık API'nize localhost:5001/predict adresinden erişebilirsiniz.
curl -X POST -H "Content-Type: application/json" \
-d '[{"sepal length (cm)": 5.1, "sepal width (cm)": 3.5, "petal length (cm)": 1.4, "petal width (cm)": 0.2}]' \
http://localhost:5001/predict
Bu akış, veri bilimcinin bir modeli lokal olarak geliştirip test etmesine, sürümlemesine ve dağıtımını simüle etmesine olanak tanır. Gerçek bir CI/CD boru hattında, bu adımlar otomatikleştirilir ve genellikle bulut ortamına veya üretim sunucularına dağıtılır. Ancak lokal ortamda bu simülasyon, geliştirme döngüsünü inanılmaz derecede hızlandırır ve hataları erken aşamada yakalamaya yardımcı olur.
Model Sürümleme ve İzleme: MLflow ile Verimliliği Artırma Yolları
Makine öğrenimi projelerinin karmaşıklığı arttıkça, modelleri, denemeleri, veriyi ve kodu izlemek ve sürümlemek hayati hale gelir. Bu durum, özellikle birden fazla veri bilimcinin aynı proje üzerinde çalıştığı veya zamanla model performansının takip edilmesi gerektiği senaryolarda önemlidir. MLflow, bu zorlukları aşmak için tasarlanmış açık kaynaklı bir platformdur ve Docker Compose ile entegre edildiğinde, lokal ortamınızda güçlü bir MLOps yeteneği sunar.
MLflow Tracking ile Deneme Takibi
MLflow Tracking bileşeni, makine öğrenimi denemelerini loglamak ve karşılaştırmak için tasarlanmıştır. Bu, bir veri bilimcinin farklı hiperparametre setleri, veri önişleme teknikleri veya model mimarileri ile yaptığı denemeleri sistematik bir şekilde kaydetmesini sağlar. MLflow sunucumuz Docker Compose ile çalışırken, JupyterLab ortamından yaptığımız her denemeyi bu sunucuya yönlendirebiliriz.
import mlflow
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
# MLflow izleme sunucusu URL'sini ayarlayın
mlflow.set_tracking_uri("http://mlflow_server:5000") # docker-compose servis adı ve portu
mlflow.set_experiment("Model_Performance_Tuning")
iris = load_iris()
X, y = iris.data, iris.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Farklı parametrelerle denemeler yapalım
for C_param in [0.1, 1.0, 10.0]:
with mlflow.start_run():
model = LogisticRegression(C=C_param, solver='liblinear')
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
mlflow.log_param("C_parameter", C_param)
mlflow.log_metric("accuracy", accuracy)
mlflow.sklearn.log_model(model, "logistic_regression_model")
print(f"C={C_param}, Accuracy={accuracy}")
Bu kod bloğu, farklı C parametreleriyle LogisticRegression modelini eğitir ve her denemenin parametrelerini, metriklerini ve eğitilmiş modelini MLflow sunucusuna kaydeder. http://localhost:5000 adresindeki MLflow UI'da, bu denemeleri kolayca karşılaştırabilir, en iyi performansı gösteren modeli bulabilirsiniz. Bu, geliştirme aşamasında "ne işe yaradı, ne yaramadı" sorusuna hızlı yanıtlar almanızı sağlar.
MLflow Model Registry ile Model Sürümleme
MLflow Model Registry, MLflow Tracking tarafından loglanan makine öğrenimi modellerinin tam yaşam döngüsünü yönetmenizi sağlar. Bu, modelleri sürümlemek, açıklama eklemek, sahne geçişleri yapmak (örn. Staging'den Production'a) ve merkezi bir depoda kayıt altına almak anlamına gelir. Docker Compose ortamımızda, MLflow sunucusunun PostgreSQL veritabanını arka uç deposu olarak kullanması sayesinde, model kayıtları da kalıcı olarak saklanır.
# En iyi performans gösteren bir run_id'yi seçtiğinizi varsayalım
# run_id = "your_best_run_id_from_mlflow_ui"
# model_uri = f"runs:/{run_id}/logistic_regression_model"
# Eğer modeli ilk kez kaydediyorsanız
# model_version = mlflow.register_model(model_uri=model_uri, name="IrisLogisticRegression")
# print(f"Model '{model_version.name}' versiyon {model_version.version} kaydedildi.")
# Mevcut bir modeli bir sahneye geçirmek için (örneğin, Staging'e)
# client = mlflow.tracking.MlflowClient()
# client.transition_model_version_stage(
# name="IrisLogisticRegression",
# version=1, # modelin versiyon numarası
# stage="Staging"
# )
MLflow UI üzerinden de modelleri kayıt defterine ekleyebilir ve yaşam döngülerini yönetebilirsiniz. Bu merkezi model deposu, hangi modelin hangi versiyonunun nerede ve ne amaçla kullanıldığının takibini kolaylaştırır. Özellikle model dağıtım süreçlerinde, "en son üretim modeli nedir?" sorusunun yanıtını hızlıca almanızı sağlar.
Model İzleme ve Geri Bildirim Döngüleri
Model dağıtıldıktan sonra performansı izlemek kritik öneme sahiptir. MLflow Tracking, yeni veri setleri üzerinde modelin nasıl performans gösterdiğini sürekli olarak loglamanıza olanak tanır. Örneğin, bir üretim ortamında (veya lokal simülasyonunuzda) modelinizden elde edilen tahminleri ve gerçek sonuçları MLflow'a geri loglayarak modelin drift edip etmediğini gözlemleyebilirsiniz. Bu, modelin zamanla bozulup bozulmadığını anlamanıza ve gerektiğinde yeniden eğitim kararları almanıza yardımcı olur.
MLflow'un bu yetenekleri, lokal MLOps ortamınızda gerçek bir MLOps kültürünün temelini atar. Veri bilimciler, denemelerini şeffaf bir şekilde yönetebilir, en iyi modellerini kolayca sürümleyebilir ve modelin yaşam döngüsünü uçtan uca izleyebilirler. Bu da, daha güvenilir, tutarlı ve yönetilebilir makine öğrenimi çözümlerine yol açar.
Performans ve Güvenlik İçin İleri Düzey İpuçları: Lokal Ortamı Optimize Etme
Docker Compose ile lokal MLOps ortamı kurmak harika bir başlangıç olsa da, daha verimli ve güvenli hale getirmek için bazı ileri düzey ipuçları ve en iyi uygulamalar mevcuttur. Bu optimizasyonlar, hem geliştirme sürecinizi hızlandırır hem de olası güvenlik zafiyetlerini minimize eder.
1. Kaynak Sınırlamaları ile Performansı Yönetme
Docker konteynerleri varsayılan olarak ana makinenin tüm kaynaklarına erişebilir. Ancak, birden fazla servis çalışırken, bir servisin diğerlerini olumsuz etkilemesini önlemek için kaynak sınırlamaları (CPU, bellek) tanımlamak önemlidir. Bu, özellikle sınırlı kaynaklara sahip bir geliştirme makinesinde çalışıyorsanız kritik bir performans ipucudur.
services:
jupyter:
# ... diğer ayarlar ...
deploy:
resources:
limits:
cpus: '2.0' # 2 CPU çekirdeği ile sınırla
memory: 4G # 4 GB RAM ile sınırla
reservations:
cpus: '0.5' # Minimum 0.5 CPU çekirdeği garanti et
memory: 1G # Minimum 1 GB RAM garanti et
Bu yapılandırma, Jupyter servisinin kaynak tüketimini kontrol altında tutarak, diğer servislerin de düzgün çalışmasını sağlar. Bu sayede, aynı anda hem model eğitimi yapabilir hem de MLflow UI'ı sorunsuz bir şekilde kullanabilirsiniz.
2. Veri Kalıcılığı ve Performans için Volume Yönetimi
Docker Volume'ler, verilerinizi konteynerden bağımsız olarak saklamanızı sağlar. İki ana volume türü vardır: bind mount'lar (yerel dosya sisteminizdeki bir dizini doğrudan konteynere bağlar) ve named volume'ler (Docker tarafından yönetilir). Genellikle, kod ve konfigürasyon dosyaları için bind mount'lar, veritabanı verileri veya büyük artifact'ler için named volume'ler tercih edilir.
- Bind Mounts: Geliştirme sırasında kodunuzu anında konteyner içinde güncellemek için idealdir (örneğin,
./notebooks:/home/jovyan/work). Ancak performans açısından, özellikle büyük dosya operasyonlarında, named volume'lerden daha yavaş olabilirler. - Named Volumes: Daha iyi I/O performansı sunarlar ve Docker tarafından daha iyi yönetilirler. Veritabanı verileri (
postgres_data:/var/lib/postgresql/data) veya MLflow artifact'leri için (mlruns_data:/mlruns) kullanılması önerilir. Kendi./mlrunsklasörünüzü kullanmak yerine,mlruns_dataadında bir volume tanımlayabilir ve bu volume'ümlflow_serverservisine bağlayabilirsiniz. Bu, verilerinizin ana sistemden bağımsız olarak daha optimize bir şekilde depolanmasını sağlar.
volumes:
postgres_data:
mlruns_data: # Yeni named volume
driver: local # Varsayılan sürücü, ancak farklı sürücüler de kullanılabilir
services:
mlflow_server:
# ...
volumes:
- mlruns_data:/mlruns # Named volume kullan
# ...
3. Güvenlik İpuçları: Ortam Değişkenleri ve Ağ İzolasyonu
- Gizli Bilgileri Yönetme (.env Dosyası): Veritabanı şifreleri veya API anahtarları gibi hassas bilgileri
docker-compose.ymldosyanızda doğrudan tutmak yerine, bir.envdosyası kullanın. Docker Compose bu dosyayı otomatik olarak yükler..envdosyası:POSTGRES_USER=myuser POSTGRES_PASSWORD=mysupersecretpassword MLFLOW_DB=mlops_dbdocker-compose.ymldosyasında kullanım:postgres: environment: POSTGRES_DB: ${MLFLOW_DB} POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} - Ağ İzolasyonu: Docker Compose ile tanımlanan servisler varsayılan olarak aynı ağda olsalar da, yalnızca gerekli portları dışarıya açtığınızdan emin olun. Örneğin, PostgreSQL servisini doğrudan ana makinenize açmak yerine, sadece Jupyter ve MLflow gibi iç servislerin erişimine izin verin (eğer dışarıdan erişim gerekmiyorsa
portskısmınıpostgresservisinden kaldırın). - Minimum Yetki Prensibi: Konteyner içindeki uygulamaların gereğinden fazla yetkiye sahip olmamasını sağlayın. Örneğin, Jupyter konteynerinde
user: rootkullanmak yerine, mümkünse daha kısıtlı bir kullanıcı ile çalışın.
4. Özelleştirilmiş Docker İmajları ve Dockerfile Optimizasyonu
Varsayılan imajlar yerine, projenizin özel bağımlılıklarını içeren kendi Docker imajlarınızı oluşturmak, kontrolü artırır ve başlangıç sürelerini hızlandırır. Dockerfile'ınızı optimize ederken:
- Katmanları (layers) akıllıca kullanın: Sık değişmeyen bağımlılıkları daha erken katmanlara ekleyin.
- Minimal imajlar kullanın:
alpineveyaslimtabanlı imajlar, imaj boyutunu küçültür. - Gereksiz dosyaları kaldırmak için
.dockerignorekullanın. RUNkomutlarını zincirleyin (RUN apt-get update && apt-get install -y some-package), bu da katman sayısını azaltır.
# Örnek Dockerfile for Jupyter
FROM jupyter/scipy-notebook:latest
USER root # Gerekirse geçici olarak root yetkisi al
RUN apt-get update && apt-get install -y --no-install-recommends \
git \
build-essential \
&& rm -rf /var/lib/apt/lists/* # Gereksiz önbelleği temizle
USER $NB_UID # Geri kullanıcıya dön
COPY requirements.txt /home/jovyan/requirements.txt
RUN pip install --no-cache-dir -r /home/jovyan/requirements.txt
# Opsiyonel: Kendi kodunuzu kopyalayın
COPY ./src /home/jovyan/work/src
WORKDIR /home/jovyan/work
Bu ipuçları, lokal MLOps ortamınızı hem daha dayanıklı, hem daha hızlı hem de daha güvenli hale getirerek, veri bilimi projelerinizdeki verimliliği artırmanıza yardımcı olacaktır. Unutmayın, iyi bir geliştirme ortamı, başarılı bir projenin temelidir.
Sonuç: Lokal MLOps Geleceği ve Sıkça Sorulan Sorular
Bu makalede, veri bilimi ve makine öğrenimi projeleri için "bulut benzeri" bir lokal geliştirme ve MLOps ortamının Docker Compose ile nasıl kurulabileceğini ve yönetilebileceğini ayrıntılı bir şekilde ele aldık. Gördüğümüz gibi, Docker Compose sadece konteynerleri bir araya getirmekle kalmıyor, aynı zamanda maliyet etkinliği, veri gizliliği, yüksek geliştirme hızı ve vendor lock-in'den kaçınma gibi önemli avantajlar sunarak bulut çözümlerine güçlü bir alternatif oluşturuyor.
Bir ML projesinin başlangıcından, veri hazırlığından model eğitimine, sürümlemeden dağıtım simülasyonuna kadar tüm aşamalarını lokal ortamda tutarlı ve tekrarlanabilir bir şekilde yönetmenin mümkün olduğunu gösterdik. MLflow gibi araçların entegrasyonuyla, deneme takibi ve model sürümleme süreçleri basitleştirilerek veri bilimcilerin daha şeffaf ve verimli çalışması sağlandı. Ayrıca, kaynak yönetimi, volume optimizasyonu ve güvenlik pratikleri gibi ileri düzey ipuçlarıyla ortamınızı daha sağlam hale getirme yollarını da keşfettik. Tüm bu yaklaşımlar, veri bilimcilerin ve ekiplerin bağımsızlığını artırırken, karmaşık bağımlılık yönetiminden kaynaklanan baş ağrılarını da ortadan kaldırıyor.
Lokal MLOps, özellikle küçük ve orta ölçekli ekipler için veya hassas veriyle çalışan kuruluşlar için mükemmel bir başlangıç noktasıdır. Hatta büyük kuruluşlarda bile, buluta dağıtım öncesi hızlı prototipleme ve test aşamaları için vazgeçilmez bir araçtır. Gelecekte, daha da gelişen konteyner orkestrasyon araçları ve açık kaynaklı MLOps platformlarıyla birlikte, lokal MLOps çözümlerinin yetenekleri artmaya devam edecektir. Bu nedenle, Docker Compose gibi araçlara hakim olmak, her veri bilimcinin ve ML mühendisinin araç kutusunda bulunması gereken temel bir yetkinliktir. Bu sayede, hem bugünün hem de yarının makine öğrenimi zorluklarına karşı daha donanımlı olacaksınız.
Sıkça Sorulan Sorular
A: Hayır, Docker Compose genellikle geliştirme ve test ortamları için idealdir. Üretim ortamlarında, genellikle Kubernetes gibi daha gelişmiş konteyner orkestrasyon araçları kullanılır. Kubernetes, daha iyi ölçeklenebilirlik, yüksek erişilebilirlik, otomatik iyileşme ve karmaşık dağıtım stratejileri sunar. Ancak lokal Docker Compose kurulumunuz, Kubernetes'e dağıtım yapmadan önce projenizi geliştirmenizi ve kapsamlı bir şekilde test etmenizi sağlar.
A: Büyük veri setleriyle çalışırken lokal ortamın performansı, ana makinenizin donanım özelliklerine (CPU, RAM, SSD hızı) bağlıdır. Çok büyük veri setleri (>100GB) için lokal makine yetersiz kalabilir. Bu durumda, verinin bir kısmını örneklemek, dağıtık işlem çerçeveleri kullanmak veya doğrudan bulut tabanlı depolama/işlem servislerine geçiş yapmak daha uygun olabilir. Ancak çoğu orta ölçekli veri bilimi projesi için lokal bir Docker Compose kurulumu yeterli performansı sağlayacaktır.
A: Docker Compose'un en büyük avantajlarından biri taşınabilirliğidir. docker-compose.yml dosyanızı ve varsa Dockerfile ile uygulama kodunuzu içeren proje dizininizi (örneğin Git deposu aracılığıyla) paylaşmanız yeterlidir. Ekip üyelerinin sadece Docker ve Docker Compose'u kurulu olması gerekir. Ortamı başlatmak için docker compose up -d komutunu çalıştırmaları yeterli olacaktır, bu da tüm bağımlılıkların otomatik olarak kurulmasını sağlar.
A: Evet, kesinlikle mümkün. MLflow, artifact'lar için S3 (AWS), Azure Blob Storage veya Google Cloud Storage gibi çeşitli bulut depolama çözümlerini destekler. docker-compose.yml dosyasındaki MLflow servisi için MLFLOW_DEFAULT_ARTIFACT_ROOT ortam değişkenini ilgili bulut depolama URI'sine ayarlayarak bunu yapabilirsiniz (örneğin s3://my-mlflow-bucket/artifacts). Bu, lokal ortamınızda çalışırken bile artifact'larınızı merkezi ve bulut tabanlı bir depoda saklamanıza olanak tanır.
A: Lokal MLOps ortamınızda GPU kullanmak için NVIDIA Container Toolkit'i kurmanız gerekir. Kurulumdan sonra, docker-compose.yml dosyanızdaki ilgili servislere (örneğin Jupyter) deploy bölümünde resources altına reservations ekleyerek GPU'ları ayırabilirsiniz. Örneğin:
services:
jupyter:
# ...
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1 # Kullanılacak GPU sayısı
capabilities: [gpu]
Bu, konteynerinizin ana makinedeki GPU'ya erişmesini sağlar ve derin öğrenme modellerini eğitmek gibi yoğun hesaplama görevleri için lokal ortamınızı güçlendirir.