Megatron-LM GPT2

news2024/11/26 11:35:17

 

内容

  • 使用原始 Megatron-LM 训练 GPT-2
    • 训练数据设置
    • 运行未修改的 Megatron-LM GPT2 模型
  • 启用 DeepSpeed
    • 参数解析
    • 初始化和训练
      • 初始化
      • 使用训练 API
        • 前向传播
        • 反向传播
        • 更新模型参数
        • 损失缩放
    • 检查点保存和加载
    • DeepSpeed 激活检查点(可选)
    • 训练脚本
  • 使用 GPT-2 的 DeepSpeed 评估

如果您还没有,我们建议您在逐步完成本教程之前先通读入门指南。

在本教程中,我们将向 Megatron-LM GPT2 模型添加 DeepSpeed,这是一个强大的大型变压器。Megatron-LM 支持模型并行多节点训练。更多详情请参阅相应论文:Megatron-LM: Training Multi-Billion Parameter Language Models Using Model Parallelism。

首先,我们讨论数据和环境设置以及如何使用原始 Megatron-LM 训练 GPT-2 模型。接下来,我们将逐步使该模型能够与 DeepSpeed 一起运行。最后,我们展示了使用 DeepSpeed 带来的性能提升内存占用减少。

使用原始 Megatron-LM 训练 GPT-2

我们已将原始模型代码从Megatron-LM复制到 DeepSpeed Megatron-LM中,并将其作为子模块提供。要下载,请执行:

<span style="background-color:#263238"><span style="color:#eeffff"><code>git submodule update <span style="color:#89ddff">--init</span> <span style="color:#89ddff">--recursive</span>
</code></span></span>

训练数据设置

  • 按照 Megatron 的说明下载webtext数据并将符号链接置于DeepSpeedExamples/Megatron-LM/data

运行未修改的 Megatron-LM GPT2 模型固定链接

  • 对于单个 GPU 运行:
    • 更改scripts/pretrain_gpt2.sh,将其--train-data参数设置为"webtext"
    • 跑步bash scripts/pretrain_gpt2.sh
  • 对于多个 GPU 和/或节点运行:
    • 改变scripts/pretrain_gpt2_model_parallel.sh
      • 将其--train-data参数设置为"webtext"
      • GPUS_PER_NODE表示测试中涉及的每个节点有多少 GPU
      • NNODES指示有多少个节点参与测试
    • 跑步bash scripts/pretrain_gpt2_model_parallel.sh

启用 DeepSpeed固定链接

要使用 DeepSpeed,我们将修改三个文件:

  • arguments.py:参数配置
  • pretrain_gpt2.py: 训练的主要切入点
  • utils.py:检查点保存和加载实用程序

参数解析

第一步是将 DeepSpeed 参数添加到 Megatron-LM GPT2 模型,使用deepspeed.add_config_arguments()in arguments.py.

<span style="background-color:#263238"><span style="color:#eeffff"><code><span style="color:#c792ea">def</span> <span style="color:#82aaff">get_args</span><span style="color:#eeffff">():</span>
    <span style="color:#c3e88d">"""Parse all the args."""</span>

    <span style="color:#eeffff">parser</span> <span style="color:#89ddff">=</span> <span style="color:#eeffff">argparse</span><span style="color:#eeffff">.</span><span style="color:#eeffff">ArgumentParser</span><span style="color:#eeffff">(</span><span style="color:#eeffff">description</span><span style="color:#89ddff">=</span><span style="color:#c3e88d">'PyTorch BERT Model'</span><span style="color:#eeffff">)</span>
    <span style="color:#eeffff">parser</span> <span style="color:#89ddff">=</span> <span style="color:#eeffff">add_model_config_args</span><span style="color:#eeffff">(</span><span style="color:#eeffff">parser</span><span style="color:#eeffff">)</span>
    <span style="color:#eeffff">parser</span> <span style="color:#89ddff">=</span> <span style="color:#eeffff">add_fp16_config_args</span><span style="color:#eeffff">(</span><span style="color:#eeffff">parser</span><span style="color:#eeffff">)</span>
    <span style="color:#eeffff">parser</span> <span style="color:#89ddff">=</span> <span style="color:#eeffff">add_training_args</span><span style="color:#eeffff">(</span><span style="color:#eeffff">parser</span><span style="color:#eeffff">)</span>
    <span style="color:#eeffff">parser</span> <span style="color:#89ddff">=</span> <span style="color:#eeffff">add_evaluation_args</span><span style="color:#eeffff">(</span><span style="color:#eeffff">parser</span><span style="color:#eeffff">)</span>
    <span style="color:#eeffff">parser</span> <span style="color:#89ddff">=</span> <span style="color:#eeffff">add_text_generate_args</span><span style="color:#eeffff">(</span><span style="color:#eeffff">parser</span><span style="color:#eeffff">)</span>
    <span style="color:#eeffff">parser</span> <span style="color:#89ddff">=</span> <span style="color:#eeffff">add_data_args</span><span style="color:#eeffff">(</span><span style="color:#eeffff">parser</span><span style="color:#eeffff">)</span>

    <span style="color:#b2ccd6"># Include DeepSpeed configuration arguments
</span>    <span style="color:#eeffff">parser</span> <span style="color:#89ddff">=</span> <span style="color:#eeffff">deepspeed</span><span style="color:#eeffff">.</span><span style="color:#eeffff">add_config_arguments</span><span style="color:#eeffff">(</span><span style="color:#eeffff">parser</span><span style="color:#eeffff">)</span>
</code></span></span>

初始化和训练固定链接

我们将修改pretrain.py以启用 DeepSpeed 训练。

初始化固定链接

我们用来deepspeed.initialize创建model_engine,optimizer和 LR scheduler。下面是它的定义:

