Monthly Archives: January 2019

Setting up Docker Container with Tensorflow/Keras using Ubuntu Nvidia GPU acceleration

Deep learning is all the rage now. Here’s a quick and dirty guide to setting up a docker container with tensorflow/keras and leveraging gpu accelerations. The info here is available on the official sites of Docker, Nvidia, Ubuntu, and Tensorflow, but I put it all together here for you so you don’t have to hunt around.

I’m assuming you’re on Ubuntu with an Nvidia GPU. (I tested on Ubuntu 18)
In AWS, you can set your instance type to anything that starts with p* (e.g. p3.16xlarge).

Download the Nvidia driver

Visit https://www.nvidia.com/object/unix.html
(Probably pick the Latest Long Lived Branch Version of Linux x86_64/AMD64/EM64T)

wget the download link
e.g.

wget http://us.download.nvidia.com/XFree86/Linux-x86_64/410.93/NVIDIA-Linux-x86_64-410.93.run

Run the nvidia driver install script

chmod +x NVIDIA-Linux-x86_64-410.93.run
sudo ./NVIDIA-Linux-x86_64-410.93.run

Install Docker
reference

sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"

sudo apt-get update

sudo apt-get install docker-ce

Install Nvidia-Docker 2
reference

# Add the package repositories
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | \
  sudo apt-key add -

distribution=$(. /etc/os-release;echo $ID$VERSION_ID)

curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | \
  sudo tee /etc/apt/sources.list.d/nvidia-docker.list

sudo apt-get update

# Install nvidia-docker2 and reload the Docker daemon configuration
sudo apt-get install -y nvidia-docker2
sudo pkill -SIGHUP dockerd

# Test nvidia-smi with the latest official CUDA image
sudo docker run --runtime=nvidia --rm nvidia/cuda:9.0-base nvidia-smi

This is some personal misc setup

Create a “notebooks” under your home dir (/home/ubuntu)

mkdir ~/notebooks

Create a jupyter start up script in your home folder (/home/ubuntu)
filename: jup
Content:

if [ $# -eq 0 ]
  then
    cd $NOTEBOOK_HOME && jupyter notebook --ip=0.0.0.0 --allow-root --NotebookApp.token=''
  else
    cd $1 && jupyter notebook --ip=0.0.0.0 --allow-root --NotebookApp.token=''
fi

Start Docker container with tensorflow-gpu

sudo docker run --runtime=nvidia --env NOTEBOOK_HOME=/home/ubuntu/notebooks -p 8888:8888 -p 8080:8080 -v /home:/home -it --rm tensorflow/tensorflow:latest-gpu-py3-jupyter bash

This docker container will give you tensorflow with gpu support, python3, and a jupyter notebook.
For a list of other tensorflow container (e.g. non-gpu or python2 versions), see here.

If you created the jup script earlier, you can call that to start the Jupyter Notebook. This will also point the notebook home dir to ~/notebooks folder you created:

/home/ubuntu/jup

If you did not install the jup script, then you can run the following command.

jupyter notebook --allow-root

Note that the first time you invoke this, you’ll need to hit the url with the token that’s given to you

To exit the terminal without shutting down Jupyter notebook and the docker container:

Hit Ctrl+p+q

Inside Jupyter Notebook
Open a browser to:

http://SERVER:8888/tree

Some packages require git, so you may install it like so

!apt-get update
!apt-get install --assume-yes git

Inside the notebook, you can install python libraries like so:

!pip install keras
!pip install git+https://www.github.com/keras-team/keras-contrib.git

You can check to make sure your keras is using gpu as backend:

from keras import backend
assert len(backend.tensorflow_backend._get_available_gpus()) > 0
backend.tensorflow_backend._get_available_gpus()

And that’s how you create a docker container with gpu support in ubuntu.
After you install your packages, feel free to save your docker image so you don’t have to redo the apt-get and pip installs every time.

Advertisements
Tagged , , , ,

Deep Learning with Google Colab

I am beginning to learn deep learning and I’ve been working in the AWS environment with dockerized containers of tensorflow and keras. But it’s been a bit of a pain, transferring files fro/to the machines, starting/stopping them, etc. It’s also pretty expensive for a gpu machine.

Google is now offering free GPU-acclerated Jupyter notebooks which they call Colab. You just create a folder in your Google Drive and a Colaboratory App.
Just follow this tutorial and you’ll be up and running in 5 minutes!

Google Colab Free GPU Tutorial

(Only hitch I had was in mounting the drive. Blog said to run

drive.mount(‘/content/drive/’)

That gave me an error. Instead I ran

drive.mount(‘/content/drive’)

Note the removal of the trailing slash

Tagged ,

Angularjs: programmatically clicking a link on behalf of user

If you have a link, you can give embed it in the html for the user

<a>Click here</a>

But what if you didn’t have the url already but it had to be fetched. When does this scenario arise? As an example, I’ve developed a protocol where the user clicks a link which invokes an API that generates some data, which then the user can click on. Now I could have the user click the button once to generate a one-time download link and then write that link on the page and have the user click again. But that’s 2 clicks. Can we do the 2nd click on behalf of the user?

Yes, we can. Here’s how.

<a href="">Click here</a>

$scope.initiateDownloadSequence = function(first_url) {
  $http.get(first_url)
    .then(function(resp) {
      var second_url = resp.data;

      var anchor = document.createElement("a");
      anchor.href = second_url;

      // next 2 lines only if it's a download url
      // var filename = my-download.txt;
      // anchor.download = filename; 
    
      anchor.click();
    })
}
Tagged ,

AngularJs: Initiating Downloads with Headers

If you have an url to download a file, you can simply just put it in the html like so

<a href="/path/to/download" download>Download Now</a>

But what if that path is an API that requires authentication or some other headers to be set when it’s invoked? The above solution does not send over any headers that your app needs. Instead do this:

<a href="">Download Now</a>

  $scope.startDownload = function(downloadUrl) {

    $http({
      method: 'GET',
      url: downloadUrl,
      headers: {
        'Authorization': 'Bearer XSDREDX...'
      }
    }).then(function(resp) {
        var data = JSON.stringify(resp.data);
        var blob = new Blob([data], { type: "text/plain" });
        let objectUrl = window.URL.createObjectURL(blob);

        let anchor = document.createElement("a");
        anchor.href = objectUrl;
        var filename = 'downloaded-file.txt';
        anchor.download = filename;

        // some browsers (firefox) requires element to be attached to body
        anchor.style.display = 'none';
        document.body.appendChild(anchor);

        anchor.click();

        document.body.removeChild(anchor);

        window.URL.revokeObjectURL(objectUrl);      
      })
  }

Tagged ,

ellipsis

Use this to ellipsicize content that doesn’t fit within its specified width.

.ellipsis {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  -o-text-overflow: ellipsis;
}
Tagged