您的位置:首頁>正文

手把手|AWS上窮玩機器學習攻略 如何省下八成開支

編譯團隊 | Aileen, 吳蕾, 寒小陽

在一個陰雨連綿的冬日清晨, 一份帳單進入我的眼簾。 ‘這些錢夠我買半個很好的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.

1.2私有雲虛擬機器(VPC)

首先, 我們需要設立一個私有雲虛擬機器, 這是一個有趣的虛擬網路,

來啟動你的虛擬機器器。 設置VPC有點嚇人, 很顯然, 對我這種第一次用的人來說操作細節仍是有些稀裡糊塗。 不過好消息是, 這只要做一次就可以了。 一個辦法是根據亞馬遜手冊(http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_Scenario1.html)來操作。 更好一些的辦法是, 用Fast.ai的課程Deep Learning for Coders(http://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(http://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

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

使用競價實例一個月之後,亞馬遜帳單來了,這回只有幾十美元,而不是幾百美元,呵呵,今天天氣真好啊。

我們可以用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

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

使用競價實例一個月之後,亞馬遜帳單來了,這回只有幾十美元,而不是幾百美元,呵呵,今天天氣真好啊。

同類文章
Next Article
喜欢就按个赞吧!!!
点击关闭提示