fastapi + MLflow + streamlit + AWS = MLOps

4 minute read

Published:


Aylık maliyetinin yüksek olması nedeniyle AWS üzerindeki uygulamayı kapattım. Uygulamanın arayüzüne ait ekran görüntülerine buradan ulaşabilirsiniz.

Reddit’te dolanırken denk geldiğim bir gönderide MLFlow, fastapi ve streamlit’i kullanarak şablon bir proje paylaşılmıştı. Hızlıca incelediğimde başlagınç için bir hayli iyi olabileceğini düşündüm ve bu repo’yu temel alarak üzerine eklemeler yaptım. Çalışmada MNIST veri seti ile PyTorch kullanılarak bir model kurulmuş ve streamlit arayüzünde tekrar eğitim ve kullanıcının çizdiği görseli tahmin eden bir tahmin sayfası vardı. Uygulama aynı zamanda dockerize edilmişti ve docker-compose ile tüm bileşenler ayağa kaldırılabiliyordu. İyi bir pratik olacağını düşündüğüm için öncelikle veri ve modeli değiştirdim. Ek olarak değişken önemi kısmını ekledim ve normalde localhost üzerinde çalışmak üzere hazırlanmış yapıyı AWS EC2 üzerinde IAS olacak şekilde geliştirdim. Buradaki amacım daha önce docker-compose kullanmamış olmam ve fastapi & streamlit ile frontend/backend pratiği yapmaktı. İşin içine bir de AWS katarak canlıda çalışan bir uygulama oluşturmak istedim.

Veri Seti

Daha önceki Github Actions ile CML yazımda kullandığım IBM HR Analytics Employee Attrition & Performance verisini tercih ettim. O çalışmada değişken seçimi yapmıştım, tahmin aşaması olacağı için değişken sayısını azaltmak adına seçilen değişkenleri kullandım. Buradaki amaç uçtan uca çalışan bir yapı kurmak olduğu için veri ve modelleme aşaması basit tutuldu. Veri ve model ile alakalı kodlar.

Backend

fastapi

API tarafında fastapi’nin temel alındığı bir yapı bulunmakta. Burada streamlit önyüzünden gelecek komutlar (train & predict & feature importance) için çalışacak endpoint’ler bulunuyor. Burada bulunan endpoint’ler;

  • root ("/") a.k.a. healthcheck: Load Balancer için healthcheck kontrolünde kullanılıyor.
  • /uri - mlflow’a ait tracking ve registriy URL’lerini döndürüyor.
  • /models - mlflow’dan versiyonlanmış model listesini döndürüyor.
  • /train - streamlit arayüzünden seçilen hiper parametreleri kullanarak yeni modelin eğitilmesini sağlıyor.
  • /predict - Son versiyonlanan modeli geri yükleyerek streamlit arayüzünden girilen değişkenler için tahmin sonucunun döndürülmesini sağlıyor.
  • /importance - Son versiyonanlan modele ait değişken önemini (Feature Importance) döndürüyor.

MLFlow

fastapi’yi temel alan yapıda model takibinin yapılmasını sağlıyor. Eğitilen modeller mlflow’a ait sqlite veritabanına deney id’si, kullanılan parametreler, elde edilen skorlar vb. pek çok meta veri ile birlikte yazılıyor ve tahmin aşamasında da modele ait son versiyon çağrılıyor. Model kaydetme ve yükleme işlemleri mlflow tarafından yürütülüyor. Aynı zamanda mlflow’a ait arayüz ile de bunların takibi yapılabiliyor.

Frontend

streamlit

Önyüzde yapı değiştiği için bir çok değişiklik yapıldı. İlk olarak bir ana sayfa ekledim ve çalışmada yapılanları özetledim. Train sayfasında model tipi (şu an için sadece RF 😢), model adı (MLFlow buna göre versiyonluyor) ve modelin alabileceği hiper parametreler olan ağaç sayısı, bölünme kriteri, ağaçta kullanılacak maksimum değişken sayısı ve sınıf için ağırlandırma kullanımını ekledim. Bu seçimler yapıldıktan sonra Train butonuna basıldığında fastapi üzerinden /train tetikleniyor ve model kurularak mlflow ile kaydediliyor. Predict sayfasında ise eğitilmiş en son model çağrılarak arayüzden girilen değerler için tahmin yapılıyor ve sonuç ekrana yazdırılıyor. Son olarak Feature Importance sayfasında ise eğitilmiş son modele ait değişken önemi tablosu gösteriliyor.

Canlıya Alınması - AWS

EC2

Çalışmayı localhost’un dışına taşımak adına EC2’da Ubuntu Server 18.04 LTS kullanan bir makine oluşturdum. İlk etapta t2.large (2x vCPU & 8G) makine tercih ettim ama daha sonra kullanımı takip ettiğimde kaynak ihtiyacının çok fazla olmadığını gördüm ve bu nedenle t2.micro’ya (1x vCPU & 1G) geçtim. Bunun avantajı ise hem OS’in hem de makine tipinin AWS Free Tier olması oldu. Dezavantajı ise network konusunda biraz daha verimsiz olması ama sürekli kullanımda olmayacağı için gözardı edilebilecek bir durum bu.

Load Balancer

Aynı makine üzerinde 3 farklı porttan çalışan sevislere domain ile erişilebilmesi için Network Load Balancer tercih ettim. İlgili port’lar için listener ekleyerek load balancer’lar oluşturdum ve bunları kullanarak Route53 ile subdomain’ler oluşturdum.

Route53

Github Student Pack‘te bulunan namecheap ve name.com tekliflerini kullandığım için .tech’ten bir domain aldım. Bu domain’i kullanarak Route53 ile öncelikle hosted zone oluşturdum. Bu zone üzerinde Load Balancer’dan gelen URL’lerin A kaydı ile yönlendirilmesi için subdomain’leri belirledim. Böylece mlflow’a ve streamlit sayfasına subdomain’ler ile Load Balancer’ler üzerinden erişilebiliyor.

Streamlit URL: streamlit.gumustas.tech
MLFlow URL: mlflow.gumustas.tech
Github Repo’su: hr-attrition-mlops
streamlit Weekly Roundup

Yapılacaklar / Yapılabilecekler

  • EC2 üzerinde IAS olarak çalışıyor. Docker yapısı ECR/ECS’e alınarak CI/CD yapısına geçilebilir.
  • Şu an için tek model ile çalışıyor. Farklı modeller eklenerek ilgili modele ait arayüz (hiper parametre seçimi için) güncellemesi yapılabilir.
  • Şu an için yine tek modele ait son versiyon otomatik olarak seçiliyor. Arayüzde MLFlow’dan alınacak versiyon listesi ile predict sayfasında seçilen model versiyonuna göre tahmin alınabilir.
  • Let’s Encrypt ile Load Balancer’lara sertifika yüklenmesi ve bağlantının https’e çevrilmesi.