手把手 | AWS上窮玩兒機器攻略 如何省下八成開支
在一個陰雨連綿的冬日清晨,一份賬單進入我的眼簾。‘這些錢夠我買半個很好的GPU了。’我想。對於機器學習來說,在Amazon租用一流的GPU是最佳方案,但是價格過於昂貴。為了將成本降低80%,我采取了種種舉措後得到了一些經驗,在此與諸位分享。
內容目錄
1. 利用競價實例,運行機器學習項目
1.1 所需的工具
1.2 私有虛擬雲(VPC)
1.3 創建實例
1.4 登錄並測試
2. 競價實例的持久性-方法1:附著卷
2.1 創建一個卷
2.2 將卷附著至實例
2.3 將卷安裝至實例
3. Spot Instance的持久性: 方法2-根卷的切換
3.1 用一個新的實例
3.2 用一個已有的實例
4. 停止一個競價實例
通常,Amazon網絡業務(AWS)會為雲端虛擬機(instance)的使用提供不同的計費方式:
-
按需實例:按照特定的容量需求(CPU,內存等)租用實例,如果暫時不用了,可以將其‘關電’(stop)。之後你也可以再將它‘啟動’(start),延續之前的工作。隻有運行的實例是計費的。
-
預留實例:你為實例先預支一段時間的費用(通常1-3年)獲得使用權,這會比按需實例便宜50%左右。
-
競價實例:在任何時間,利用Amazon的剩餘容量進行計算。你可以對這部分容量進行競價,通常會比按需實例便宜,甚至比預留資源還便宜。
我研究了一下AWS賬單,很明顯,最大的成本確實在於運行實例。位居第二的是存儲成本,遠遠低於前者。這點很幸運,因為我們可以從競價實例中獲得便宜的價格。不過,用競價實例能便宜多少是因不同類型的實例有區別的。我通常使用P2競價實例,能夠節省70-80%的開銷(看下圖)。
競價實例使用提醒
競價實例確實便宜很多,不過有些限製需要在此提醒大家:
競價實例無法在暫停後重新啟用,它們隻能被終止。這是最大的不便之處。終止實例會造成破壞,你在停止了一個實例後再度運行,你之前所作出的更改無法得以保留。你可以保存終止任務的卷/盤上的內容,但是你新建一個實例後無法再使用它。
你有可能隨時麵臨超標的問題。如果此事發生,競價實例會自動終止運行。不過在我使用的幾個月的時間裏麵,隻發生過一次超標問題。
出於自身的需要,我找到了一些方法來規避競價實例的弱點。
1.用競價實例來運行機器學習程序
首先,我們來學習如何創建一個競價實例來開發並運行機器學習模型。我們想要使用P2實例,它配備了一塊或多塊強勁的NVIDIA K80 GPU,11G內存用於測試和訓練模型。P2有三種尺寸:
我們來看一下他們是如何運作的。
1.1所需工具
-
安裝AWS.cli,AWS cli是命令行工具箱,可以替代網頁版的AWS Console來管理AWS業務。
-
然後,運行aws configure來配置你的key,secret和region. AWS支持P2實例的地區(region)有北弗吉尼亞(us-east-1),俄勒岡(us-west-2)和愛爾蘭(eu-west-1)。通常,應選取地理位置靠近你的那個region.
-
最後,我們需要下載幫助腳本(helper scripts),支持我們的創建工作:git clone --depth=1 https://github.com/slavivanov/ec2-spotter.git
1.2私有雲虛擬機(VPC)
首先,我們需要設立一個私有雲虛擬機,這是一個有趣的虛擬網絡,來啟動你的虛擬機器。設置VPC有點嚇人,很顯然,對我這種第一次用的人來說操作細節仍是有些稀裏煳塗。不過好消息是,這隻要做一次就可以了。一個辦法是根據亞馬遜手冊(https://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_Scenario1.html)來操作。更好一些的辦法是,用Fast.ai的課程Deep Learning for Coders(https://course.fast.ai/)中提到的腳本,進行一些適配後去操作。如果你已經裝好了上麵提到的‘所需工具’,那麼直接運行下麵的腳本:. ec2-spotter/fast_ai/create_vpc.sh
它將幫助你創建一個VPC,Internet網管,子網,路由表,安全組,最重要的是密鑰對。我們會需要用最新創好的密鑰(位於~/.ssh/aws-key-fast-ai.pem)來進行實例創建工作。它還會打印出剛才創建的子網和安全組的ID信息,這些信息後麵會需要用到。
1.3 Create the Instance 創建一個實例
我們當然也可以遵循Amazon’s instructions for launching a spot instance(https://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_Scenario1.html)來進行操作,不過呢,如果希望更cool一些,我們可以用helper script中的start_spot_no_swap.sh來啟動實例。
我們需要將它傳到下麵的參數:
-
ami – 取決於我們挑選了那個地區,以及我們願意用Amazon image還是Fast.ai image,必須要挑選一個。
-
subnetId - 用create_vpc.sh打印出來的子網ID
-
securityGroupId – 用create_vpc.sh打印出來的安全組ID。
以下為示例:
ec2-spotter/fast_ai/start_spot_no_swap.sh --ami ami-53b23433 --subnetIdsubnet-9f69c3d6 --securityGroupId sg-a62f2ede
The script will then print the IP of our new Spot instance.
接下來,腳本就會打印出我們的競價實例的IP地址。
如果有需要,我們可以導入下述參數:volume_size(根卷的容量大小,以GB為單位,默認為128),密鑰名(在登入實例的時候,我們需要的密鑰文件的名字。默認是: aws-key-fast-ai), ec2spotter_instance_type(啟動實例的類型,默認是p2.xlarge), bid_price(我們願意付出的最大價格,以美元計價,默認是0.5)
1.4登錄及測試
用ssh進行連接,所需競價實例的IP地址是由上一步得到。
instance_ip=instance_ip_from_previous_step
ssh -i ~/.ssh/aws-key-fast-ai.pem ubuntu@$instance_ip
現在我們可以愉快地進行機器學習模塊的開發測試了。例如,我們運行MNIST上的Tensorflow教程:
python src/tensorflow/tensorflow/models/image/mnist/convolutional.py
結果:
...
I tensorflow/core/common_runtime/gpu/gpu_device.cc:885] Found device 0 with properties:
name: Tesla K80
major: 3 minor: 7 memoryClockRate (GHz) 0.8235
pciBusID 0000:00:1e.0
Total memory: 11.17GiB
Free memory: 11.11GiB
...
Step 0 (epoch 0.00), 771.1 ms
Minibatch loss: 8.334, learning rate: 0.010000
Minibatch error: 85.9%
Validation error: 84.6%
Step 100 (epoch 0.12), 12.2 ms
Minibatch loss: 3.262, learning rate: 0.010000
Minibatch error: 6.2%
Validation error: 7.3%
看上去都沒問題!
我們擁有了一個虛擬的私有網絡,一個價廉物美的競價實例,甚至還有一個模型在訓練。但是這一切還不完美。
如果我們費盡心血,獲得了上述的MNIST腳本,達到了理想的精度,卻在晚上關閉了實例,那這些這些超棒的模型將會付之東流。我們必須設法找到在競價實例上永久存儲數據的方法。很幸運,我們找到了兩種辦法。
2.競價實例的持久性:方法1-附著的卷
我們將要看一下我用來保存對競價實例更改的兩種主要方法。第一個辦法是用單獨的卷來存放模型和數據。這個卷是附著在競價實例上的。下麵是如何操作的步驟。
第一步,啟動一個競價實例(參考上述篇幅:用競價實例來運行機器學習程序)
2.1 創建一個卷
(隻要做一遍)我們可以用AWS cli或者網頁版AWS Console來做。
用AWS Console來創建一個卷:打開AWS console,選擇EC2,然後
第一步:打開“Volumes”;
第二步:點擊“Create Volume” 按鈕;
第三步:確認卷類型是“General Purpose SSD(GP2)” 高速SSD能讓我們頻繁快速地進入硬盤-例如:當我們的超大數據需要適配內存的時候;
第四步:選擇合適大小的卷,我一般選100GB;
第五步:確認Availability Zone和實例所在地是一致的。
用aws cli來創建卷
在以下bash命令中,根據需要更改卷的大小,並將可用區設置為實例所在的可用區。
volume_size=100
availability_zone=us-east-1e
aws ec2 create-volume --size $volume_size --availability-zone $availability_zone --volume-type gp2 --output text --query 'VolumeId'
2.2 將卷附著至實例
我們仍然使用cli或者web console。
用aws cli進行卷附著:剛才create-volume步驟中,已經獲得了卷ID。如果我們還不知道實例ID,我們可以在此查看實例(https://console.aws.amazon.com/ec2/v2/home#instances)。
aws ec2 attach-volume --volume-id --instance-id --device /dev/sdh
用AWS Console進行卷附著:打開AWS Console,選擇EC2,然後:
第一步:選擇我們剛才創建的卷(如果不確信,可以參看創建過的數據)
第二步:打開“Actions”
第三步:單擊“Attach Volume”
第四步:單擊實例區域,實例列表會彈出。
第五步:選擇實例,單機將其附著至卷。我們保留Device域為默認值。
第六步:確認並點擊“Attach”按鈕。
2.3 安裝卷
下麵步驟來自於Amazon的教程“如何令Amazon EBS卷可用”:
第一步:啟動SSH進入你的實例
ssh -i ~/.ssh/aws-key-fast-ai.pem ubuntu@$instance_ip
第二步:運行lsblk 查看這個卷是附著在哪個名字底下。
通常情況下,在ubuntu裏麵它會命名為“xvdf”,是列表中的最後一條記錄。
第三步:如果我們隻是創建新卷,我們需要對其進行文件係統格式化。運行命令:sudo mkfs -t ext4 device_name,其中device_name=/dev/加上第二步中獲得的設備名稱。例如:/dev/xvdh
第四步: 創建目錄,安裝卷:sudo mkdir mount_point
第五步:最後,安裝卷sudo mount device_name mount_point,至此所有你放置於mount_point目錄的東西都會被儲存於附著卷上。這就意味著,你可以終止競價實例,之後重啟一個新的,按照上麵的方法把這個卷附著並安裝上去,繼續中斷的工作。你可能還會需要用aws cli和crontab自動附著和安裝卷。
這個辦法我用了一段時間,發現了一個很大的缺陷—如果你把實例終止,所有永久卷之外的數據都會丟失。你可以嚐試對附著卷應用移動你的用戶目錄的方法,我試過但是不行,而下麵的方法能夠圓滿解決這個問題。
3.競價實例的永久性:方法2-切換根卷
很快地,我就厭煩於每次啟動競價實例的安裝工作,因此我嚐試尋找更好的方法。用這個方法,我終於成功地使競價實例獲得了按需實例能夠媲美的表現。通過啟動後迅速反轉根卷(操作係統工作卷)到另一個卷,這個方法得以實現。我花了好大的力氣才實驗成功,所以希望能夠幫到別人。用這個腳本處理一個新的實例,或者已有的實例。
第0步:
-
確認你已經裝載jq
-
確認你下載了幫助腳本,如果沒有,請運行git clone --depth=1 https://github.com/slavivanov/ec2-spotter.git
3.1 用一個新的實例
第一步:啟動一個競價實例(參考上述“用競價實例來運行機器學習程序)
第二步:運行sh ec2-spotter/fast_ai/config_from_instance.sh 它將創建一個配置文件,用於從一個既有的實例或者是按需實例來啟動一個競價實例,名稱為fast-ai-gpu-machine(下一步會用到)如果不想用名稱來尋找實例,你或許可以可以用腳本來實現:config_from_instance.sh --instance_id i-0fd47cabf6ce1d534
注意:這個腳本會終止第一步的腳本。如果你另外有一個實例以fast-ai-gpu-machine啟動,這個腳本或許會終止實例,所以,運行腳本之前,請先對其進行改名。sh ec2-spotter/fast_ai/config_from_instance.sh
第三步:每次需要P2競價實例的時候,隻要運行sh fast_ai/start_spot.sh.
這樣就會啟動一個新的競價實例,在boot的時候,其根卷就會切換到第一步創建的實例上去。這個過程會持續2-5分鍾。之後你就能夠中斷實例,再重啟(用start_spot.sh),任何對文件係統的更改都將得以保存。
3.2 用一個已有的實例
第一步:停止已有實例,從根卷上分離(detach)
第二步:將分離下來的卷,取一個新的名字
第三步:為example.conf創建一個拷貝,命名為my.confcp ec2-spotter/example.conf ec2-spotter/my.conf
第四步:更改my.conf中的設置,尤其是:
ec2spotter_volume_name : the name you gave the volume in step 2.用第二步中為卷取的名稱。
ec2spotter_launch_zone : the availability zone where you want to launch your instance.你想要啟動實例的區域
ec2spotter_subnet : ID of the subnet to use.準備使用的子網ID
ec2spotter_security_group : ID of the security group to attach to the instance.準備附著的安全組ID
ec2spotter_preboot_image_id : The image to preboot the instance with. Both Amazon and Fast.ai use Ubuntu 16.04 as base for their ML images. So we need to supply the Ubuntu 16.04 ami here: ami-a58d0dc5 (Oregon), ami-405f7226 (Ireland) or ami-6edd3078 (Virginia).預啟動實例的鏡像文件。Amazon和Fast.ai都用Ubuntu 16.04作為他們機器學習的基地。所以我們要在此提供Ubuntu 16.04:ami-a58d0dc5 (Oregon)
如果你還不知道子網ID,可以從你的子網得到,對於安全組,也是一樣的,從安全組得到。
第五步:每次你需要P2競價實例,就運行:
sh fast_ai/start_spot.sh.
這個腳本就會啟動一個新的競價實例,在boot階段就會切換到第一步創建的卷上去,這個過程會持續2-5分鍾。之後你就能夠中斷實例,再重啟(用start_spot.sh),任何對文件係統的更改都將得以保存。
4.停止一個競價實例
完成了當日工作後,如果沒有需要訓練的模型了,我就會用以下命令停止實例:
# Change $instance_id to your instance id obviously.
aws ec2 terminate-instances --instance-ids $instance_id
使用競價實例一個月之後,亞馬遜賬單來了,這回隻有幾十美元,而不是幾百美元,嗬嗬,今天天氣真好啊。
原文發布時間為:2017-03-30
本文來自雲棲社區合作夥伴“大數據文摘”,了解相關信息可以關注“BigDataDigest”微信公眾號
最後更新:2017-05-19 14:32:05