【问题标题】:TPU utilization low due to output fusion由于输出融合,TPU 利用率低
【发布时间】:2019-03-08 07:10:09
【问题描述】:

我正在 Google Cloud TPU 上训练 U-Net。可以,但是利用率很低。

由于我无法在此处上传跟踪的配置文件(?),最慢部分的屏幕截图在这里:

输出融合是最有害的部分。 58% 的时间,但只有 12% 的利用率。下一个耗时部分(9%)是“卷积”,利用率为 74%。我不确定需要调整哪些操作才能更好地利用输出融合?

下面是我创建U-Net的代码,可能里面有一个slow layer?:

class UNet:
def create(self, input, start_ch, depth, inc_rate,
           dropout, batchnorm, maxpool, upconv, residual, leaky_relu_alpha):
    with tf.variable_scope('Generator', reuse=tf.AUTO_REUSE):
        o = self._level_block(input, start_ch, depth, inc_rate, dropout, batchnorm, maxpool, upconv, residual,
                              leaky_relu_alpha)
        out_ch = input.shape[3]
        o = tf.layers.conv2d(o, out_ch, 1)
        o = tf.tanh(o)
        return o

def _conv_block(self, m, dim, bn, res, leaky_relu_alpha, do=0):
    n = tf.layers.conv2d(m, dim, 3, padding='same')
    n = tf.nn.leaky_relu(n, alpha=leaky_relu_alpha)
    n = tf.layers.batch_normalization(n) if bn else n
    n = tf.layers.dropout(n, do) if do else n
    n = tf.layers.conv2d(n, dim, 3, padding='same')
    n = tf.nn.leaky_relu(n, alpha=leaky_relu_alpha)
    n = tf.layers.batch_normalization(n)if bn else n
    return tf.concat([m, n], axis=-1) if res else n

def _level_block(self, m, dim, depth, inc, do, bn, mp, up, res, leaky_relu_alpha):
    if depth > 0:
        n = self._conv_block(m, dim, bn, res, leaky_relu_alpha)
        m = tf.layers.max_pooling2d(n, [2, 2], [2, 2]) if mp else tf.layers.conv2d(n, dim, 3, strides=2, padding='same')
        m = self._level_block(m, int(inc * dim), depth - 1, inc, do, bn, mp, up, res, leaky_relu_alpha)
        if up:
            m = tf.image.resize_nearest_neighbor(m, (2*m.shape[1], 2*m.shape[2]))
            m = tf.layers.conv2d(m, dim, 2, padding='same')
            m = tf.nn.leaky_relu(m, alpha=leaky_relu_alpha)
        else:
            m = tf.layers.conv2d_transpose(m, dim, 3, strides=2, padding='same')
            m = tf.nn.leaky_relu(m, alpha=leaky_relu_alpha)

        n = tf.concat([n, m], axis=-1)
        m = self._conv_block(n, dim, bn, res, leaky_relu_alpha)
    else:
        m = self._conv_block(m, dim, bn, res, leaky_relu_alpha, do)
    return m

我的输入批量大小为 128。U-Net 深度为 4。不使用 BatchNorm 层 (batchnorm=False)、conv2d_transpose (upconv=False)、residual=False 和 maxpool=True。所以 U-Net 只包含 Conv2D、Conv2D_Transpose、Dropout、Leaky ReLU、Max Pooling 和 Concatenation 层。

知道我需要调整什么以获得更好的“输出融合”利用率吗?或者至少是什么影响了输出融合?

【问题讨论】:

    标签: google-compute-engine google-cloud-tpu


    【解决方案1】:

    我可以看到卷积。114 有很多填充,128*8 中有 16*1。由于您的全局批处理大小为 128,因此每个内核的本地批处理大小仅为 16 (128/8)。您是否可以将模型的批量大小增加到 1024?

    【讨论】:

    • 如果批量大小超过 128,则会出现内存耗尽错误。你认为它与太小批量相关吗?你知道“输出融合”究竟是什么意思吗?
    • 输出融合意味着任何元素操作与卷积或 matmul 融合(matmuls 现在被降低为卷积,所以它始终是卷积)。请注意,元素操作是否融合到卷积 LHS 输入、RHS 输入或输出中是无关紧要的——它始终是输出融合。输出融合好。在您的 HLO 配置文件中有很多它表明编译器正在做好事。对于内存耗尽错误,您可以使用 memory_viewer 工具查看填充量并对其进行优化。
    • 感谢您的解释!但为什么“好”融合的利用率如此之低?顺便说一句,我将输入尺寸减少到 128x128 图像,因此可以将批量大小增加到 1024。对于输出融合,利用率增加到大约 33% 的整体利用率。尽管如此,这仍然没有我预期的那么好。
    • 触发器利用率被归一化为 TPU 矩阵乘法单元的峰值触发器。在您的输出融合中,有许多元素明智的操作具有低 FLOP,例如广播和常量。这些降低了平均 FLOPS 利用率。如果您查看未融合的单个卷积操作的 FLOPS,通常会很高。
    猜你喜欢
    • 2022-01-14
    • 2019-02-24
    • 2019-09-26
    • 1970-01-01
    • 1970-01-01
    • 2019-07-15
    • 1970-01-01
    • 1970-01-01
    • 2020-08-13
    相关资源
    最近更新 更多