TensorFlow Lite 的 GPU 代理

使用图形处理单元 (GPU) 运行机器学习 (ML) 模型可以显着提高模型的性能和 ML 增强应用程序的用户体验。TensorFlow Lite 通过称为 代理 的硬件驱动程序启用 GPU 和其他专用处理器的使用。在 TensorFlow Lite ML 应用程序中启用 GPU 使用可以带来以下好处

  • 速度 - GPU 专为大规模并行工作负载的高吞吐量而设计。这种设计使它们非常适合深度神经网络,深度神经网络由大量运算符组成,每个运算符都在可以并行处理的输入张量上工作,这通常会导致更低的延迟。在最佳情况下,在 GPU 上运行您的模型可能运行得足够快,可以实现以前不可能的实时应用程序。
  • 能效 - GPU 以非常高效和优化的方式执行 ML 计算,通常比在 CPU 上运行相同任务消耗更少的能量并产生更少的热量。

本文档概述了 TensorFlow Lite 中的 GPU 支持,以及 GPU 处理器的一些高级用法。有关在特定平台上实现 GPU 支持的更具体信息,请参阅以下指南

GPU ML 运算支持

TensorFlow Lite GPU 代理可以加速的 TensorFlow ML 运算(或运算符)存在一些限制。代理支持以下运算符,精度为 16 位和 32 位浮点数

  • ADD
  • AVERAGE_POOL_2D
  • CONCATENATION
  • CONV_2D
  • DEPTHWISE_CONV_2D v1-2
  • EXP
  • FULLY_CONNECTED
  • LOGICAL_AND
  • LOGISTIC
  • LSTM v2(仅限基本 LSTM)
  • MAX_POOL_2D
  • MAXIMUM
  • MINIMUM
  • MUL
  • PAD
  • PRELU
  • RELU
  • RELU6
  • RESHAPE
  • RESIZE_BILINEAR v1-3
  • SOFTMAX
  • STRIDED_SLICE
  • SUB
  • TRANSPOSE_CONV

默认情况下,所有运算符仅在版本 1 中受支持。启用 量化支持 将启用相应的版本,例如 ADD v2。

GPU 支持故障排除

如果 GPU 代理不支持某些运算符,框架将仅在 GPU 上运行图的一部分,并在 CPU 上运行剩余部分。由于 CPU/GPU 同步成本很高,因此这种拆分执行模式通常会导致比整个网络单独在 CPU 上运行更慢的性能。在这种情况下,应用程序会生成警告,例如

WARNING: op code #42 cannot be handled by this delegate.

由于这不是实际的运行时错误,因此没有针对此类错误的回调。在使用 GPU 代理测试模型执行时,您应该注意这些警告。大量这些警告可能表明您的模型不适合用于 GPU 加速,可能需要重构模型。

示例模型

以下示例模型旨在利用 TensorFlow Lite 的 GPU 加速,并提供参考和测试

针对 GPU 优化

以下技术可以帮助您在使用 TensorFlow Lite GPU 委托在 GPU 硬件上运行模型时获得更好的性能

  • 重塑操作 - 一些在 CPU 上很快的操作在移动设备上的 GPU 上可能成本很高。重塑操作尤其昂贵,包括 BATCH_TO_SPACESPACE_TO_BATCHSPACE_TO_DEPTH 等等。您应该仔细检查重塑操作的使用,并考虑它们可能仅用于探索数据或模型的早期迭代。删除它们可以显着提高性能。

  • 图像数据通道 - 在 GPU 上,张量数据被切分成 4 个通道,因此对形状为 [B,H,W,5] 的张量的计算在形状为 [B,H,W,8] 的张量上执行效果大致相同,但明显不如 [B,H,W,4]。如果您使用的相机硬件支持 RGBA 格式的图像帧,则馈送该 4 通道输入会快得多,因为它避免了从 3 通道 RGB 到 4 通道 RGBX 的内存复制。

  • 移动优化模型 - 为了获得最佳性能,您应该考虑使用移动优化网络架构重新训练您的分类器。针对设备上推理进行优化可以通过利用移动硬件功能来显着降低延迟和功耗。

高级 GPU 支持

您可以使用 GPU 处理的额外高级技术来为您的模型实现更好的性能,包括量化和序列化。以下部分将更详细地描述这些技术。

使用量化模型

本节说明 GPU 委托如何加速 8 位量化模型,包括以下内容

为了优化性能,请使用同时具有浮点输入和输出张量的模型。

它是如何工作的?

由于 GPU 后端仅支持浮点执行,因此我们通过为其提供原始模型的“浮点视图”来运行量化模型。从高层次来看,这需要以下步骤

  • 常量张量(例如权重/偏差)在 GPU 内存中一次性反量化。当为 TensorFlow Lite 启用委托时,此操作会发生。

  • 输入和输出到 GPU 程序,如果为 8 位量化,则在每次推理时分别反量化和量化。此操作在 CPU 上使用 TensorFlow Lite 的优化内核完成。

  • 量化模拟器插入操作之间以模拟量化行为。对于操作期望激活遵循量化期间学习的边界的模型,这种方法是必要的。

有关使用 GPU 委托启用此功能的信息,请参阅以下内容

使用序列化减少初始化时间

GPU 委托功能允许您从之前运行中序列化并保存在磁盘上的预编译内核代码和模型数据中加载。这种方法避免了重新编译,可以将启动时间缩短高达 90%。这种改进是通过用磁盘空间换取时间节省来实现的。您可以使用一些配置选项启用此功能,如以下代码示例所示

C++

    TfLiteGpuDelegateOptionsV2 options = TfLiteGpuDelegateOptionsV2Default();
    options.experimental_flags |= TFLITE_GPU_EXPERIMENTAL_FLAGS_ENABLE_SERIALIZATION;
    options.serialization_dir = kTmpDir;
    options.model_token = kModelToken;

    auto* delegate = TfLiteGpuDelegateV2Create(options);
    if (interpreter->ModifyGraphWithDelegate(delegate) != kTfLiteOk) return false;
      

Java

    GpuDelegate delegate = new GpuDelegate(
      new GpuDelegate.Options().setSerializationParams(
        /* serializationDir= */ serializationDir,
        /* modelToken= */ modelToken));

    Interpreter.Options options = (new Interpreter.Options()).addDelegate(delegate);
      

使用序列化功能时,请确保您的代码符合以下实现规则

  • 将序列化数据存储在其他应用程序无法访问的目录中。在 Android 设备上,使用 getCodeCacheDir(),它指向当前应用程序专用的位置。
  • 模型令牌对于特定设备的特定模型必须是唯一的。您可以通过使用 farmhash::Fingerprint64 等库从模型数据生成指纹来计算模型令牌。