捷徑

推論模式

c10::InferenceMode 是一個新的 RAII 保護機制,類似於 NoGradMode,當您確定您的操作不會與 autograd (例如模型訓練) 產生互動時使用。 與 NoGradMode 相比,在此模式下運行的程式碼透過停用 autograd 相關的工作(如視圖追蹤和版本計數器遞增)獲得更好的效能。 但是,在 c10::InferenceMode 內部建立的張量在與 autograd 系統互動時也有更多限制。

可以為給定的程式碼區塊啟用 InferenceMode。 在 InferenceMode 內部,所有新分配的 (非視圖) 張量都標記為推論張量。 推論張量

  • 沒有版本計數器,因此如果您嘗試讀取其版本 (例如,因為您儲存了此張量以進行反向傳播),則會引發錯誤。

  • InferenceMode 外部是不可變的。 因此,如果您嘗試以下操作,則會引發錯誤:- 在 InferenceMode 外部變更其數據。 - 在 InferenceMode 外部將它們變更為 requires_grad=True。 要解決此問題,您可以在 InferenceMode 外部進行複製,以在變更之前獲得一個正常的張量。

當且僅當在 InferenceMode 內部分配非視圖張量時,它才是推論張量。 當且僅當它所視圖的張量是推論張量時,視圖張量才是推論張量。

InferenceMode 區塊內,我們保證以下效能

  • NoGradMode 類似,即使其輸入具有 requires_grad=True,所有操作也不會記錄 grad_fn。 這適用於推論張量和正常張量。

  • 對推論張量的視圖操作不會進行視圖追蹤。 視圖和非視圖推論張量無法區分。

  • 保證對推論張量的原地操作不會進行版本遞增。

有關 InferenceMode 的更多實作詳細資訊,請參閱 RFC-0011-InferenceMode

AutoNonVariableTypeMode 遷移的指南

在 PyTorch 用於推論工作負載的生產使用中,我們已經看到 C++ 保護機制 AutoNonVariableTypeMode (現在是 AutoDispatchBelowADInplaceOrView) 的使用激增,它停用了 autograd、視圖追蹤和版本計數器遞增。 不幸的是,目前對此保護機制用於推論工作負載的通俗用法是不安全的:可以使用 AutoNonVariableTypeMode 來繞過 PyTorch 的安全檢查,並導致靜默的錯誤結果,例如,PyTorch 在儲存以進行反向傳播的張量隨後發生變更時會拋出錯誤,但是在 AutoNonVariableTypeMode 內部發生的變更會靜默地繞過檢查,並向使用者返回錯誤的梯度。

AutoNonVariableTypeMode 的目前使用者考慮遷移時,以下步驟可能有助於您決定最佳替代方案

  1. 嘗試僅在推論模式下執行工作負載 (例如載入預先訓練的 JIT 模型並在 C++ 運行時中執行推論) 的使用者應新增 c10::InferenceMode guard 以保護對張量的所有操作 (包括模型載入)。 請參閱下面的推論工作負載範例

c10::InferenceMode guard;
model.load_jit(saved_model);
auto inputs = preprocess_tensors(data);
auto out = model.forward(inputs);
auto outputs = postprocess_tensors(out);

請注意,c10::InferenceMode 提供了一個可直接替換 AutoNonVariableTypeMode 的方案,它保留了 AutoNonVariableTypeMode 的效能特性。但它們之間也存在一些差異,使用者應額外注意。

  • 這兩種保護機制都會影響張量執行流程,以跳過與推論無關的工作,但 InferenceMode 還會影響張量的建立,而 AutoNonVariableTypeMode 不會。 換句話說,在 InferenceMode 內部建立的張量會被標記為推論張量,以便在退出 InferenceMode 後可以應用某些限制。

  • InferenceMode 的啟用/停用狀態可以巢狀結構方式存在,而 AutoNonVariableTypeMode 僅允許啟用狀態。

{
  InferenceMode guard(true);
  // InferenceMode is on
  {
    InferenceMode guard(false);
    // InferenceMode is off
  }
  // InferenceMode is on
}
// InferenceMode is off
  1. 想要實作自定義核心並希望在 Autograd 分發鍵下重新分發的使用者,應使用 AutoDispatchBelowADInplaceOrView 來代替。 請注意,AutoDispatchBelowADInplaceOrView 只是 AutoNonVariableTypeMode 的一個新名稱,因為它更好地解釋了保護機制的功用。 我們正在棄用 AutoNonVariableTypeMode,它將在 1.10 版本中移除。 請參閱 pytorch/vision 中的自定義核心 ROIAlignFunction 作為範例。

class ROIAlignFunction : public torch::autograd::Function<ROIAlignFunction> {
 public:
  static torch::autograd::variable_list forward(
      torch::autograd::AutogradContext* ctx,
      const torch::autograd::Variable& input,
      const torch::autograd::Variable& rois,
      double spatial_scale,
      int64_t pooled_height,
      int64_t pooled_width,
      int64_t sampling_ratio,
      bool aligned) {
    ctx->saved_data["spatial_scale"] = spatial_scale;
    ctx->saved_data["pooled_height"] = pooled_height;
    ctx->saved_data["pooled_width"] = pooled_width;
    ctx->saved_data["sampling_ratio"] = sampling_ratio;
    ctx->saved_data["aligned"] = aligned;
    ctx->saved_data["input_shape"] = input.sizes();
    ctx->save_for_backward({rois});
    // Used to be at::AutoNonVariableTypeMode g;
    at::AutoDispatchBelowADInplaceOrView guard;
    auto result = roi_align(
        input, rois, spatial_scale, pooled_height,
        pooled_width, sampling_ratio, aligned);
    return {result};
  }

除了上述保護機制之外,自定義的 inplace 和 view 核心還需要一些特殊處理,更多詳細資訊請參閱自定義核心教學

文檔

取得 PyTorch 的完整開發者文件

查看文件

教學

取得初學者和進階開發人員的深入教學

查看教學

資源

尋找開發資源並獲得您的問題解答

查看資源