<span style="background-color:#263238"><span style="color:#eeffff"><code><span style="color:#c792ea">def</span> <span style="color:#82aaff">initialize</span><span style="color:#eeffff">(</span><span style="color:#eeffff">args</span><span style="color:#eeffff">,</span>
               <span style="color:#eeffff">model</span><span style="color:#eeffff">,</span>
               <span style="color:#eeffff">optimizer</span><span style="color:#89ddff">=</span><span style="color:#eeffff">None</span><span style="color:#eeffff">,</span>
               <span style="color:#eeffff">model_parameters</span><span style="color:#89ddff">=</span><span style="color:#eeffff">None</span><span style="color:#eeffff">,</span>
               <span style="color:#eeffff">training_data</span><span style="color:#89ddff">=</span><span style="color:#eeffff">None</span><span style="color:#eeffff">,</span>
               <span style="color:#eeffff">lr_scheduler</span><span style="color:#89ddff">=</span><span style="color:#eeffff">None</span><span style="color:#eeffff">,</span>
               <span style="color:#eeffff">mpu</span><span style="color:#89ddff">=</span><span style="color:#eeffff">None</span><span style="color:#eeffff">,</span>
               <span style="color:#eeffff">dist_init_required</span><span style="color:#89ddff">=</span><span style="color:#eeffff">True</span><span style="color:#eeffff">,</span>
               <span style="color:#eeffff">collate_fn</span><span style="color:#89ddff">=</span><span style="color:#eeffff">None</span><span style="color:#eeffff">):</span>
</code></span></span>

对于 Megatron-LM GPT2 模型,我们在其setup_model_and_optimizer()函数中初始化 DeepSpeed,如下所示,以传递原始的modeloptimizerargs,lr_schedulermpu.

<span style="background-color:#263238"><span style="color:#eeffff"><code><span style="color:#c792ea">def</span> <span style="color:#82aaff">setup_model_and_optimizer</span><span style="color:#eeffff">(</span><span style="color:#eeffff">args</span><span style="color:#eeffff">):</span>
    <span style="color:#c3e88d">"""Setup model and optimizer."""</span>

    <span style="color:#eeffff">model</span> <span style="color:#89ddff">=</span> <span style="color:#eeffff">get_model</span><span style="color:#eeffff">(</span><span style="color:#eeffff">args</span><span style="color:#eeffff">)</span>
    <span style="color:#eeffff">optimizer</span> <span style="color:#89ddff">=</span> <span style="color:#eeffff">get_optimizer</span><span style="color:#eeffff">(</span><span style="color:#eeffff">model</span><span style="color:#eeffff">,</span> <span style="color:#eeffff">args</span><span style="color:#eeffff">)</span>
    <span style="color:#eeffff">lr_scheduler</span> <span style="color:#89ddff">=</span> <span style="color:#eeffff">get_learning_rate_scheduler</span><span style="color:#eeffff">(</span><span style="color:#eeffff">optimizer</span><span style="color:#eeffff">,</span> <span style="color:#eeffff">args</span><span style="color:#eeffff">)</span>

    <span style="color:#c792ea">if</span> <span style="color:#eeffff">args</span><span style="color:#eeffff">.</span><span style="color:#eeffff">deepspeed</span><span style="color:#eeffff">:</span>
        <span style="color:#89ddff">import</span> <span style="color:#ffcb6b">deepspeed</span>

        <span style="color:#eeffff">print_rank_0</span><span style="color:#eeffff">(</span><span style="color:#c3e88d">"DeepSpeed is enabled."</span><span style="color:#eeffff">)</span>

        <span style="color:#eeffff">model</span><span style="color:#eeffff">,</span> <span style="color:#eeffff">optimizer</span><span style="color:#eeffff">,</span> <span style="color:#eeffff">_</span><span style="color:#eeffff">,</span> <span style="color:#eeffff">lr_scheduler</span> <span style="color:#89ddff">=</span> <span style="color:#eeffff">deepspeed</span><span style="color:#eeffff">.</span><span style="color:#eeffff">initialize</span><span style="color:#eeffff">(</span>
            <span style="color:#eeffff">model</span><span style="color:#89ddff">=</span><span style="color:#eeffff">model</span><span style="color:#eeffff">,</span>
            <span style="color:#eeffff">optimizer</span><span style="color:#89ddff">=</span><span style="color:#eeffff">optimizer</span><span style="color:#eeffff">,</span>
            <span style="color:#eeffff">args</span><span style="color:#89ddff">=</span><span style="color:#eeffff">args</span><span style="color:#eeffff">,</span>
            <span style="color:#eeffff">lr_scheduler</span><span style="color:#89ddff">=</span><span style="color:#eeffff">lr_scheduler</span><span style="color:#eeffff">,</span>
            <span style="color:#eeffff">mpu</span><span style="color:#89ddff">=</span><span style="color:#eeffff">mpu</span><span style="color:#eeffff">,</span>
            <span style="color:#eeffff">dist_init_required</span><span style="color:#89ddff">=</span><span style="color:#eeffff">False</span>
       <span style="color:#eeffff">)</span>
</code></span></span>

请注意,启用 FP16 后,Megatron-LM GPT2 会向Adam优化器添加一个包装器。DeepSpeed 有自己的 FP16 优化器,所以我们需Adam直接将优化器传递给 DeepSpeed,而不需要任何包装器get_optimizer()我们从启用 DeepSpeed 时返回展开的 Adam 优化器。

<span style="background-color:#263238"><span style="color:#eeffff"><code><span style="color:#c792ea">def</span> <span style="color:#82aaff">get_optimizer</span><span style="color:#eeffff">(</span><span style="color:#eeffff">model</span><span style="color:#eeffff">,</span> <span style="color:#eeffff">args</span><span style="color:#eeffff">):</span>
    <span style="color:#c3e88d">"""Setup the optimizer."""</span>

    <span style="color:#eeffff">......</span>

    <span style="color:#b2ccd6"># Use Adam.
</span>    <span style="color:#eeffff">optimizer</span> <span style="color:#89ddff">=</span> <span style="color:#eeffff">Adam</span><span style="color:#eeffff">(</span><span style="color:#eeffff">param_groups</span><span style="color:#eeffff">,</span>
                     <span style="color:#eeffff">lr</span><span style="color:#89ddff">=</span><span style="color:#eeffff">args</span><span style="color:#eeffff">.</span><span style="color:#eeffff">lr</span><span style="color:#eeffff">,</span> <span style="color:#eeffff">weight_decay</span><span style="color:#89ddff">=</span><span style="color:#eeffff">args</span><span style="color:#eeffff">.</span><span style="color:#eeffff">weight_decay</span><span style="color:#eeffff">)</span>

    <span style="color:#c792ea">if</span> <span style="color:#eeffff">args</span><span style="color:#eeffff">.</span><span style="color:#eeffff">deepspeed</span><span style="color:#eeffff">:</span>
        <span style="color:#b2ccd6"># fp16 wrapper is not required for DeepSpeed.
</span>        <span style="color:#c792ea">return</span> <span style="color:#eeffff">optimizer</span>
</code></span></span>

使用训练 API固定链接

返回modeldeepspeed.initializeDeepSpeed 模型引擎,我们将使用它来使用前向、后向和步进 API 训练模型。

