Copying ImageNet to EFS.

January 10, 2019 ยท View on GitHub

{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "Copies ImageNet from Edinburgh to AWS\n", "==================================\n", "\n", "The [original notebook][original] downloads imagenet from Kaggle. I'm paranoid, and I downloaded ImageNet from image-net.org directly. I want to absolutely sure that the version of ImageNet I'm running on AWS is the same as the one I'm running locally. So, I'm going to copy it from our machines to AWS.\n", "\n", "[original]: https://github.com/fastai/imagenet-fast/blob/master/aws/download_imagenet.ipynb" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "1. Create spot instance\n", "2. Mount EFS\n", "3. Copy from Edinburgh to AWS" ] }, { "cell_type": "code", "execution_count": 79, "metadata": {}, "outputs": [], "source": [ "# not goint to edit code so don't need this\n", "#%reload_ext autoreload\n", "#%autoreload 2\n", "#%matplotlib inline" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "from aws_setup import " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Define parameters" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "vpc_name='degenerate'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Get Existing VPC by tag name" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "vpc = get_vpc(vpc_name); vpc" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "None\n" ] } ], "source": [ "print(vpc)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Why did that fail?\n", "\n", "Because this list is empty:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(ec2.vpcs.filter(Filters=[{'Name': 'tag-value', 'Values': [vpc_name]}]))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Why is that list empty?" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "ec2.vpcsCollection(ec2.ServiceResource(), ec2.Vpc)" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ec2.vpcs.filter()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Looks like it's trying to connect to a fast-ai virtual cloud that exists in a different region. I guess I'll make my own, working from this boto4 tutorial." ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "vpc-0db9a09055c68d289\n" ] } ], "source": [ "# create VPC\n", "vpc = ec2.create_vpc(CidrBlock='192.168.0.0/16')\n", "# we can assign a name to vpc, or any resource, by using tag\n", "vpc.create_tags(Tags=[{"Key": "Name", "Value": f"{vpc_name}"}])\n", "vpc.wait_until_available()\n", "print(vpc.id)" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "ec2.Vpc(id='vpc-0db9a09055c68d289')" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "vpc = get_vpc(vpc_name); vpc" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Create EFS (if you haven't already)" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [], "source": [ "efs_tag = f'{vpc_name}-efs'" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Could not get VPC info: list index out of range\n" ] }, { "ename": "UnboundLocalError", "evalue": "local variable 'sg' referenced before assignment", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mUnboundLocalError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mefs\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcreate_efs\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mefs_tag\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvpc\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mperformance_mode\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'maxIO'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m~/repos/imagenet-fast/aws/aws_setup.py\u001b[0m in \u001b[0;36mcreate_efs\u001b[0;34m(name, vpc, performance_mode)\u001b[0m\n\u001b[1;32m 216\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mtime\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0msleep\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 217\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mcreate_efs\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvpc\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mperformance_mode\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'generalPurpose'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 218\u001b[0;31m \u001b[0msg_id\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msubnet_id\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_vpc_info\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvpc\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 219\u001b[0m \u001b[0mefsc\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0msession\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mclient\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'efs'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 220\u001b[0m \u001b[0mefs_response\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mefsc\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcreate_file_system\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mCreationToken\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34mf'{name}'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mPerformanceMode\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mperformance_mode\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/repos/imagenet-fast/aws/aws_setup.py\u001b[0m in \u001b[0;36mget_vpc_info\u001b[0;34m(vpc, availability_zone)\u001b[0m\n\u001b[1;32m 26\u001b[0m \u001b[0msubnet\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlist\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvpc\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msubnets\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfilter\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mFilters\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0msubnet_filters\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 27\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mException\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Could not get VPC info: '\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 28\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0msg\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mid\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msubnet\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mid\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 29\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 30\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mcreate_ec2_keypair\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mUnboundLocalError\u001b[0m: local variable 'sg' referenced before assignment" ] } ], "source": [ "efs = create_efs(efs_tag, vpc, performance_mode='maxIO')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Looks like our VPC doesn't have a security group. I suppose I should have continued to set up the VPC properly, as in the tutorial." ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "igw-05f0c305d061243a4\n", "rtb-045a88a127749ade1\n", "subnet-04f6f32213886fb81\n", "sg-0279bcfad97a5dbc7\n" ] } ], "source": [ "# create then attach internet gateway\n", "ig = ec2.create_internet_gateway()\n", "vpc.attach_internet_gateway(InternetGatewayId=ig.id)\n", "print(ig.id)\n", "\n", "# create a route table and a public route\n", "route_table = vpc.create_route_table()\n", "route = route_table.create_route(\n", " DestinationCidrBlock='0.0.0.0/0',\n", " GatewayId=ig.id\n", ")\n", "print(route_table.id)\n", "\n", "# create subnet\n", "subnet = ec2.create_subnet(CidrBlock='192.168.1.0/24', VpcId=vpc.id)\n", "print(subnet.id)\n", "\n", "# associate the route table with the subnet\n", "route_table.associate_with_subnet(SubnetId=subnet.id)\n", "\n", "# Create sec group\n", "sec_group = ec2.create_security_group(\n", " GroupName=f'{vpc_name}-security-group', Description=f'{vpc_name} sec group', VpcId=vpc.id)\n", "sec_group.authorize_ingress(\n", " CidrIp='0.0.0.0/0',\n", " IpProtocol='icmp',\n", " FromPort=-1,\n", " ToPort=-1\n", ")\n", "print(sec_group.id)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we can try and get that security group again:" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "ec2.SecurityGroup(id='sg-0279bcfad97a5dbc7')\n" ] } ], "source": [ "vpc_tag_name = list(filter(lambda i: i['Key'] == 'Name', vpc.tags))[0]['Value']\n", "sg = list(vpc.security_groups.filter(Filters=[{'Name': 'group-name', 'Values': [f'{vpc_tag_name}-security-group']}]))[0]\n", "print(sg)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "What about the subnet?" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "ename": "NameError", "evalue": "name 'subnet_filters' is not defined", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0msubnet_filters\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m{\u001b[0m\u001b[0;34m'Name'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;34m'tag-value'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Values'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0msubnet\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlist\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvpc\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msubnets\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfilter\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mFilters\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0msubnet_filters\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mNameError\u001b[0m: name 'subnet_filters' is not defined" ] } ], "source": [ "if None: subnet_filters.append({'Name': 'tag-value', 'Values': [None]})\n", "subnet = list(vpc.subnets.filter(Filters=subnet_filters))[0]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Our subnet didn't have the right tags:" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[ec2.Tag(resource_id='subnet-04f6f32213886fb81', key='Name', value='degenerate-subnet')]" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "subnet.create_tags(Tags=[{"Key": "Name", "Value": f"{vpc_name}-subnet"}])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now the above function should work." ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [], "source": [ "efs = create_efs(efs_tag, vpc, performance_mode='maxIO')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Request Spot instance" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "I don't need as fast a spot instance as the one used here, because I'm not going to be doing any preprocessing." ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "t3.micro 0.003500\n", "m1.small 0.006400\n", "t3.medium 0.013300\n", "m4.large 0.032900\n", "m5a.large 0.034100\n", "m5.large 0.034200\n", "m5d.large 0.036600\n", "m2.2xlarge 0.056600\n", "m3.xlarge 0.062300\n", "m5a.xlarge 0.069900\n", "m5.xlarge 0.077100\n", "m5d.xlarge 0.085700\n", "c1.medium 0.094300\n", "m1.large 0.111800\n", "m3.2xlarge 0.134300\n", "m5a.2xlarge 0.136000\n", "m5.2xlarge 0.138700\n", "m4.2xlarge 0.140800\n", "m5d.2xlarge 0.161100\n", "m5d.4xlarge 0.276400\n", "m4.4xlarge 0.279000\n", "m5a.4xlarge 0.310300\n", "m5.4xlarge 0.348200\n", "m4.10xlarge 0.654300\n", "m5.12xlarge 0.820900\n", "m5d.12xlarge 0.965000\n", "m4.16xlarge 1.062900\n", "i3.metal 1.690800\n", "m5d.24xlarge 1.823100\n", "m5a.24xlarge 3.595600\n" ] } ], "source": [ "spot_prices = get_spot_prices()\n", "sort_prices = sorted(list(spot_prices.items()), key=lambda x: x[1])\n", "for n, p in sort_prices:\n", " if 'm' in n:\n", " print(n,p)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The m4.large seems like a safe choice." ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [], "source": [ "instance_name = f'{vpc_name}-copy-imagenet'\n", "# Recommend a high compute instance as we need to do multi-threaded resizing later on\n", "instance_type = 'm4.large'" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Spot price: 0.032900, Bid price: 0.0987\n" ] } ], "source": [ "spot_price = get_spot_prices()[instance_type]\n", "bid_price = "%.4f" % (float(spot_price)3)\n", "print(f'Spot price: {spot_price}, Bid price: {bid_price}')" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [], "source": [ "launch_specs = LaunchSpecs(vpc, instance_type=instance_type).build()" ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [], "source": [ "launch_specs['BlockDeviceMappings'][0]['Ebs']['VolumeSize'] = 1000" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'ImageId': 'ami-c6ac1cbc',\n", " 'InstanceType': 'm4.large',\n", " 'KeyName': 'aws-key-degenerate',\n", " 'NetworkInterfaces': [{'DeviceIndex': 0,\n", " 'SubnetId': 'subnet-04f6f32213886fb81',\n", " 'Groups': ['sg-0279bcfad97a5dbc7'],\n", " 'AssociatePublicIpAddress': True}],\n", " 'BlockDeviceMappings': [{'DeviceName': '/dev/sda1',\n", " 'Ebs': {'VolumeSize': 1000,\n", " 'DeleteOnTermination': True,\n", " 'VolumeType': 'gp2'}}]}" ] }, "execution_count": 52, "metadata": {}, "output_type": "execute_result" } ], "source": [ "launch_specs" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [ { "ename": "ClientError", "evalue": "An error occurred (InvalidKeyPair.NotFound) when calling the RequestSpotInstances operation: The key pair 'aws-key-degenerate' does not exist", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mClientError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0minstance\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcreate_spot_instance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minstance_name\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlaunch_specs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mspot_price\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mbid_price\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m;\u001b[0m \u001b[0minstance\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m~/repos/imagenet-fast/aws/aws_setup.py\u001b[0m in \u001b[0;36mcreate_spot_instance\u001b[0;34m(name, launch_specs, spot_price)\u001b[0m\n\u001b[1;32m 198\u001b[0m \u001b[0mspot_requests\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mec2c\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrequest_spot_instances\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mLaunchSpecification\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mlaunch_specs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 199\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 200\u001b[0;31m \u001b[0mspot_requests\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mec2c\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrequest_spot_instances\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mSpotPrice\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mspot_price\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mLaunchSpecification\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mlaunch_specs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 201\u001b[0m \u001b[0mspot_request\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mspot_requests\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'SpotInstanceRequests'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 202\u001b[0m \u001b[0minstance_id\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mwait_on_fulfillment\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mspot_request\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/.local/lib/python3.7/site-packages/botocore/client.py\u001b[0m in \u001b[0;36m_api_call\u001b[0;34m(self, args, **kwargs)\u001b[0m\n\u001b[1;32m 355\u001b[0m "%s() only accepts keyword arguments." % py_operation_name)\n\u001b[1;32m 356\u001b[0m \u001b[0;31m# The "self" in this scope is referring to the BaseClient.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 357\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_make_api_call\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0moperation_name\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 358\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 359\u001b[0m \u001b[0m_api_call\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__name__\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpy_operation_name\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/.local/lib/python3.7/site-packages/botocore/client.py\u001b[0m in \u001b[0;36m_make_api_call\u001b[0;34m(self, operation_name, api_params)\u001b[0m\n\u001b[1;32m 659\u001b[0m \u001b[0merror_code\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mparsed_response\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m"Error"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m"Code"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 660\u001b[0m \u001b[0merror_class\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mexceptions\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfrom_code\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0merror_code\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 661\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0merror_class\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mparsed_response\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0moperation_name\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 662\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 663\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mparsed_response\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mClientError\u001b[0m: An error occurred (InvalidKeyPair.NotFound) when calling the RequestSpotInstances operation: The key pair 'aws-key-degenerate' does not exist" ] } ], "source": [ "instance = create_spot_instance(instance_name, launch_specs, spot_price=bid_price); instance" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Guess we have to create a keypair first:" ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Created keypair\n" ] } ], "source": [ "create_ec2_keypair(vpc_name)" ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Waiting on spot fullfillment...\n", "Waiting on spot fullfillment...\n", "Waiting on spot fullfillment...\n", "Waiting on spot fullfillment...\n", "Waiting on spot fullfillment...\n", "Waiting on spot fullfillment...\n", "Waiting on spot fullfillment...\n", "Fulfillment completed. InstanceId: i-02d21e221f464e4c6\n", "Rebooting...\n", "Completed. SSH: ssh -i ~/.ssh/aws-key-degenerate.pem ubuntu@54.172.175.127\n" ] }, { "data": { "text/plain": [ "ec2.Instance(id='i-02d21e221f464e4c6')" ] }, "execution_count": 56, "metadata": {}, "output_type": "execute_result" } ], "source": [ "instance = create_spot_instance(instance_name, launch_specs, spot_price=bid_price); instance" ] }, { "cell_type": "code", "execution_count": 57, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'ssh -i ~/.ssh/aws-key-degenerate.pem ubuntu@54.172.175.127'" ] }, "execution_count": 57, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# instance = get_instance(instance_name); instance\n", "get_ssh_command(instance)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Tried to connect by ssh on command line now. Wasn't able to connect, hangs trying to connect to that IP.\n", "\n", "Signed into AWS console to inspect and found that it's only open to ICMP connections, not TCP, so sshing on the console will fail. I suppose the ssh in this notebook uses ICMP?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### SSH" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This function was hardcoded to use the fast-ai key name, fixed it:" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "instances = ec2.instances.filter(\n", " Filters=[{'Name': 'instance-state-name', 'Values': ['running']}])" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "i-02d21e221f464e4c6 m4.large\n" ] } ], "source": [ "for instance in instances:\n", " print(instance.id, instance.instance_type)" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Connecting to SSH...\n", "Connected!\n" ] } ], "source": [ "client = connect_to_instance(instance, keypath=f"{os.environ['HOME']}/.ssh/{instance.key_name}.pem")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Mount EFS" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'fs-85703864.efs.us-east-1.amazonaws.com'" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "efs_addr = get_efs_address(f'{vpc_name}-efs'); efs_addr" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "_ = run_command(client, 'mkdir ~/efs')" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "efs_mount_cmd = f'sudo mount -t nfs -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2 {efs_addr}:/ ~/efs'\n", "_ = run_command(client, efs_mount_cmd)" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "('', '')" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "run_command(client, 'ls ~/efs') # no reformatting" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "## Tmux" ] }, { "cell_type": "code", "execution_count": 68, "metadata": {}, "outputs": [], "source": [ "tsess = TmuxSession(client, 'sess')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Copying Files" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Using rsync to copy imagenet files:" ] }, { "cell_type": "code", "execution_count": 74, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "ILSVRC-train.lmdb\tILSVRC-val.lmdb\r\n", "ILSVRC-train.lmdb-lock\tILSVRC-val.lmdb-lock\r\n" ] } ], "source": [ "!ls /disk/scratch_big/imagenet/" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Oh it's not actually on this server. It is on this one though:" ] }, { "cell_type": "code", "execution_count": 78, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "stty: standard input: Inappropriate ioctl for device\r\n", "train\r\n", "val\r\n" ] } ], "source": [ "!ssh apollo1 "ls /disk/scratch/datasets/imagenet"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "OK, I'm not running this rsync command in notebook (I want verbose output, and it would clog the notebook), but it is:\n", "\n", "\n", "rsync -avz -e \"ssh -i ~/.ssh/aws-key-degenerate.pem\" $PWD ubuntu@54.172.175.127:/home/ubuntu/efs_mount\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Checking progress. Full size to transfer is:" ] }, { "cell_type": "code", "execution_count": 80, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "stty: standard input: Inappropriate ioctl for device\n", "146G\t/disk/scratch/datasets/imagenet\n" ] } ], "source": [ "!ssh apollo1 "du -hs /disk/scratch/datasets/imagenet"" ] }, { "cell_type": "code", "execution_count": 85, "metadata": {}, "outputs": [], "source": [ "full_size = 1461e9" ] }, { "cell_type": "code", "execution_count": 83, "metadata": {}, "outputs": [], "source": [ "efs_size = lambda : 1e9float(run_command(client, "du -hs ~/efs_mount")[0].split('G')[0])" ] }, { "cell_type": "code", "execution_count": 87, "metadata": {}, "outputs": [], "source": [ "a = efs_size()\n", "time.sleep(605) # wait for five minutes\n", "b = efs_size()" ] }, { "cell_type": "code", "execution_count": 93, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "9204.545454545454\n", "153.4090909090909\n", "2.5568181818181817\n" ] } ], "source": [ "remaining = full_size - b\n", "seconds_remaining = 605remaining/(b-a)\n", "print(seconds_remaining)\n", "print(seconds_remaining/60.)\n", "print(seconds_remaining/(60.**2))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Should be done in about 3 hours." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Copying onto EFS\n", "\n", "I put the files in a directory on the EBS volume by accident. Copying from there to the EFS volume, that's now mounted at ~/efs." ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "('', '')" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "run_command(client, 'cp -r ~/efs_mount ~/efs') # no reformatting" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Get rid of that instance:" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'TerminatingInstances': [{'CurrentState': {'Code': 32,\n", " 'Name': 'shutting-down'},\n", " 'InstanceId': 'i-02d21e221f464e4c6',\n", " 'PreviousState': {'Code': 16, 'Name': 'running'}}],\n", " 'ResponseMetadata': {'RequestId': '94d722d5-32a2-45ef-b769-52556e2d2a83',\n", " 'HTTPStatusCode': 200,\n", " 'HTTPHeaders': {'content-type': 'text/xml;charset=UTF-8',\n", " 'transfer-encoding': 'chunked',\n", " 'vary': 'Accept-Encoding',\n", " 'date': 'Thu, 10 Jan 2019 21:28:44 GMT',\n", " 'server': 'AmazonEC2'},\n", " 'RetryAttempts': 0}}" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "instance.terminate()" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.2" } }, "nbformat": 4, "nbformat_minor": 2 }