16 ядер і 30 Гб під капотом Вашого Jupyter за $0.25 на годину

Якщо Вам не дуже пощастило, і на роботі немає n-ядерного монстра, якого можна завантажити своїми скриптами, то ця стаття для Вас. Також якщо Ви звикли запускати скрипти на всю ніч і вранці читати, що десь забули скобочку, і 6 годин обчислень пропали) — у Вас є шанс нарешті познайомитися з Amazon Web Services.



У цій статті я розповім, як почати працювати з сервісом EC2. По суті це покрокова інструкція по напівавтоматичного оренду спотового инстанса AWS для роботи з Jupyter-блокнотами і складанням бібліотек Anaconda. Буде корисно, наприклад, тим, хто в змаганнях Kaggle все ще користується своїм іграшковим маком.



Напевно, реакція кожного, хто в перший раз зайшов на сайт Amazon Web Services — це розгубленість від великої кількості пропонованих послуг і віртуальних машин (які там називаються инстансами).
У цьому тьюториале я покажу, як недорого орендувати обчислювальний інстанси AWS і швидко налаштувати на ньому сервер Jupyter, щоб користуватись настільки улюбленими блокнотами. Акцент зробимо на складанні Anaconda і задачі машинного навчання, але зрозуміло, що сервер можна в різних цілях використовувати, хоч биткоины майнить :)

Мотивація: хочемо швидко (протягом 5-7 хвилин) отримувати доступ з Jupyter-блокнотів до обчислювальних ресурсів серйозніше, ніж у домашнього компа.
Взагалі є під цю справу непоганий тьюториал. Стаття, яку Ви читаєте — вільний переклад з доповненнями. Ми ще напишемо скрипт, який буде запускатися кожен раз при оренді машини. А ось і результат для тих, хто в поспіху.

Арендовывать ми будемо спотовий інстанси с3.4xlarge з 16 ядрами і 30 Гб RAM.
«Спотовий» означає, що по суті ми будемо брати участь в аукціоні і, призначивши ціну за годину користування машиною, мати до неї доступ до тих пір, поки попит не зросте. Якщо попит зросте, і ринкова ціна перевищить ту, яку ми призначили, машина від нас «втече», причому раптово. Саме з цієї причини (нестабільності) багато бояться користуватися спотовими инстансами, хоча на них можна сильно заощадити в порівнянні з инстансами «на вимогу». Та ж машина, але в більш стабільному режимі, обійдеться приблизно в $0.85/годину, ми витратимо вчетверо менше.

Тепер про типи машин. Вони непогано описані в документації AWS, так що вибираємо тип З — машини, оптимізовані для обчислень.

Оренда машини

Для початку зареєструємося на сайт Amazon Web Services. Тут інструкцій писати не буду — все як звичайно, треба буде підтвердити і по телефону, і по e-mail. До акаунта треба буде кредитну картку прив'язати, але якщо боїтеся витрат, можна інстанси m4large (2 CPU, 8 Gb RAM) взяти за $0.05/год.

Заходимо в свою консоль AWS і знаходимо в Services службу EC2 (Elastic Compute Cloud)



У розділі Spot Requests тиснемо «Request Spot Instance».



Вибираємо тип ОС, яка буде стояти на віртуальній машині. У загальних рисах: Windows дорожче, серед *Nix не так важливо, яку саме вибирати, нехай це буде Ubuntu.



На наступній вкладці нам пропонують вибрати власне інстанси. Тут позалипаем, посравниваем (тут все детальніше описано) і прокрутимо до с3.4xlarge.



Потім найголовніше — призначити ціну за годину користування виртуалкой. Ми бачимо поточні ціни у вибраних регіонах.