前向传播固定链接

前向传播 API 与 PyTorch 兼容,无需更改。

反向传播固定链接

反向传播是通过backward(loss)直接调用模型引擎来完成的。

<span style="background-color:#263238"><span style="color:#eeffff"><code>    <span style="color:#c792ea">def</span> <span style="color:#82aaff">backward_step</span><span style="color:#eeffff">(</span><span style="color:#eeffff">optimizer</span><span style="color:#eeffff">,</span> <span style="color:#eeffff">model</span><span style="color:#eeffff">,</span> <span style="color:#eeffff">lm_loss</span><span style="color:#eeffff">,</span> <span style="color:#eeffff">args</span><span style="color:#eeffff">,</span> <span style="color:#eeffff">timers</span><span style="color:#eeffff">):</span>
        <span style="color:#c3e88d">"""Backward step."""</span>

        <span style="color:#b2ccd6"># Total loss.
</span>        <span style="color:#eeffff">loss</span> <span style="color:#89ddff">=</span> <span style="color:#eeffff">lm_loss</span>

        <span style="color:#b2ccd6"># Backward pass.
</span>        <span style="color:#c792ea">if</span> <span style="color:#eeffff">args</span><span style="color:#eeffff">.</span><span style="color:#eeffff">deepspeed</span><span style="color:#eeffff">:</span>
            <span style="color:#eeffff">model</span><span style="color:#eeffff">.</span><span style="color:#eeffff">backward</span><span style="color:#eeffff">(</span><span style="color:#eeffff">loss</span><span style="color:#eeffff">)</span>
        <span style="color:#c792ea">else</span><span style="color:#eeffff">:</span>
            <span style="color:#eeffff">optimizer</span><span style="color:#eeffff">.</span><span style="color:#eeffff">zero_grad</span><span style="color:#eeffff">()</span>
            <span style="color:#c792ea">if</span> <span style="color:#eeffff">args</span><span style="color:#eeffff">.</span><span style="color:#eeffff">fp16</span><span style="color:#eeffff">:</span>
                <span style="color:#eeffff">optimizer</span><span style="color:#eeffff">.</span><span style="color:#eeffff">backward</span><span style="color:#eeffff">(</span><span style="color:#eeffff">loss</span><span style="color:#eeffff">,</span> <span style="color:#eeffff">update_master_grads</span><span style="color:#89ddff">=</span><span style="color:#eeffff">False</span><span style="color:#eeffff">)</span>
            <span style="color:#c792ea">else</span><span style="color:#eeffff">:</span>
                <span style="color:#eeffff">loss</span><span style="color:#eeffff">.</span><span style="color:#eeffff">backward</span><span style="color:#eeffff">()</span>
</code></span></span>

在使用小批量更新权重后,DeepSpeed 会自动处理梯度归零

此外,DeepSpeed 解决了分布式数据并行和 FP16 问题,在多个地方简化了代码。

(A) DeepSpeed 还在梯度累积边界处自动执行梯度平均。所以我们跳过 allreduce 通信

<span style="background-color:#263238"><span style="color:#eeffff"><code>        <span style="color:#c792ea">if</span> <span style="color:#eeffff">args</span><span style="color:#eeffff">.</span><span style="color:#eeffff">deepspeed</span><span style="color:#eeffff">:</span>
            <span style="color:#b2ccd6"># DeepSpeed backward propagation already addressed all reduce communication.
</span>            <span style="color:#b2ccd6"># Reset the timer to avoid breaking timer logs below.
</span>            <span style="color:#eeffff">timers</span><span style="color:#eeffff">(</span><span style="color:#c3e88d">'allreduce'</span><span style="color:#eeffff">).</span><span style="color:#eeffff">reset</span><span style="color:#eeffff">()</span>
        <span style="color:#c792ea">else</span><span style="color:#eeffff">:</span>
            <span style="color:#eeffff">torch</span><span style="color:#eeffff">.</span><span style="color:#eeffff">distributed</span><span style="color:#eeffff">.</span><span style="color:#eeffff">all_reduce</span><span style="color:#eeffff">(</span><span style="color:#eeffff">reduced_losses</span><span style="color:#eeffff">.</span><span style="color:#eeffff">data</span><span style="color:#eeffff">)</span>
            <span style="color:#eeffff">reduced_losses</span><span style="color:#eeffff">.</span><span style="color:#eeffff">data</span> <span style="color:#89ddff">=</span> <span style="color:#eeffff">reduced_losses</span><span style="color:#eeffff">.</span><span style="color:#eeffff">data</span> <span style="color:#89ddff">/</span> <span style="color:#eeffff">args</span><span style="color:#eeffff">.</span><span style="color:#eeffff">world_size</span>
            <span style="color:#c792ea">if</span> <span style="color:#89ddff">not</span> <span style="color:#eeffff">USE_TORCH_DDP</span><span style="color:#eeffff">:</span>
                <span style="color:#eeffff">timers</span><span style="color:#eeffff">(</span><span style="color:#c3e88d">'allreduce'</span><span style="color:#eeffff">).</span><span style="color:#eeffff">start</span><span style="color:#eeffff">()</span>
                <span style="color:#eeffff">model</span><span style="color:#eeffff">.</span><span style="color:#eeffff">allreduce_params</span><span style="color:#eeffff">(</span><span style="color:#eeffff">reduce_after</span><span style="color:#89ddff">=</span><span style="color:#eeffff">False</span><span style="color:#eeffff">,</span>
                                       <span style="color:#eeffff">fp32_allreduce</span><span style="color:#89ddff">=</span><span style="color:#eeffff">args</span><span style="color:#eeffff">.</span><span style="color:#eeffff">fp32_allreduce</span><span style="color:#eeffff">)</span>
                <span style="color:#eeffff">timers</span><span style="color:#eeffff">(</span><span style="color:#c3e88d">'allreduce'</span><span style="color:#eeffff">).</span><span style="color:#eeffff">stop</span><span style="color:#eeffff">()</span>

</code></span></span>

(B) 我们也跳过更新主梯度,因为 DeepSpeed 在内部解决了它。

