<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>article Introducing the DeepSpeed Distributor on Databricks in Technical Blog</title>
    <link>https://community.databricks.com/t5/technical-blog/introducing-the-deepspeed-distributor-on-databricks/ba-p/59641</link>
    <description>&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-right" image-alt="torchdistributed.png" style="width: 284px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/6205i8AE54D16FF195CD6/image-dimensions/284x284?v=v2" width="284" height="284" role="button" title="torchdistributed.png" alt="torchdistributed.png" /&gt;&lt;/span&gt;&lt;SPAN&gt;The GPU shortage is real, and being able to scale up and optimize the training of large language models will help accelerate the delivery of an AI project.&amp;nbsp;&lt;/SPAN&gt;&lt;A style="font-family: inherit; background-color: #ffffff;" href="https://github.com/microsoft/DeepSpeed" target="_blank" rel="noopener"&gt;DeepSpeed&lt;/A&gt; &lt;SPAN&gt;is a framework that can reduce GPU memory requirements by up to 4x.&amp;nbsp;Setting up and triggering DeepSpeed jobs is complex, however, and Databricks is here to help.&amp;nbsp;That is why we are pleased to announce the release of the new DeepSpeed Distributor,&amp;nbsp;a fully open source extension to Spark that builds upon our work with both the &lt;A href="https://docs.databricks.com/en/machine-learning/train-model/distributed-training/spark-pytorch-distributor.html" target="_self"&gt;TorchDistributor&lt;/A&gt; and the &lt;A href="https://docs.databricks.com/en/machine-learning/train-model/distributed-training/spark-tf-distributor.html" target="_self"&gt;spark-tensorflow-distributor&lt;/A&gt;,&amp;nbsp;Now you can trigger DeepSpeed powered training jobs with a simple PySpark function - the hassles of cluster configuration, communications and monitoring are all handled for you! In this article, we review the key features of DeepSpeed that you will need to advance your AI journey in the development of large language models (LLM) and computer vision (CV) applications.&lt;/SPAN&gt;&lt;/P&gt;
