W tym wpisie zajmiemy się śledzeniem zmian, jak również porównaniem i śledzeniem wdrażania modeli Machine Learning z wykorzystaniem biblioteki MLflow. Później ustawimy zasoby w Azure Cloud, aby móc udostępnić nasz model, a także stworzymy potok Azure DevOps, aby wdrożyć nowy model, wystarczy tylko popchnąć go do repozytorium Azure GIT. Podkreśli to jak łatwa jest konfiguracja z ML - nie jest ona tak długa ani tak trudna jak myślisz, jeśli wiesz co robisz!

Nie będziemy się koncentrować na hipertuningu parametrów modelu, eksploracji funkcji czy czyszczeniu danych. W naszym przykładzie użyjemy "Richter's Predictor": Modelowanie uszkodzeń spowodowanych przez trzęsienie ziemi", którego gospodarzem jest DrivenData.

Proces rozwoju aplikacji IT

Kiedy tworzymy aplikację desktopową, produkt mobilny lub stronę internetową, zawsze zaczynamy od zaplanowania funkcji, które mamy zamiar dostarczyć (jest to część podstawowego projektu produktu). Następnie programujemy i wdrażamy je na serwer w sposób ciągły.

Przez "ciągły" rozumiem, że spośród wszystkich funkcji, które planujemy dostarczyć, wybieramy niewielki podzbiór i pracujemy nad nim. Po zakończeniu pracy i przetestowaniu, zmiany są wdrażane na serwer, przez programistów lub zespół wdrożeniowy. Jest to tzw. Continuous Integration, Continuous Delivery (CI/CD) i stanowi część podejścia DevOps.

Ponieważ pracujemy w ten sposób, klient może zacząć korzystać z już ukończonych przez nas funkcji, podczas gdy my pracujemy nad innym podzbiorem funkcji. Aby śledzić wszystkie zmiany w bazie kodowej, zawsze chcemy wykorzystać jakiś system kontroli wersji, jak na przykład Git. Dlaczego? Ktoś może zapytać. W złożonych aplikacjach, nawet najmniejsze zmiany w już napisanym kodzie - wymagane do postępu pracy nad bieżącą funkcjonalnością - mogą przypadkowo złamać jakąś inną funkcjonalność. Podobnie, jeśli nastąpiła jakaś zmiana wymagań, po której nastąpiły poprawki w bazie kodu, to druga część aplikacji mogła być ściśle uzależniona od tego, jak działała przed modyfikacją. Ta część teraz zepsutego kodu oczywiście nie będzie działać po zmianie, ale może się to czasami wymknąć podczas testów.

Takie sytuacje zdarzają się czasami i dlatego chcemy być w stanie zobaczyć wszystkie zmiany, być w stanie zobaczyć wszystkie poprzednie prace, które zostały wykonane i znaleźć winowajcę, który spowodował przerwanie funkcji. Pozwala nam to również w razie potrzeby łatwo powrócić do poprzednich wersji. Po dostarczeniu wszystkich funkcji, nie ma wiele więcej do zrobienia, więc przechodzimy na konserwację i tylko naprawiamy błędy bez opracowywania nowych funkcji.

Czy rozwój modelu uczenia się maszyn jest tak różny?

Podczas gdy implementacja aplikacji jest w fazie iteracyjnej, możemy dokładnie zaplanować, co należy zrobić. Z drugiej strony, implementacja modelu jest procesem bardziej odkrywczym i jako taka nie wiemy, co trzeba będzie zrobić, aby osiągnąć najlepsze rezultaty.

Oczywiście możemy zaplanować niektóre z głównych kroków, takich jak integracja danych, analiza danych, walidacja danych, szkolenie lub budowanie modelu, a nawet jego wdrożenie. Rzadko jednak możemy dokładnie określić, co należy zrobić, ponieważ zawsze jest miejsce na dalsze doskonalenie modelu.