<span style="background-color:#263238"><span style="color:#eeffff"><code>        <span style="color:#b2ccd6"># Update master gradients.
</span>        <span style="color:#c792ea">if</span> <span style="color:#89ddff">not</span> <span style="color:#eeffff">args</span><span style="color:#eeffff">.</span><span style="color:#eeffff">deepspeed</span><span style="color:#eeffff">:</span>
            <span style="color:#c792ea">if</span> <span style="color:#eeffff">args</span><span style="color:#eeffff">.</span><span style="color:#eeffff">fp16</span><span style="color:#eeffff">:</span>
                <span style="color:#eeffff">optimizer</span><span style="color:#eeffff">.</span><span style="color:#eeffff">update_master_grads</span><span style="color:#eeffff">()</span>

            <span style="color:#b2ccd6"># Clipping gradients helps prevent the exploding gradient.
</span>            <span style="color:#c792ea">if</span> <span style="color:#eeffff">args</span><span style="color:#eeffff">.</span><span style="color:#eeffff">clip_grad</span> <span style="color:#89ddff">></span> <span style="color:#f78c6c">0</span><span style="color:#eeffff">:</span>
                <span style="color:#c792ea">if</span> <span style="color:#89ddff">not</span> <span style="color:#eeffff">args</span><span style="color:#eeffff">.</span><span style="color:#eeffff">fp16</span><span style="color:#eeffff">:</span>
                    <span style="color:#eeffff">mpu</span><span style="color:#eeffff">.</span><span style="color:#eeffff">clip_grad_norm</span><span style="color:#eeffff">(</span><span style="color:#eeffff">model</span><span style="color:#eeffff">.</span><span style="color:#eeffff">parameters</span><span style="color:#eeffff">(),</span> <span style="color:#eeffff">args</span><span style="color:#eeffff">.</span><span style="color:#eeffff">clip_grad</span><span style="color:#eeffff">)</span>
                <span style="color:#c792ea">else</span><span style="color:#eeffff">:</span>
                    <span style="color:#eeffff">optimizer</span><span style="color:#eeffff">.</span><span style="color:#eeffff">clip_master_grads</span><span style="color:#eeffff">(</span><span style="color:#eeffff">args</span><span style="color:#eeffff">.</span><span style="color:#eeffff">clip_grad</span><span style="color:#eeffff">)</span>

        <span style="color:#c792ea">return</span> <span style="color:#eeffff">lm_loss_reduced</span>

</code></span></span>

更新模型参数

DeepSpeed 引擎中的函数step()更新模型参数以及学习率。

<span style="background-color:#263238"><span style="color:#eeffff"><code>     <span style="color:#c792ea">if</span> <span style="color:#eeffff">args</span><span style="color:#eeffff">.</span><span style="color:#eeffff">deepspeed</span><span style="color:#eeffff">:</span>
         <span style="color:#eeffff">model</span><span style="color:#eeffff">.</span><span style="color:#eeffff">step</span><span style="color:#eeffff">()</span>
     <span style="color:#c792ea">else</span><span style="color:#eeffff">:</span>
         <span style="color:#eeffff">optimizer</span><span style="color:#eeffff">.</span><span style="color:#eeffff">step</span><span style="color:#eeffff">()</span>

         <span style="color:#b2ccd6"># Update learning rate.
</span>         <span style="color:#c792ea">if</span> <span style="color:#89ddff">not</span> <span style="color:#eeffff">(</span><span style="color:#eeffff">args</span><span style="color:#eeffff">.</span><span style="color:#eeffff">fp16</span> <span style="color:#89ddff">and</span> <span style="color:#eeffff">optimizer</span><span style="color:#eeffff">.</span><span style="color:#eeffff">overflow</span><span style="color:#eeffff">):</span>
             <span style="color:#eeffff">lr_scheduler</span><span style="color:#eeffff">.</span><span style="color:#eeffff">step</span><span style="color:#eeffff">()</span>
         <span style="color:#c792ea">else</span><span style="color:#eeffff">:</span>
             <span style="color:#eeffff">skipped_iter</span> <span style="color:#89ddff">=</span> <span style="color:#f78c6c">1</span>

</code></span></span>

损失缩放

GPT2 训练脚本记录训练期间的损失缩放值。在 DeepSpeed 优化器内部,此值存储为 ascur_scale而不是loss_scaleMegatron 优化器中的 as。因此,我们在日志字符串中适当地替换它。

<span style="background-color:#263238"><span style="color:#eeffff"><code>             <span style="color:#c792ea">if</span> <span style="color:#eeffff">args</span><span style="color:#eeffff">.</span><span style="color:#eeffff">fp16</span><span style="color:#eeffff">:</span>
                 <span style="color:#eeffff">log_string</span> <span style="color:#89ddff">+=</span> <span style="color:#c3e88d">' loss scale {:.1f} |'</span><span style="color:#eeffff">.</span><span style="color:#eeffff">format</span><span style="color:#eeffff">(</span>
                     <span style="color:#eeffff">optimizer</span><span style="color:#eeffff">.</span><span style="color:#eeffff">cur_scale</span> <span style="color:#c792ea">if</span> <span style="color:#eeffff">args</span><span style="color:#eeffff">.</span><span style="color:#eeffff">deepspeed</span> <span style="color:#c792ea">else</span> <span style="color:#eeffff">optimizer</span><span style="color:#eeffff">.</span><span style="color:#eeffff">loss_scale</span><span style="color:#eeffff">)</span>

</code></span></span>

检查点保存和加载

DeepSpeed 引擎具有用于检查点保存和加载的灵活 API,以处理来自客户端模型及其内部的状态。

<span style="background-color:#263238"><span style="color:#eeffff"><code><span style="color:#c792ea">def</span> <span style="color:#82aaff">save_checkpoint</span><span style="color:#eeffff">(</span><span style="color:#eeffff">self</span><span style="color:#eeffff">,</span> <span style="color:#eeffff">save_dir</span><span style="color:#eeffff">,</span> <span style="color:#eeffff">tag</span><span style="color:#eeffff">,</span> <span style="color:#eeffff">client_state</span><span style="color:#89ddff">=</span><span style="color:#eeffff">{})</span>
<span style="color:#c792ea">def</span> <span style="color:#82aaff">load_checkpoint</span><span style="color:#eeffff">(</span><span style="color:#eeffff">self</span><span style="color:#eeffff">,</span> <span style="color:#eeffff">load_dir</span><span style="color:#eeffff">,</span> <span style="color:#eeffff">tag</span><span style="color:#eeffff">)</span>
</code></span></span>

要使用 DeepSpeed,我们需要更新utils.pyMegatron-LM GPT2 保存和加载检查点的位置。

创建一个新函数save_ds_checkpoint(),如下所示。新函数收集客户端模型状态并通过调用 DeepSpeed 的save_checkpoint().

