分片#

分片允许 DALI 将数据集划分为不重叠的片段,每个 DALI pipeline 实例可以在这些片段上工作。此功能解决了全局和共享状态的问题,该问题允许在不同 rank 之间分配训练样本。默认情况下,在每个 epoch 之后,DALI pipeline 会前进到下一个分片,以增加此 pipeline 所看到数据的熵。您可以通过设置 stick_to_shard reader 参数来更改此行为。

然而,当数据集大小不能被使用的 pipeline 数量整除,或者当分片大小不能被批次大小整除时,这种操作模式会导致问题。为了解决这个问题并调整行为,您可以使用 pad_last_batch reader 参数。

此参数要求 reader 复制分片中最后一个批次的最后一个样本,这可以防止 DALI 在批次大小不能整除其大小时从下一个分片读取数据。当一个批次可以被批次大小整除,但其他批次大小多一个样本时,此参数还确保所有 pipeline 返回相同数量的批次。此过程将每个分片填充到相同大小,该大小是批次大小的倍数。

框架迭代器配置#

DALI 通过专用迭代器在深度学习框架中使用,这些迭代器需要了解此填充和其他 reader 属性。

以下是迭代器选项

  • reader_name - 允许您提供驱动迭代器并提供必要参数的 reader 的名称。

    注意

    我们建议您使用此选项,以便接下来的两个选项(sizelast_batch_padded)可以从 pipeline 配置中自动获得。如果使用此选项,则不应将 sizelast_batch_padded 显式提供给迭代器。

    此选项更加灵活和准确,并考虑到当分片轮换时,pipeline 的分片大小在 epoch 之间可能会有所不同。
  • size: 提供迭代器的分片大小,或者,如果存在多个分片,则提供所有包装 pipeline 的所有分片大小的总和。

  • last_batch_padded: 确定数据尾部是由来自下一个分片的数据 (False) 组成,还是由重复的虚拟数据 (True) 组成。
    当分片大小不是批次大小的倍数时,此选项适用,
  • last_batch_policy - 确定当分片大小不能被批次大小整除时,如何处理最后一个批次。
    它仅影响部分填充数据的批次。有关可能的值,请参阅 LastBatchPolicy() 枚举。
  • fill_last_batch –(已弃用,建议使用 last_batch_policy)确定最后一个批次是否应该是完整的,无论分片大小是否可以被批次大小整除。

枚举#

class nvidia.dali.plugin.base_iterator.LastBatchPolicy(value)#

描述当 epoch 中没有足够的样本来填充整个批次时,最后批次策略的行为。

  • FILL - 最后一个批次通过重复最后一个样本或通过包装数据集来填充。精确的行为取决于 reader 的 pad_last_batch 参数

  • DROP - 如果最后一个批次无法完全用当前 epoch 的数据填充,则丢弃最后一个批次

  • PARTIAL - 最后一个批次部分填充当前 epoch 的剩余数据,其余样本保持为空

FILL#
DROP#
PARTIAL#

分片计算#

以下是计算分片 ID 的分片大小的公式

floor((id + 1) * dataset_size / num_shards) -
    floor(id * dataset_size / num_shards)

当 pipeline 在 epoch 中前进并且 reader 移动到下一个分片时,公式需要扩展以反映此更改

floor(((id + epoch_num) % num_shards + 1) * dataset_size / num_shards) -
    floor(((id + epoch_num) % num_shards) * dataset_size / num_shards)

当使用第二个公式时,仅在训练开始时提供一次 size 值仅在启用 stick_to_shard reader 选项并防止 DALI 轮换分片时才有效。发生这种情况时,请使用第一个公式。

为了应对这些挑战,请使用 reader_name 参数并允许迭代器自动处理配置。