<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by François Lagunas on Medium]]></title>
        <description><![CDATA[Stories by François Lagunas on Medium]]></description>
        <link>https://medium.com/@francois.lagunas?source=rss-42901dd712e6------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/2*boZ7PQLsRYKRUFrw3RhHYw.jpeg</url>
            <title>Stories by François Lagunas on Medium</title>
            <link>https://medium.com/@francois.lagunas?source=rss-42901dd712e6------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Wed, 27 May 2026 09:12:15 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@francois.lagunas/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Sparse Neural Networks (2/N): GPU Performance.]]></title>
            <link>https://medium.com/huggingface/sparse-neural-networks-2-n-gpu-performance-b8bc9ce950fc?source=rss-42901dd712e6------2</link>
            <guid isPermaLink="false">https://medium.com/p/b8bc9ce950fc</guid>
            <category><![CDATA[nvidia]]></category>
            <category><![CDATA[hardware]]></category>
            <category><![CDATA[ampere]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[gpu]]></category>
            <dc:creator><![CDATA[François Lagunas]]></dc:creator>
            <pubDate>Thu, 28 May 2020 21:23:50 GMT</pubDate>
            <atom:updated>2020-05-28T21:23:50.389Z</atom:updated>
            <content:encoded><![CDATA[<h3>Sparse Neural Networks (2/N): Understanding GPU Performance.</h3><p><strong>NVIDIA Ampere A100 introduces fine-grained structured sparsity</strong></p><p>Welcome back for this series on Sparse Neural Networks. In case you have not read our first introductory episode, <a href="https://link.medium.com/In4bINyeO3">here it is</a>.</p><p>I told you last time that<strong> sparsity would a major topic in 2020</strong>, and it looks like it’s getting indeed some steam: <strong>Nvidia</strong> is announcing with the <strong>Ampere</strong> GPU generation that<strong> sparsity is directly baked into their GPU design.</strong></p><p>It’s quite a bold move: if you consider the time it takes to design and produce a new GPU line, they made this decision at least 2 years ago, and you need some vista to understand that it would be an important trend 2 years later.</p><figure><img alt="André Ampère" src="https://cdn-images-1.medium.com/max/337/1*M1ky4jno_MmGg5eR3tgGyg.png" /><figcaption>André Ampère, 1825 (from Wikipedia)</figcaption></figure><p>So that’s the perfect pretext to make a large digression on <strong>GPU architectures</strong> and why knowing better about them may matter for your daily Machine Learning jobs.</p><p>To be honest, this will more matter to you if you are working on some low-level code.</p><p>If you are using PyTorch or other libraries, and you are just using the extremely good tools it provides, you are probably fine.</p><p>But<strong> </strong><a href="https://www.joelonsoftware.com/2002/11/11/the-law-of-leaky-abstractions/"><strong>leaky abstractions</strong></a><strong> come back at you </strong>faster than you’d think<strong>.</strong> Your model got a bit heavier? Want to train faster? OK, let’s use a DataParallel PyTorch node, and we’ll be fine on 8 GPUs. But wait, why my GPU usage is down the gutter? And on 8 GPUs it’s only 3 times as fast as on a single one?</p><p>It especially matters to me, as I have been telling you last time that the <strong>performance of sparse matrices operations was not satisfactory</strong>. Today we’ll see why it can be hard to get good performance on GPUs, how it depends on your data structure and algorithms, and how you can overcome it, or at some times at least mitigate some issues.</p><p>And of course, all this is a good pretext to read about some mind-blowing GFlops numbers and killer optimizations, nothing to sneeze at…</p><h3>Some physics</h3><p>You may wonder why your PC/Mac is not significantly faster than a few years ago. That’s because most of the apps you are using are mostly sequential: they are doing only one thing at a time, or almost, and sequential performance has been stagnating for some years.</p><p>That’s because sequential performance is mostly limited by <strong>operating</strong> <strong>frequency</strong>, which is itself limited by:</p><ul><li>the<strong> size of the finest details</strong> that are drawn on the silicon, something that is getting harder and harder to improve,</li><li>the amount of <strong>heat</strong> that is created by the chips, a function of voltage and frequency. First, a <strong>transistor</strong> emits heat when <strong>changing state</strong>, so proportionally to frequency. Second, <strong>the higher the frequency, the higher the voltage</strong> you need. So in the end <strong>emitted heat is more than linear in the frequency</strong>, not something ideal.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0b-KUkO2e22UPpPKrRi9PQ.png" /><figcaption>From <a href="https://youtu.be/Knd-U-avG0c?t=109">https://youtu.be/Knd-U-avG0c</a></figcaption></figure><p>So if you could efficiently and cheaply remove heat from the chips, you could get higher frequencies, but only marginally, and it gets quickly impractical (water-cooling, you know, is <em>cool</em>, but <a href="https://www.avadirect.com/blog/leaking-liquid-cooler-whats-next/">not when it leaks</a>…).</p><p><strong>The recent ARM takeover is not an accident</strong>. When you work for years on <strong>low consumption and so low heat producing chips,</strong> when everybody hits the “heat wall”, you are in a <strong>good position to</strong><a href="https://9to5mac.com/2018/11/01/geekbench-ipad-pro-performance/"><strong> push performance higher</strong></a>, even if computers migrating to your pocket was the opportunity that made the difference.</p><h3>Chip design</h3><p>So people invented tricks to make use of the same amount of cycles to do more, to do almost any instruction in one single cycle, to forecast what’s the next instruction etc. Very different architectures to tackle the same issues were used (<a href="https://cs.stanford.edu/people/eroberts/courses/soco/projects/risc/risccisc/">RISC, CISC</a>). But the returns are diminishing, as always.</p><p>So what can you do to feed the hungry “Moore’s Law Beast”, and the marketing guys who keep asking why the numbers are flattening?</p><p>You look for problems that need to do the same kind of task a billion times, and each task does not need the result of another task, so all tasks can be computed at the same time. (the technical slang for this is “<a href="https://en.wikipedia.org/wiki/Embarrassingly_parallel"><strong>Embarrassingly Parallel</strong></a>” …).</p><p>Fortunately, there are a lot of them. <strong>Linear Algebra</strong>, for example, is highly parallel by nature, and <strong>machine learning</strong> is using it a lot, like lots of <strong>physics</strong> <strong>simulation</strong>, <strong>computer</strong> <strong>graphics</strong>, and so on.</p><p>So instead of increasingly complex single cores processors, we see much simpler (and smaller on silicon) cores but grouped by the hundreds or thousands. This way you are guaranteed that the ratio computation/silicon area is getting through the roof.</p><p>Great. That’s a simple idea. But of course, reality is more complex than that.</p><h3>Bottlenecks</h3><p><strong>If you have a lot of computing power available, you have to feed it with data. </strong>Memory is getting faster with time, but it’s harder than just duplicating cores. Because<strong> memory buses are basically 1D, and compute cores are 2D</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Fruof2lsq_v7hdrXZUhRjg.png" /><figcaption>From <a href="https://unsplash.com/photos/VEVfbQtyB8s">https://unsplash.com/photos/VEVfbQtyB8s</a></figcaption></figure><p>You can think about it as a <strong>city</strong> (the computing cores), and the suburban workers coming each morning in the city (the data). <strong>The city is 2D, the highways are 1D,</strong> and of course, you get some heavy traffic jams. So you add some new <strong>lanes</strong> on the <strong>highways</strong> (the width of the memory bus), but it’s always the <strong>bottleneck</strong></p><p>If you want to maximize the highway utility, you would have to use all day long, encouraging people to come to and leave from work earlier or later.</p><p>That’s the same thing for the memory bus: <strong>you have to make sure that you are balancing computation and memory transfers so you don’t waste time waiting without using the memory bus or the compute cores</strong>. That’s why it’s hard to reach peak performance for every task.</p><p>Some tasks even prefer to compute twice the same thing instead of transferring some data: <strong>compute is plentiful and memory bandwidth is scarce </strong>(and the gap is growing each year). In graphics, procedural texturing is used more and more for this exact reason: textures need bandwidth, and so if you can generate the same result with few memory transfers but some additional compute, it’s a win.</p><h3>GPU Architecture principles</h3><p>A lot of the complexities of GPU architectures exist to overcome those bottlenecks.</p><h4>Hierarchy</h4><p><strong>You don’t get the 1000s of cores in a GPU in a single bag: they are grouped at multiple levels. </strong>We’ll take the example of the new Ampere A100. Numbers change according to the generation, but the general principles are slowly evolving. (Numbers below come mostly from the <a href="https://devblogs.nvidia.com/nvidia-ampere-architecture-in-depth/">Nvidia blog</a>)</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*i60_7GqIKxjgunaXe7CiCw.png" /><figcaption><em>The GA100 streaming multiprocessor (SM)</em></figcaption></figure><p>At the lower level you have a Streaming Processor (SP). He is part of a group of 16 SP which computes the same sequence of instructions at the same time.</p><p>(To be more precise, you have 16 FP32 cores, 8 FP64 cores, 16 INT32 cores, 1 Tensor Core, and 1 texture unit per group. More on tensor cores later)</p><p><strong>The first constraint is the following: the 16 SP in the group cannot diverge from a single sequence instruction. This is called SIMD: Same Instruction, Multiple Data.</strong> That’s not exactly true, the instructions can contain “if“ statement, but if different branches are taken, some compute will be lost because every processor will have to execute both branches, and throw the results that are not useful for its own work.</p><p>4 groups of 16 SPs form a Streaming Multiprocessor (SM). Each group executes the same kernel (=function), but not in a strictly synchronized way. Still, you’ll have at least 64 cores working on the same task, or you’ll lose some computing capacity.</p><p>Then, you group 2 SMs to form a “Texture Processing Cluster” (TPC), and you group 8 TPCs to form a GPC (GPU Processing Cluster). 8GPCs and you have an A100 GPU. Pfew!</p><p><strong>To sum it up, there are 128 SMs in an A100, so 8192 FP32 cores, but as you can see, we are far from getting a flat set of “8192” cores! </strong>(those are maximum numbers, first processors won’t have the full set of cores)<strong>.</strong></p><p>If you compare the A100 structure with the Volta V100, these structural numbers are almost the same, except for the PCs, and so for the grand total of course. The innards of the cores of course have changed too, but it looks like that the communication structure of the V100 was considered quite good for the kind of job it’s usually given. The Tensor Cores seems to be the area where the most innovation is taking place (more on this later).</p><p>You can see in the comparison below that all those numbers varied significantly with time, in search of the best performance :</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*MmPCD_ypvtHDhwAGUZhqHQ.png" /></figure><h4>Why so many levels? Performance</h4><p><strong>The main reason is of course to improve real-life performance. And in real life, you don’t have a single task to be done.</strong></p><p>First, there may be several processes using your GPU at the same time on your machine. Not sure if it’s a good idea to get some good performance, but it’s of course something very usual.</p><p><strong>In the new Ampere GPU, you can even partition your GPU to server multiple Virtual Machines with strong guarantees on your data security: the new feature is called “Multi-Instance GPU”.</strong></p><p>In a single process, if your network contains <strong>several layers</strong>, some linear, some non-linear, some embedding, each one will use one or <strong>several kernels</strong> to do its job.</p><p>You may think that they are executed one after the other. It’s true to some extent, but in order to<strong> keep your GPU busy</strong>, your <strong>CPU</strong> is sending a <strong>stream of tasks to be done</strong>, not a task after the other, and the GPU will do them without the CPU waiting for each one to complete.</p><p>The CPU will basically wait after a full batch has been processed, after the forward and backward pass, because he has to update the full model before starting a new batch.</p><p>There are several reasons to have this “stream of task” model:</p><ul><li>The first reason is that starting a task takes some time, so the GPU can prepare the next task before the previous is started: changing the active kernel on some part of the GPU takes some time, <strong>pipelining</strong> saves time.</li><li>Second, in the task stream, some tasks are not dependent on each other, so both can be executed in parallel in the GPU, so more work to be done, so less chance some part of the GPU is idling.</li></ul><p>Some <strong>networks</strong> are <strong>very, very parallel </strong>to compute, like <strong>Transformers</strong>, and so their efficiency is very good:</p><ul><li>there are only a <strong>few different layers</strong>, so <strong>few kernel changes</strong> and a lot of work for each kernel</li><li>there are only <strong>loose dependencies between computations</strong> (eg for each token), so the GPU has a lot of degrees of freedom when scheduling the different parts of the computation: if a kernel is waiting for some data, maybe another one can compute its result because it already has its own data available.</li></ul><h4>Why so many levels? Economics</h4><p>Another reason is that it’s hard to get zero-defect silicon at this level of detail.</p><p><strong>Ampere GPUs</strong> contain <strong>54 billion transistors</strong>. Any defective transistor, and you may have to throw the GPU to the bin. <strong>The fraction of chips that pass the test is called the <em>yield</em>.</strong> Those chips are huge, and silicon real estate costs a lot, so each failed chip is a big loss, just for a small defect on a single transistor somewhere in the silicon.</p><p>So instead of throwing the chip to the bin, <strong>you test some sub-parts of the chip, and you just disable the failing sub-parts</strong>. That means, for example, disabling a GPC (remember, there are 7 of them in a A100, instead of a theoretical 8). And you sell it in a lower-end card, <strong>with reduced specs</strong>. This process is called <strong><em>binning</em></strong>. If you are really good, and your chips are all perfect, you may even disable perfectly working parts of your chip, to segment your offer (and back in time, some users were able to re-enable those disabled parts of silicon to get the bang without the buck…)</p><h3>Developing for GPUs</h3><p>So what are the consequences of the GPU architecture choices on development?</p><h4>Kernels</h4><p>First, <strong>you have to write some kernels,</strong> using the primitives you get. It’s a quite specific exercise, as you have to manually manage caches, registers, the synchronization of the different cores, etc. For simple stuff like matrix products, or activation layers, it’s quite straightforward, as they are completely parallel by nature.</p><p>But for some algorithms, like sorting, it can be a lot trickier to have something efficient, because you will have some issues using all the cores all the time.</p><h4><strong>Grids and performance</strong></h4><p>That’s because the kernel is only a small part of the problem, the other is the way you distribute the work among cores. And the performance gains are often made more on the distribution than on an optimal kernel.</p><p>The way you distribute the work is usually done by<strong> partitioning your job into a 2D or 3D grid, </strong>then mapping each point of the grid to a thread, and finally mapping those threads to physical cores. Those dimensions will correspond for example to the dimensions of the output of a layer, plus the batch dimension.</p><p>As you have seen, in a GPU you get thousands of cores to work with, but with a really complex multi-layered structure. And this structure change according to the generation and model of the GPU. <strong>So it’s hard to find the right way to choose those mappings.</strong> You often have to make some benchmarks to find the right way to do a computation with given dimensions on a specific GPU, and that information will be used in the future to choose the best strategy at runtime.</p><h4>Memory</h4><p><strong>But the main and the most difficult hurdle a developer face while developing for GPU’s architecture is managing memory.</strong> And specifically memory transfers. The available memory bandwidth is huge, but the computing power is even larger. And just as you did not get a flat space of computing cores, you don’t get completely random access to the memory for free.</p><p><strong>If you want to access a float number stored in the main memory from a GPU core, you will wait literally for <em>ages </em>compared to the time it takes to compute a sum or a multiply.</strong> So you need to be able to start hundreds of computations at once, and when the data is finally available, you resume your kernel, you execute a few local operations, until you need some more data from the main memory.</p><p>Some special ops like “prefetch” exist, to declare that you will need some data in a few instructions, and the role of the compiler is to reorder the instructions so you keep the memory controllers busy while keeping the core busy too. And at runtime, a large part of the GPU silicon is devoted to handling all those threads that are “in flight” and their current memory requests.</p><p>But there are some low-level constraints that may cost you a lot. Just like the base computation unit is 16 cores doing the same job,<strong> you really get peak memory performance if you load memory by quite large contiguous blocks, </strong>for example, 16 floats = 64 bytes, by a group of threads (called warp in CUDA lingo). This is called <strong><em>coalesced</em></strong> access. This is another reason, and often the main one, why choosing the right grid to dispatch your task on is important.</p><p>So now, let’s unroll back to our initial issue if you still remember (I would forgive you, I can barely): <strong>why sparse matrices ops are slow?</strong></p><p><strong>If you look at the memory access pattern you need to make a sparse matrix/ matrix multiplication, you’ll see that by definition it’s hard to have those blocks of 16 floats when reading the matrix weights</strong>. And reading 16 contiguous floats is just a minimum, you’ll need to read more data at once to reach full performance.</p><p>That explains why a naive implementation can be at least an order of magnitude slower than the dense version.</p><p>Unless you make some compromise and use a <strong>block sparse matrix</strong>: each block, if large enough, will produce <strong>large contiguous accesses</strong>. 8x8 blocks is a minimum in <a href="https://openai.com/blog/block-sparse-gpu-kernels/">OpenAI implementation</a>, but you will get even better performance with 32x32 blocks.</p><p>But of course, you have to make sure that your model is working in a similar fashion with block sparse compared to pure sparse matrices. It can be the case if your matrices are large enough so block size is small in comparison, but you have to check.</p><p>The other way is to convince an executive at Nvidia to add some hardware sparse support into their next-gen GPU, and now it’s done. More on this below!</p><h4>Inter-GPU memory transfer</h4><p><strong>Memory bottlenecks exist within the GPU, but if you work with multiple GPUs sharing a single model, the available bandwidth is way lower than between memory and cores.</strong></p><p>The <a href="https://pytorch.org/tutorials/beginner/blitz/data_parallel_tutorial.html"><strong>DataParallel</strong></a> node of <strong>PyTorch</strong> is convenient, but it is no magic: after each batch, the GPUs must send their gradients to a single GPU, and then this latter must broadcast the updated model to each GPU. <strong>If your model is big enough, this transfer can take very significant time, and the performance will suffer. </strong>Another point is that the transfers are synchronous, no GPU can work if the new model has not been received.</p><p>Another way to use multiple GPUs is to split a single model between the different GPUs, and then transfer only the “frontier” layers from a GPU to the next. Same thing for backpropagation. This may not be ideal either as the first layer will have to wait for the last to complete before the backpropagation can occur. The performance will depend heavily on the morphology of the network.</p><h3>Ampere Highlights</h3><p>Let’s finish where we started, with the latest Nvidia announcement.</p><h4>Tensor Cores</h4><p>With Volta, Nvidia introduced new “<strong>Tensor Core units</strong>”, and it looks like they are here to stay. Turing and now <strong>Ampere</strong> iterated on these new units.</p><p>You can see them as ultra-specialized units, with some significant dedicated silicon.</p><p>And this means a lot in terms of speed, especially quantized networks inference :</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*e7SMvK3WdZmz32poFUQaJA.gif" /><figcaption>From <a href="https://youtu.be/yyR0ZoCeBO8?t=19">https://youtu.be/yyR0ZoCeBO8?t=19</a></figcaption></figure><p>For training, it was a bit more difficult on Volta, as working with FP16 was possible but a bit tricky (the 8x gain in speed was indeed tempting).</p><p><strong>But now with Ampere, Nvidia announces support for FP32 and even FP64 for Tensor Cores.</strong> <strong>And it looks like FP32 is now 20 times faster than on Volta with sparsity, and 10 times without sparsity.</strong> And this is for training and inference because it’s just big tensor ops, nothing special here.</p><p>It looks like we’ll be getting some nice toys to play with.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*rBrF53VkNYC5gL6YJExXxQ.png" /></figure><h4>Sparsity</h4><p>From the <a href="https://devblogs.nvidia.com/nvidia-ampere-architecture-in-depth/#">Nvidia Blog</a> :</p><blockquote>NVIDIA has developed a simple and universal recipe for sparsifying deep neural networks for inference using this 2:4 structured sparsity pattern.</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*xq_MGzOOGVazlgAT8766uA.png" /></figure><p>If you have read the first part of this series, you should feel at home.</p><p><strong>The idea</strong> is simple: maybe using a fully dense matrix is not useful. And what Nvidia is claiming is that it’s true, <strong>keeping only half the weights has a minimal impact on precision.</strong></p><p>And so they propose a method to reduce the number of weights. <strong>But what is more interesting, is that the A100 GPU has new instructions to process efficiently these sparse matrices, at twice the speed of dense ones </strong>(no magic here, only half the multiply occurs of course).</p><p>So anyone can try its own method to sparsify the matrices and use the new instructions to speed things up. <strong>The only constraint is that the sparse pattern is fixed, as every 4 cells must have 2 sparse ones at most.</strong></p><p>You can compare this to the way textures are compressed to save memory but for floating computation and not just graphics.</p><p><strong>I see it mostly for inference at first, but I am sure some clever people will come with imaginative ways to use those new capabilities for training too, as it’s just some new compute ops.</strong></p><p>What about “sparse block sparse matrices”, by combining soon to be released OpenAI “block sparse matrices” with this? We’ll see.</p><h3>Conclusion</h3><p>I hope you enjoyed this second part of our trip to sparse land, even if it may have been a bit harder to digest.</p><p>I hope too this will help you to better understand th<strong>e level of mastery developers in the PyTorch or Keras team show</strong>: they manage to <strong>hide all this complexity </strong>and make it easy for mere mortals to use these supercomputer-on-a-chip to their full power, in just a <strong>few lines of python.</strong></p><p>Next time we will get back to more usual depths: we’ll see some<strong> techniques we can use to train sparse networks</strong>, and how performance is impacted.</p><p>By the way, congrats to Victor Sanh, Thomas Wolf, and Alexander M. Rush for their latest paper “<a href="https://arxiv.org/abs/2005.07683">Movement Pruning: Adaptive Sparsity by Fine-Tuning</a>”!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b8bc9ce950fc" width="1" height="1" alt=""><hr><p><a href="https://medium.com/huggingface/sparse-neural-networks-2-n-gpu-performance-b8bc9ce950fc">Sparse Neural Networks (2/N): GPU Performance.</a> was originally published in <a href="https://medium.com/huggingface">HuggingFace</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Comment arrêter le coronavirus ?]]></title>
            <link>https://medium.com/@francois.lagunas/comment-arr%C3%AAter-le-coronavirus-9f6cfb2c2ed3?source=rss-42901dd712e6------2</link>
            <guid isPermaLink="false">https://medium.com/p/9f6cfb2c2ed3</guid>
            <category><![CDATA[coronavirus]]></category>
            <category><![CDATA[pandemic]]></category>
            <category><![CDATA[epidemic]]></category>
            <category><![CDATA[epidemiology]]></category>
            <category><![CDATA[covid19]]></category>
            <dc:creator><![CDATA[François Lagunas]]></dc:creator>
            <pubDate>Thu, 12 Mar 2020 16:18:12 GMT</pubDate>
            <atom:updated>2020-03-13T09:49:09.506Z</atom:updated>
            <content:encoded><![CDATA[<h3>Comment arrêter le coronavirus ?</h3><p>Avec une quarantaine stricte. Il n’y a plus d’autre moyen.</p><h3>Est-t-il dangereux ?</h3><p>Oui, pour les personnes âgées. Pour elles, il est considéré comme étant <strong>10x plus dangereux que la grippe</strong>. La mortalité est de :</p><ul><li>3.6% pour les 60–69 ans</li><li>8.0% pour les 70–79 ans</li><li>22% pour les 80+ ans</li></ul><p>(<a href="https://www.worldometers.info/coronavirus/coronavirus-age-sex-demographics/">source</a>)</p><p>Donc oui, vous ne prenez pas de mesures pour vous, mais <strong>pour vos parents et vos grand-parents.</strong></p><h3>Est-il plus contagieux que la grippe ?</h3><p>Il est <strong>très contagieux</strong>. Beaucoup plus que la grippe.</p><p><strong>Le nombre de personnes qui sont actuellement en train de mourir en Italie double tous les 2.2 jours. </strong>Oui, vous avez bien lu. En une semaine, le nombre de victimes augmente d’un facteur 9. Et la semaine suivante aussi. Vérifiez par vous-même (toutes les données de ce billet proviennent de l’<a href="https://www.ecdc.europa.eu/">ECDC</a> ):</p><pre>Mardi 25 février :   6<br>Mardi  3 mars    :  52 (x 8.6)<br>Mardi 10 mars    : 464 (x 8.9)</pre><p>La seule explication de ceci est que <strong>le coronavirus se propage a très grande vitesse </strong>dans la population. Il serait intéressant de savoir pourquoi, et comment, mais nous n’avons pas vraiment besoin ici de le savoir en détail. <strong>Les chiffres sont là: le virus est horriblement contagieux.</strong></p><p>Ne faites aucune hypothèse sur ce qu’il est prudent de faire. Evitez tout contact, que ce soit par la peau ou par la respiration. Porter un masque paraît une mesure de bon sens, en particulier au contact de personnes fragiles, mais c’est utile de façon générale.</p><p><a href="https://www.news.com.au/lifestyle/health/health-problems/how-coronavirus-spreads-twice-as-far-on-trains-buses-public-transport/news-story/938b067e72449cd536c1b2d2d0f53070">Les transports publics et toutes les activités non strictement nécessaires doivent être immédiatement arrêtées si elles mettent des personnes en contact, même en petits nombres.</a></p><p>Vous avez besoin d’un seul graphique pour cela.</p><h3>Le graphique</h3><p>Voici le nombre de morts total pour quelques pays, sur un graphique légèrement spécial que nous allons expliquer.</p><p>(<a href="https://github.com/madlag/coronavirus_study/blob/master/notebooks/Coronavirus_by_country.ipynb">le code source </a>est ici, il sera mis à jour quotidiennement)</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*QbBOOqbpbGWABCvVxlo0jw.png" /></figure><p>Pour ceux qui ne sont <strong>pas familiers des maths</strong>, ne vous inquiétez pas, <strong>nous resterons très simple</strong>.</p><p>L’axe vertical est dit “logarithmique”. C’est un gros mot pour dire que chaque fois qu’on progresse d’une unité vers le haut, les valeurs sont multipliées par 10. Regardez sur la gauche : 10¹ signifie 10, 10² -&gt;100, 10³ -&gt;1000 etc.</p><p>Nous utilisons cette <strong>échelle</strong>, car sur un tel graphique <strong>une épidémie se traduira au début par une ligne droite</strong>. Après que des <strong>mesures</strong> soient prises, <strong>la ligne devrait s’infléchir vers le bas</strong>, traduisant une propagation ralentie (voyez par exemple la courbe de la Chine).</p><p>La ligne en pointillés représente la croissance dont nous parlions au début : un doublement du nombre des morts tous les 2.2 jours.</p><h3>Que pouvons-nous dire sur l’Italie ?</h3><p>Le nombre de mort en <strong>Italie</strong> suit précisément la <strong>ligne en pointillés</strong>.</p><p>Pas d’infléchissement. Et donc pas de signe d’amélioration.</p><p>Ceci dit, il s’agit du nombre de morts, ce sera la dernière chose à s’améliorer, car il y a un délai entre le moment où les personnes deviennent malades et le moment où elles décèdent éventuellement.</p><p>Il est donc possible que la situation soit déjà en train de s’améliorer, sans que cela se voie sur le graphique. Cependant, pour la même raison, le nombre de morts continuera un certain temps à augmenter, pendant une à trois semaines donc.<strong> Cela signifie potentiellement 9x, 81x ou plus de morts par rapport au décompte actuel. </strong>Et nous avons déjà dépassé les 800 morts en Italie (au 11 mars 2020).</p><h3>Mais l’Italie a fait des erreurs au départs, cela n’arrivera pas à mon pays.</h3><p><strong>C’est peu probable.</strong> Comme vous pouvez le voir sur le graphique, <strong>la même tendance se produit exactement pour la France</strong>, et c’est aussi le cas de nombreux autres pays occidentaux qui ne sont pas représentés. Pire, l’Espagne paraît prendre une trajectoire encore plus grave.</p><p>Les seuls pays qui <em>semblent </em>s’en sortir un peu mieux sont :</p><p><strong>Beaucoup mieux:</strong></p><ul><li>La Chine et la Corée sur Sud: ils ont traité le problème différemment, mais cela a fonctionné, et malgré cela le bilan de la Chine a été très lourd.</li><li>Hong Kong, Taïwan: ils ont réussi à éviter l’épidémie et n’ont eu que quelques cas.</li></ul><p><strong>Seulement un peu mieux:</strong></p><ul><li>L’Allemagne mais les autorités ne semblent pas compter les cas avec des co-morbidités.</li><li>Les Etats-Unis, mais après vérification leur nombre de cas double bien en suivant la même tendance, ce qui tendrait à prouver que leur nombre de morts est sous-évalué</li><li>l’Iran, mais il est difficile de savoir exactement ce qu’il s’y passe vraiment.</li></ul><h3>Mais prendre des mesures proportionnées ralentit déjà la propagation !</h3><p><strong>Faux</strong>. Le bon sens tendrait à dire que cela devrait avoir un impact. <strong>Mais regardez le graphique.</strong> L’Italie a pris des <strong>mesures sérieuses</strong>, après un mauvais départ, similaires aux mesures prises par la France. <strong>Pourtant, la courbe est une ligne droite.</strong> Pas d’effet visible. Et la même chose est vraie pour la France et l’Espagne</p><p>Pourquoi? Parce que le virus est trop contagieux. Quand vous mettez en quarantaine une seule région, vous pensiez qu’il n’y avait pas de gens contaminés en dehors de cette région, ou en petit nombre. Mais vous avez tort. Il y a déjà 10x plus de gens contaminés, sans aucun symptôme <strong>EN DEHORS </strong>de la région en quarantaine. Votre quarantaine régionale / proportionnelle n’a aucun effet mesurable.</p><p>Regardez le graphique. Réfléchisez-y. Voyez-vous la moindre amélioration après les quarantaines locales ? Voyez-vous la moindre amélioration en France à un moment quelconque ?</p><p>La <strong>quarantaine</strong> <strong>totale</strong> pour <strong>l’Italie</strong> est maintenant <strong>effective</strong>. Mais cela ne se verra <strong>pas avant un moment sur ce graphique</strong>, à cause du délai dont nous avons parlé. <strong>Il faudra donc que la population soit patiente, la situation s’améliorera, mais cela ne sera pas visible avant quelques semaines.</strong></p><p><strong>Il est illusoire de dire aux gens de ne pas aller travailler s’ils ne sont pas malades. Vous pouvez être porteur sain du virus sans jamais le savoir. </strong>D’autant plus qu’il est impossible de se faire tester sans symptôme.</p><h3>Mais mon pays a 2 foix plus de lits en réanimation qu’en Italie.</h3><p>C’est bien. Votre pays résistera deux jours de plus. C’est ainsi que fonctionne une épidémie:</p><p><strong>2 jours de plus, 2 fois plus d’infectés, 2 fois plus de patients en réanimation, et 2 fois plus de morts.</strong></p><p><strong>Seule une quarantaine stricte pourra amener une amélioration et le fameux “ralentissement” recherché pour que les services de santé puissent gérer la charge de nouveaux patients.</strong></p><p>Les autres mesures se sont montrées inefficaces, non pas parce qu’elles ont été mal menées, j’ai toute confiance par exemple dans les enquêtes épidémiologiques, mais parce que le <strong>virus est plus rapide que nous</strong>.</p><p><strong>Si nous agissons trop tard, nos hôpitaux seront </strong><a href="https://www.theguardian.com/world/2020/mar/09/italian-hospitals-short-beds-coronavirus-death-toll-jumps"><strong>submergés</strong></a><strong>, quelque soit le nombre de lits que nous avons.</strong> Et il déjà trop tard pour un bon nombre de pays occidentaux pour éviter d’atteindre cette capacité maximale.</p><p>La raison ? Le virus est trop contagieux. Le pic sera naturellement bien trop haut si nous attendons, avec une progression trop rapide.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*2dzy7wKfCGHqaR6eWPV6ug.png" /></figure><h3>Que puis-je faire ?</h3><p><strong>Demandez à vos autorités locales</strong> d’agir maintenant, et de faire respecter une <strong>quarantaine stricte.</strong> Pas une quarantaine où les gens peuvent se rendre au travail, et évitent d’aller au restaurant après 18h.</p><p>La Chine a mis en quarantaine Hubei lorsqu’il y avait 50 morts à peine. Leur bilan final est de 3000 morts. Et leur quarantaine était des plus strictes.</p><p>Rappelez-vous les images d’une cité déserte. Pensez-vous que votre pays s’en <strong>sortira mieux avec une quarantaine à moitié respectée </strong>? Vous avez tort. <strong>Si votre pays a plus de 50 morts aujourd’hui, il aura plus de 3000 morts à la fin, c’est presque une certitude.</strong> Et il y a déjà 10–100x plus de cas invisibles dans votre pays que ceux qui sont détectés.</p><p><strong>Une quarantaine stricte. Tout le monde reste à la maison. Pour tous les pays contaminés. Pour un mois. En aidant financièrement les personnes qui ne peuvent pas se permettre de ne pas aller au travail. En aidant les personnes âgées qui sont à la maison en leur fournissant de la nourriture et en leur évitant tout contact. Et l’épidémie sera en grande partie contenue, ou presque. C’est notre meilleure chance.</strong></p><p>L’alternative est de prendre des demi-mesures, ou des mesures désynchronisées d’un pays à l’autre, qui chacun recontaminerait les autres, et qui ferait durer la pandémie des mois.</p><p>Cela ne serait pas bon pour notre économie.</p><h3><strong>Et cela tuerait un grand nombre de nos aînés.</strong></h3><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=9f6cfb2c2ed3" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How can we contain the coronavirus?]]></title>
            <link>https://medium.com/@francois.lagunas/how-can-we-contain-the-coronavirus-a7613358dd1c?source=rss-42901dd712e6------2</link>
            <guid isPermaLink="false">https://medium.com/p/a7613358dd1c</guid>
            <category><![CDATA[coronavirus]]></category>
            <category><![CDATA[pandemic]]></category>
            <category><![CDATA[epidemic]]></category>
            <dc:creator><![CDATA[François Lagunas]]></dc:creator>
            <pubDate>Wed, 11 Mar 2020 11:40:12 GMT</pubDate>
            <atom:updated>2020-03-13T17:22:16.457Z</atom:updated>
            <content:encoded><![CDATA[<h4>TLDR: strict quarantine. No other measure will have an effect.</h4><h4>Is it deadly?</h4><p>Yes, for the elderly. You can consider it to be something like <strong>10x deadlier than the flu</strong> for the elderly:</p><ul><li>3.6% for 60–69</li><li>8.0% for 70–79</li><li>22% for 80+</li></ul><p>(<a href="https://www.worldometers.info/coronavirus/coronavirus-age-sex-demographics/">source</a>)</p><p>So, yes, you are not taking precautions for yourself, but<strong> for your parents and for your grandparents.</strong></p><h4>Is it more contagious than the flu?</h4><p>It’s <strong>very</strong> <strong>contagious</strong>. Much more than the flu.</p><p>The number of people that are currently <strong>dying in Italy is doubling every 2.2 days</strong>. Yes, you read that correctly. In one week, the death count multiplies roughly by 9. As well as the next week. Check out Italy for yourself: (all data from this post are from <a href="https://www.ecdc.europa.eu/">ECDC</a> ):</p><pre>Tuesday, Feb 25 :   6<br>Tuesday, Mar 03 :  52 (x 8.6)<br>Tuesday, Mar 10 : 464 (x 8.9)</pre><p>The only explanation for this is that the<strong> coronavirus is propagating at a very fast pace.</strong> It would be interesting to know why, and how, but you don’t really need to.<strong> The numbers are: it’s terribly contagious.</strong></p><p><strong>Do not assume anything about what is safe. Avoid contact, period.</strong></p><p><a href="https://www.news.com.au/lifestyle/health/health-problems/how-coronavirus-spreads-twice-as-far-on-trains-buses-public-transport/news-story/938b067e72449cd536c1b2d2d0f53070">Public transportation and all non-necessary activities should be immediately stopped.</a></p><p>You need a single graph to understand this.</p><h4>The graph</h4><p>Here is the count of deaths for a few countries, in a somewhat special chart that we’ll explain below.</p><p>(<a href="https://github.com/madlag/coronavirus_study/blob/master/notebooks/Coronavirus_by_country.ipynb">source code here</a>, it will be updated each day)</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*8rsbSctG7hIByPTWBfjrTQ.png" /></figure><p>For those that are not familiar with maths, don’t worry, we’ll keep it simple.</p><p>The vertical axis is logarithmic. That’s a big word to say that each time you go up one unit, the value is multiplied by 10. Look on the left side: 10⁰ means 1, 10¹ means 10, 10² means 100, 10³ means 1000, etc.</p><p>We are using it because on such a chart, <strong>an epidemic should initially look like a straight line</strong>. After some <strong>precautions</strong> are taken, the line <strong>should curve downwards</strong> (see the China curve for an example).</p><p><strong>This dotted line represents the rate we talked about: doubling every 2.2 days.</strong></p><h4>What can we say about Italy?</h4><p>The death count in <strong>Italy </strong>is<strong> exactly following the dotted line.</strong></p><p><strong>No bending. No sign of improvement.</strong></p><p>That being said, it’s a death count, so it will be the last thing to improve, as there is some lag between getting ill and then dying, which is somewhere between one and three weeks.</p><p>So maybe things are improving right now. But for the same reason (lag) the current trend of deaths will probably go on for one to three weeks. <strong>That means 9x, 81x, or more deaths than now.</strong> And we have already surpassed 600 deaths in that single country.</p><h4>But Italy made mistakes initially, it won’t happen to my country</h4><p><strong>Implausible.</strong> As you can see on the graph, the<strong> exact same trend is observed in France and Spain</strong>, with a delay of 9 days. The only countries that <em>seem </em>to fare better now are:</p><p><strong>Much better:</strong></p><ul><li>China and South Korea: they did it differently, but it worked in the end</li><li>Hong Kong, Taïwan: they avoided it almost completely.</li></ul><p><strong>Only <em>slightly</em> better:</strong></p><ul><li>Germany, but Germany seems to not report cases with co-morbidities</li><li>USA, but when checking the “cases” I realized that cases are growing at the 2.2 days doubling rate, so it’s implausible that on another side deaths are not growing at the same rate.</li><li>Iran (same remark)</li></ul><h4>But taking soft measures is already slowing down the spread.</h4><p><strong>Wrong</strong>. Look at the graph. Italy took some serious measures after an initial delay. The curve is still a straight line. No visible effect. And the same is true for France or Spain.</p><p>Why? Because it’s so <strong>contagious</strong>. When you are locking down a region, you think that there were contaminated people only in this region. You’re wrong. There are already 10x (or more) people contaminated, without any symptoms, <strong>OUTSIDE</strong> the locked-down region. <strong>So your regional/proportional lockdown has no measurable effect.</strong></p><p>See the graph. Think about it. Do you see any improvement in Italy after regional lockdowns? Do you see any improvement in France at any point?</p><p>Right now the lockdown is effective for the full country of Italy, but it won’t show on the graph for some time, as it takes some time to fall ill. <strong>Thus people will have to be patient, improvement will come, but it won’t be visible until a few weeks.</strong></p><h4>But my country’s hospitals have 2x the number of ICU beds Italy has.</h4><p>Fine. Your country will resist 2 days more. That’s the nature of an epidemic:</p><p><strong>2 days more, twice the infected, twice the ICU patients, twice the deaths.</strong></p><p>Only when the lockdown is in effect you will see an improvement on this.</p><p>If you act too late, your hospitals will be <a href="https://www.theguardian.com/world/2020/mar/09/italian-hospitals-short-beds-coronavirus-death-toll-jumps">overwhelmed</a>, no matter the number of beds you have. <strong>And it’s already too late for western countries to avoid reaching hospitals’ full capacity.</strong></p><p>The reason? The virus is way too contagious. So the spike will naturally be ‘peaky’.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*2dzy7wKfCGHqaR6eWPV6ug.png" /></figure><h4>What can I do?</h4><p>Ask for your local authority to act now, and enforce a <strong>total lockdown</strong>. This is not something where people are going to work or just avoiding going out to eat in the evening.</p><p><strong>China locked down Hubei when there were only 50 deaths or so.</strong> They ended with 3000 deaths. And their lockdown was militarily enforced. Recall the images of a deserted city. Do you think your country will fare better with a partially enforced lock-down? You are wrong. <strong>If your country has more than 50 deaths now, you will have more than 3000 deaths in the end. </strong>There are already 10–100x more cases that are just invisible in your country.</p><p><strong>A FULL lockdown. Everybody staying at home. For all countries. For at least one month. Financially helping individuals who cannot afford not to work. Helping elderly people that are at home with providing them with food and avoiding all contact. With these measures this will soon be over, or almost. This is our best shot at stopping this.</strong></p><p>The alternative is to take half-measures, or desynchronized measures across countries, so we re-contaminate each other, and let the pandemic carry on for months.</p><p>It would not be good for our economy.</p><h4>And it would kill a lot of our elders.</h4><p>Thanks to Meg Wilmore for the proofreading.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a7613358dd1c" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Is the future of Neural Networks Sparse? An Introduction (1/N)]]></title>
            <link>https://medium.com/huggingface/is-the-future-of-neural-networks-sparse-an-introduction-1-n-d03923ecbd70?source=rss-42901dd712e6------2</link>
            <guid isPermaLink="false">https://medium.com/p/d03923ecbd70</guid>
            <category><![CDATA[transformers]]></category>
            <category><![CDATA[cuda]]></category>
            <category><![CDATA[sparse-matrix]]></category>
            <category><![CDATA[openai]]></category>
            <category><![CDATA[machine-learning]]></category>
            <dc:creator><![CDATA[François Lagunas]]></dc:creator>
            <pubDate>Tue, 04 Feb 2020 17:08:58 GMT</pubDate>
            <atom:updated>2020-02-04T17:09:54.360Z</atom:updated>
            <content:encoded><![CDATA[<h4>From principles to real-world library support.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7e9p9imPoRBYh5WYF3FFrQ.png" /><figcaption>TLDR: Yes</figcaption></figure><h4><strong>Hi, I am François Lagunas.</strong></h4><p>I am doing Machine Learning research, and I have been working for the last months on using sparse matrices, especially in Transformers. The recent <a href="https://openai.com/blog/openai-pytorch/"><strong>announcement</strong></a> that <strong>OpenAI</strong> is porting its <a href="https://openai.com/blog/block-sparse-gpu-kernels/"><strong>block sparse toolbox</strong></a> in <strong>PyTorch</strong> is really big news:</p><blockquote>“We are in the process of writing PyTorch bindings for our highly-optimized blocksparse kernels, and will open-source those bindings in upcoming months”</blockquote><p>I was talking about it with the outstanding <a href="https://huggingface.co/">Hugging Face</a> team, (I am one of their early investors), and I wanted to share with you my excitement!</p><h3>What is a Sparse Matrix?</h3><p>A <strong><em>sparse</em></strong> matrix is just a matrix with some zeros. Usually, a lot of them. So every place you are using a <strong><em>dense matrix</em></strong>, in a linear layer, for example, you could be using a sparse one.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*tf99LCAMrO70WAO4tkgFBw.png" /><figcaption>Matrices with increasing sparsity</figcaption></figure><p>The <strong><em>sparsity</em></strong> of the matrix is the fraction of zeros against the size of the matrix</p><p><strong>The pros?</strong> If you have a lot of zeros, you don’t have to compute some multiplications, and you don’t have to store them. So you <strong><em>may</em></strong> gain on size and speed, for training and inference (more on this today).</p><p><strong>The cons? </strong>Of course, having all these zeros will probably have an impact on network accuracy/performance. But to what extent? You may be surprised.</p><h3>Where are they from?</h3><p>The first researchers/engineers to use sparse matrices were <a href="https://en.wikipedia.org/wiki/Finite_element_method">Finite Elements</a> users.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/760/1*IvRIZEjC7kgUBuozUFlSng.png" /><figcaption>A 2D mesh (roof of Omni Coliseum, Atlanta) and its finite element matrix (<a href="https://www.cise.ufl.edu/research/sparse/matrices/HB/bcsstk14.html">source</a>).</figcaption></figure><p>When you have to deal with large physical simulations, you get a large graph of interconnected vertices.</p><p>Each vertex is a point of your system, and each edge connects two vertices. That means that these <strong>two points</strong> will have some <strong>influence</strong> on each other in the model. And so there is a <strong>non-zero</strong> value in the matrix that describes the graph.</p><p>This last sentence sums it up: you need non-zero values in the matrix when two dimensions are interacting in some way.</p><p><strong>Now getting back to ML, you should ask yourself the same question: are all the dimensions of my input vector interacting with all the others? </strong>Usually not. So going sparse maybe useful.</p><p>We have actually a very good, and famous, example of a successful trip to sparse-land: <strong>convolutional layers</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/627/1*3WLh11vam1ktq7kWJ9aKpg.jpeg" /><figcaption>Learned convolutional filters. From <a href="http://cs231n.github.io/convolutional-networks/">http://cs231n.github.io/convolutional-networks/</a></figcaption></figure><p>Convolutional layers are a smart and efficient way to implement a sparse transformation on an input tensor.</p><p>When processing images, it comes down to two things:</p><p><strong>Sparsity</strong>: the transformation is local → each output pixel should depend on a few neighboring input pixels.</p><p><strong>Invariance</strong>: the transformation does not depend on the position in the image</p><p>Then you just add the constraint that the transformation is linear: if you were to represent this transformation, you would get a HUGE matrix with only a few non-zeros. But of course, the right way to do this is to do a multiplication of the input tensor with a small set of small matrices (each square in the image before).</p><p>The importance of convolutions in today’s ML success is obvious. But you can see that <strong>finding a clever way to make things sparse sounds like a good recipe to save time and space.</strong></p><h3>Where are they useful?</h3><p>Convolutions are already an efficient form of sparsity, so you could try to make them <a href="https://arxiv.org/abs/1902.05967">even</a> more <a href="http://arxiv.org/abs/1907.04840">sparse</a>, but some other networks contain much larger matrices that may benefit from sparsity: Transformers.</p><p>And those are getting bigger and bigger. We have greatly exceeded the 1 billion parameters in 2019, and it’s not stopping here. The cost to train and to use those networks is getting unpractical, so every method to reduce their size will be welcome.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/850/0*m3oTlwLmwuXuBCVg.jpg" /><figcaption>From <a href="https://devblogs.nvidia.com/training-bert-with-gpus/">https://devblogs.nvidia.com/training-bert-with-gpus/</a></figcaption></figure><h3>Why the OpenAI announcement is so important?</h3><p>So, if everything is fine in sparse-land, we should all be trying sparse matrices, shouldn’t we?</p><p>Yes. But there is this stupid thing called <strong>implementation</strong>. It’s easy to see the theoretical improvements we could get with sparse compute. But the support in libraries is quite … sparse.</p><p>PyTorch <a href="https://github.com/soumith">developers</a>, for example, have done a <strong>significant</strong> <strong>effort</strong> to support sparse compute. But there is still a big gap in performance between dense and sparse matrices operations, which defeats the whole purpose of using them. Even memory usage is quite large: sparsity has to be more than 80% to save some room on sparse matrices (more on that in my next post). Even basic serialization was broken before version 1.4. The reason is that the underlying libraries (for example cuSPARSE) are not doing a great job because the problem is ill-suited to the way GPU works.</p><p>So the <strong>OpenAI</strong> <strong>announcement</strong> on their block sparse tools is <strong>very</strong> <strong>good</strong> <strong>news</strong> for those who want to use sparse ops without sacrificing training speed (and it looks like some <a href="https://github.com/openai/blocksparse/issues/2">people</a> have been waiting for some time now). And we are not talking about a few percents.</p><blockquote>“Our kernels typically performed <strong>one or two orders of magnitude faster</strong> in terms of GFLOPS.”</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/664/1*qXMoK7emiT7J6CA_3O29_A.png" /><figcaption>From OpenAI <a href="https://d4mucfpksywv.cloudfront.net/blocksparse/blocksparsepaper.pdf">blocksparse paper</a></figcaption></figure><p>(The worst thing is that the <a href="https://d4mucfpksywv.cloudfront.net/blocksparse/blocksparsepaper.pdf">paper</a> concludes that cuBLAS is faster that cuSPARSE even with very sparse matrices. How sad.)</p><p>The magic keyword here is “<strong>block</strong>”. <strong>It’s hard to implement general sparse matrice computations on GPUs in an efficient way</strong>. But it gets much easier if you add a “reasonable” constraint on the form of the matrices: their non-zeros should be grouped in small fixed-size blocks, and that makes GPU processing much easier to parallelize efficiently. Typically 8x8, 16x16 or 32x32 blocks, 16x16 already giving a very good performance, with 32x32 giving a slightly better one.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/338/1*rHFMCfJ8Td-vhJi0e0zAQw.png" /><figcaption>A 8-block-sparse matrice</figcaption></figure><p>Of course, the “block” constraint may be crippling some sparsification algorithms, or at least it would require some changes to take it into account.</p><p>But at least we can play with large high sparsity matrices, and the block constraint may not be a big issue: if you think about it, it means that there is <strong>some locality in the dimensions</strong>, and that sounds a quite reasonable constraint. That’s the same reason band matrices have been useful in the past (finite difference, finite elements), and it was a much stronger constraint.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/338/1*zknKSiBQpsppvjDJFIFbqw.png" /><figcaption>Band matrix</figcaption></figure><h3>Conclusion</h3><p>I hope I have convinced you that 2020 will be the sparse network year (it already has two zeros, that’s a sign).</p><p><strong>Next time </strong>for those who are curious about what happens when they are using some CUDA based PyTorch code, we’ll dig a bit deeper in <strong>GPU internals</strong>, (and we will understand<strong> why block sparse code is outrunning sparse code by a large margin</strong>).</p><p><strong>This article series will continue on the different techniques that have been proposed to make sparse networks, and what are the potential long term benefits.</strong></p><h4>More reading</h4><p>First, here is a <a href="https://towardsdatascience.com/sparse-matrices-in-pytorch-part-2-gpus-fd9cc0725b71"><strong>study</strong></a><strong> of PyTorch sparse performance.</strong></p><p>If you want to have a very detailed review of <strong>different complementary approaches to network size reduction</strong>, and not just about sparse ones, you should definitely read <a href="http://mitchgordon.me/machine/learning/2020/01/13/do-we-really-need-model-compression.html">this article</a>.</p><p>And if you want to <strong>create illustrations like the header of this blog post</strong>, you will find the code I used on my <a href="https://github.com/madlag/medium_posts/tree/master/sparse_matrices_1"><strong>github</strong></a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d03923ecbd70" width="1" height="1" alt=""><hr><p><a href="https://medium.com/huggingface/is-the-future-of-neural-networks-sparse-an-introduction-1-n-d03923ecbd70">Is the future of Neural Networks Sparse? An Introduction (1/N)</a> was originally published in <a href="https://medium.com/huggingface">HuggingFace</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>