<span style="background-color:#263238"><span style="color:#eeffff"><code> <span style="color:#c792ea">def</span> <span style="color:#82aaff">save_ds_checkpoint</span><span style="color:#eeffff">(</span><span style="color:#eeffff">iteration</span><span style="color:#eeffff">,</span> <span style="color:#eeffff">model</span><span style="color:#eeffff">,</span> <span style="color:#eeffff">args</span><span style="color:#eeffff">):</span>
     <span style="color:#c3e88d">"""Save a model checkpoint."""</span>

     <span style="color:#eeffff">sd</span> <span style="color:#89ddff">=</span> <span style="color:#eeffff">{}</span>
     <span style="color:#eeffff">sd</span><span style="color:#eeffff">[</span><span style="color:#c3e88d">'iteration'</span><span style="color:#eeffff">]</span> <span style="color:#89ddff">=</span> <span style="color:#eeffff">iteration</span>
     <span style="color:#b2ccd6"># rng states.
</span>     <span style="color:#c792ea">if</span> <span style="color:#89ddff">not</span> <span style="color:#eeffff">args</span><span style="color:#eeffff">.</span><span style="color:#eeffff">no_save_rng</span><span style="color:#eeffff">:</span>
         <span style="color:#eeffff">sd</span><span style="color:#eeffff">[</span><span style="color:#c3e88d">'random_rng_state'</span><span style="color:#eeffff">]</span> <span style="color:#89ddff">=</span> <span style="color:#eeffff">random</span><span style="color:#eeffff">.</span><span style="color:#eeffff">getstate</span><span style="color:#eeffff">()</span>
         <span style="color:#eeffff">sd</span><span style="color:#eeffff">[</span><span style="color:#c3e88d">'np_rng_state'</span><span style="color:#eeffff">]</span> <span style="color:#89ddff">=</span> <span style="color:#eeffff">np</span><span style="color:#eeffff">.</span><span style="color:#eeffff">random</span><span style="color:#eeffff">.</span><span style="color:#eeffff">get_state</span><span style="color:#eeffff">()</span>
         <span style="color:#eeffff">sd</span><span style="color:#eeffff">[</span><span style="color:#c3e88d">'torch_rng_state'</span><span style="color:#eeffff">]</span> <span style="color:#89ddff">=</span> <span style="color:#eeffff">torch</span><span style="color:#eeffff">.</span><span style="color:#eeffff">get_rng_state</span><span style="color:#eeffff">()</span>
         <span style="color:#eeffff">sd</span><span style="color:#eeffff">[</span><span style="color:#c3e88d">'cuda_rng_state'</span><span style="color:#eeffff">]</span> <span style="color:#89ddff">=</span> <span style="color:#eeffff">get_accelerator</span><span style="color:#eeffff">().</span><span style="color:#eeffff">get_rng_state</span><span style="color:#eeffff">()</span>
         <span style="color:#eeffff">sd</span><span style="color:#eeffff">[</span><span style="color:#c3e88d">'rng_tracker_states'</span><span style="color:#eeffff">]</span> <span style="color:#89ddff">=</span> <span style="color:#eeffff">mpu</span><span style="color:#eeffff">.</span><span style="color:#eeffff">get_cuda_rng_tracker</span><span style="color:#eeffff">().</span><span style="color:#eeffff">get_states</span><span style="color:#eeffff">()</span>

     <span style="color:#eeffff">model</span><span style="color:#eeffff">.</span><span style="color:#eeffff">save_checkpoint</span><span style="color:#eeffff">(</span><span style="color:#eeffff">args</span><span style="color:#eeffff">.</span><span style="color:#eeffff">save</span><span style="color:#eeffff">,</span> <span style="color:#eeffff">iteration</span><span style="color:#eeffff">,</span> <span style="color:#eeffff">client_state</span> <span style="color:#89ddff">=</span> <span style="color:#eeffff">sd</span><span style="color:#eeffff">)</span>

</code></span></span>

在 Megatron-LM GPT2 的save_checkpoint()函数中,添加以下行来为 DeepSpeed 调用上述函数。

<span style="background-color:#263238"><span style="color:#eeffff"><code> <span style="color:#c792ea">def</span> <span style="color:#82aaff">save_checkpoint</span><span style="color:#eeffff">(</span><span style="color:#eeffff">iteration</span><span style="color:#eeffff">,</span> <span style="color:#eeffff">model</span><span style="color:#eeffff">,</span> <span style="color:#eeffff">optimizer</span><span style="color:#eeffff">,</span>
                     <span style="color:#eeffff">lr_scheduler</span><span style="color:#eeffff">,</span> <span style="color:#eeffff">args</span><span style="color:#eeffff">):</span>
     <span style="color:#c3e88d">"""Save a model checkpoint."""</span>
     <span style="color:#c792ea">if</span> <span style="color:#eeffff">args</span><span style="color:#eeffff">.</span><span style="color:#eeffff">deepspeed</span><span style="color:#eeffff">:</span>
         <span style="color:#eeffff">save_ds_checkpoint</span><span style="color:#eeffff">(</span><span style="color:#eeffff">iteration</span><span style="color:#eeffff">,</span> <span style="color:#eeffff">model</span><span style="color:#eeffff">,</span> <span style="color:#eeffff">args</span><span style="color:#eeffff">)</span>
     <span style="color:#c792ea">else</span><span style="color:#eeffff">:</span>
		<span style="color:#eeffff">......</span>

</code></span></span>

load_checkpoint()函数中,使用如下所示的 DeepSpeed 检查点加载 API,并返回客户端模型的状态。