Po zbudowaniu jednego modelu staramy się zbudować kolejny, aby osiągnąć jeszcze lepsze wyniki. Możemy użyć różnych technik uczenia się, zmienić nieco hiperparametry obecnego algorytmu (aby lepiej odzwierciedlał rzeczywistość), spróbować zintegrować nowe dane, a może spróbować radykalnie innego podejścia. Istnieje nieskończona ilość możliwości, aby spróbować określić, czy pomagają one w osiągnięciu dokładności naszego modelu.

Jednak, podobnie jak przy tworzeniu aplikacji, chcemy śledzić pracę, która została już wykonana, więc nie robimy tych samych rzeczy dwa razy - lub więcej! Musimy też mieć możliwość porównania wyników, ponieważ łączenie różnych rozwiązań może często prowadzić do jeszcze lepszego. Jednak przechowywanie całego kodu dla różnych modeli, jak również wszystkich parametrów i wyników w wielu katalogach i arkuszach kalkulacyjnych Excel, byłoby prawdziwym bólem.

Rzadko zdarza się również pracować w jednoosobowych zespołach, więc musimy być w stanie odtworzyć nasze eksperymenty lub podzielić się nimi z innymi badaczami danych. Wdrażanie nowego modelu to kolejna rzecz, którą musimy się zająć.Ręczne tworzenie obrazów dokera i wdrażanie na serwerze nie jest takie trudne, ale wymaga cennego czasu, który moglibyśmy poświęcić na testowanie innego modelu. Chcielibyśmy więc, aby proces wdrażania był łatwy, bezproblemowy i automatyczny.

MLflow na ratunek

MLflow skupia się na trzech podstawowych celach:

  • Śledzenie eksperymentów, aka parametrów wyników innych artefaktów

Pakietowy kod ML, w formie wielokrotnego użytku i powtarzalnej, pozwala na dzielenie się danymi z innymi naukowcami i przeniesienie modelu do produkcji, a także pomaga przy wdrożeniach, ponieważ obsługuje różne biblioteki i platformy Cloud. Jednak w tym artykule główny nacisk zostanie położony na śledzenie modelu i wdrażanie chmury.

Na szczęście obejmuje to wspomniane wcześniej problemy związane ze śledzeniem, udostępnianiem i wdrażaniem. MLflow jest dość prosty w użyciu i nie wymaga tak wielu zmian w kodzie, co jest dużym plusem. Pozwala także na przechowywanie artefaktów każdego eksperymentu, takich jak parametry i kod, a także modeli przechowywanych zarówno lokalnie, jak i na zdalnych serwerach/maszynach. Jeśli to nie wystarczy, istnieje bardzo ładny interfejs do porównywania eksperymentów, które mają wbudowane wykresy, więc nie trzeba ich tworzyć samodzielnie.

Wreszcie, obsługuje również wiele modeli z bibliotek takich jak scikit-learn, Keras, PyTorch lub ONNX, obok języków takich jak Python, R, Java i REST API, jak również linii poleceń.

Zaczynajmy

Użyjemy tego prostego przykładu, aby pokazać jak śledzić model i wdrożyć go do Azure Cloud za pomocą Pythona. W poniższym kodzie szkolimy bardzo prosty model sekwencyjny przy użyciu biblioteki Keras. Podczas procesu uczenia sieci neuronowej, dane są prezentowane do algorytmu sieci neuronowej wielokrotnie. Jedno przejście do przodu i jedno przejście do tyłu wszystkich przykładów treningu do modelu nazywane jest epoką. Po każdym pojedynczym uruchomieniu sieci neuronowej rejestrowana jest dokładność i utrata każdej z epok, zarówno na zestawach danych treningowych jak i testowych, parametrów, które zostały użyte i zapisywane w modelu sieci neuronowej.

Aby uruchomić skrypt, będziemy musieli zainstalować kilka bibliotek, więc zainstalujmy je najpierw:

Teraz, gdy mamy już potrzebne biblioteki, spójrzmy na skrypt.

