Machine learning z Tensorflow w chmurze na AWS EC2 z GUI!

Pomysł

Nie zawsze twój komputer jest na tyle wydajną maszyną by było to dla ciebie wygodne środowisko programistyczne. Czasami zdarza się tak, że trzeba sięgnąć jednak po coś szybszego. Nie zawsze chcesz kupować nowy komputer tylko na potrzeby jednego projektu, prawda? Niezależnie od powodów zakładamy, że skoro czytasz ten wpis to chcesz zająć się uczeniem maszynowym z Tensorflow na EC2 czyli AWSowym serwisem – Elastic Compute Cloud. Co więcej, będziemy chcieli by dostęp do systemu odbywać się przez GUI co daje o wiele większe pole manewru przy Machine Learning, który przecież może dotykać każdego medium, czy to tekst, dźwięk, obraz czy wideo.

robot playing piano
Photo by Franck V. on Unsplash

Pisałem o Tensorflow, ale w niemalże identyczny sposób możesz wykorzystać EC2 do programowania przy użyciu innych popularnych bibliotek, takich jak:

  • PyTorch
  • Apache MXNet
  • Chainer
  • Microsoft Cognitive Toolkit
  • Gluon
  • Horovod
  • Keras

(aktualna lista https://aws.amazon.com/machine-learning/amis/)

https://aws.amazon.com/machine-learning/amis/

Warunki wstępne

Założenie konta nie powinno sprawić ci większych trudności. AWS dość dobrze i dokładnie tłumaczy jak to zrobić.  Jeżeli dopiero teraz zakładasz konto, na pocieszenie pamiętaj o wykorzystaniu bonusów z AWS Free Tier  https://aws.amazon.com/free/ . Jest to na prawdę ciekawa możliwość na przetestowanie wielu serwisów AWS-a przez pierwszy rok za darmo (a niektórych nawet dłużej niż rok). Oczywiście to ‚testowanie’ jest poddane ograniczeniom jednak często w zupełności wystarcza do stworzenia prostych serwisów.
Ale teraz do meritum.

https://aws.amazon.com/ec2

Pierwsze kroki

Zakładając, że masz już konto na AWS. Możemy przejść do ciekawszych spraw. 
W konsoli AWS, przechodzimy do serwisu EC2 i tworzymy nową instancję. Jaki region wybrać? Proponuje Frankfurt ew. Irlandia (prawy górny róg).

Wybór regionu

Przechodzimy do uruchamiania instancji.

Naszym oczom ukazuje się obraz wyboru obrazu, którego chcemy użyć. Wybieramy odpowiedni AMI, czyli Amazon Machine Image. Wpisujemy w pole wyszukiwania ‚Deep Learning’. To specjalnie przygotowane obrazy z narzędziami do Machine Learning jak np. tytułowy Tensorflow. Oczywiście moglibyśmy zainstalować wszystko od zera. Moglibyśmy też kupić sobie maszynkę i nie używać chmury itd… 🙂 W każdym razie, powinniśmy zobaczyć ekran:

Ja np. wybrałem maszynkę z najnowszym Ubuntu i jeżeli nie masz swoich preferencji to wybierz ją także.

 Rodzaj instancji

Kuszące może być skorzystanie z wersji ‚micro’ by wykorzystać ww. Free Tier. Jednak szczerze to odradzam tego rodzaju skąpstwo. Używamy AWS gdyż zapewnia nam wygodne skalowanie maszyny do problemu, ale na maszynie ‚micro’ raczej nie rozwiążemy żadnego problemu. Na początek możesz wybrać np. t2.xlarge. Jest to instancja generalnego przeznaczenia i traktujemy ją jak playground. Później w każdej chwili możemy przesiąść się na coś bardziej dedykowanego pod Machine Learning.
Pamiętaj, żeby przed użyciem maszyny zapoznać się z cennikiem, tak żeby nie było, że nie uprzedzałem https://aws.amazon.com/ec2/pricing/

Warto nadmienić, że w następnym wpisie mogę pokazać ci jak znacząco ograniczyć koszta poprzez wykorzystanie tzw. ‚spot instances’ jednak tutaj nie chcę nadmiernie komplikować rozwiązania.
Klikamy kolejno na ‚Review and Launch’
I potem ‚Launch’

Credentials

Dobrą praktyką będzie stworzenie osobnych kluczy, wybieramy ‚Create a new pair’

Jeżeli teraz spróbujemy użyć kluczy, możemy napotkać na problem z kompatybilnością ich formatu. Jeżeli tak się stanie, a dla mnie się to stało, to będziemy potrzebować aplikacji putty  https://www.putty.org/ więc proszę ściągnij ją. Odpalamy narzędzie puttygen.exe przychodzące w zestawie z putty i ładujemy klucz ściągnięty z AWSa. 

I zapisujemy w formacie ppk. Uff mamy klucz do drzwi. Ale gdzie są drzwi???!


Wracamy do naszej świeżo wypieczonej instancji EC2. Na stronie z instancjami EC2 mamy na dole panel ze szczegółami dotyczącymi naszej instancji. Nas przede wszystkim interesuje adres publiczny IP i adres prywatny IP. To przez te adresy spróbujemy połączyć się z naszego komputera do instancji. 

Putty


Tak, zwracamy się o pomoc do Pana Putty. 

Naszym oczom ukazuje się ekran niczym z … dobra nie hejtujmy, putty to na prawdę świetne rozwiązanie. 

w pole Host Name wpisujemy nasz publiczny adres i przechodzimy do Connection>SSH>Auth i klikamy Browse wybrać klucz który uprzednio skonwertowaliśmy 

Teraz otwieramy zakładkę ‚Tunnel’ i tworzymy tunel do naszej instancji, jako port źródłowy podajemy dowolny wolny port, u mnie np. 8080 i jako cel tunelu: prywatne IP instancji EC2 oraz port 3389. Dzięki temu ruch na nasz localhost:8080 zostanie przekierowany przez Putty do AWS do naszej prywatnej maszynki przez port 22 na adres prywatny i port 3389 (RDP).

Ważna sprawa, po każdej zmianie zapisujemy sesję, by nie stracić dotychczasowego nakładu pracy:

Dobra ale nasza instancja nie jest jeszcze gotowa by pokazać swój desktop. By ją do tego przygotować otwieramy naszą sesję (Open) i pokaże nam się okno w stylu:

Przy pierwszym połączeniu jest to oczekiwany rezultat. Przechodzimy dalej klikając Yes.

Na następnym ekranie wita nas już terminal naszego systemu. Login to: ubuntu
Jeżeli widzisz ekran taki jak

to brawo, udało się, jesteśmy połączeni. Teraz możemy przystosować naszą instancję by umożliwić tryb GUI.

Pamiętaj żeby zachować hasło, które podasz za chwilę, w przeciwnym wypadku połączenie będzie niemożliwe.

sudo apt update &&  sudo apt upgrade

sudo sed -i 's/^PasswordAuthentication no/PasswordAuthentication yes/' /etc/ssh/sshd_config

sudo /etc/init.d/ssh restart

sudo passwd ubuntu

sudo apt install xrdp xfce4 xfce4-goodies tightvncserver

echo xfce4-session> /home/ubuntu/.xsession

sudo cp /home/ubuntu/.xsession /etc/skel

sudo sed -i '0,/-1/s//ask-1/' /etc/xrdp/xrdp.ini

sudo service xrdp restart

źródło powyższego skryptu: youtube  https://www.youtube.com/watch?v=6x_okhl_CF4

Po wykonaniu powyższych instrukcji przystępujemy do ostatniego etapu. Uruchamiamy Remote Desktop Connection (RDP) i podajemy adres localhost:8080 (lub jakikolwiek inny port skonfigurowany w putty)

Mamy to! Tryb GUI na AWS EC2!

Tak wygląda ekran naszego ubuntu

Jeszcze tylko włączmy odpowiednie środowiko uczenia maszynowego i jesteśmy w domu. Przebyliśmy dziś długą drogę, ale na szczęście aktywacja Tensforflow na naszej maszynie będzie bardzo prosta dzięki obrazowi (AMI), który wybraliśmy (Deap learning).
Wykorzystujemy najnowszą wersję Tensorflow przy użyciu:

source activate tensorflow2_latest_p37

i w konsoli możemy już zaczynać pracę.

Jeżeli wolisz jakąś inną wersję Tensorflow-a, bądź też całkiem inny pre-instalowany framework, zawsze możesz wykorzystać komendę listującą dostępne środowiska i wybrać coś innego:

Po wyborze i aktywacji odpowiedniego środowiska możemy przetestować, że wszystko poszło po naszej myśli. W moim wypadku w konsoli python-a wpisuję:

import tensorflow
print(tensorflow.__version__)

Wszystko gra. Przed nami otwierają się nowe możliwości.

Aha, no i przypominam, że z wykorzystaniem AWSa wiążą się koszty, czasami całkiem konkretne, zapoznaj się z cennikiem https://aws.amazon.com/ec2/pricing/, po skończonej pracy wyłączaj maszyny, używaj spot instances, minimalizuj wykorzystane volumes i generalnie czytaj cenniki rzeczy których używasz i trzymaj rękę na pulsie przez umieszczenie alarmów na wykorzystane środki na AWS

Linki:

Komunikacja między mikroserwisami

Jednym z pierwszych wyzwań stojących przed mikroserwisami jest wybór sposobu komunikacji.

photo-1475691058852-37b5d9b6a878

Wybór rodzaju interakcji

Wybierając odpowiedni w danym przypadku styl interakcji musimy zbadać jakiego rodzaju komunikacją mamy do czynienia. Mamy tutaj do wyboru:

  1. Jeden do jednego – inicjator wykonuje żądanie, które jest przetwarzane przez dokładnie jeden serwis odbierający żądanie
  2. Jeden do wielu – w tym modelu wiadomość może być przetwarzana przez wiele serwisów odbierających (w szczególnym wypadku może być to jeden lub zero serwisów). Zazwyczaj dla serwisu inicjującego konwersacje, będzie transparentne to ile serwisów przetwarza to żądanie

Styl interakcji

Wybór stylu interakcji sprowadza się do pytania czy komunikacja ma charakter synchroniczny czy asynchroniczny:

  1. Komunikacja synchroniczna – inicjator czeka na odpowiedź
  2. Komunikacja asynchroniczna – inicjator nie czeka na odpowiedź

tony-stoddard-DgZxBnZeQo8-unsplashsource:Photo by Tony Stoddard on Unsplash

Najpopularniejszymi wzorcami interakcji są:

  1. Odpal i zapomnij (ang. fire-and-forget) – inicjator konwersacji wysyła wiadomość, która dociera do odbiorcy. I to w zasadzie tyle. Ciężko sobie wyobraźić prostszy schemat konwersacji.2017-07-23 18_22_11-BlogGD - microservices pt3.png - Paint
  2. Zapytanie/odpowiedź – najczęściej stosowana metoda interakcji. Strona inicjująca odpytuje drugą i czeka na odpowiedź, która powinna pojawić się w określonym czasie.2017-07-23 18_24_32-BlogGD - microservices pt3.png - Paint
  3. Zapytanie/asynchroniczna odpowiedź – polega na wysłaniu zapytania przez klienta do serwisu, który odpowiada asynchronicznie. Jakie ma to implikacje? Otóż klient może w sposób nieblokujący czekać na odpowiedź. Nic nie stoi na przeszkodzie by w tym czasie robić inne obliczenia. Do klienta należy obsługa całkiem prawdopodobnej sytuacji, iż takiej odpowiedź nie dojdzie.2017-07-23 18_24_43-BlogGD - microservices pt3.png - Paint
  4. Publikacja/subskrypcja – przesyłanie wiadomości polega tutaj na udostępnianiu informacji przez publikatorów, a ich odbiorcami są wszystkie jednostki w systemie, które są zainteresowane danym komunikatem.2017-07-23 18_24_55-BlogGD - microservices pt3.png - Paint

Technikalia

Posiadając do wyboru kilka możliwych wzorców interakcji musimy zdecydować się jeszcze na techniczne szczegóły co do sposobu w jaki taka interakcja zostanie zrealizowana.

By zapewnić jak najlepszą niezawodność systemu przy wysokiej wydajności i skalowalności, najczęściej najlepszym wyborem będzie kombinacja technologii komunikacji. W różnych miejscach systemu możemy zastosować różne sposoby komunikacji:

  1. HTTP/REST API
  2. Wiadomości (messaging)
  3. Inny, specyficzny dla domeny protokół komunikacji

W zależności od tego który ze sposobów komunikacji wybierzemy musimy liczyć się z konsekwencjami. I tak:

1. HTTP/REST API

pavan-trikutam-71CjSSB83Wo-unsplashSource:Photo by Pavan Trikutam on Unsplash

Szybki, elastyczny sposób na implementację komunikacji pomiędzy serwisami. Dla większości programistów będzie to także po prostu najprostsze w użyciu narzędzie. Często wykorzystywany do wykonywania zapytań (w odróżnieniu do komend). Dużym plusem jest brak narzutu co do konkretnej technologii. Serwisy wykorzystujące komunikację poprzez HTTP/REST API mogą korzystać z szerokiej gamy rozwiązań. Co najważniejsze, nie ma problemu by po obu stronach komunikacji występowały całkowicie różne technologie.

Ta technologia, w najprostszej wersji, charakteryzuje się synchronicznością działania co w zależności od kontekstu będzie zaletą bądź też wadą. Dzięki powszechnej znajomości tego rozwiązania zazwyczaj nie będzie problemu z zastosowaniem tego rozwiązania. Definitywnym minusem tego rozwiązania jest wrażliwość na problemy z dostępem do sieci, w chwili wykonywania zapytania obie strony interakcji muszą działać. Inną wadą jest wymaganie znajomości adresu serwisu przez klienta. Intuicyjnie może to nie wydawać się jak duży problem, aczkolwiek skalowanie systemu wymaga od nas by klient mógł i wiedział jak może połączyć się z wszystkimi instancjami danego serwisu.

2. Wiadomości (messaging)

andrew-buchanan-2EdeFVe8TOE-unsplash

Wymiana informacji pomiędzy serwisami za pomocą wiadomości to świetny sposób na rozluźnienie powiązania pomiędzy nimi. Ta, z natury asynchroniczna, komunikacja polega na tym, że jedna ze stron komunikacji zapisuje wiadomość, natomiast druga ją odczytuje. Dobrze to współgra z wzorcami architektonicznymi takimi jak CQRS i EDD (Event-Driven Development). Decydując się na ten sposób komunikacji, musimy podjąć decyzję jakiej technologii użyjemy. Przykładowymi, popularnymi rozwiązaniami są: Apache Kafka, AWS Kinesis Streams, Azure Service Bus, RabbitMQ, NServiceBus, MassTransit, MSMQ. Wspomniane rozwiązania różnią się znacznie podejściem do architektury systemu, poziomem abstrakcji i sam opis tychże różnic to spory temat. Dodatkowo mamy tutaj spory wachlarz wzorców komunikacji jak np. : publikacja/subskrypcja czy też zapytanie/odpowiedź. Możemy tutaj uzyskać wysoką skalowalność jak i wysoką dostępność systemu za cenę dodatowej złożoności systemu spowodowanej wykorzystaniem infrastruktury umożliwiającej komunikację przez wiadomości.

3. Specyficzny protokół komunikacji taki przesył danych binarnych, JSON czy też XML.

Czasami sytuacja zmusza lub też zachęca nas do użycia jakiegoś innego formatu danych. Często jest to uwarunkowane specyficznymi wymaganiami w konkretnej domenie i umożliwia to np. wydajny streaming multimediów.

Komunikacja między serwisami wymaga od nas znajomości charakteru interakcji co potem wpływa na wybór technologii. Każda z tych decyzji niesie za sobą zalety ale i wady, ale mając ich świadomość jesteśmy w stanie zbudować system, który w wydajny sposób się komunikuje i wykorzystuje infrastrukturę by uzyskać zarówno wysoką dostępność jak i niezawodność.

Bibliografia i inne ciekawe materiały: