分布式训练:如何训练一个模型

Basic computations in distributed training

Author

Published

2025-05-13 11:26:36+0800

本节中,我们将介绍模型训练的基本数学原理,以及在分布式训练中我们需要考虑的精度,优化器等问题。

训练的数学原理

在最优化里面,我们需要解决的问题一般有如下形式:

minx f(x)\min_x\ f(x)

这里 ff是我们的目标函数, xx是我们的变量。一个比较简单的例子就是求一个给定函数的最小值。

如果说,我们想要基于数据来训练一个模型,这个时候,我们目标函数的输入就包括两部分,一部分是模型参数,另一部分是数据,为了方便起见,我们使用θ\theta来代表模型的参数,用 {xi,yi}i=1N\{x_i,y_i\}_{i=1}^N 来表示模型的训练集。上述的优化问题改写如下:

minθ 1Ni=1Nf(xi,yi  θ)\min_{\theta}\ \frac{1}{N}\sum_{i=1}^Nf(x_i,y_i\;\theta)

比如我们训练 resnet 作为分类器,那么 resnet 的模型参数就是这里的 θ\theta, 训练集就是我们的图片和对应的标签,比如ImageNet等,对应的ff可以设定为 cross entropy loss.

现在有了优化问题之后,我们就需要设计算法求解这个优化问题。一个最简单的优化算法就是梯度下降算法:

θk+1=θkαk1Ni=1Nθf(xi,yi;θk)\theta^{k+1} = \theta^k - \alpha_k\frac{1}{N}\sum_{i=1}^N\nabla_{\theta}f(x_i,y_i;\theta^k)

这里 θf(x;θk)\nabla_{\theta}f(x;\theta^k)ff 相对于 θ\thetaθk\theta^k 处的梯度。

但是,当我们模型过于复杂的时候,梯度往往计算起来非常复杂。为了简化模型的训练,现在的框架如tensorflow和pytorch都支持自动微分。因此,我们只需要定义如何从输入 (xi,yi)(x_i,y_i)计算得到 f(xi,yi;θ)f(x_i,y_i;\theta) 就可以了,框架会帮我们计算参数的梯度。

自动微分

自动微分的目的是将求导的过程交给框架,从而让用户专注于模型的开发(也就是设计forward函数)。

自动微分的核心思想就是链式法则.

假设我们有一个复合函数 y=f(g(h(x)))y= f(g(h(x))), 一般来说,我们求 yy 关于 xx的导数过程为

dydx=dydfdfdgdgdhdhdx\frac{dy}{dx} = \frac{dy}{df}\frac{df}{dg}\frac{dg}{dh}\frac{dh}{dx}

如果我们的中间函数 gg, hh非常复杂的话,那么整个求导过程就会非常复杂。而链式法则则是将这样一个全局过程给分解成了若干个局部过程。我们将 yy 表示为:

y=f(y1)y1=g(y2)y2=h(y3)y3=x\begin{aligned} y &= f(y_1)\\ y_1&=g(y_2)\\ y_2&=h(y_3)\\ y_3&=x \end{aligned}

接下来,

总结

在本文中,我们简单介绍了一下如何训练一个模型,我们使用pytorch作为例子展示了现在训练框架的工作方式。在下一篇博客中,我们将会探究训练精度和优化器。训练精度和优化器是模型在训练过程中需要考虑的重点之一。

训练

优化器

SGD

Adam

AdamW

精度