<span style="background-color:#263238"><span style="color:#eeffff"><code> <span style="color:#c792ea">def</span> <span style="color:#82aaff">load_checkpoint</span><span style="color:#eeffff">(</span><span style="color:#eeffff">model</span><span style="color:#eeffff">,</span> <span style="color:#eeffff">optimizer</span><span style="color:#eeffff">,</span> <span style="color:#eeffff">lr_scheduler</span><span style="color:#eeffff">,</span> <span style="color:#eeffff">args</span><span style="color:#eeffff">):</span>
     <span style="color:#c3e88d">"""Load a model checkpoint."""</span>

     <span style="color:#eeffff">iteration</span><span style="color:#eeffff">,</span> <span style="color:#eeffff">release</span> <span style="color:#89ddff">=</span> <span style="color:#eeffff">get_checkpoint_iteration</span><span style="color:#eeffff">(</span><span style="color:#eeffff">args</span><span style="color:#eeffff">)</span>

     <span style="color:#c792ea">if</span> <span style="color:#eeffff">args</span><span style="color:#eeffff">.</span><span style="color:#eeffff">deepspeed</span><span style="color:#eeffff">:</span>
         <span style="color:#eeffff">checkpoint_name</span><span style="color:#eeffff">,</span> <span style="color:#eeffff">sd</span> <span style="color:#89ddff">=</span> <span style="color:#eeffff">model</span><span style="color:#eeffff">.</span><span style="color:#eeffff">load_checkpoint</span><span style="color:#eeffff">(</span><span style="color:#eeffff">args</span><span style="color:#eeffff">.</span><span style="color:#eeffff">load</span><span style="color:#eeffff">,</span> <span style="color:#eeffff">iteration</span><span style="color:#eeffff">)</span>

         <span style="color:#c792ea">if</span> <span style="color:#eeffff">checkpoint_name</span> <span style="color:#89ddff">is</span> <span style="color:#eeffff">None</span><span style="color:#eeffff">:</span>
             <span style="color:#c792ea">if</span> <span style="color:#eeffff">mpu</span><span style="color:#eeffff">.</span><span style="color:#eeffff">get_data_parallel_rank</span><span style="color:#eeffff">()</span> <span style="color:#89ddff">==</span> <span style="color:#f78c6c">0</span><span style="color:#eeffff">:</span>
                 <span style="color:#c792ea">print</span><span style="color:#eeffff">(</span><span style="color:#c3e88d">"Unable to load checkpoint."</span><span style="color:#eeffff">)</span>
             <span style="color:#c792ea">return</span> <span style="color:#eeffff">iteration</span>
     <span style="color:#c792ea">else</span><span style="color:#eeffff">:</span>
         <span style="color:#eeffff">......</span>

</code></span></span>

DeepSpeed 激活检查点(可选)固定链接

DeepSpeed 可以通过跨模型并行 GPU 划分激活检查点或将它们卸载到 CPU 来减少模型并行训练期间的激活内存。这些优化是可选的,可以跳过,除非激活内存成为瓶颈。为了启用分区激活,我们使用deepspeed.checkpointingAPI 来替换 Megatron 的激活检查点随机状态跟踪器 API。替换应该在第一次调用这些 API 之前发生。

a) 替换为pretrain_gpt.py

<span style="background-color:#263238"><span style="color:#eeffff"><code>    <span style="color:#b2ccd6"># Optional DeepSpeed Activation Checkpointing Features
</span>    <span style="color:#b2ccd6">#
</span>    <span style="color:#c792ea">if</span> <span style="color:#eeffff">args</span><span style="color:#eeffff">.</span><span style="color:#eeffff">deepspeed</span> <span style="color:#89ddff">and</span> <span style="color:#eeffff">args</span><span style="color:#eeffff">.</span><span style="color:#eeffff">deepspeed_activation_checkpointing</span><span style="color:#eeffff">:</span>
        <span style="color:#eeffff">set_deepspeed_activation_checkpointing</span><span style="color:#eeffff">(</span><span style="color:#eeffff">args</span><span style="color:#eeffff">)</span>

<span style="color:#c792ea">def</span> <span style="color:#82aaff">set_deepspeed_activation_checkpointing</span><span style="color:#eeffff">(</span><span style="color:#eeffff">args</span><span style="color:#eeffff">):</span>

    <span style="color:#eeffff">deepspeed</span><span style="color:#eeffff">.</span><span style="color:#eeffff">checkpointing</span><span style="color:#eeffff">.</span><span style="color:#eeffff">configure</span><span style="color:#eeffff">(</span><span style="color:#eeffff">mpu</span><span style="color:#eeffff">,</span>
                            <span style="color:#eeffff">deepspeed_config</span><span style="color:#89ddff">=</span><span style="color:#eeffff">args</span><span style="color:#eeffff">.</span><span style="color:#eeffff">deepspeed_config</span><span style="color:#eeffff">,</span>
                            <span style="color:#eeffff">partition_activation</span><span style="color:#89ddff">=</span><span style="color:#eeffff">True</span><span style="color:#eeffff">)</span>

    <span style="color:#eeffff">mpu</span><span style="color:#eeffff">.</span><span style="color:#eeffff">checkpoint</span> <span style="color:#89ddff">=</span> <span style="color:#eeffff">deepspeed</span><span style="color:#eeffff">.</span><span style="color:#eeffff">checkpointing</span><span style="color:#eeffff">.</span><span style="color:#eeffff">checkpoint</span>
    <span style="color:#eeffff">mpu</span><span style="color:#eeffff">.</span><span style="color:#eeffff">get_cuda_rng_tracker</span> <span style="color:#89ddff">=</span> <span style="color:#eeffff">deepspeed</span><span style="color:#eeffff">.</span><span style="color:#eeffff">checkpointing</span><span style="color:#eeffff">.</span><span style="color:#eeffff">get_cuda_rng_tracker</span>
    <span style="color:#eeffff">mpu</span><span style="color:#eeffff">.</span><span style="color:#eeffff">model_parallel_cuda_manual_seed</span> <span style="color:#89ddff">=</span>
                    <span style="color:#eeffff">deepspeed</span><span style="color:#eeffff">.</span><span style="color:#eeffff">checkpointing</span><span style="color:#eeffff">.</span><span style="color:#eeffff">model_parallel_cuda_manual_seed</span>
</code></span></span>

b) 替换为mpu/transformer.py

<span style="background-color:#263238"><span style="color:#eeffff"><code><span style="color:#c792ea">if</span> <span style="color:#eeffff">deepspeed</span><span style="color:#eeffff">.</span><span style="color:#eeffff">checkpointing</span><span style="color:#eeffff">.</span><span style="color:#eeffff">is_configured</span><span style="color:#eeffff">():</span>
    <span style="color:#c792ea">global</span> <span style="color:#eeffff">get_cuda_rng_tracker</span><span style="color:#eeffff">,</span> <span style="color:#eeffff">checkpoint</span>
    <span style="color:#eeffff">get_cuda_rng_tracker</span> <span style="color:#89ddff">=</span> <span style="color:#eeffff">deepspeed</span><span style="color:#eeffff">.</span><span style="color:#eeffff">checkpoint</span><span style="color:#eeffff">.</span><span style="color:#eeffff">get_cuda_rng_tracker</span>
    <span style="color:#eeffff">checkpoint</span> <span style="color:#89ddff">=</span> <span style="color:#eeffff">deepspeed</span><span style="color:#eeffff">.</span><span style="color:#eeffff">checkpointing</span><span style="color:#eeffff">.</span><span style="color:#eeffff">checkpoint</span>

