<?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 Ali Hassani on Medium]]></title>
        <description><![CDATA[Stories by Ali Hassani on Medium]]></description>
        <link>https://medium.com/@alihassanijr?source=rss-4abdade9a78d------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*Cp3eBMAM7JiC54dOtk74cw.jpeg</url>
            <title>Stories by Ali Hassani on Medium</title>
            <link>https://medium.com/@alihassanijr?source=rss-4abdade9a78d------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 02:02:26 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@alihassanijr/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[Distributed GEMM]]></title>
            <link>https://blog.shi-labs.com/distributed-gemm-88be6a481e2b?source=rss-4abdade9a78d------2</link>
            <guid isPermaLink="false">https://medium.com/p/88be6a481e2b</guid>
            <category><![CDATA[cutlass]]></category>
            <category><![CDATA[nvidia]]></category>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[hpc]]></category>
            <category><![CDATA[tensor-parallelism]]></category>
            <dc:creator><![CDATA[Ali Hassani]]></dc:creator>
            <pubDate>Mon, 02 Dec 2024 04:07:41 GMT</pubDate>
            <atom:updated>2025-01-18T15:21:36.528Z</atom:updated>
            <content:encoded><![CDATA[<h4>A novel CUTLASS-based implementation of Tensor Parallelism for NVLink-enabled systems</h4><p>with Michael Isaev², Nic McDonald², Jie Ren³, Vijay Thakkar² ⁴, Haicheng Wu², and Humphrey Shi¹.</p><p>¹ <a href="https://shi-labs.com/">SHI Labs</a> @ Georgia Tech, ² <a href="https://www.nvidia.com/">NVIDIA</a>, ³ <a href="https://www.kaust.edu.sa/en/">KAUST</a>, ⁴ <a href="https://hpcgarage.org/wp/">HPC Garage</a> @ Georgia Tech.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*o7lCHrXqhSjkgltbrYTQ8g.gif" /></figure><h3>Introduction</h3><p>Much of AI today is continuing to scale up due to massively parallel systems. General purpose GPUs (GPGPUs) are made up of many parallel processors, each with their own local memory, execution engines, and register files. However, we are long past the time that single GPUs were enough to scale up, and are now in the age of much larger systems, such as <a href="https://www.nvidia.com/en-us/data-center/gb200-nvl72/">NVIDIA’s GB200 NVL72</a>, which pack tens of GPUs together, with an amazingly high-bandwidth network of switches enabling fast peer-to-peer communication. To end users, the GB200 NVL72 system will be “One giant CUDA GPU”.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ni_QvYy8Lqo4cTLBkbiBOQ.png" /><figcaption><strong>Figure 1. </strong>GB200 NVL72.</figcaption></figure><p>For scaling up to the order of trillions of parameters, and utilizing the massive compute power provided by such systems, model parallelism techniques are the way forward, and among them, Tensor Parallelism (TP) has been the de-facto standard for large-scale training and inference in NVLink-based networks. However, communication can be a pain point for developers, researchers, and other end users. Not only can communication become a bottleneck and lead to under-utilization of compute resources, it would also require extra implementation effort.</p><p>In this post, we introduce a new implementation of Tensor Parallel GEMMs, which we call Distributed GEMM. This approach makes use of software and hardware features provided by the CUDA runtime and driver APIs alone to pipeline and overlap communication and computation, and makes very few assumptions about the specifics of the underlying GEMM kernel. More specifically, Distributed GEMMs use CUDA Graphs to allow the GPU Copy Engine (CE) to handle communication, leaving the Streaming Multiprocessors (SMs) and Tensor Cores (TCs) free to execute fast and performant GEMMs, unburdened by additional communication kernels and communication-related instructions. This approach can provide concurrency without breaking the CUDA programming model, and minimizes kernel launch latency gaps not just by using graphs, but also <a href="https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#programmatic-dependent-launch-and-synchronization">Programmatic Dependent Launch (PDL)</a>, a feature new to the Hopper architecture.</p><p>Distributed GEMM is implemented entirely using NVIDIA’s open source linear algebra framework, <a href="https://github.com/NVIDIA/cutlass/">CUTLASS</a>, and additional calls to the runtime and driver APIs. Distributed GEMMs can therefore extend the incredibly fast and performance-optimized kernels from NVIDIA to their tensor parallel form, with only a few lines of code added, and no additional dependencies!</p><h3>Background</h3><p>When you train or query a model on multiple GPUs, the simplest choice is data parallelism; that is to replicate weights across GPUs, and feed them different mini-batches of data. If you’ve ever used PyTorch’s <a href="https://pytorch.org/tutorials/intermediate/ddp_tutorial.html">Distributed Data Parallelism</a>, as the name suggests, you’ve used data parallelism. However, data parallelism isn’t always the best approach, given that it forces users to have a minimum batch size, and in the classical case assumes the entire model can fit on a single GPU.</p><p>Model parallelism techniques on the other hand distribute weights across multiple processors, and this is especially important in larger models like LLMs, where memory capacity is a concern. Among those are Pipeline Parallelism (PP), Expert Parallelism (EP), Fully-Sharded Data Parallelism (FSDP) [3], and Tensor Parallelism (TP) [1,2]. Each of these techniques have their own advantages and limitations. In this post, we focus specifically on Tensor Parallelism, as it achieves lower memory capacity requirements and better GPU utilization when implemented in low-latency high-bandwidth networks such as NVLink. For that reason, it became the de-facto standard for many LLM implementations across various frameworks. That is especially the case in most LLM training infrastructure today, and has been since the technique was first introduced in Megatron-LM [1,2]. We’ll quickly go over a few basics in Tensor Parallelism.</p><p>The figure below from Korthikanti et al. [2] illustrates how a Transformer layer is divided across multiple processors. Since both activation and weight tensors are divided across processors, certain operations produce partial results, which will require communication.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*lh5_u4Hmr9e50EOK" /><figcaption><strong>Figure 2. </strong>Illustration from Korthikanti et al. [2]. Tensor and sequence parallelism in Transformer layers. Boxes with dark green background are communication primitives: g is All Gather in forward pass and Reduce Scatter in backward pass, and g is Reduce Scatter in forward pass and All Gather in backward pass.</figcaption></figure><p>For simplicity, we’ll exclude attention for now, which today uses Context Parallelism, an approach compatible with fused attention. In the MLP block, there are two back-to-back linear layers, separated by a GELU activation (which is typically fused into the preceding kernel). The communication and computation patterns fall into two categories here: All Gather + GEMM, and GEMM + Reduce Scatter. In both cases, each device “owns” a slice of the weights and activations. In the typical All Gather + GEMM scenario, activation slices which are distributed across devices are gathered locally on each device, and then the GEMM can produce a slice of the output. In the typical GEMM + Reduce Scatter scenario, each device produces a partial result of the output, which requires a reduction (summation) and scattering of slices of the output.</p><p>In either case, we can break down the computation and communication further into stages in order to pipeline some or potentially all communication behind computation.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*3DzZCyfJK3kRoRO_" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*U07gtt03eYfC7DYS" /><figcaption><strong>Figure 3. </strong>Single-stage vs pipelined All Gather + GEMM and GEMM + Reduce Scatter. You can either communicate and compute once, or break it down into stages. However, note that both communication and computation have some constant time that does not correlate with your problem size (latency for communication, and ramp up and ramp down time for computation), which means pipelining may not be necessarily faster in smaller problem sizes. In addition, smaller problem sizes can result in more memory-bandwidth-bound GEMMs on modern architectures like Hopper.</figcaption></figure><p>Aside from saving on activation memory, with pipelined tensor parallelism, we can also hide the exposed communication step under certain conditions. Instead of performing collective communications, we can use point-to-point communication and allow each processor to start working on its local buffers immediately in the first iteration. This eliminates the exposed communication step, as illustrated in the figure below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*w9Z0Tp_hAtMf-Ww_" /><figcaption><strong>Figure 4.</strong> By switching from collective to point-to-point (P2P) communication, we can allow the first stage of the pipeline to run immediately and on its locally available shard of data, and rotate buffers around processors during each stage. This, in theory, allows elimination of exposed communication in Tensor Parallelism.</figcaption></figure><p>This means that the wall time will nearly only reflect computation time, as all communication will be hidden behind it. However, note that single-stage TP can still be a more performant choice in more latency-bound cases, such as small-batch short-sequence decoding. To make matters worse, the local GEMM stages in such cases can also easily wind up memory-bandwidth-bound.</p><p>The concept is not by any means new and has <a href="https://people.eecs.berkeley.edu/~demmel/cs267/lecture11/lecture11.html">long existed in HPC</a>, and was adopted in AI applications relatively late, by Google Research [5], Microsoft Research [6], ByteDance [7], and PyTorch [8].</p><p>The difference with our new approach is not in functionality, but rather in implementation. Instead of relying on communication primitives in libraries such as NCCL, or fusing communication steps into a specific kernel, we simply use host-side CuTe layout logic, peer-to-peer access, and existing CUDA graph APIs to implement Distributed GEMMs, adding very few instructions to the GEMM kernels themselves. Aside from being more extensible and being much less prone to register spills, this approach also does not limit itself to a specific kernel, making performance optimization through profiling much more convenient.</p><h3>Approach</h3><p><a href="https://github.com/NVIDIA/cutlass/">CUTLASS</a> is a framework for writing performant kernels targeting NVIDIA’s Tensor Cores, since their introduction with the <a href="https://www.nvidia.com/en-us/data-center/volta-gpu-architecture/">Volta architecture</a> in 2017. The more recent introduction of the Hopper architecture, which included a <a href="https://developer.nvidia.com/blog/nvidia-hopper-architecture-in-depth/">Tensor Memory Accelerator (TMA)</a>, led to a change in the programming model that led to the CUTLASS 3 API, powered by an expressive framework for tensor layout algebra, <a href="https://github.com/NVIDIA/cutlass/tree/main/include/cute">CuTe</a>. However, most compute-heavy kernels within CUTLASS (GEMMs and convolution, both of which are matrix-matrix multiplications and thus target Tensor Cores) are designed to run on a single GPU, and can deliver very high performance.</p><p>We approach the implementation of Distributed GEMMs from a perspective that makes the following observations:</p><ol><li>In most compute-bound problems, we prefer to pipeline the local GEMMs and overlap communication and computation.</li><li>Kernels written for modern architectures like Hopper heavily rely on SM occupancy (persistent kernels), which means communication primitives should try and avoid occupying SMs entirely.</li><li>Given the many choices of kernel parameters that the Hopper programming model allows for, computation kernels cannot realistically be rewritten entirely for distributed settings.</li><li>Kernel launch latency (the gap between multiple pipeline stages of the compute kernel) can be an extra overhead that should be avoided.</li></ol><p>To that end, we introduce Distributed GEMMs, which aside from pipelining local GEMMs, take a direct-access approach, where communication is primarily done by peer devices directly accessing each other’s buffers to rotate partial inputs or partial results around the network. This, when carefully handled, will allow the Copy Engine (CE) to handle data movement, while the SMs are free to execute their single wave of persistent threadblocks uninterrupted.</p><p>This simple approach allows us to transform any existing GEMM kernel into a Distributed GEMM kernel by prepending only a few instructions to the kernel code, which are mainly agnostic to the underlying structure and programming model of the kernel.</p><p>If you’re already familiar with CUTLASS, or more specifically CUTLASS 3, you already know that creating a GEMM kernel is a matter of instantiating one (directly in CUTLASS 2, or using Collectives in CUTLASS 3), and wrapping it with the universal GEMM API:</p><pre>using CollectiveEpilogue = typename CollectiveBuilder&lt;<br> ArchTag, OperatorClass,<br> TileShape, ClusterShape,<br> EpilogueTileType,<br> ElementAccumulator, ElementCompute,<br> ElementC, LayoutC, AlignmentC,<br> ElementD, LayoutD, AlignmentD,<br> EpilogueSchedule<br>  &gt;::CollectiveOp;<br><br>using CollectiveMainloop = typename CollectiveBuilder&lt;<br> ArchTag, OperatorClass,<br> ElementA, LayoutA, AlignmentA,<br> ElementB, LayoutB, AlignmentB,<br> ElementAccumulator,<br> TileShape, ClusterShape,<br> StageCount,<br> KernelSchedule<br>  &gt;::CollectiveOp;<br><br>using GemmKernel = GemmUniversal&lt;<br>  ProblemShapeProfile,<br>  CollectiveMainloop,<br>  CollectiveEpilogue&gt;;<br><br>using Gemm = GemmUniversalAdapter&lt;GemmKernel&gt;;</pre><p>And in this case, all you would need to do is declare a <strong><em>Gemm</em></strong> type operator, instantiate with your operand pointers and other runtime parameters, and run.</p><p>But what if you were interested in distributing this among multiple GPUs (let’s say 8 for instance) on an NVLink-based network?<br>With Distributed GEMM it’s very simple. First you would need to define your tensor parallelism strategy:</p><pre>using DistSchedule = AllGather1D_TilingCD_RotatingA&lt;_8&gt;;</pre><p>In this case, we’re doing an AllGather + GEMM operation which rotates the left hand side GEMM operand (A), with single-dimensional tiling. In the context of a Tensor Parallel transformer, this just means operand A will be your activations (what was previously running with sequence parallelism.)</p><p>Here’s a list of schedules implemented so far:</p><pre>  AllGather1D_TilingCD_RotatingA<br>  AllGather1D_TilingCD_RotatingB<br>  ReduceScatter1D_TilingA_RotatingC<br>  ReduceScatter1D_TilingB_RotatingC</pre><p>Distributed GEMM implements these schedules mainly by providing an interface through which we can define sharding, tiling, and buffering patterns, all through CuTe primitives.<br>After that, all we really need is to instantiate our GEMM kernel with a Distributed GEMM wrapper:</p><pre>using DistGemmKernel = DistributedGemmKernelWrapper&lt;GemmKernel, DistSchedule&gt;;<br><br>using DistGemm = DistributedGemmUniversalAdapter&lt;DistGemmKernel&gt;;</pre><p>And that is really most of it! The rest comes down to defining, initializing, and running the distributed GEMM, the same way you would a single-GPU GEMM. There’s obviously some additional logic that you would need, because now we’re setting up a CUDA context and stream on multiple devices instead of a single one, and similarly breaking down one problem into 8. To run a typical single-process single-GPU GEMM in CUTLASS you would write:</p><pre>Gemm gemm;<br>assert(gemm.can_implement(args));<br>gemm.initialize(args, workspace_ptr, stream);<br>gemm.run(stream);</pre><p>where <strong><em>args</em></strong> is the operator arguments instance, <strong><em>workspace_ptr</em></strong> is a global memory pointer to scratch space required by the operator, and <strong><em>stream</em></strong> is the cuda stream.</p><p>Now with Distributed GEMM, to run a single-process multi-GPU GEMM in CUTLASS you would write:</p><pre>DistGemm dist_gemm_arr[TP];<br><br>for (int i = 0; i &lt; 8; ++i) {<br>  assert(dist_gemm_arr[i].can_implement(args_arr[i]));<br>}<br><br>for (int i = 0; i &lt; 8; ++i) {<br>  cudaDeviceSet(i);<br>  dist_gemm_arr[i].initialize(<br>    args_arr,<br>    workspace_ptr_arr,<br>    exclusive_workspace_ptr_arr,<br>    i,<br>    stream_arr[i]);<br>}<br><br>for (int i = 0; i &lt; 8; ++i) {<br>  cudaDeviceSet(i);<br>  dist_gemm_arr[i].run(stream_arr[i]);<br>}</pre><p>where arguments, workspace pointers, streams, and operator instances are all arrays. There’s also an additional exclusive workspace, which is reserved for synchronization primitives (e.g. barriers) that must last across runs. The space allocated for these must not overlap with any other scratch space in the memory pool, but this is a detail that concerns memory management in frameworks and software integrating this operation.</p><p>For more details, you can refer to <a href="https://github.com/NVIDIA/cutlass/tree/main/examples/65_distributed_gemm">example 65 in CUTLASS</a>.</p><h3>Performance</h3><p>Our setup environment is a single DGX box with 8 H100s with NVL18 (any-to-any), therefore we ran everything with TP=8.</p><p>We used problem sizes from fc1 and fc2 linear layers in Llama 70B and 405B, which are listed below:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/7714140c707cf669363af18f0cf8cfed/href">https://medium.com/media/7714140c707cf669363af18f0cf8cfed/href</a></iframe><p>For our baseline, we consider a few options.</p><p>First is a single-stage Distributed GEMM which would have fully exposed communication, as illustrated in Figure 3. However, given that this schedule is not yet implemented in the Distributed GEMM framework, we only run a single GEMM excluding the communication. Since we would shard across output columns (N) for AG + GEMM, and across the contracting dimension (K) for GEMM + RS, the problem shapes for this baseline are as follows:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/6475a19334a0588b59f5e6b92d224522/href">https://medium.com/media/6475a19334a0588b59f5e6b92d224522/href</a></iframe><p>Our second baseline is the same GEMM shape that Distributed GEMM would run at each stage. Since we cut the GEMMs into TP stages in order to do point-to-point communication and attempt to fully hide communication behind computation, the shapes would be further divided by TP along tokens (M):</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/65d3472c03ade8814aeafa1d51d06c23/href">https://medium.com/media/65d3472c03ade8814aeafa1d51d06c23/href</a></iframe><p>We run these two baselines directly through the <a href="https://github.com/NVIDIA/cutlass/blob/main/media/docs/profiler.md">CUTLASS profiler</a>, which runs a number of different kernels that can support these problem shapes, through which we can figure out the best GEMM kernel for these shapes, and its performance level.</p><p>Since Distributed GEMM is not yet supported in the CUTLASS profiler, we chose the same kernel configuration for it as the second option. While this is a useful proxy, DistGEMMs must still be profiled holistically in order to get the best performance.</p><p>After profiling each problem shape (all assuming FP16), the following kernel configuration was among the best-performing ones for all four cases: Ping-ponging warp-specialized kernel with TMA epilogue, 128x256x64 tile shape, and 1x2x1 cluster size.</p><p>The table below reports best achievable performance according to the CUTLASS profiler when running: 1. A single-GPU GEMM, 2. Single-stage GEMM, and 3. Pipelined GEMM. All three exclude communication and are run on a single GPU.</p><p>The final column reports the performance of a fully functional DistGEMM from the <a href="https://github.com/NVIDIA/cutlass/tree/main/examples/65_distributed_gemm">example in CUTLASS</a>, with the kernel configuration above.</p><p>All instances were profiled for approximately 1 second, with approximately 1 second of warm-up, in order to measure sustainable performance.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/6306260d4479400ad0c3dfceab1178bf/href">https://medium.com/media/6306260d4479400ad0c3dfceab1178bf/href</a></iframe><p>DistGEMM achieves 91%, 99%, 85%, and 93% of the best performance achievable by a single-stage GEMM (excluding communication) in the four cases.</p><p>It also achieves 92%, 93%, 89%, and 91% of the best performance achievable by an 8-stage GEMM (also excluding communication) in the four cases.</p><p>While we see that local GEMM kernels (those without communication) typically reach around 80–85% of peak performance, DistGEMM appears to reach only 70–80% of peak performance. We believe that this is mainly due to overheads from synchronization and communication, which could potentially be minimized with a DistGEMM profiler.</p><p>Based on our estimates of collective communications in state-of-the-art Tensor Parallelism solutions, DistGEMM could achieve up to 15% speedup in the 405B cases, and up to 24% speedup in the 70B cases. DistGEMM is also faster than the All Reduce setting (All Reduce + GEMM + GEMM instead of All Gather + GEMM + GEMM + Reduce Scatter) could achieve up to 8% and 12% speedup in the 405B and 70B cases. However, note that these are still operation-level comparisons, and not from running an entire LLM or a layer of an LLM.</p><h3>Conclusion</h3><p>In conclusion, we discussed the role of Tensor Parallelism in today’s AI infrastructure, and its potential with cutting-edge systems such as the <a href="https://www.nvidia.com/en-us/data-center/gb200-nvl72/">GB200 NVL72</a>. While Distributed GEMM is not yet integrated into any major framework or library, we hope that its simplicity in design, extensibility, and potential to fully overlap communication and computation, leading to massive performance gains in certain communication-bound scenarios, will lead to its adoption in deep learning frameworks and linear algebra libraries.</p><p>What we’ll be working on in the near term will involve improving the existing implementation, extending it to support more schedules, and setting up the basic infrastructure required for profiling and measuring its performance.</p><p>If you have any questions or suggestions, feel free to join the discussion on our <a href="https://github.com/NVIDIA/cutlass/pull/1907">pull request</a>.</p><h4>Acknowledgements</h4><p>We’d like to thank Cris Cecka, Amr Elmeleegy, Alan Kaatz, Jack Kosaian, dePaul Miller, Brian Pharris, Richard Vuduc, Bing Xu, and Xiuxia Zhang for their feedback.</p><h3>References</h3><ol><li>Shoeybi, Mohammad, Mostofa Patwary, Raul Puri, Patrick LeGresley, Jared Casper, and Bryan Catanzaro. “<a href="https://arxiv.org/abs/1909.08053">Megatron-lm: Training multi-billion parameter language models using model parallelism</a>.” arXiv preprint arXiv:1909.08053 (2019).</li><li>Korthikanti, Vijay Anand, Jared Casper, Sangkug Lym, Lawrence McAfee, Michael Andersch, Mohammad Shoeybi, and Bryan Catanzaro. “<a href="https://arxiv.org/abs/2205.05198">Reducing activation recomputation in large transformer models</a>.” Proceedings of Machine Learning and Systems 5 (2023).</li><li>Zhao, Yanli, Andrew Gu, Rohan Varma, Liang Luo, Chien-Chin Huang, Min Xu, Less Wright et al. “<a href="https://arxiv.org/abs/2304.11277">PyTorch FSDP: Experiences on Scaling Fully Sharded Data Parallel</a>.” Proceedings of the VLDB Endowment 16, no. 12 (2023): 3848–3860.</li><li>Vaswani, Ashish, Noam Shazeer, Niki Parmar, Jakob Uszkoreit, Llion Jones, Aidan N. Gomez, Lukasz Kaiser, and Illia Polosukhin. “<a href="https://arxiv.org/abs/1706.03762">Attention is all you need</a>.” Advances in Neural Information Processing Systems (2017).</li><li>Wang, Shibo, Jinliang Wei, Amit Sabne, Andy Davis, Berkin Ilbeyi, Blake Hechtman, Dehao Chen et al. “<a href="https://dl.acm.org/doi/abs/10.1145/3567955.3567959">Overlap communication with dependent computation via decomposition in large deep learning models</a>.” In Proceedings of the 28th ACM International Conference on Architectural Support for Programming Languages and Operating Systems (2022).</li><li>Jangda, Abhinav, Jun Huang, Guodong Liu, Amir Hossein Nodehi Sabet, Saeed Maleki, Youshan Miao, Madanlal Musuvathi, Todd Mytkowicz, and Olli Saarikivi. “<a href="https://arxiv.org/abs/2105.05720">Breaking the computation and communication abstraction barrier in distributed machine learning workloads</a>.” In Proceedings of the 27th ACM International Conference on Architectural Support for Programming Languages and Operating Systems (2022).</li><li>Chang, Liwen, Wenlei Bao, Qi Hou, Chengquan Jiang, Ningxin Zheng, Yinmin Zhong, Xuanrun Zhang et al. “<a href="https://arxiv.org/abs/2406.06858">FLUX: Fast Software-based Communication Overlap On GPUs Through Kernel Fusion</a>.” arXiv preprint arXiv:2406.06858 (2024).</li><li>Wang, Yifu, and Horace He, Less Wright, Luca Wehrstedt, Tianyu Liu, Wanchao Liang. “<a href="https://discuss.pytorch.org/t/distributed-w-torchtitan-introducing-async-tensor-parallelism-in-pytorch/209487">[Distributed w/ TorchTitan] Introducing Async Tensor Parallelism in PyTorch</a>.” (2024).</li></ol><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=88be6a481e2b" width="1" height="1" alt=""><hr><p><a href="https://blog.shi-labs.com/distributed-gemm-88be6a481e2b">Distributed GEMM</a> was originally published in <a href="https://blog.shi-labs.com/">SHI Labs</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>