<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type="text/xsl" href="https://blog.de-souza.eu/xml/base.min.xml"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Léo’s Blog</title><link>https://blog.de-souza.eu/</link><description>Recent content on Léo’s Blog</description><generator>Hugo -- gohugo.io</generator><language>en</language><copyright>Copyright © 2019 Léo De Souza – Except where otherwise noted, content on this site is licensed under a Creative Commons Attribution 4.0 International License (http://creativecommons.org/licenses/by/4.0/).</copyright><lastBuildDate>Fri, 01 Mar 2019 10:00:11 +0100</lastBuildDate><atom:link href="https://blog.de-souza.eu/index.xml" rel="self" type="application/rss+xml"/><item><title>One-Click Deep Learning VM for fast.ai</title><link>https://blog.de-souza.eu/posts/one-click-deep-learning-vm-for-fast-ai/</link><pubDate>Fri, 01 Mar 2019 10:00:11 +0100</pubDate><guid>https://blog.de-souza.eu/posts/one-click-deep-learning-vm-for-fast-ai/</guid><description>&lt;p>In this post I will present the steps I used to set up a deep learning virtual machine, ready to use in one click with Google Cloud Platform.&lt;/p>
&lt;h3 id="creating-the-vm">
&lt;a class="Heading-link u-clickable" href="https://blog.de-souza.eu/posts/one-click-deep-learning-vm-for-fast-ai/#creating-the-vm">Creating the VM&lt;/a>
&lt;/h3>
&lt;p>Following the fast.ai course &lt;a href="https://course.fast.ai/start_gcp.html">recommendations&lt;/a>, the VM is based on the &lt;code>n1-highmem-8&lt;/code> machine type with a Nvidia Tesla P4 GPU. This GPU is not available in all regions &amp;ndash; I went with the region &lt;code>us-central1-a&lt;/code>.&lt;/p>
&lt;p>The boot disk size is set to 200 GB and the &amp;ldquo;Deep Learning Image&amp;rdquo; is installed (this image includes Anaconda, PyTorch and fastai). In the Management options, preemptibility is switched on.&lt;/p>
&lt;p>All commands below are sent to the VM via SSH.&lt;/p>
&lt;h3 id="jupyter-notebook-configuration">
&lt;a class="Heading-link u-clickable" href="https://blog.de-souza.eu/posts/one-click-deep-learning-vm-for-fast-ai/#jupyter-notebook-configuration">Jupyter Notebook Configuration&lt;/a>
&lt;/h3>
&lt;p>First, a SSL certificate is generated to access the Notebook via HTTPS:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">mkdir certs
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cd&lt;/span> certs
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">openssl req -x509 -nodes -days &lt;span class="m">365&lt;/span> -newkey rsa:1024 -keyout mycert.pem -out mycert.pem&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;p>Next, a password is created for Jupyter Notebook with IPython:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="n">ipython&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">IPython.lib&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">passwd&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">passwd&lt;/span>&lt;span class="p">()&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;p>This command takes a password and returns a cryptographic hash that will be saved in the Jupyter Notebook configuration. This configuration file is then generated and edited with the commands:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">jupyter notebook --generate-config
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">nano ~/.jupyter/jupyter_notebook_config.py&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;p>Four lines are added to the configuration file:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="n">c&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">NotebookApp&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">certfile&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s1">&amp;#39;/home/username/certs/mycert.pem&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">c&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">NotebookApp&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">ip&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s1">&amp;#39;0.0.0.0&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">c&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">NotebookApp&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">open_browser&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="kc">False&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">c&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">NotebookApp&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">password&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s1">&amp;#39;sha1:123456...789&amp;#39;&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;p>Where &lt;code>username&lt;/code> is the actual username and &lt;code>'sha1:123456...789'&lt;/code> is the hash returned by the &lt;code>passwd()&lt;/code> command above.&lt;/p>
&lt;h3 id="systemd-configuration">
&lt;a class="Heading-link u-clickable" href="https://blog.de-souza.eu/posts/one-click-deep-learning-vm-for-fast-ai/#systemd-configuration">Systemd Configuration&lt;/a>
&lt;/h3>
&lt;p>To access Jupyter Notebook directly from the VM&amp;rsquo;s IP address, traffic needs to be redirected from the default port to port 443. A systemd service is created for this purpose:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">sudo nano /etc/systemd/system/redirect-https.service&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;p>This oneshot service adds an iptable rule on startup to redirect all TCP traffic from port 443 to Jupyter Notebook&amp;rsquo;s default port 8888. The file is edited as follows:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-systemd" data-lang="systemd">&lt;span class="line">&lt;span class="cl">&lt;span class="k">[Unit]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na">Description&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">Redirect TCP from Port 443 to Port 8888&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">[Service]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na">Type&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">oneshot&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na">RemainAfterExit&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">yes&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na">ExecStart&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">/sbin/iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8888&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">[Install]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na">WantedBy&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">multi-user.target&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;p>To run Jupyter Notebook automatically on the VM startup, a second systemd service is created:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">sudo nano /etc/systemd/system/jupyter.service&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;p>This simple service runs Jupyter Notebook with the previously generated configuration in the user&amp;rsquo;s home directory and is edited as follows:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-systemd" data-lang="systemd">&lt;span class="line">&lt;span class="cl">&lt;span class="k">[Unit]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na">Description&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">Jupyter Notebook&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">[Service]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na">Type&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">simple&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na">User&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">username&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na">Group&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">username&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na">ExecStart&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">/opt/anaconda3/bin/jupyter-notebook --config=/home/username/.jupyter/jupyter_notebook_config.py&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na">WorkingDirectory&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">/home/username&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na">Restart&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">on-failure&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na">RestartSec&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">10&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">[Install]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na">WantedBy&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">multi-user.target&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;p>Where &lt;code>username&lt;/code> is replaced by the actual usename. Finally, both services are activated:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">sudo systemctl &lt;span class="nb">enable&lt;/span> redirect-https.service
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">sudo systemctl &lt;span class="nb">enable&lt;/span> jupyter.service&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;p>That&amp;rsquo;s it! In one click, the VM is started from the Google Cloud Platform console and Jupyter Notebook is available on its external IP address.&lt;/p></description></item><item><title>Hugo Flex</title><link>https://blog.de-souza.eu/posts/hugo-flex/</link><pubDate>Thu, 28 Feb 2019 18:00:00 +0100</pubDate><guid>https://blog.de-souza.eu/posts/hugo-flex/</guid><description>&lt;p>Today I released the theme I made for this blog, &lt;a href="https://themes.gohugo.io/hugo-flex/">Hugo Flex&lt;/a>. It can be used with the static site generator &lt;a href="https://gohugo.io/">Hugo&lt;/a>.&lt;/p>
&lt;p>As it is my first project with HTML and CSS, it is made with simplicity in mind and does not rely on any framework or external dependency.&lt;/p>
&lt;p>While developing this theme I made some opinionated choices:&lt;/p>
&lt;ul>
&lt;li>I decided not to go with the &amp;ldquo;&lt;a href="https://meyerweb.com/eric/tools/css/reset/">reset CSS&lt;/a>&amp;rdquo; approach and let the browsers decide on most of the basic styles (font sizes, paragraphs margins&amp;hellip;);&lt;/li>
&lt;li>I went with the &lt;a href="https://css-tricks.com/snippets/css/system-font-stack/">system font stack&lt;/a> used by Medium and Wordpress websites;&lt;/li>
&lt;li>I included all the CSS directly in every page;&lt;/li>
&lt;li>Last, I did not care about compatibility with older browsers and used CSS3 to make the theme responsive. This allowed me not to include any Javascript in the theme (except for optional &lt;a href="https://gohugo.io/content-management/shortcodes/">shortcodes&lt;/a>);&lt;/li>
&lt;/ul>
&lt;p>Feel free to use and modify this theme. Its repository can be found at: &lt;a href="https://github.com/de-souza/hugo-flex">https://github.com/de-souza/hugo-flex&lt;/a>&lt;/p></description></item></channel></rss>