Welford计算是一种在线计算均值和方差的方法。一方面,它可以在不存储所有样本的情况下,逐步计算所有样本的均值和方差,更适合处理海量数据;另一方面,它只需要对数据进行一次遍历,能减少访存次数,提高计算性能。本接口为Welford算法的后处理。
LayerNorm算法中reduce轴较大的场景,可以通过切分reduce轴,联合使用本接口与WelfordUpdate,能够实现等效计算LayerNorm。本接口的计算公式如下:
其中,为均值输出,
为方差输出。
代表输入的第
个均值,
代表输入的第
个方差。
代表Reduce轴拆分后一次计算的大小,
代表Reduce轴按
拆分的次数(只有整除的情况下使用此公式)。
1 2 | template <bool isReuseSource = false> __aicore__ inline void WelfordFinalize(const LocalTensor<float>& outputMean, const LocalTensor<float>& outputVariance, const LocalTensor<float>& inputMean, const LocalTensor<float>& inputVariance, const LocalTensor<uint8_t>& sharedTmpBuffer, WelfordFinalizePara& para) |
1 2 | template <bool isReuseSource = false> __aicore__ inline void WelfordFinalize(const LocalTensor<float>& outputMean, const LocalTensor<float>& outputVariance, const LocalTensor<float>& inputMean, const LocalTensor<float>& inputVariance, const LocalTensor<int32_t>& counts, const LocalTensor<uint8_t>& sharedTmpBuffer, WelfordFinalizePara& para) |
1 2 | template <bool isReuseSource = false> __aicore__ inline void WelfordFinalize(const LocalTensor<float>& outputMean, const LocalTensor<float>& outputVariance, const LocalTensor<float>& inputMean, const LocalTensor<float>& inputVariance, WelfordFinalizePara& para) |
1 2 | template <bool isReuseSource = false> __aicore__ inline void WelfordFinalize(const LocalTensor<float>& outputMean, const LocalTensor<float>& outputVariance, const LocalTensor<float>& inputMean, const LocalTensor<float>& inputVariance, const LocalTensor<int32_t>& counts, WelfordFinalizePara& para) |
由于该接口的内部实现中涉及复杂的计算,需要额外的临时空间来存储计算过程中的中间变量。临时空间支持接口框架申请和开发者通过sharedTmpBuffer入参传入两种方式。
接口框架申请的方式,开发者需要预留临时空间;通过sharedTmpBuffer传入的情况,开发者需要为tensor申请空间。临时空间大小BufferSize的获取方式如下:通过WelfordFinalize Tiling中提供的GetWelfordFinalizeMaxMinTmpSize接口获取所需最大和最小临时空间大小,最小空间可以保证功能正确,最大空间用于提升性能。
参数名 |
描述 |
---|---|
isReuseSource |
该参数预留,传入默认值false即可。 |
参数名 |
输入/输出 |
描述 |
||
---|---|---|---|---|
outputMean |
输出 |
均值目的操作数。 类型为LocalTensor,支持的TPosition为VECIN/VECCALC/VECOUT。 |
||
outputVariance |
输出 |
方差目的操作数。 类型为LocalTensor,支持的TPosition为VECIN/VECCALC/VECOUT。 |
||
inputMean |
输入 |
均值源操作数。shape为[abLength]。 类型为LocalTensor,支持的TPosition为VECIN/VECCALC/VECOUT。 |
||
inputVariance |
输入 |
方差源操作数。shape为[abLength]。 类型为LocalTensor,支持的TPosition为VECIN/VECCALC/VECOUT。 |
||
counts |
输入 |
源操作数。shape为[abLength]。 类型为LocalTensor,支持的TPosition为VECIN/VECCALC/VECOUT。 |
||
sharedTmpBuffer |
输入 |
临时空间。 类型为LocalTensor,支持的TPosition为VECIN/VECCALC/VECOUT。 接口内部复杂计算时用于存储中间变量,由开发者提供。 临时空间大小BufferSize的获取方式请参考WelfordFinalize Tiling。 |
||
para |
输入 |
计算所需的参数信息。WelfordFinalizePara类型,定义如下。
|
无
1 2 3 4 | pipe.InitBuffer(sharedTmpBuffer, stackBufferSize); AscendC::LocalTensor<uint8_t> tmpLocalTensor = sharedTmpBuffer.Get<uint8_t>(); struct AscendC::WelfordFinalizePara para = {rnLength, abLength, head, headLength, tail, tailLength, abRec, rRec}; AscendC::WelfordFinalize<false>(meanLocal, varianceLocal, inputMeanLocal, inputVarianceLocal, inputCountsLocal, tmpLocalTensor, para); |