&lt;DIV class="mce-toc"&gt;
&lt;H2&gt;Table of Contents&lt;/H2&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="#mcetoc_1hmhf6r923f" target="_blank"&gt;Overcoming GPU bottlenecks&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#mcetoc_1hmhf6r923g" target="_blank"&gt;Understanding DeepSpeed and the DeepSpeed Distributor&lt;/A&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="#mcetoc_1hmhf6r923h" target="_blank"&gt;Model Precision Settings&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#mcetoc_1hmhf6r923i" target="_blank"&gt;Optimizer and Gradient Settings&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#mcetoc_1hmhf6r923j" target="_blank"&gt;How to trigger a DeepSpeed training job&lt;/A&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="#mcetoc_1hmhf6r923k" target="_blank"&gt;Triggering a function from notebooks&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#mcetoc_1hmhf6r923l" target="_blank"&gt;Triggering a Python script&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#mcetoc_1hmhf6r923m" target="_blank"&gt;Tricks and Tips to be productive&lt;/A&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="#mcetoc_1hmhf6r923n" target="_blank"&gt;Estimating Memory Requirements&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#mcetoc_1hmhf6r923o" target="_blank"&gt;Setting Hugging Face Caches&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#mcetoc_1hmhf6r923p" target="_blank"&gt;Configuring MLflow with DeepSpeed&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#mcetoc_1hmhf6r923q" target="_blank"&gt;Tensorboard Integration&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#mcetoc_1hmhf6r923r" target="_blank"&gt;Gradient Accumulation&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#mcetoc_1hmhf6r923s" target="_blank"&gt;Gradient Checkpointing&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#mcetoc_1hmhf6r923t" target="_blank"&gt;Finding the optimal configuration&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#mcetoc_1hmhf6r923u" target="_blank"&gt;Monitoring and debugging&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#mcetoc_1hmhf6r923v" target="_blank"&gt;Conclusion&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/DIV&gt;
&lt;H2 id="mcetoc_1hmhf6r923f"&gt;Overcoming GPU bottlenecks&lt;/H2&gt;
&lt;P&gt;The major bottleneck in deep learning training today is the amount of RAM per GPU - they simply don’t have a lot of it.&lt;/P&gt;
&lt;TABLE style="height: 400px; border-style: solid; width: 100%;" border="1" width="100%"&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD width="25%" height="50px"&gt;
&lt;P&gt;&lt;STRONG&gt;GPU Model&lt;/STRONG&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="25%" height="50px"&gt;
&lt;P&gt;&lt;STRONG&gt;VRAM (GB)&lt;/STRONG&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="25%" height="50px"&gt;
&lt;P&gt;&lt;STRONG&gt;AWS&lt;/STRONG&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="25%" height="50px"&gt;
&lt;P&gt;&lt;STRONG&gt;Azure&lt;/STRONG&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD width="25%" height="50px"&gt;
&lt;P&gt;&lt;SPAN&gt;T4&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="25%" height="50px"&gt;
&lt;P&gt;&lt;SPAN&gt;16&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="25%" height="50px"&gt;
&lt;P&gt;&lt;SPAN&gt;g4dn&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="25%" height="50px"&gt;
&lt;P&gt;&lt;SPAN&gt;NCasT4_v3&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD width="25%" height="50px"&gt;
&lt;P&gt;&lt;SPAN&gt;V100&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="25%" height="50px"&gt;
&lt;P&gt;&lt;SPAN&gt;16&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="25%" height="50px"&gt;
&lt;P&gt;&lt;SPAN&gt;p3&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="25%" height="50px"&gt;
&lt;P&gt;&lt;SPAN&gt;NC_v3&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD width="25%" height="50px"&gt;
&lt;P&gt;&lt;SPAN&gt;V100&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="25%" height="50px"&gt;
&lt;P&gt;&lt;SPAN&gt;32&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="25%" height="50px"&gt;
&lt;P&gt;&lt;SPAN&gt;p3dn&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="25%" height="50px"&gt;
&lt;P&gt;&lt;SPAN&gt;NDv2&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD width="25%" height="50px"&gt;
&lt;P&gt;&lt;SPAN&gt;A10&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="25%" height="50px"&gt;
&lt;P&gt;&lt;SPAN&gt;24&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="25%" height="50px"&gt;
&lt;P&gt;&lt;SPAN&gt;g5&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="25%" height="50px"&gt;
&lt;P&gt;&lt;SPAN&gt;NVadsA10_v5&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD width="25%" height="50px"&gt;
&lt;P&gt;&lt;SPAN&gt;A100&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="25%" height="50px"&gt;
&lt;P&gt;&lt;SPAN&gt;40&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="25%" height="50px"&gt;
&lt;P&gt;&lt;SPAN&gt;p4d&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="25%" height="50px"&gt;
&lt;P&gt;&lt;SPAN&gt;NDasrA100_v4&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD width="25%" height="50px"&gt;
&lt;P&gt;&lt;SPAN&gt;A100&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="25%" height="50px"&gt;
&lt;P&gt;&lt;SPAN&gt;80&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="25%" height="50px"&gt;
&lt;P&gt;&lt;SPAN&gt;p4de&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="25%" height="50px"&gt;
&lt;P&gt;&lt;SPAN&gt;NDm_A100_v4&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD width="25%" height="50px"&gt;
&lt;P&gt;&lt;SPAN&gt;H100&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="25%" height="50px"&gt;
&lt;P&gt;&lt;SPAN&gt;80&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="25%" height="50px"&gt;
&lt;P&gt;&lt;SPAN&gt;p5&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="25%" height="50px"&gt;
&lt;P&gt;&lt;SPAN&gt;NDm_H100_v5&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;P class="lia-align-center"&gt;Common GPUs - their instance types and available RAM&lt;/P&gt;
&lt;P&gt;To address this issue, two main paradigms have emerged: &lt;EM&gt;data parallel&lt;/EM&gt; and &lt;EM&gt;model parallel&lt;/EM&gt; training.&lt;/P&gt;
&lt;P&gt;Data parallel training involves splitting the data across multiple GPUs. In this scenario, each GPU needs to contain a full copy of the model and training artifacts (the optimizer state and gradients), greatly reducing available RAM for training data.&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Data Parallel Training - We still need all the Training Artifacts and the Full Model which takes up most of our VRAM" style="width: 712px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/6183i3B43FEF45E17CF3C/image-size/large?v=v2&amp;amp;px=999" role="button" title="brian_law_0-1707658364567.png" alt="Data Parallel Training - We still need all the Training Artifacts and the Full Model which takes up most of our VRAM" /&gt;&lt;span class="lia-inline-image-caption" onclick="event.preventDefault();"&gt;Data Parallel Training - We still need all the Training Artifacts and the Full Model which takes up most of our VRAM&lt;/span&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;On the other hand, model parallel training splits the model itself across multiple GPUs, freeing up RAM on each machine.&amp;nbsp; In this scenario a new bottleneck appears - the available network bandwidth between the distributed GPUs. &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Model Parallel Training - We have now split the model up but that means we need to get the data through all three GPUs to get a full forward and backward pass" style="width: 686px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/6190i26706B8ACD670384/image-size/large?v=v2&amp;amp;px=999" role="button" title="brian_law_0-1707659684027.png" alt="Model Parallel Training - We have now split the model up but that means we need to get the data through all three GPUs to get a full forward and backward pass" /&gt;&lt;span class="lia-inline-image-caption" onclick="event.preventDefault();"&gt;Model Parallel Training - We have now split the model up but that means we need to get the data through all three GPUs to get a full forward and backward pass&lt;/span&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;In the model parallel paradigm, the memory efficiency of DeepSpeed can be leveraged to allow us to train larger models without incurring exorbitant costs.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 id="mcetoc_1hmhf6r923g"&gt;&lt;SPAN&gt;Understanding DeepSpeed and the DeepSpeed Distributor&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;The DeepSpeed library consists of three key modules: the training of, inference with and compression of deep learning models. In this article we focus on model training.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;To understand how DeepSpeed fits and how to configure it, we must first unpack the training process. There are two constraints when training large language models and their computer vision cousins: the input / output speeds for loading training data and the amount of memory available per GPU card.&amp;nbsp;For data loading optimizations, refer to our &lt;A href="https://www.databricks.com/blog/contributing-spark-loader-for-hugging-face-datasets" target="_blank" rel="noopener"&gt;collaboration with Hugging Face&lt;/A&gt; and the &lt;A href="https://delta.io/blog/deltatorch-intro/" target="_self"&gt;Torchdelta&lt;/A&gt;&amp;nbsp;extension.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;For model training, there are three main memory hogs: the model and its weights, the optimizer state and gradients, and the size of the training data. &lt;/STRONG&gt;&lt;SPAN&gt;To reduce training time, we want to maximize the amount of data we load on the GPU. This requires configuring DeepSpeed to limit the RAM footprint of the model, optimizer and gradients. Let’s walk through those settings now.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H3 id="mcetoc_1hmhf6r923h"&gt;&lt;SPAN&gt;Model Precision Settings&lt;/SPAN&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN&gt;To ensure a high quality chat experience for end users of our LLM applications we want to use the largest models we can. By default, model weights are stored as 32-bit floating point, so even 7 billion parameter models take up all the RAM on smaller GPUs and a considerable chunk on larger ones. &lt;/SPAN&gt;&lt;STRONG&gt;DeepSpeed includes optimizations that allow us to train at 16-bit floating point instead, greatly reducing model size. &lt;/STRONG&gt;&lt;SPAN&gt;When using 16-bit floating point precision, a good rule of thumb is that an average model requires approximately 2x its number of parameters (billions) in GPU RAM (GB) rather than 4x with the default &lt;/SPAN&gt;&lt;I&gt;&lt;SPAN&gt;fp32&lt;/SPAN&gt;&lt;/I&gt;&lt;SPAN&gt;. Whilst it is possible to use lower precision, these techniques are still more experimental.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;There are two types of 16-bit precision to choose from: the normal &lt;I&gt;fp16&lt;/I&gt; and &lt;I&gt;bfloat16&lt;/I&gt;. When working with newer Nvidia GPUs (A10/A100/H100) it is recommended to use &lt;I&gt;bfloat16&lt;/I&gt;, which can be set as follows in the JSON config file.&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL class="lia-list-style-type-circle"&gt;
&lt;LI&gt;&lt;LI-CODE lang="python"&gt;"bf16": { 
   "enabled": true 
}&lt;/LI-CODE&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL class="lia-list-style-type-circle"&gt;
&lt;LI&gt;
&lt;P&gt;&lt;SPAN&gt;Older GPUs do not support &lt;/SPAN&gt;&lt;I&gt;&lt;SPAN&gt;bfloat16&lt;/SPAN&gt;&lt;/I&gt;&lt;SPAN&gt; and hence we will fallback to the older less efficient &lt;/SPAN&gt;&lt;I&gt;&lt;SPAN&gt;fp16&lt;/SPAN&gt;&lt;/I&gt;&lt;SPAN&gt; format, shown below.&lt;/SPAN&gt;&lt;/P&gt;
&lt;LI-CODE lang="python"&gt;"fp16": { 
        "enabled": "auto", 
        "loss_scale": 0, 
        "loss_scale_window": 1000, 
        "initial_scale_power": 16, 
        "hysteresis": 2, 
        "min_loss_scale": 1 
    }&lt;/LI-CODE&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;We recommend using &lt;/STRONG&gt;&lt;STRONG&gt;&lt;I&gt;bfloat&lt;/I&gt;&lt;/STRONG&gt;&lt;STRONG&gt; compatible GPUs where possible.&lt;/STRONG&gt;&lt;SPAN&gt; It has been noted that &lt;/SPAN&gt;&lt;I&gt;&lt;SPAN&gt;fp16&lt;/SPAN&gt;&lt;/I&gt;&lt;SPAN&gt; training can be unstable and may require manual intervention during the training to change learning rates and avoid &lt;/SPAN&gt;&lt;I&gt;&lt;SPAN&gt;NaN&lt;/SPAN&gt;&lt;/I&gt;&lt;SPAN&gt; losses which is partially why &lt;/SPAN&gt;&lt;I&gt;&lt;SPAN&gt;fp16&lt;/SPAN&gt;&lt;/I&gt;&lt;SPAN&gt; also has so many additional settings.; For more details check the &lt;/SPAN&gt;&lt;A href="https://www.deepspeed.ai/docs/config-json/#bfloat16-training-options" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;documentation&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt; and Nvidia's guide on &lt;/SPAN&gt;&lt;A href="https://docs.nvidia.com/deeplearning/performance/mixed-precision-training/index.html#training" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;mixed precision training&lt;/SPAN&gt;&lt;/A&gt;&lt;/P&gt;