Якщо бачите, що у Вас ціни набагато вище, ніж на скріншоті, значить, зараз в поточному регіоні сплеск — змініть регіон (в правому верхньому кутку поряд з Вашим ім'ям). Я поки що з успіхом використовую регіон Frankfurt, але можна і повивчати статистику, подивитися, які регіони подешевше і зі стабільними цінами.

Ціну краще призначати в 1.5 рази вище поточної ринкової вартості инстанса в даному регіоні. При такому розкладі ціна буде трохи коливатися, але рідко перевищувати заявлену Вами. Відповідно, так машина не часто буде «відвалюватися».

Тепер підключимо сховище. Amazon пригощає тридцятьма Гб, так що чому б не взяти всі 30…



Тегування инстанса можна пропустити. І далі налаштування портів. Тут головне — відкрити порт, який ми будемо використовувати під Jupyter-сервер. Нехай за традицією це буде 8888. Тиснемо «Add rule», залишаємо варіант «Custom TCP rule» і вказуємо порт 8888. Також додаємо протоколи HTTP і HTTPS і говоримо, хто може прослуховувати порти. Досить вибрати праворуч галки My IP.



На наступному кроці створюємо ключ (pem-файл), який буде нас ідентифікувати при віддаленому підключенні до машини через SSH протокол. Можна його назвати як завгодно — головне після скачування знати, де він лежить і в жодному разі (!!!) не викладати на GitHub або кудись ще онлайн. Ставтеся до цього файлику майже як до пароля від банківської карти. Amazon рекомендує періодично оновлювати pem-файли (їх можна мати по 2 в кожному регіоні, другий раз завантажити той самий ключ не можна).



Нарешті всі підтверджуємо, чекаємо пару хвилин, поки інстанси запуститься, і в EC2 на вкладці «Instances» помічаємо, що щось з'явилося.



Вибираємо з'явився інстанси і тиснемо Connect. Amazon дає інструкції, що робити далі.

Якщо Ви сидите під Windows, то для Вас читання статті не закінчується (зазвичай на цьому місці в тьюторіалах можна прочитати «Windows? Good luck!»). Треба тільки прочитати інструкції Amazon, як підключитися за допомогою Putty.
Якщо ж Ви під *NIX, то виконуємо зазначені 2 команди:

chmod 400 <PEM file-name>.pem
ssh -i <PEM file-name>.pem ubuntu@<HOST>

Перша піклується про те, щоб не у всякого проходить був доступ до Вашого pem-файлу. Друга — це власне підключення до виртуалке зі своїм унікальним хостом.

Налаштування машини

Якщо все пройшло гладко, ви як юзер ubuntu потрапите в термінал віддаленої машини.
Можемо робити що завгодно, запускати будь-які скрипти, але ми зупинимося на налаштуванні инстанса для завдань машинного навчання з Jupyter. Всі команди далі описані, щоб у них було простіше розібратися (і переконатися, що все обійшлося без жартів в стилі rm -rf /), але взагалі вдруге і далі ми це будемо запускати bash-скриптом.

Викачуємо і встановлюємо Miniconda. Вона все ж набагато легше Anaconda, а необхідні бібліотеки ми довстановимо (втім, seaborn у мене не попер, а з Anaconda все нормально). Ми з машинкою ненадовго, навряд чи більше ніж на кілька годин, так що без перфекціонізму — встановлюємо все в домашній каталог.

wget -c http://repo.continuum.io/miniconda/Miniconda-latest-Linux-x86_64.sh
bash Miniconda-latest-Linux-x86_64.sh -b -p ~/miniconda
export PATH=~/miniconda/bin:$PATH

Тепер встановимо всі бібліотеки, які захочемо.
conda install -y numpy scipy pandas scikit-learn jupyter

Можна, наприклад, Vowpal Wabbit поставити (спритні лінійні моделі, які на великих вибірках часом вважаються і швидше MapReduce-реалізацій).
sudo apt-get -qq install vowpal-wabbit

Не завадить і Git — так можна відразу потрібний репозиторій завантажити (використання Amazon S3 я в даному тюьториале не розглядаю).
sudo apt-get -qq install git

Створимо сертифікат, щоб входити на Jupyter по паролю — так набагато безпечніше. Зараз зробимо це руками, з другого разу цей створений сертифікат буде використовуватися скриптом.

openssl req -x509 -nodes -365 days rsa:2048 -keyout jupyter.pem -out jupyter.pem


З'явиться запит про інформацію користувача. В принципі це не обов'язково заповнювати.

Тепер створимо пароль для входу на Jupyter-сервер.
Можна скористатися функцією passwd з Ipython
python
>>> from IPython.lib import passwd
>>> passwd('Sample password')

З'явиться хеш пароля. Копіюємо його.
'sha1:d0c0b7eb515e:f0e59fcd04aec7bb50886084ae8e1fa9a273f88e'

Нарешті, створюємо профіль IPython і запускаємо сервер, попередньо вказавши у файлі налаштувань, який порт ми хочемо використовувати і з яких адрес дозволений доступ. Вказуємо хешований пароль. У Вас пароль буде відрізнятися — треба вставити свій.
ipython create profile nbserver

printf "\n# Configuration file for ipython-notebook.\n
c = get_config()\n
# Notebook config\n
c.NotebookApp.ip = '*'\n
c.NotebookApp.password = u"sha1:d0c0b7eb515e:f0e59fcd04aec7bb50886084ae8e1fa9a273f88e"\n
c.NotebookApp.open_browser = False\n
c.NotebookApp.port = 8888\n" >> ~/.ipython/profile_nbserver/ipython_notebook_config.py

Останнє, що ми робимо тільки на віддаленій машині — запускаємо IPython-сервер.
(Чому IPython, а не Jupyter?.. Чому certfile явно вказано? Відповідь проста: милиці. Jupyter не хотів бачити config-файл, а потім не хотів у ній бачити налаштування файлу сертифіката. Перевірте, може, у Вас і з командою jupyter запуститься, і без явного вказівки файлу налаштування і сертифіката).
ipython notebook --config="~/.ipython/profile_nbserver/ipython_notebook_config.py" --certfile=jupyter.pem

Якщо все пройшло вдало, Ви побачите в кінці прочитаєте щось типу цього.
[I 10:09:08.774 NotebookApp] Serving notebooks from local directory: /home/ubuntu
[I 10:09:08.775 NotebookApp] 0 active kernels 
[I 10:09:08.775 NotebookApp] The Jupyter Notebook is running at: https://[all ip addresses on your system]:8888/
[I 10:09:08.775 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).

Профіт
Тепер переходимо в браузері на HOST:8888, де HOST — це, як і раніше, адресу вашого инстанса. Увага! Протокол повинен бути саме HTTPS, може також знадобитися підтвердження сертифіката. (Наприклад, в Chrome треба ткнути «Додаткові» і підтвердити перехід на сайт).

Вводимо свій пароль (тут вже, само собою, не хешований, а «звичайний») і бачимо приємну картинку файлову систему з Jupyter.



Створюємо новий блокнот і радіємо кількості ядер під капотом.



Тепер повернемося в термінал (нашого компа, а не віддаленої машини) і закинем на наш інстанси який-небудь набір даних. Скажімо, змагання Kaggle "Forest Type Cover Prediction".
scp -i <PEM file-name>.pem <LOCAL_PATH_TO_DATA> ubuntu@<HOST>:/~

Про машинне навчання, звичайно, цікаво поговорити, але тут ми просто запустимо випадковий ліс Sklearn на сирих даних.


Зверніть увагу на параметр n_jobs — тут ми якраз і задіємо всі 16 ядер.
1000 дерев максимальної глибини 15 навчилися ~ за 5 секунд — у 3 рази швидше, ніж на моєму MacBook Air з 4 ядрами і 4 Гб пам'яті. На великих вибірках різниця, звичайно, буде суттєвішим.



Те ж саме скриптом

Процес можна автоматизувати. З допомогою Python Amazon SDK по імені boto можна і резервування спотового инстанса скриптом робити. Але поки ми подивимося на скрипти, які готують машину для роботи з Jupyter вже після того, як вона запустилася.

Все це — в репозиторії Github.

Всього знадобляться 3 файлу:
  • config.txt записуєте шлях до свого pem-файлу, хост свіжо виданого инстанса, а також хешований пароль доступу до Jupyter-сервера, який ми створювали трохи раніше.
    pemfile='<PEM file->.pem'
    host='<HOST>'
    jupyter_password='<JUPYTER_PASSWORD>'
    

  • remote_setup.sh дописуєте все, що хочете виконати на віддаленій машині.

    # Installing Miniconda
    wget -c http://repo.continuum.io/miniconda/Miniconda-latest-Linux-x86_64.sh
    bash Miniconda-latest-Linux-x86_64.sh -b -p /home/ubuntu/miniconda
    export PATH=/home/ubuntu/miniconda/bin:$PATH
    
    #Installing neccesary libraries
    conda install -y numpy scipy pandas scikit-learn jupyter
    
    #Can add whatever you want to install
    #sudo apt-get -qq install vowpal-wabbit
    #sudo apt-get -qq install git
    
    ipython create profile nbserver
    
    printf "\n# Configuration file for ipython-notebook.\n
    c = get_config()\n
    # Notebook config\n
    c.NotebookApp.password = u'"$1"'\n
    c.NotebookApp.ip = '*'\n
    c.NotebookApp.open_browser = False\n
    c.NotebookApp.port = 8888\n" > ~/.ipython/profile_nbserver/ipython_notebook_config.py
    
    ipython notebook --config="~/.ipython/profile_nbserver/ipython_notebook_config.py" --certfile=jupyter.pem
    

  • Скрипт launch_remote_setup.sh просто виконує remote_setup.sh з потрібними параметрами на віддаленій машині.

    source 'config.txt'
    
    scp -i $pemfile ./ipython.pem ubuntu@$remote_host:~
    
    ssh -i $pemfile ubuntu@$remote_host 'bash -s' < remote_setup.sh $jupyter_password
    



У потрібному каталозі:
sh launch_remote_setup.sh


5-7 хвилин, і все! Можна працювати з Jupyter-сервером.

Вже зібрався було налити чаю. Але! Дуже важливий момент!
По закінченні роботи зупиніть ваш інстанси.
EC2 -> Instances -> Actions -> Instance State -> Terminate.

Саме terminate, а не stop (хоча для спотових це тільки й доступно). Але в разі запуску инстансов на вимогу stop не повністю вимикає машину, можуть набігати гроші за обмін даними.



Наостанок можна трохи обговорити фінанси. Поточний рахунок перевіряється в Amazon при натисканні на своє ім'я і потім на «Billing & Cost Management».
$0.25 / год — це близько $25 на місяць, якщо користуватися по 4 години кожен будній день. Далі кожен сам вирішує, чи готовий на такі витрати.

Можна тут прорекламувати і GitHub Student developer's Pack — я особисто з їх допомогою отримав сертифікат Amazon на $110, все ще ним користуюся. Крім того, для серйозних наукових проектів можна отримати грант Amazon.

Висновок
На цьому поки все. Думаю, для деяких це був jump-start в Amazon Web Services EC2. Дамо своїх машинок відпочити вночі!

PS. Зауваження / поради / обмін досвідом / pull request'и вітаються.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.