Po pierwsze, zapisujemy wszystkie parametry, które zostały przekazane do metody, którą będziemy wkrótce badać. Następnie ustawiamy run_learning główny katalog, więc wszystkie artefakty są zapisywane w katalogu bazowym, a nie tam, gdzie działa notebook jupyter, po czym ustawiamy nazwę eksperymentu i uruchamiamy go. Jeśli chcemy ustawić katalog lokalnie, przed ścieżką musimy dodać prefiks "file:", dla HTTP URI (Uniform Resource Identifier), dodajemy "https:", a jeśli chcemy użyć obszaru roboczego "databricks", dodajemy "databricks://". Zamiast klauzuli 'z ... jak ...', możemy przypisać ją do zmiennej, ale musimy pamiętać o ręcznym zamknięciu eksperymentu, używając wtedy metody 'end_run'. Zapis 'z ... jak ...' jest podatny na błędy, dlatego będziemy trzymać się tego podejścia.

Pierwszą rzeczą, którą robimy po rozpoczęciu eksperymentu, jest logowanie parametrów przy pomocy metody 'mlflow.log_param', ale oczywiście kolejność logowania nie jest ważna - tak długo, jak długo pozostaje w zakresie eksperymentu. Następnie tworzymy tymczasowy katalog dla artefaktów, obok tworzenia, dopasowywania, treningu i punktowania modelu Kerasa.

Kiedy to zostanie zrobione, logujemy wszystkie wyniki za pomocą 'log_metric' w podobny sposób, jak to już zostało opisane. MLflow nie obsługuje tablic z pudełka, więc musimy użyć metody trójparametrowej. Wyliczamy tablicę i logujemy każdą epokę osobno w pętli.

Na koniec zapisujemy model i instruujemy MLflow, aby przeniósł artefakt na wcześniej określoną ścieżkę, a na koniec usuwamy pliki tymczasowe.

Teraz, gdy już wyjaśniliśmy skrypt, uruchommy go w notebooku jupitera i zobaczmy interfejs MLflow.

Oto przykładowy wynik po kilkukrotnym uruchomieniu skryptu uczącego się z różnymi parametrami.

Możemy podzielić każdy parametr/metryczny na osobne kolumny klikając na nazwę parametru

Na przykład, jak tak:

Możemy spojrzeć na jeden eksperyment klikając na hiperłącze daty, gdzie możemy zobaczyć wszystkie zarejestrowane parametry, metryki i artefakty. Artefakt można również pobrać po jego wybraniu.

Możemy również spojrzeć na metrykę straty, która została zalogowana w pętli, klikając na nią.

Kolejną świetną rzeczą jest nieszablonowe porównanie pomiędzy różnymi wynikami uruchomień. Aby to zrobić, wystarczy zaznaczyć pola wyboru i kliknąć przycisk 'porównaj'.

Możemy również porównać zmiany dokładności w każdej epoce pomiędzy wybranymi modelami.

Po porównaniu wszystkich wyników i wybraniu najlepszego modelu, możemy pobrać zarchiwizowaną wersję, którą zapisaliśmy jako artefakt, który zostanie później wykorzystany.

Wdrażanie modelu Kerasów

Zdecydowaliśmy się na hosting naszego modelu w Azure Cloud, więc musimy skonfigurować nasze usługi Azure, aby móc hostować model, który stworzyliśmy w ostatnim kroku. Wskakujmy w to teraz!

Najpierw udaj się do portalu Azure i zaloguj się. Jeśli nie posiadasz konta, możesz utworzyć je w kilku prostych krokach. Teraz, stwórzmy nową grupę zasobów. Będzie ona służyła do grupowania wszystkich zasobów, takich jak nasza aplikacja, kontener obrazów i tak dalej. Kliknij na "Grupy zasobów", a następnie na "Dodaj", nadaj grupie zasobów nazwę, wybierz region i kliknij na "Przeglądaj + twórz", a następnie na "Utwórz".