&lt;H3 id="mcetoc_1hmhf6r923i"&gt;&lt;SPAN&gt;Optimizer and Gradient Settings&lt;/SPAN&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN&gt;The next area that we can look for memory savings is with the optimizer and gradient calculations. This can be done through leveraging the Zero Redundancy Optimizer (ZeRO) settings. ZeRO is the core of DeepSpeed and was first introduced in the &lt;/SPAN&gt;&lt;A href="https://arxiv.org/pdf/1910.02054.pdf" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;research paper&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt;. The authors noted that a lot of the weights, states and gradients stored during training are redundant, allowing for them to be partitioned across GPUs and even onto CPU and disk. This does result in the need to move data around and increases network traffic, but the savings in GPU RAM are worth it.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;ZeRO has three settings:&lt;/SPAN&gt;&lt;SPAN&gt;&lt;BR /&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Stage 1: Optimizer State Partitioning&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Stage 2: Optimizer and Gradient Partitioning&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Stage 3: Optimizer, Gradient and Parameter Partitioning&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN&gt;Beyond stage 3 we can also offload calculations onto the CPU and attached storage, though this can come with hefty performance constraints. For an understanding of the possible space savings, see the below diagram from the original ZeRO paper where Stage 1 = Pos, Stage 2 = Pos+g and Stage 3 = Pos+g+p.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="brian_law_0-1707660628666.png" style="width: 521px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/6191i72AAFBCF40510A28/image-dimensions/521x306?v=v2" width="521" height="306" role="button" title="brian_law_0-1707660628666.png" alt="brian_law_0-1707660628666.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;As we go from Stages 1 to 3, we can see that we get more and more VRAM savings. Whilst the formulas for calculating VRAM consumption are a little complex, here is a visualization of estimated VRAM requirements per GPU.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Calculations assume 4 GPUs we can reduce further with" style="width: 550px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/6192i82311D5F30F7DD79/image-dimensions/550x349?v=v2" width="550" height="349" role="button" title="brian_law_0-1707660684950.png" alt="Calculations assume 4 GPUs we can reduce further with" /&gt;&lt;span class="lia-inline-image-caption" onclick="event.preventDefault();"&gt;Calculations assume 4 GPUs we can reduce further with&lt;/span&gt;&lt;/span&gt;&lt;/P&gt;
&lt;TABLE border="1" width="100%"&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD width="32.5609756097561%"&gt;
&lt;P&gt;&lt;STRONG&gt;Model Parameter Count (B)&lt;/STRONG&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="20.975609756097562%"&gt;
&lt;P&gt;&lt;STRONG&gt;Base VRAM (GB)&lt;/STRONG&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="15.487804878048781%"&gt;
&lt;P&gt;&lt;STRONG&gt;ZeRo 1 (GB)&lt;/STRONG&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="15.487804878048781%"&gt;
&lt;P&gt;&lt;STRONG&gt;ZeRo 2 (GB)&lt;/STRONG&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="15.487804878048781%"&gt;
&lt;P&gt;&lt;STRONG&gt;ZeRo 3 (GB)&lt;/STRONG&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD width="32.5609756097561%"&gt;
&lt;P&gt;&lt;SPAN&gt;7&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="20.975609756097562%"&gt;
&lt;P&gt;&lt;SPAN&gt;112&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="15.487804878048781%"&gt;
&lt;P&gt;&lt;SPAN&gt;49&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="15.487804878048781%"&gt;
&lt;P&gt;&lt;SPAN&gt;38.5&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="15.487804878048781%"&gt;
&lt;P&gt;&lt;SPAN&gt;28&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD width="32.5609756097561%"&gt;
&lt;P&gt;&lt;SPAN&gt;13&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="20.975609756097562%"&gt;
&lt;P&gt;&lt;SPAN&gt;208&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="15.487804878048781%"&gt;
&lt;P&gt;&lt;SPAN&gt;91&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="15.487804878048781%"&gt;
&lt;P&gt;&lt;SPAN&gt;71.5&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="15.487804878048781%"&gt;
&lt;P&gt;&lt;SPAN&gt;52&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD width="32.5609756097561%"&gt;
&lt;P&gt;&lt;SPAN&gt;34&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="20.975609756097562%"&gt;
&lt;P&gt;&lt;SPAN&gt;544&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="15.487804878048781%"&gt;
&lt;P&gt;&lt;SPAN&gt;238&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="15.487804878048781%"&gt;
&lt;P&gt;&lt;SPAN&gt;187&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="15.487804878048781%"&gt;
&lt;P&gt;&lt;SPAN&gt;136&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD width="32.5609756097561%"&gt;
&lt;P&gt;&lt;SPAN&gt;70&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="20.975609756097562%"&gt;
&lt;P&gt;&lt;SPAN&gt;480&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="15.487804878048781%"&gt;
&lt;P&gt;&lt;SPAN&gt;210&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="15.487804878048781%"&gt;
&lt;P&gt;&lt;SPAN&gt;165&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="15.487804878048781%"&gt;
&lt;P&gt;&lt;SPAN&gt;120&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;P&gt;&lt;SPAN&gt;Beyond ZeRo 3, it is also possible to offload the optimizer states, gradients and parameters into either CPU RAM or attached NVMe drives. Whilst offload will cause a performance hit, it can allow small setups to train much larger models. &lt;/SPAN&gt;&lt;/P&gt;
&lt;UL class="lia-list-style-type-circle"&gt;
&lt;LI&gt;&lt;SPAN&gt;&lt;SPAN&gt;&lt;SPAN&gt;Offload can be set in the JSON configuration:&lt;BR /&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;LI-CODE lang="python"&gt;# cpu offload
"offload_optimizer": {"device": "cpu"},
"offload_param": {"device": "cpu"},&lt;/LI-CODE&gt;&lt;LI-CODE lang="python"&gt;# gpu offload
"offload_optimizer": {"device": "nvme", 
    "nvme_path": "/local_disk0/optimizer"},