</code></span></span>

deepspeed.checkpointing.configure通过这些替换,可以在文件中或在文件中指定各种 DeepSpeed 激活检查点优化,例如激活分区、连续检查点和 CPU 检查点deepspeed_config

训练脚本固定链接

我们假设webtext数据已在上一步中准备好。要开始训练应用了 DeepSpeed 的 Megatron-LM GPT2 模型,请执行以下命令开始训练。

  • 单 GPU 运行
    • 跑步bash scripts/ds_pretrain_gpt2.sh
  • 多个 GPU/节点运行
    • 跑步bash scripts/ds_zero2_pretrain_gpt2_model_parallel.sh

使用 GPT-2 的 DeepSpeed 评估固定链接

DeepSpeed 可以通过先进的ZeRO 优化器有效地训练非常大的模型。2020 年 2 月,我们在 DeepSpeed 中发布了 ZeRO 的优化子集执行优化器状态分区。我们将它们称为 ZeRO-1。2020 年 5 月,我们扩展了 DeepSpeed 中的 ZeRO-1,以包括来自 ZeRO 的额外优化,包括梯度和激活分区,以及连续内存优化。我们将此版本称为 ZeRO-2。

ZeRO-2 显着减少了训练大型模型的内存占用,这意味着大型模型可以在 i) 较少的模型并行度和 ii) 较大的批量大小下进行训练。较低的模型并行度通过增加计算的粒度来提高训练效率,例如矩阵乘法,其中性能与矩阵的大小直接相关。此外,较少的模型并行性还会导致模型并行 GPU 之间的通信减少,从而进一步提高性能较大的批量大小具有增加计算粒度和减少通信的类似效果,也会带来更好的性能。因此,通过将 DeepSpeed 和 ZeRO-2 集成到威震天中,与单独使用威震天相比,我们将模型规模和速度提升到了一个全新的水平。

图 2:ZeRO-2 可扩展到 1700 亿个参数,具有高达 10 倍的吞吐量,获得超线性加速,并通过避免对多达 130 亿个参数的模型进行代码重构来提高可用性。

更具体地说,DeepSpeed 和 ZeRO-2 在四个方面表现出色(如图 2 所示),支持数量级更大的模型,速度提高 10 倍,具有超线性可扩展性,并提高了使大型模型训练民主化的可用性。下面就这四个方面进行详细介绍。

模型大小:最先进的大型模型,如 OpenAI GPT-2、NVIDIA Megatron-LM、Google T5 和 Microsoft Turing-NLG,其参数大小分别为 1.5B、8.3B、11B 和 17B。ZeRO-2 提供系统支持以高效运行 1700 亿个参数的模型,比这些最大的模型大一个数量级(图 2,左上角)。

速度:提高内存效率可以提高吞吐量和加快训练速度。图 2(左下)显示了 ZeRO-2 和 ZeRO-1 的系统吞吐量(两者都结合了 ZeRO 支持的数据并行性和 NVIDIA Megatron-LM 模型并行性)以及使用最先进的模型并行性方法 Megatron- LM 单独(图 2 中的基线,左下角)。ZeRO-2 在 400 个 NVIDIA V100 GPU 集群上运行 1000 亿个参数模型,每个 GPU 超过 38 teraflops,聚合性能超过 15 petaflops。对于相同大小的模型,ZeRO-2 的训练速度比单独使用 Megatron-LM 快 10 倍,比 ZeRO-1 快 5 倍。

可扩展性:我们观察到超线性加速(图 2,右上角),当 GPU 数量增加一倍时,性能会增加一倍以上。随着我们提高数据并行度,ZeRO-2 减少了模型状态的内存占用,使我们能够适应每个 GPU 更大的批处理大小,从而获得更好的性能。

大众化大型模型训练:ZeRO-2 使模型科学家能够有效地训练多达 130 亿个参数的模型,而无需任何通常需要模型重构的模型并行性(图 2,右下角)。130 亿个参数比大多数最先进的模型(例如 Google T5,有 110 亿个参数)都要大。因此,模型科学家可以自由地试验大型模型,而不必担心模型并行性。相比之下,经典数据并行方法(例如 PyTorch 分布式数据并行)的实现在 14 亿参数模型下会耗尽内存,而 ZeRO-1 支持多达 60 亿参数进行比较。

此外,在没有模型并行性的情况下,这些模型可以在低带宽集群上进行训练,同时与使用模型并行性相比仍然可以获得明显更好的吞吐量。例如,与在通过 40 Gbps Infiniband 互连连接的四节点集群上使用模型并行相比,使用 ZeRO 驱动的数据并行可以训练 GPT-2 模型快近 4 倍,其中每个节点有四个 NVIDIA 16GB V100 GPU 与 PCI-E 连接. 因此,随着这种性能提升,大型模型训练不再局限于具有超快速互连的 GPU 集群,也可以在带宽有限的适度集群上进行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/649813.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

拆分代码 + 预加载,减少首屏资源,提升首屏性能及应用体验

route-resource-preload 组件懒加载可以极大地提升我们的应用首屏加载体验, 但我们在进行组件资源拆包后&#xff0c;一旦加载某个组件资源出现以上时间过长的情况&#xff0c;则会出现视图无法正常渲染的问题&#xff08;导致页面白屏/组件出不来/交互卡顿等情况&#xff09;。…

Pytest教程__钩子方法setup、teardown、setup_class、teardown_class(8)

pytest跳过用例执行的用法与unittest跳过用例大致相同。 pytest跳过用例的方法如下&#xff1a; pytest.mark.skip(reason)&#xff1a;无条件用例。reason是跳过原因&#xff0c;下同。pytest.mark.skipIf(condition, reason)&#xff1a;condition为True时跳过用例。 pyte…

代码随想录算法训练营第五十八天|739. 每日温度|496.下一个更大元素 I

LeetCode739. 每日温度 基本思路&#xff1a;什么时候使用单调栈呢&#xff1f;通常是一维数组&#xff0c;要寻找任一个元素的右边或者左边第一个比自己大或者小的元素的位置&#xff0c;此时我们就要想到可以用单调栈了。时间复杂度为O(n)。例如本题其实就是找找到一个元素右…