W lewym panelu należy kliknąć na "Create resource", następnie na "AI + Machine Learning" i na "Machine Learning service workspace". Podaj nazwę przestrzeni nazw, wybierz wcześniej utworzoną grupę zasobów i stwórz ją. Następnie po prostu poczekaj, aż Azure zakończy tworzenie tych zasobów.

Teraz dodajmy główny serwis, który pozwoli nam na dostęp do naszych zasobów z naszego kodu. Najpierw kliknij na "Azure Active Directory" w lewym panelu, następnie na "App registrations", a następnie kliknij na przycisk "Add" i stwórz aplikację.

Zostaniemy przekierowani do szczegółów rejestracji aplikacji, którą właśnie stworzyliśmy. Skopiuj identyfikator aplikacji (klienta) i identyfikator katalogu (najemcy), ponieważ będzie on potrzebny później. Teraz kliknij na przycisk "Certyfikaty i tajemnice" i stwórz sekret klikając na "Nowy sekret klienta". Skopiuj ten sekret gdzieś, ponieważ będzie on potrzebny później.

Teraz mamy zleceniodawcę usługi, którego możemy użyć do zalogowania się z kodu, musimy dać mu dostęp do wszystkich zasobów utworzonych wcześniej. Wróćmy do grup zasobów i wybierzmy zasób, który utworzyliśmy wcześniej, a następnie 'Kontrola dostępu (IAM)'.

Możemy sprawdzić, kto może uzyskać dostęp do naszych zasobów, przeglądając przypisane do nich role, więc kliknijmy 'obejrzyj'. Teraz powinniśmy zobaczyć wszystkie aplikacje, użytkowników i grupy, które mają dostęp do tej grupy zasobów. Dostęp do wszystkich zasobów w tej grupie zasobów jest dziedziczony, więc aby uzyskać dostęp do wcześniej utworzonych usług uczenia maszynowego, musimy tylko dodać tutaj naszego dyrektora serwisu.

Przejdźmy dalej i kliknijmy na przycisk 'Dodaj', a następnie 'Dodaj przydział ról'. Powinien pojawić się nowy panel, w którym wybierzemy rolę, aby określić/wskazać, kto otrzyma tę rolę. Zalecane jest ustawienie roli jako współtwórcy, aby mogła ona zarządzać wszystkim, ale ograniczała zmianę praw dostępu do zasobu. Następnie chcemy wybrać utworzoną przez nas aplikację i kliknąć przycisk Zapisz. Teraz ustawiamy wszystko, łącznie z kilkoma innymi ustawieniami konfiguracyjnymi, które muszą być ustawione:

  • lokalizacja - jest to tylko lokalizacja dla naszych zasobów, upewnijmy się więc, że jest ona taka sama jak lokalizacja grupy resource_group - nazwa grupy zasobów, która została utworzona obszar roboczy_name - nazwa utworzonego obszaru roboczego subscription_id - identyfikator abonamentu (wystarczy wyszukać abonament w górnym pasku) account_name - nazwa konta przechowywania, które zostało utworzone w grupie zasobów (przejdź do grup zasobów -> wybierz resource -> i wyszukaj konto przechowywania i skopiuj jego nazwę) account_key - klucz dostępu do konta przechowywania (znajduje się w zakładce Access Keys w koncie przechowywania) service_principal_id, service_principal_password, oraz tenant_id mogą być dostępne poprzez rejestrację aplikacji w Active Directory Azure. tenant_id to "ID Katalogu (najemcy)" service_principal_id to "ID aplikacji (klienta)" service_principal_password to "tajemnica klienta", którą stworzyliśmy w zakładce "Certyfikaty i tajemnice".

Teraz, spójrzmy na skrypt wdrożeniowy.

Na początku importujemy bezpieczne zmienne, takie jak nazwa konta, główne id i hasło, ze środowiska. Następnie rozpakowujemy model, po którym następuje model ładowania, aby sprawdzić, czy jest on poprawny. Następnie tworzymy obiekt uwierzytelniający, korzystając z narzędzia service principal (aplikacja, którą stworzyliśmy wcześniej) id i hasła.

Następnie tworzymy lub otrzymujemy przestrzeń roboczą, z ustawioną na True właściwością 'exist_ok', która pozwala nam kontynuować bez tworzenia przestrzeni roboczej, jeśli ona już istnieje; w przeciwnym razie otrzymamy wyjątek. W następnym kroku, obraz jest budowany, a następnie wdrażany.

Przed uruchomieniem skryptu, wstaw ścieżkę do swojego modelu!

Teraz wiemy jak wdrożyć model, więc zróbmy to automatycznie!

Azure DevOps Pipeline Set-Up

Chcemy stworzyć rurociąg, który będzie wdrażał nasz model do Lazurowej Chmury po tym, jak zostanie on przeniesiony do repozytorium.

Przejdźmy do strony Azure DevOps i zalogujmy się. Po pierwsze, musimy stworzyć projekt, jeśli jeszcze tego nie zrobiliśmy. Następnie zaimportujmy repozytorium. Przejdź do Repozytorium, kliknij na Import i wklej adres URL repozytorium szablonu.

Teraz stwórzmy potok. Przejdź do Pipelines, New pipeline, Azure Repos Git i wybierz repozytorium. Powinieneś teraz zobaczyć kod YAML i w prawym górnym rogu kliknąć na zmienne i dodać te, które zostały wymienione wcześniej - pamiętaj, aby sprawdzić te wrażliwe jako sekret!

Zapisz zmienne i kliknij "Uruchom". Teraz, podczas gdy rozmieszczenie jest uruchomione, spójrzmy na YAML.

Rurociąg ma tylko kilka kroków. Najpierw wybiera wersję maszyny wirtualnej, następnie wybiera wersję Pythona i instaluje wszystkie wymagane zależności, a następnie uruchamia notebook wdrożeniowy, wraz ze wszystkimi zmiennymi dodanymi do środowiska. Na koniec, na koniec, drukuje punktowy URL.

Jeśli chodzi o skrypt wdrożeniowy, jest on bardzo podobny do skryptu, który opisywaliśmy wcześniej, ponieważ wprowadzono tylko kilka zmian. Po zaimportowaniu tajemnic, skanujemy katalog i wybieramy model z najwyższą wersją. Nazwy modeli powinny być następujące v.zip.

Podsumowanie

Więc, czego się dowiedzieliśmy? Pokazaliśmy, jak śledzić zmiany w modelu ML i porównywać modele między sobą, korzystając z biblioteki MLflow. Dowiedzieliśmy się również, jak tworzyć zasoby Azure, dzięki czemu możemy wdrożyć model z kodu. Następnie omówiliśmy konfigurację rurociągu Azure DevOps.

Teraz, jeśli chcemy wdrożyć nowy model, wystarczy, że przeniesiemy go do naszego repozytorium GIT, a zbuduje on obraz, zapisze w rejestrze kontenera i wdroży w Azure Cloud.

Mam nadzieję, że to pokazuje, jak łatwo jest skonfigurować szereg aplikacji i rozwiązań ML. W połączeniu z Azure Cloud - nie tylko Azure, ale również AWS i Google Cloud Platform, jest bardzo możliwe uzyskanie wszechstronnych i wyjątkowych aplikacji ML dla każdej firmy.

Perspektywa biznesowa

Dzięki platformom Cloud, takim jak Azure, mamy teraz łatwy dostęp do testowania i śledzenia naszych modeli Machine Learning. Oprócz efektywnego kosztowo zarządzania zasobami, umożliwia to firmom łatwe rozpoczęcie pracy z ML i jak najszybsze uzyskanie korzyści.

 

Komentarze (0)

Zostaw komentarz