"offload_param": {"device": "nvme",
"nvme_path": "/local_disk0/param"}&lt;/LI-CODE&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN&gt;On Databricks clusters, &lt;/SPAN&gt;&lt;I&gt;&lt;SPAN&gt;/local_disk0&lt;/SPAN&gt;&lt;/I&gt;&lt;SPAN&gt; is the mount path for direct attached storage that you can use as a temporary cache. Offload also requires the installation of &lt;/SPAN&gt;&lt;I&gt;&lt;SPAN&gt;libaio-dev&lt;/SPAN&gt;&lt;/I&gt;&lt;SPAN&gt;, an OS-level library that will require installing via init script (&lt;/SPAN&gt;&lt;A href="https://docs.databricks.com/en/init-scripts/index.html" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;AWS&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt;/&lt;/SPAN&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/databricks/init-scripts/" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;Azure&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt;). When using offload, it is important to make sure that there is sufficient CPU RAM and NVMe storage. It is recommended to set the &lt;/SPAN&gt;&lt;I&gt;&lt;SPAN&gt;autoscale local storage&lt;/SPAN&gt;&lt;/I&gt;&lt;SPAN&gt; setting when creating your cluster if you will use NVMe storage.&lt;/SPAN&gt;&lt;SPAN&gt;&lt;BR /&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="brian_law_0-1707660898074.png" style="width: 400px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/6193i384B81E42F7F82B6/image-size/medium?v=v2&amp;amp;px=400" role="button" title="brian_law_0-1707660898074.png" alt="brian_law_0-1707660898074.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;H2 id="mcetoc_1hmhf6r923j"&gt;&lt;SPAN&gt;How to trigger a DeepSpeed training job&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;Now that we understand the workings of key DeepSpeed configs, we can look at how to code and launch our pipelines. The beauty of the design around the DeepSpeed Distributor is that it doesn't require extensive code changes in order to leverage it within your workflows. Just like the TorchDistributor, the DeepSpeed flavor can be utilized in two ways:&lt;/SPAN&gt;&lt;SPAN&gt;&lt;BR /&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Trigger a function written within the existing notebook context&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Trigger an external Python script&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3 id="mcetoc_1hmhf6r923k"&gt;&lt;SPAN&gt;Triggering a function from notebooks&lt;/SPAN&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN&gt;In this example, we assume that the training function is called &lt;/SPAN&gt;&lt;I&gt;&lt;SPAN&gt;train&lt;/SPAN&gt;&lt;/I&gt;&lt;SPAN&gt; and it accepts the arguments &lt;/SPAN&gt;&lt;I&gt;&lt;SPAN&gt;training_arguments&lt;/SPAN&gt;&lt;/I&gt;&lt;SPAN&gt; and &lt;/SPAN&gt;&lt;I&gt;&lt;SPAN&gt;dataset.&lt;/SPAN&gt;&lt;/I&gt;&lt;/P&gt;
&lt;UL class="lia-list-style-type-circle"&gt;
&lt;LI&gt;&lt;SPAN&gt;&lt;SPAN&gt;Running on single node:&lt;BR /&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;LI-CODE lang="python"&gt;from pyspark.ml.deepspeed.deepspeed_distributor import DeepspeedTorchDistributor

distributor = DeepspeedTorchDistributor(numGpus=1, nnodes=1, localMode=True, 
                                        useGpu=True, 
deepspeedConfig = deepspeed_dict)

completed_trainer = distributor.run(train, training_arguments, dataset)&lt;/LI-CODE&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;&lt;SPAN&gt;Running in distributed fashion:&lt;BR /&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;LI-CODE lang="python"&gt;from pyspark.ml.deepspeed.deepspeed_distributor import DeepspeedTorchDistributor

distributor = DeepspeedTorchDistributor(numGpus=4, nnodes=2, localMode=True, 
                                        useGpu=True, 
deepspeedConfig = deepspeed_dict)

completed_trainer = distributor.run(train, training_arguments, dataset)&lt;/LI-CODE&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN&gt;To elaborate on the parameters available to &lt;/SPAN&gt;&lt;I&gt;&lt;SPAN&gt;DeepSpeedTorchDistributor&lt;/SPAN&gt;&lt;/I&gt;&lt;SPAN&gt;:&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;I&gt;&lt;SPAN&gt;numGpus&lt;/SPAN&gt;&lt;/I&gt;&lt;SPAN&gt;: number of GPUs per node&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;I&gt;&lt;SPAN&gt;nnodes&lt;/SPAN&gt;&lt;/I&gt;&lt;SPAN&gt;: number of nodes to train on&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;I&gt;&lt;SPAN&gt;localMode&lt;/SPAN&gt;&lt;/I&gt;&lt;SPAN&gt;: if True, trains on the driver node only (for single node cluster) if False will train on the workers&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;I&gt;&lt;SPAN&gt;useGpu&lt;/SPAN&gt;&lt;/I&gt;&lt;SPAN&gt;: whether to train using GPUs&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;I&gt;&lt;SPAN&gt;deepspeedConfig&lt;/SPAN&gt;&lt;/I&gt;&lt;SPAN&gt;: JSON file with all configuration parameters&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN&gt;While &lt;/SPAN&gt;&lt;I&gt;&lt;SPAN&gt;useGPU&lt;/SPAN&gt;&lt;/I&gt;&lt;SPAN&gt; is available, it is worth mentioning that DeepSpeed should ideally be used with GPUs.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H3 id="mcetoc_1hmhf6r923l"&gt;&lt;SPAN&gt;Triggering a Python script&lt;/SPAN&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN&gt;In addition to executing a &lt;/SPAN&gt;&lt;I&gt;&lt;SPAN&gt;train&lt;/SPAN&gt;&lt;/I&gt;&lt;SPAN&gt; function defined in a notebook, it is possible to use &lt;/SPAN&gt;&lt;I&gt;&lt;SPAN&gt;DeepspeedTorchDistributor&lt;/SPAN&gt;&lt;/I&gt;&lt;SPAN&gt; to load and execute a training script by specifying the path to the Python file and passing command line arguments to it.&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL class="lia-list-style-type-circle"&gt;
&lt;LI&gt;&lt;SPAN&gt;&lt;SPAN&gt;&lt;SPAN&gt;Running on single node:&lt;BR /&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;LI-CODE lang="python"&gt;from pyspark.ml.deepspeed.deepspeed_distributor import DeepspeedTorchDistributor

distributor = DeepspeedTorchDistributor(numGpus=4, nnodes=1, localMode=False, 
                                        useGpu=True, 
deepspeedConfig = deepspeed_dict)

completed_trainer = distributor.run('&amp;lt;path_to_file&amp;gt;/train.py', "--var1 value1", "--var2 value2")&lt;/LI-CODE&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN&gt;&lt;SPAN&gt;&lt;SPAN&gt;Running in distributed fashion:&lt;BR /&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;LI-CODE lang="python"&gt;from pyspark.ml.deepspeed.deepspeed_distributor import DeepspeedTorchDistributor

distributor = DeepspeedTorchDistributor(numGpus=4, nnodes=2, localMode=False, 
                                        useGpu=True, 
deepspeedConfig = deepspeed_dict)

completed_trainer = distributor.run('&amp;lt;path_to_file&amp;gt;/train.py', "--var1 value1", "--var2 value2")&lt;/LI-CODE&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2 id="mcetoc_1hmhf6r923m"&gt;&lt;SPAN&gt;Tricks and Tips to be productive&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;Now that you understand the key &lt;I&gt;DeepSpeed &lt;/I&gt;configs and how to launch your training job, we will cover some other considerations that you should be aware of to ensure the smoothest possible experience.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H3 id="mcetoc_1hmhf6r923n"&gt;&lt;SPAN&gt;Estimating Memory Requirements&lt;/SPAN&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN&gt;Managing and understanding the requirements to fine tune a particular model can be hard. There are a few helpful rules of thumb first to assess the viability of our training job before consuming any GPU resources.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;As discussed, the number of parameters in a model will dictate the amount of VRAM it and its training states will take. If we are training with &lt;/SPAN&gt;&lt;I&gt;&lt;SPAN&gt;fp16&lt;/SPAN&gt;&lt;/I&gt;&lt;SPAN&gt; or &lt;/SPAN&gt;&lt;I&gt;&lt;SPAN&gt;bfloat16&lt;/SPAN&gt;&lt;/I&gt;&lt;SPAN&gt; we can use a simple formula:&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;2 X number of params (B) = VRAM required (GB)&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Thus, a 7 billion parameter model like &lt;/SPAN&gt;&lt;I&gt;&lt;SPAN&gt;llama_v2_7b&lt;/SPAN&gt;&lt;/I&gt;&lt;SPAN&gt; will take approximately 14GB VRAM to load in &lt;/SPAN&gt;&lt;I&gt;&lt;SPAN&gt;bfloat16&lt;/SPAN&gt;&lt;/I&gt;&lt;SPAN&gt; format.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Next, we need to factor in the type of fine-tuning that we are doing. The memory footprint for model weights, weight gradients, adapter weights and optimizer state will depend on whether we are using LoRa, QLoRa, or full fine-tuning (excluding activations / input gradients).&amp;nbsp; The total memory usage per parameter is summarized in the table below.&lt;/SPAN&gt;&lt;/P&gt;
&lt;TABLE border="1" width="99.8780487804878%"&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD width="19.878048780487806%"&gt;
&lt;P&gt;&lt;STRONG&gt;Tuning Method&lt;/STRONG&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="9.268292682926829%"&gt;
&lt;P&gt;&lt;STRONG&gt;Weights&lt;/STRONG&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="18.170731707317074%"&gt;
&lt;P&gt;&lt;STRONG&gt;Weight Gradients&lt;/STRONG&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="16.21951219512195%"&gt;
&lt;P&gt;&lt;STRONG&gt;Optimizer State&lt;/STRONG&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="17.4390243902439%"&gt;
&lt;P&gt;&lt;STRONG&gt;Adapter Weights&lt;/STRONG&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="18.902439024390244%"&gt;
&lt;P&gt;&lt;STRONG&gt;Total&lt;/STRONG&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD width="19.878048780487806%"&gt;
&lt;P&gt;&lt;SPAN&gt;Full Fine-Tuning&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="9.268292682926829%"&gt;
&lt;P&gt;&lt;SPAN&gt;2 bytes&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="18.170731707317074%"&gt;
&lt;P&gt;&lt;SPAN&gt;2 bytes&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="16.21951219512195%"&gt;
&lt;P&gt;&lt;SPAN&gt;8 bytes&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="17.4390243902439%"&gt;
&lt;P&gt;&lt;SPAN&gt;N/A&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="18.902439024390244%"&gt;
&lt;P&gt;&lt;SPAN&gt;12 bytes/parameter&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD width="19.878048780487806%"&gt;
&lt;P&gt;&lt;SPAN&gt;LoRa Fine-Tuning&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="9.268292682926829%"&gt;
&lt;P&gt;&lt;SPAN&gt;16 bits&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="18.170731707317074%"&gt;
&lt;P&gt;&lt;SPAN&gt;~0.4 bits&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="16.21951219512195%"&gt;
&lt;P&gt;&lt;SPAN&gt;~0.8 bits&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="17.4390243902439%"&gt;
&lt;P&gt;&lt;SPAN&gt;~0.4 bits&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="18.902439024390244%"&gt;
&lt;P&gt;&lt;SPAN&gt;17.6 bits/parameter&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD width="19.878048780487806%"&gt;
&lt;P&gt;&lt;SPAN&gt;QLoRa Fine-Tuning*&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="9.268292682926829%"&gt;
&lt;P&gt;&lt;SPAN&gt;4 bits&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="18.170731707317074%"&gt;
&lt;P&gt;&lt;SPAN&gt;~0.4 bits&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="16.21951219512195%"&gt;
&lt;P&gt;&lt;SPAN&gt;~0.8 bits&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="17.4390243902439%"&gt;
&lt;P&gt;&lt;SPAN&gt;~0.4 bits&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="18.902439024390244%"&gt;
&lt;P&gt;&lt;SPAN&gt;5.6 bits/parameter&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;P class="lia-align-center"&gt;&lt;I&gt;&lt;SPAN&gt;*Note that currently QLoRa and DeepSpeed ZeRo 3 are incompatible.&lt;/SPAN&gt;&lt;/I&gt;&lt;/P&gt;
&lt;P class="lia-align-left"&gt;Combining our formula for model size memory requirements with the additional fine-tuning memory requirements, we can estimate the total RAM required for a training run:&lt;/P&gt;
&lt;TABLE border="1" width="99.8780487804878%"&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD width="13.536585365853659%"&gt;
&lt;P&gt;&lt;STRONG&gt;Model&lt;/STRONG&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="11.829268292682926%"&gt;
&lt;P&gt;&lt;STRONG&gt;Model Size (&lt;/STRONG&gt;&lt;STRONG&gt;&lt;I&gt;fp32&lt;/I&gt;&lt;/STRONG&gt;&lt;STRONG&gt;)&lt;/STRONG&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="15.121951219512194%"&gt;
&lt;P&gt;&lt;STRONG&gt;Model Size (&lt;/STRONG&gt;&lt;STRONG&gt;&lt;I&gt;bfloat16&lt;/I&gt;&lt;/STRONG&gt;&lt;STRONG&gt;)&lt;/STRONG&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="24.75609756097561%"&gt;
&lt;P&gt;&lt;STRONG&gt;Full Finetune Requirements (&lt;/STRONG&gt;&lt;STRONG&gt;&lt;I&gt;bfloat16&lt;/I&gt;&lt;/STRONG&gt;&lt;STRONG&gt;)&lt;/STRONG&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="16.951219512195124%"&gt;
&lt;P&gt;&lt;STRONG&gt;LoRa Requirements&lt;/STRONG&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="17.682926829268293%"&gt;
&lt;P&gt;&lt;STRONG&gt;QLoRa Requirements&lt;/STRONG&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD width="13.536585365853659%"&gt;
&lt;P&gt;&lt;SPAN&gt;llama_v2_7b&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="11.829268292682926%"&gt;
&lt;P&gt;&lt;SPAN&gt;28GB&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="15.121951219512194%"&gt;
&lt;P&gt;&lt;SPAN&gt;~14GB&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="24.75609756097561%"&gt;
&lt;P&gt;&lt;SPAN&gt;~84GB&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="16.951219512195124%"&gt;
&lt;P&gt;&lt;SPAN&gt;~15.4GB&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="17.682926829268293%"&gt;
&lt;P&gt;&lt;SPAN&gt;~4.55GB&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD width="13.536585365853659%"&gt;
&lt;P&gt;&lt;SPAN&gt;llama_v2_13b&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="11.829268292682926%"&gt;
&lt;P&gt;&lt;SPAN&gt;52GB&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="15.121951219512194%"&gt;
&lt;P&gt;&lt;SPAN&gt;~25GB&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="24.75609756097561%"&gt;
&lt;P&gt;&lt;SPAN&gt;~150GB&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="16.951219512195124%"&gt;
&lt;P&gt;&lt;SPAN&gt;~28.6GB&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="17.682926829268293%"&gt;
&lt;P&gt;&lt;SPAN&gt;~8.45GB&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD width="13.536585365853659%"&gt;
&lt;P&gt;&lt;SPAN&gt;MNPT_7b&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="11.829268292682926%"&gt;
&lt;P&gt;&lt;SPAN&gt;28GB&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="15.121951219512194%"&gt;
&lt;P&gt;&lt;SPAN&gt;~14GB&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="24.75609756097561%"&gt;
&lt;P&gt;&lt;SPAN&gt;~84GB&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="16.951219512195124%"&gt;
&lt;P&gt;&lt;SPAN&gt;~15.4GB&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="17.682926829268293%"&gt;
&lt;P&gt;&lt;SPAN&gt;~4.55GB&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;P&gt;&lt;SPAN&gt;Now that we size up the viability of our job with our available resources, we can look into the rest of the training setup.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H3 id="mcetoc_1hmhf6r923o"&gt;&lt;SPAN&gt;Setting Hugging Face Caches&lt;/SPAN&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN&gt;When using Hugging Face libraries it is important to understand how it caches. Caching can generally be set at an individual item level (a specific call to dataset or model), at a library level (for all dataset or transformer objects) or at a global level (for all Hugging Face libraries).&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;There is also a hierarchy in that setting a cache when instantiating an item will override the global default. All the Hugging Face libraries default to &lt;I&gt;~/.cache&lt;/I&gt; which is the root OS folder on databricks nodes. This can quickly result in the root OS folder filling up and causing the cluster to crash. &lt;STRONG&gt;To alleviate pressure on root, it is recommended to set the cache directories to either a DBFS directory or /&lt;/STRONG&gt;&lt;STRONG&gt;&lt;I&gt;local_disk0&lt;/I&gt;&lt;/STRONG&gt;&lt;STRONG&gt; path.&lt;/STRONG&gt; This can be configured through environment variables to ensure they are set prior to instantiating your model and dataset classes.&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL class="lia-list-style-type-circle"&gt;
&lt;LI&gt;&lt;EM&gt;&lt;EM&gt;&lt;EM&gt;Configuring environment variables:&lt;BR /&gt;&lt;/EM&gt;&lt;/EM&gt;&lt;/EM&gt;&lt;LI-CODE lang="python"&gt;import os

# Setting Hugging Face cache to /local_disk0
os.environ['HF_HOME'] = '/local_disk0/hf_home'
os.environ['HF_DATASETS_CACHE'] = '/local_disk0/hf_home'
os.environ['TRANSFORMERS_CACHE'] = '/local_disk0/hf_home'&lt;/LI-CODE&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN&gt;Whilst caching on DBFS guarantees persistence even after clusters get shut down, caching on &lt;/SPAN&gt;&lt;I&gt;&lt;SPAN&gt;local_disk0&lt;/SPAN&gt;&lt;/I&gt;&lt;SPAN&gt; can offer better performance for frequently accessed data like a Hugging Face dataset. &lt;/SPAN&gt;&lt;STRONG&gt;A rule of thumb is to cache transformer models to DBFS since they are loaded only once, while datasets can be cached to &lt;/STRONG&gt;&lt;STRONG&gt;&lt;I&gt;`local_disk0`&lt;/I&gt;&lt;/STRONG&gt;&lt;STRONG&gt;.&lt;/STRONG&gt;&lt;/P&gt;
&lt;H3 id="mcetoc_1hmhf6r923p"&gt;&lt;STRONG&gt;&lt;SPAN&gt;Configuring MLflow with DeepSpeed&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN&gt;MLflow has strong support for transformers, and we recommend installing the latest version (&lt;/SPAN&gt;&lt;A href="https://mlflow.org/docs/latest/index.html" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;2.10.1&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt;) for the best experience. It is beyond this blog to explain the basic concepts of MLflow, but there are a few tricks to using it with DeepSpeed that we will cover.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;When operating in a standard notebook environment, the Python session is initiated with a login token for MLflow. When running DeepSpeed, however, individual GPUs will each have a separate Python process that does not inherit these credentials. To proceed, we can save these parameters to Python variables using &lt;A href="https://docs.databricks.com/en/dev-tools/databricks-utils.html" target="_blank" rel="noopener"&gt;&lt;I&gt;dbutils&lt;/I&gt;&lt;/A&gt;, then assign them to environment variables within the function that &lt;I&gt;DeepspeedTorchDistributor&lt;/I&gt; will distribute.&lt;/P&gt;
&lt;UL class="lia-list-style-type-circle"&gt;
&lt;LI&gt;&lt;EM&gt;Getting and settings Databricks host, token:&lt;BR /&gt;&lt;/EM&gt;&lt;LI-CODE lang="python"&gt;# logging host and token
import os

browser_host = dbutils.notebook.entry_point.getDbutils().notebook().getContext().browserHostName().get()
db_host = f"https://{browser_host}"

db_token = dbutils.notebook.entry_point.getDbutils().notebook().getContext().apiToken().get()

os.environ['DATABRICKS_HOST'] = db_host
os.environ['DATABRICKS_TOKEN'] = db_token&lt;/LI-CODE&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN&gt;We also need to create and set the MLflow experiment, as only the primary notebook process can automatically create new experiments. Finally, when doing our MLflow logging, we should ensure that it is run only from the head node of the training process. The head node is the one that has &lt;EM&gt;global_rank&lt;/EM&gt; 0 in Nvidia parlance.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL class="lia-list-style-type-circle"&gt;
&lt;LI&gt;&lt;SPAN&gt;&lt;SPAN&gt;&lt;SPAN&gt;Getting GPU rank with PyTorch&lt;BR /&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;LI-CODE lang="python"&gt;global_rank = torch.distributed.get_rank()&lt;/LI-CODE&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3 id="mcetoc_1hmhf6r923q"&gt;&lt;SPAN&gt;Tensorboard Integration&lt;/SPAN&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN&gt;Whilst MLflow provides logging and monitoring capabilities for visualizing training runs, Tensorboard can still be useful for monitoring your run, and can be launched in Databricks by running the following commands.&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL class="lia-list-style-type-circle"&gt;
&lt;LI&gt;Launching Tensorboard in Databricks Notebooks:&lt;BR /&gt;&lt;LI-CODE lang="python"&gt;%load_ext tensorboard
# This sets up our tensorboard settings
experiment_log_dir = &amp;lt;log-directory&amp;gt;&lt;/LI-CODE&gt;&lt;LI-CODE lang="python"&gt;%tensorboard --logdir $experiment_log_dir
# This starts Tensorboard&lt;/LI-CODE&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN&gt;In order to use Tensorboard during a training run, execute this code in its own notebook. Keep in mind that when writing logs to DBFS the results may not be viewable in Tensorboard until the run is finished.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H3 id="mcetoc_1hmhf6r923r"&gt;&lt;SPAN&gt;Gradient Accumulation&lt;/SPAN&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN&gt;If we didn’t have GPU VRAM constraints then we would set larger batches to get through our training data faster. Due to VRAM constraints we commonly are restricted to batch sizes in the single digits. Gradient accumulation tells the algorithm to avoid doing a weight update till it has gone through sufficient data records. We can hence reduce our VRAM requirements at a small cost to performance.&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL class="lia-list-style-type-circle"&gt;
&lt;LI&gt;Setting gradient accumulation in the DeepSpeed JSON config:&lt;BR /&gt;&lt;LI-CODE lang="python"&gt;"gradient_accumulation_steps": 4&lt;/LI-CODE&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3 id="mcetoc_1hmhf6r923s"&gt;&lt;SPAN&gt;Gradient Checkpointing&lt;/SPAN&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN&gt;As we discussed earlier, the gradient calculations during a training run are one major source of VRAM consumption. By default, we store all the activation values for our network on the forward pass since they will be used for the backward pass. Gradient checkpointing strategically stores only a portion of the activations. It does mean that inevitably some will have to be recalculated to slow down our training loop (for more details see &lt;A href="https://arxiv.org/abs/1604.06174" target="_blank" rel="noopener"&gt;here&lt;/A&gt;).&amp;nbsp;&lt;BR /&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL class="lia-list-style-type-circle"&gt;
&lt;LI&gt;&lt;SPAN&gt;&lt;SPAN&gt;&lt;SPAN&gt;Turning on gradient checkpointing:&lt;BR /&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;LI-CODE lang="python"&gt;model.gradient_checkpointing_enable()&lt;/LI-CODE&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;In our experiments, using gradient checkpointing with &lt;/STRONG&gt;&lt;STRONG&gt;&lt;I&gt;ZeRo 3&lt;/I&gt;&lt;/STRONG&gt;&lt;STRONG&gt; offload on 4x A10Gs saved approximately 6GB VRAM per GPU. &lt;/STRONG&gt;&lt;/P&gt;
&lt;H3 id="mcetoc_1hmhf6r923t"&gt;&lt;STRONG&gt;&lt;SPAN&gt;Finding the optimal configuration&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;The goal of configuring your DeepSpeed training loop is to have it run as efficiently as possible. One of the most frustrating things that can happen is an out-of-memory error deep into your training run.&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Typical out-of-memory (OOM) exception on GPUs" style="width: 917px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/6198iB98DBEA87DCCDD31/image-size/large?v=v2&amp;amp;px=999" role="button" title="brian_law_0-1707741306041.png" alt="Typical out-of-memory (OOM) exception on GPUs" /&gt;&lt;span class="lia-inline-image-caption" onclick="event.preventDefault();"&gt;Typical out-of-memory (OOM) exception on GPUs&lt;/span&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;To limit the chance of this happening, we recommend following these steps to establish an optimal configuration:&lt;/SPAN&gt;&lt;SPAN&gt;&lt;BR /&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;OL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Estimate your memory requirements using the table above&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;For model precision, use &lt;/SPAN&gt;&lt;I&gt;&lt;SPAN&gt;bfloat16&lt;/SPAN&gt;&lt;/I&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;For optimizer and gradient settings, use &lt;/SPAN&gt;&lt;I&gt;&lt;SPAN&gt;ZeRo 3&lt;/SPAN&gt;&lt;/I&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&lt;SPAN&gt;Try a training run and see how it goes. If you find yourself running into out-of-memory issues, progressively add offload and set gradient accumulation steps and turn on gradient checkpointing. The training process may run more slowly, but it will be more likely to complete.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H3 id="mcetoc_1hmhf6r923u"&gt;&lt;SPAN&gt;Monitoring and debugging&lt;/SPAN&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN&gt;The best way to monitor and debug DeepSpeed training runs is to look at the &lt;I&gt;Metrics&lt;/I&gt; and &lt;I&gt;Driver logs&lt;/I&gt; tabs in the Databricks web UI:&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Find hardware utilization metrics and system logs from the Cluster UI" style="width: 905px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/6199i5B6D76B6D6311B52/image-size/large?v=v2&amp;amp;px=999" role="button" title="brian_law_1-1707741353341.png" alt="Find hardware utilization metrics and system logs from the Cluster UI" /&gt;&lt;span class="lia-inline-image-caption" onclick="event.preventDefault();"&gt;Find hardware utilization metrics and system logs from the Cluster UI&lt;/span&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;The metrics tab has separate dropdowns for hardware settings, including GPU and CPU utilization. &lt;/SPAN&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="GPU utilization metrics in Databricks" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/6200iA435C3EFCB96A286/image-size/large?v=v2&amp;amp;px=999" role="button" title="brian_law_2-1707741377461.png" alt="GPU utilization metrics in Databricks" /&gt;&lt;span class="lia-inline-image-caption" onclick="event.preventDefault();"&gt;GPU utilization metrics in Databricks&lt;/span&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Load and CPU utilization metrics in Databricks" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/6201iE5C716E3B647FC17/image-size/large?v=v2&amp;amp;px=999" role="button" title="brian_law_3-1707741399820.png" alt="Load and CPU utilization metrics in Databricks" /&gt;&lt;span class="lia-inline-image-caption" onclick="event.preventDefault();"&gt;Load and CPU utilization metrics in Databricks&lt;/span&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;The driver logs will give us the same debug details that would appear in a terminal session should the excerpts displayed in the notebook prove insufficient.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Additional details in driver logs" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/6202i931DA9E4EB9F7B31/image-size/large?v=v2&amp;amp;px=999" role="button" title="brian_law_4-1707741425620.png" alt="Additional details in driver logs" /&gt;&lt;span class="lia-inline-image-caption" onclick="event.preventDefault();"&gt;Additional details in driver logs&lt;/span&gt;&lt;/span&gt;&lt;/P&gt;
&lt;H2 id="mcetoc_1hmhf6r923v"&gt;&lt;SPAN&gt;Conclusion&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;The DeepSpeed Distributor on Databricks marks a pivotal advancement in efficiently training large language models by significantly reducing GPU memory requirements. It simplifies resource configurations and management, enabling scalable and optimized AI project development.&amp;nbsp; Try it out on Databricks today using the code found &lt;A href="https://github.com/Data-drone/Deepspeed_distributor" target="_blank" rel="noopener"&gt;here&lt;/A&gt;.&lt;/SPAN&gt;&lt;/P&gt;</description>
    <pubDate>Tue, 13 Feb 2024 14:51:52 GMT</pubDate>
    <dc:creator>brian_law</dc:creator>
    <dc:date>2024-02-13T14:51:52Z</dc:date>
    <item>
      <title>Introducing the DeepSpeed Distributor on Databricks</title>
      <link>https://community.databricks.com/t5/technical-blog/introducing-the-deepspeed-distributor-on-databricks/ba-p/59641</link>
      <description>&lt;P&gt;Are you training large deep learning models? Do you want to make the most of the compute resources available to you? Have you gone through the pain of configuring and setting up compute clusters? Well this article is just for you! With the new DeepSpeed distributor you all the above and more quicker and simpler! Best of all, it is in open source too for the benefit of the whole community. Take your GPU-enabled cluster and accelerate your model training and finetuning today!&amp;nbsp;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 13 Feb 2024 14:51:52 GMT</pubDate>
      <guid>https://community.databricks.com/t5/technical-blog/introducing-the-deepspeed-distributor-on-databricks/ba-p/59641</guid>
      <dc:creator>brian_law</dc:creator>
      <dc:date>2024-02-13T14:51:52Z</dc:date>
    </item>
    <item>
      <title>Re: Introducing the DeepSpeed Distributor on Databricks</title>
      <link>https://community.databricks.com/t5/technical-blog/introducing-the-deepspeed-distributor-on-databricks/bc-p/101651#M408</link>
      <description>&lt;P&gt;&lt;a href="https://community.databricks.com/t5/user/viewprofilepage/user-id/1714"&gt;@brian_law&lt;/a&gt;&amp;nbsp;In the section above on HuggingFace cache you recommend using DBFS for the model cache. Can a shared path (such as a Workspace of Volume) be used as well?&lt;/P&gt;</description>
      <pubDate>Tue, 10 Dec 2024 18:29:54 GMT</pubDate>
      <guid>https://community.databricks.com/t5/technical-blog/introducing-the-deepspeed-distributor-on-databricks/bc-p/101651#M408</guid>
      <dc:creator>pemidexx</dc:creator>
      <dc:date>2024-12-10T18:29:54Z</dc:date>
    </item>
  </channel>
</rss>

