手把手|AWS上穷玩机器学习攻略 如何省下八成开支

手把手|AWS上穷玩机器学习攻略 如何省下八成开支

大数据文摘作品,转载要求见文末

编译团队 | Aileen,吴蕾,寒小阳

在一个阴雨连绵的冬日清晨,一份账单进入我的眼帘。‘这些钱够我买半个很好的GPU了。’我想。对于机器学习来说,在Amazon租用一流的GPU是最佳方案,但是价格过于昂贵。为了将成本降低80%,我采取了种种举措后得到了一些经验,在此与诸位分享。

手把手|AWS上穷玩机器学习攻略 如何省下八成开支

内容目录

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有点吓人,很显然,对我这种第一次用的人来说操作细节仍是有些稀里糊涂。不过好消息是,这只要做一次就可以了。一个办法是根据亚马逊手册(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上穷玩机器学习攻略 如何省下八成开支

用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 <value> --instance-id <value> --device /dev/sdh

用AWS Console进行卷附着:打开AWS Console,选择EC2,然后:

第一步:选择我们刚才创建的卷(如果不确信,可以参看创建过的数据)

第二步:打开“Actions”

第三步:单击“Attach Volume”

手把手|AWS上穷玩机器学习攻略 如何省下八成开支

第四步:单击实例区域,实例列表会弹出。

第五步:选择实例,单机将其附着至卷。我们保留Device域为默认值。

第六步:确认并点击“Attach”按钮。

手把手|AWS上穷玩机器学习攻略 如何省下八成开支

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)

手把手|AWS上穷玩机器学习攻略 如何省下八成开支

第二步:将分离下来的卷,取一个新的名字

手把手|AWS上穷玩机器学习攻略 如何省下八成开支

第三步:为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

使用竞价实例一个月之后,亚马逊账单来了,这回只有几十美元,而不是几百美元,呵呵,今天天气真好啊。

相关推荐