【发电厂】发电厂模型验证应用于电网事件在线性能监测【相量测量单元 (PMU) 数据对电网事件的在线性能监控】研究(MatlabSimulink实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

(一文详解!)wrk性能测试

目录 一、简介 二、格式及用法 三、简单压测及结果分析 四、使用lua脚本进行压测 一、简介 wrk 是一款针对 Http 协议的基准测试工具&#xff0c;它能够在单机多核 CPU 的条件下&#xff0c;使用系统自带的高性能 I/O 机制&#xff0c;如 epoll&#xff0c;kqueue 等&#xff0…

华为OD机试真题 JavaScript 实现【报数游戏】【2022Q4 100分】

一、题目描述 100个人围成一圈&#xff0c;每个人有一个编码&#xff0c;编号从1开始到100。他们从1开始依次报数&#xff0c;报到为M的人自动退出圈圈&#xff0c;然后下一个人接着从1开始报数&#xff0c;直到剩余的人数小于M。请问最后剩余的人在原先的编号为多少&#xff…

Ubuntu 更新 CMake 版本

项目中有时候会出现CMake版本小于最低要求的情况,实际上没有有必要这么高的要求,但是在不能改对方代码的情况下,只能去升级自身的版本了. 尝试了网上说的直接update之后再次安装的方式,结果版本号没有改变 sudo apt-get update sudo apt-get remove cmake sudo apt-get ins…

Rust语言从入门到入坑——(3)小谈Cargo工具以及VScode配置Rust

文章目录 0 引入1、Cargo 是什么2、常用Cargo指令3、VScode配置Rust环境3.1.tasks.json3.2.launch.json 4、总结 0 引入 上一节我们谈了在编译工程的时候用到Cargo&#xff08;卡狗&#xff09; 1、Cargo 是什么 Cargo 是 Rust 的构建系统和包管理器。 Rust 开发者常用 Carg…

Metricbeat安装下载,nginx模块使用

目录 MetricbeatMetricbeat组成下载启动Metricbeat Modulesystem module配置内容 Nginx Module开启Nginx Module 配置nginx module测试 Metricbeat 定期收集操作系统或应用服务的指标数据存储到Elasticsearch中&#xff0c;进行实时分析 Metricbeat组成 Metricbeat有2部分组成…

Jmeter性能测试步骤入门

目录 前言&#xff1a; 一、Jmeter简介 1 概述 2 JMeter支持的协议 二、Jmeter实现性能测试 第一步&#xff1a;配置jdk环境 第二步&#xff1a;下载jmeter 第三步&#xff1a;启动Jmeter 四、一个http还除了上述http请求中的请求行和请求体&#xff0c;还包含请求头&#xff…

Android使用AspectJ拦截点击事件

介绍&#xff1a; AspectJ是一种AOP框架&#xff0c;它可以在编译时或运行时拦截指定的方法。在Android开发中&#xff0c;我们可以使用AspectJ来拦截UI事件并执行自己的业务逻辑。本文将说明如何使用AspectJ来拦截Android应用程序中的点击事件&#xff0c;并附有详细的代码注…

存储池和LUN

存储池是什么意思 存储池是为集体存储共享置备的存储卷的集合。这些池建立在物理存储设备的聚合上&#xff0c;根据资源需求进行隔离&#xff0c;然后由共享环境中的各种计算机或系统使用。存储池可以分为三类&#xff0c;每类都有不同的用途;主存储池、副本存储池和活动数据池…

618来了!看图技术如何在物流管理系统大显身手!

导读 近日&#xff0c;随着电商“618”购物节的临近&#xff0c;各大商家纷纷推出各类补贴活动刺激消费者热情。下单后&#xff0c;消费者的心理活动如何呢&#xff1f;蹲点抢到优惠券&#xff0c;精打细算的凑单后&#xff0c;终于完成付款。焦急的等待待发货的小红点跳至待收…

分享三个java低代码开发平台,每个都很能打,建议收藏!

来讲讲近期比较流行的低代码开发平台一词。低代码的目的是将可重复性的编程工作通过平台实现&#xff0c;将开发人员从没有技术含量的增删改查开发中解放出来&#xff0c;让其专注于更有价值的开发工作&#xff0c;例如业务建模、数据库设计、流程设计、API核心开发、业务逻辑开…

如何调用百度地图API

前言 要调用百度地图API&#xff0c;步骤操作如下 注册并创建一个API密钥。您可以在百度地图API控制台上创建您的密钥。选择要使用的API服务。百度地图API提供了多种服务&#xff0c;包括地图展示、路线规划、地点搜索、实时交通等。您可以在百度地图API控制台上查看所有可用…

大数据hadoop生态技术简介

Hadoop 生态是指围绕 Hadoop 大数据处理平台形成的一系列开源软件和工具&#xff0c;用于支持大规模数据处理、存储、管理、分析和可视化等应用场景。暂时将其核心技术分为9类&#xff1a; 数据采集技术框架&#xff1a; Flume、Logstash、FileBeat&#xff1b;Sqoop和Datax&…

【Spring】循环依赖

一、什么情况下会出现循环依赖&#xff1f; 二、解决方案 &#xff08;一&#xff09;一级缓存&#xff1a;存放完整的Bean实例对象 缺点&#xff1a;一级缓存的方式无法保证多线程下的一级缓存Bean的完整性&#xff0c;可以用加锁的方式来解决此问题。 &#xff08;二&#…

Nerf如何制作自己的llff数据集

Nerf三维重建使用Pycharm运行自己的数据集 ------------------------------------20230427更新---------------------------------------------- Nerf代码讲解&#xff0c;从零简单复现论文代码 Nerf环境配置教程 你好&#xff01; 这里是“出门吃三碗饭”本人&#xff0c;本…

数字化时代,数据治理中有哪些误区?

数据治理也不是什么简单的事情&#xff0c;或者说企业想要利用数据资产、数字化、数字化转型等加速企业的发展&#xff0c;就势必会在路途中遇到很多困难&#xff0c;数据治理只是用来解决数据问题的一种方案。所以当数据的价值开始被不断挖掘&#xff0c;企业数据资产的地位越…

分析了上百份最新的大中小厂的面经,我总结出了这份2023国内最新最强Java面试八股文

最近分析了上百份最新的大中小厂的面经&#xff0c;整理了 Java 面试中最最最常问的一些问题&#xff01;大家可以对照着这篇文章学习或者准备面试。 开始之前&#xff0c;先说一下我非常推荐的一种学习方式&#xff1a; 带着问题学习或者准备面试。 之前分享过一位字节朋友的…