• 教程 >
  • 面向 PyTorch* 的 Intel® 扩展程序
快捷方式

面向 PyTorch* 的 Intel® 扩展程序

创建日期: 2021 年 11 月 09 日 | 最后更新: 2024 年 7 月 25 日 | 最后验证: 2024 年 11 月 05 日

面向 PyTorch* 的 Intel® 扩展程序 (Intel® Extension for PyTorch*) 扩展了 PyTorch*,提供了最新的特性和优化,以在 Intel 硬件上实现额外的性能提升。这些优化利用了 Intel CPU 上的 AVX-512 矢量神经网络指令 (AVX512 VNNI) 和 Intel® Advanced Matrix Extensions (Intel® AMX),以及 Intel 独立 GPU 上的 Intel Xe Matrix Extensions (XMX) AI 引擎。此外,通过 PyTorch* xpu 设备,面向 PyTorch* 的 Intel® 扩展程序 为使用 PyTorch* 的 Intel 独立 GPU 提供了简便的 GPU 加速。

面向 PyTorch* 的 Intel® 扩展程序 已在 Github 上作为开源项目发布。

功能特性

面向 PyTorch* 的 Intel® 扩展程序 共享了 CPU 和 GPU 的大部分功能。

  • 易用 Python API: 面向 PyTorch* 的 Intel® 扩展程序 提供了简单的前端 Python API 和实用程序,用户只需少量代码修改即可获得性能优化,如图优化和算子优化。通常,只需要在原始代码中添加 2 到 3 行代码。

  • Channels Last: 与默认的 NCHW 内存格式相比,channels_last (NHWC) 内存格式可以进一步加速卷积神经网络。在 面向 PyTorch* 的 Intel® 扩展程序 中,大多数关键 CPU 算子已启用 NHWC 内存格式,尽管并非所有都已合并到 PyTorch master 分支。它们预计很快将完全落地到 PyTorch 上游。

  • 自动混合精度 (AMP): 第三代至强可扩展服务器 (Cooper Lake) 已通过 AVX512 指令集原生支持低精度数据类型 BFloat16,并在下一代 Intel® 至强® 可扩展处理器上通过 Intel® Advanced Matrix Extensions (Intel® AMX) 指令集支持,性能将进一步提升。面向 PyTorch* 的 Intel® 扩展程序 中已大规模启用对 CPU 的 BFloat16 自动混合精度 (AMP) 支持和算子 BFloat16 优化,并部分合并到 PyTorch master 分支。大多数这些优化将通过正在提交和审查的 PR 落地到 PyTorch master。Intel 独立 GPU 已启用对 BFloat16 和 Float16 数据类型的自动混合精度 (AMP) 支持。

  • 图优化: 为了通过 torchscript 进一步优化性能,面向 PyTorch* 的 Intel® 扩展程序 支持常用算子模式的融合,例如 Conv2D+ReLU、Linear+ReLU 等。融合的好处以透明的方式提供给用户。支持的详细融合模式可在此处找到。随着 oneDNN Graph API 的引入,图优化将合并到 PyTorch 上游。

  • 算子优化: 面向 PyTorch* 的 Intel® 扩展程序 还对算子进行了优化,并为若干流行拓扑结构实现了一些定制算子。例如,ROIAlign 和 NMS 在 Mask R-CNN 中定义。为了提升这些拓扑结构的性能,面向 PyTorch* 的 Intel® 扩展程序 也优化了这些定制算子。

入门

用户只需要少量代码修改即可开始使用 面向 PyTorch* 的 Intel® 扩展程序。同时支持 PyTorch 命令式模式和 TorchScript 模式。本节将介绍 面向 PyTorch* 的 Intel® 扩展程序 API 函数在命令式模式和 TorchScript 模式下的用法,涵盖 Float32 和 BFloat16 数据类型。最后还将介绍 C++ 用法。

您只需要导入 面向 PyTorch* 的 Intel® 扩展程序 包,并对其 model 对象应用 optimize 函数。如果是训练工作负载,optimize 函数也需要应用于 optimizer 对象。

对于使用 BFloat16 数据类型进行训练和推理,PyTorch 上游已启用 torch.cpu.amp 以便捷地支持混合精度。PyTorch 上游和 面向 PyTorch* 的 Intel® 扩展程序 已广泛启用 CPU 算子的 BFloat16 数据类型。同时,由 面向 PyTorch* 的 Intel® 扩展程序 注册的 torch.xpu.amp 使得在 Intel 独立 GPU 上可以轻松使用 BFloat16 和 Float16 数据类型。无论是 torch.cpu.amp 还是 torch.xpu.amp 都能自动将每个算子匹配到合适的数据类型,并返回最佳性能。

示例 – CPU

本节展示了使用 面向 PyTorch* 的 Intel® 扩展程序 在 CPU 上进行训练和推理的示例

使用 面向 PyTorch* 的 Intel® 扩展程序 所需的代码修改已高亮显示。

训练

Float32

import torch
import torchvision
import intel_extension_for_pytorch as ipex

LR = 0.001
DOWNLOAD = True
DATA = 'datasets/cifar10/'

transform = torchvision.transforms.Compose([
    torchvision.transforms.Resize((224, 224)),
    torchvision.transforms.ToTensor(),
    torchvision.transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
])
train_dataset = torchvision.datasets.CIFAR10(
        root=DATA,
        train=True,
        transform=transform,
        download=DOWNLOAD,
)
train_loader = torch.utils.data.DataLoader(
        dataset=train_dataset,
        batch_size=128
)

model = torchvision.models.resnet50()
criterion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr = LR, momentum=0.9)
model.train()
model, optimizer = ipex.optimize(model, optimizer=optimizer)

for batch_idx, (data, target) in enumerate(train_loader):
    optimizer.zero_grad()
    output = model(data)
    loss = criterion(output, target)
    loss.backward()
    optimizer.step()
    print(batch_idx)
torch.save({
     'model_state_dict': model.state_dict(),
     'optimizer_state_dict': optimizer.state_dict(),
     }, 'checkpoint.pth')

BFloat16

import torch
import torchvision
import intel_extension_for_pytorch as ipex

LR = 0.001
DOWNLOAD = True
DATA = 'datasets/cifar10/'

transform = torchvision.transforms.Compose([
    torchvision.transforms.Resize((224, 224)),
    torchvision.transforms.ToTensor(),
    torchvision.transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
])
train_dataset = torchvision.datasets.CIFAR10(
        root=DATA,
        train=True,
        transform=transform,
        download=DOWNLOAD,
)
train_loader = torch.utils.data.DataLoader(
        dataset=train_dataset,
        batch_size=128
)

model = torchvision.models.resnet50()
criterion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr = LR, momentum=0.9)
model.train()
model, optimizer = ipex.optimize(model, optimizer=optimizer, dtype=torch.bfloat16)

for batch_idx, (data, target) in enumerate(train_loader):
    optimizer.zero_grad()
    with torch.cpu.amp.autocast():
        output = model(data)
        loss = criterion(output, target)
        loss.backward()
    optimizer.step()
    print(batch_idx)
torch.save({
     'model_state_dict': model.state_dict(),
     'optimizer_state_dict': optimizer.state_dict(),
     }, 'checkpoint.pth')

推理 - 命令式模式

Float32

import torch
import torchvision.models as models

model = models.resnet50(pretrained=True)
model.eval()
data = torch.rand(1, 3, 224, 224)

#################### code changes ####################
import intel_extension_for_pytorch as ipex
model = ipex.optimize(model)
######################################################

with torch.no_grad():
  model(data)

BFloat16

import torch
from transformers import BertModel

model = BertModel.from_pretrained(args.model_name)
model.eval()

vocab_size = model.config.vocab_size
batch_size = 1
seq_length = 512
data = torch.randint(vocab_size, size=[batch_size, seq_length])

#################### code changes ####################
import intel_extension_for_pytorch as ipex
model = ipex.optimize(model, dtype=torch.bfloat16)
######################################################

with torch.no_grad():
  with torch.cpu.amp.autocast():
    model(data)

推理 - TorchScript 模式

TorchScript 模式使得图优化成为可能,因此提高了某些拓扑结构的性能。面向 PyTorch* 的 Intel® 扩展程序 启用了最常用的算子模式融合,用户无需额外的代码修改即可获得性能提升。

Float32

import torch
import torchvision.models as models

model = models.resnet50(pretrained=True)
model.eval()
data = torch.rand(1, 3, 224, 224)

#################### code changes ####################
import intel_extension_for_pytorch as ipex
model = ipex.optimize(model)
######################################################

with torch.no_grad():
  d = torch.rand(1, 3, 224, 224)
  model = torch.jit.trace(model, d)
  model = torch.jit.freeze(model)

  model(data)

BFloat16

import torch
from transformers import BertModel

model = BertModel.from_pretrained(args.model_name)
model.eval()

vocab_size = model.config.vocab_size
batch_size = 1
seq_length = 512
data = torch.randint(vocab_size, size=[batch_size, seq_length])

#################### code changes ####################
import intel_extension_for_pytorch as ipex
model = ipex.optimize(model, dtype=torch.bfloat16)
######################################################

with torch.no_grad():
  with torch.cpu.amp.autocast():
    d = torch.randint(vocab_size, size=[batch_size, seq_length])
    model = torch.jit.trace(model, (d,), check_trace=False, strict=False)
    model = torch.jit.freeze(model)

    model(data)

示例 – GPU

本节展示了使用 面向 PyTorch* 的 Intel® 扩展程序 在 GPU 上进行训练和推理的示例

使用 面向 PyTorch* 的 Intel® 扩展程序 所需的代码修改已在上一行的注释中高亮显示。

训练

Float32

import torch
import torchvision
############# code changes ###############
import intel_extension_for_pytorch as ipex
############# code changes ###############

LR = 0.001
DOWNLOAD = True
DATA = 'datasets/cifar10/'

transform = torchvision.transforms.Compose([
    torchvision.transforms.Resize((224, 224)),
    torchvision.transforms.ToTensor(),
    torchvision.transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
])
train_dataset = torchvision.datasets.CIFAR10(
        root=DATA,
        train=True,
        transform=transform,
        download=DOWNLOAD,
)
train_loader = torch.utils.data.DataLoader(
        dataset=train_dataset,
        batch_size=128
)

model = torchvision.models.resnet50()
criterion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr = LR, momentum=0.9)
model.train()
#################################### code changes ################################
model = model.to("xpu")
model, optimizer = ipex.optimize(model, optimizer=optimizer, dtype=torch.float32)
#################################### code changes ################################

for batch_idx, (data, target) in enumerate(train_loader):
    ########## code changes ##########
    data = data.to("xpu")
    target = target.to("xpu")
    ########## code changes ##########
    optimizer.zero_grad()
    output = model(data)
    loss = criterion(output, target)
    loss.backward()
    optimizer.step()
    print(batch_idx)
torch.save({
     'model_state_dict': model.state_dict(),
     'optimizer_state_dict': optimizer.state_dict(),
     }, 'checkpoint.pth')

BFloat16

import torch
import torchvision
############# code changes ###############
import intel_extension_for_pytorch as ipex
############# code changes ###############

LR = 0.001
DOWNLOAD = True
DATA = 'datasets/cifar10/'

transform = torchvision.transforms.Compose([
    torchvision.transforms.Resize((224, 224)),
    torchvision.transforms.ToTensor(),
    torchvision.transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
])
train_dataset = torchvision.datasets.CIFAR10(
        root=DATA,
        train=True,
        transform=transform,
        download=DOWNLOAD,
)
train_loader = torch.utils.data.DataLoader(
        dataset=train_dataset,
        batch_size=128
)

model = torchvision.models.resnet50()
criterion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr = LR, momentum=0.9)
model.train()
##################################### code changes ################################
model = model.to("xpu")
model, optimizer = ipex.optimize(model, optimizer=optimizer, dtype=torch.bfloat16)
##################################### code changes ################################

for batch_idx, (data, target) in enumerate(train_loader):
    optimizer.zero_grad()
    ######################### code changes #########################
    data = data.to("xpu")
    target = target.to("xpu")
    with torch.xpu.amp.autocast(enabled=True, dtype=torch.bfloat16):
    ######################### code changes #########################
        output = model(data)
        loss = criterion(output, target)
    loss.backward()
    optimizer.step()
    print(batch_idx)
torch.save({
     'model_state_dict': model.state_dict(),
     'optimizer_state_dict': optimizer.state_dict(),
     }, 'checkpoint.pth')

推理 - 命令式模式

Float32

import torch
import torchvision.models as models
############# code changes ###############
import intel_extension_for_pytorch as ipex
############# code changes ###############

model = models.resnet50(pretrained=True)
model.eval()
data = torch.rand(1, 3, 224, 224)

model = model.to(memory_format=torch.channels_last)
data = data.to(memory_format=torch.channels_last)

#################### code changes ################
model = model.to("xpu")
data = data.to("xpu")
model = ipex.optimize(model, dtype=torch.float32)
#################### code changes ################

with torch.no_grad():
  model(data)

BFloat16

import torch
import torchvision.models as models
############# code changes ###############
import intel_extension_for_pytorch as ipex
############# code changes ###############

model = models.resnet50(pretrained=True)
model.eval()
data = torch.rand(1, 3, 224, 224)

model = model.to(memory_format=torch.channels_last)
data = data.to(memory_format=torch.channels_last)

#################### code changes #################
model = model.to("xpu")
data = data.to("xpu")
model = ipex.optimize(model, dtype=torch.bfloat16)
#################### code changes #################

with torch.no_grad():
  ################################# code changes ######################################
  with torch.xpu.amp.autocast(enabled=True, dtype=torch.bfloat16, cache_enabled=False):
  ################################# code changes ######################################
    model(data)

Float16

import torch
import torchvision.models as models
############# code changes ###############
import intel_extension_for_pytorch as ipex
############# code changes ###############

model = models.resnet50(pretrained=True)
model.eval()
data = torch.rand(1, 3, 224, 224)

model = model.to(memory_format=torch.channels_last)
data = data.to(memory_format=torch.channels_last)

#################### code changes ################
model = model.to("xpu")
data = data.to("xpu")
model = ipex.optimize(model, dtype=torch.float16)
#################### code changes ################

with torch.no_grad():
  ################################# code changes ######################################
  with torch.xpu.amp.autocast(enabled=True, dtype=torch.float16, cache_enabled=False):
  ################################# code changes ######################################
    model(data)

推理 - TorchScript 模式

TorchScript 模式使得图优化成为可能,因此提高了某些拓扑结构的性能。面向 PyTorch* 的 Intel® 扩展程序 启用了最常用的算子模式融合,用户无需额外的代码修改即可获得性能提升。

Float32

import torch
from transformers import BertModel
############# code changes ###############
import intel_extension_for_pytorch as ipex
############# code changes ###############

model = BertModel.from_pretrained(args.model_name)
model.eval()

vocab_size = model.config.vocab_size
batch_size = 1
seq_length = 512
data = torch.randint(vocab_size, size=[batch_size, seq_length])

#################### code changes ################
model = model.to("xpu")
data = data.to("xpu")
model = ipex.optimize(model, dtype=torch.float32)
#################### code changes ################

with torch.no_grad():
  d = torch.randint(vocab_size, size=[batch_size, seq_length])
  ##### code changes #####
  d = d.to("xpu")
  ##### code changes #####
  model = torch.jit.trace(model, (d,), check_trace=False, strict=False)
  model = torch.jit.freeze(model)

  model(data)

BFloat16

import torch
from transformers import BertModel
############# code changes ###############
import intel_extension_for_pytorch as ipex
############# code changes ###############

model = BertModel.from_pretrained(args.model_name)
model.eval()

vocab_size = model.config.vocab_size
batch_size = 1
seq_length = 512
data = torch.randint(vocab_size, size=[batch_size, seq_length])

#################### code changes #################
model = model.to("xpu")
data = data.to("xpu")
model = ipex.optimize(model, dtype=torch.bfloat16)
#################### code changes #################

with torch.no_grad():
  d = torch.randint(vocab_size, size=[batch_size, seq_length])
  ################################# code changes ######################################
  d = d.to("xpu")
  with torch.xpu.amp.autocast(enabled=True, dtype=torch.bfloat16, cache_enabled=False):
  ################################# code changes ######################################
    model = torch.jit.trace(model, (d,), check_trace=False, strict=False)
    model = torch.jit.freeze(model)

    model(data)

Float16

import torch
from transformers import BertModel
############# code changes ###############
import intel_extension_for_pytorch as ipex
############# code changes ###############

model = BertModel.from_pretrained(args.model_name)
model.eval()

vocab_size = model.config.vocab_size
batch_size = 1
seq_length = 512
data = torch.randint(vocab_size, size=[batch_size, seq_length])

#################### code changes ################
model = model.to("xpu")
data = data.to("xpu")
model = ipex.optimize(model, dtype=torch.float16)
#################### code changes ################

with torch.no_grad():
  d = torch.randint(vocab_size, size=[batch_size, seq_length])
  ################################# code changes ######################################
  d = d.to("xpu")
  with torch.xpu.amp.autocast(enabled=True, dtype=torch.float16, cache_enabled=False):
  ################################# code changes ######################################
    model = torch.jit.trace(model, (d,), check_trace=False, strict=False)
    model = torch.jit.freeze(model)

    model(data)

C++ (仅限 CPU)

为了与 PyTorch 的 C++ 库 libtorch 配合使用,面向 PyTorch* 的 Intel® 扩展程序 也提供了其 C++ 动态库。C++ 库应仅用于处理推理工作负载,例如服务部署。对于常规开发,请使用 Python 接口。与使用 libtorch 相比,不需要特定的代码修改,除了将输入数据转换为 channels last 数据格式。编译遵循使用 CMake 的推荐方法。详细说明可在 PyTorch 教程中找到。编译期间,一旦链接了 面向 PyTorch* 的 Intel® 扩展程序 的 C++ 动态库,Intel 优化将自动激活。

example-app.cpp

#include <torch/script.h>
#include <iostream>
#include <memory>

int main(int argc, const char* argv[]) {
    torch::jit::script::Module module;
    try {
        module = torch::jit::load(argv[1]);
    }
    catch (const c10::Error& e) {
        std::cerr << "error loading the model\n";
        return -1;
    }
    std::vector<torch::jit::IValue> inputs;
    // make sure input data are converted to channels last format
    inputs.push_back(torch::ones({1, 3, 224, 224}).to(c10::MemoryFormat::ChannelsLast));

    at::Tensor output = module.forward(inputs).toTensor();

    return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(example-app)

find_package(intel_ext_pt_cpu REQUIRED)

add_executable(example-app example-app.cpp)
target_link_libraries(example-app "${TORCH_LIBRARIES}")

set_property(TARGET example-app PROPERTY CXX_STANDARD 14)

编译命令

$ cmake -DCMAKE_PREFIX_PATH=<LIBPYTORCH_PATH> ..
$ make

如果显示 Found INTEL_EXT_PT_CPUTRUE,则扩展程序已链接到二进制文件中。这可以使用 Linux 命令 ldd 进行验证。

$ cmake -DCMAKE_PREFIX_PATH=/workspace/libtorch ..
-- The C compiler identification is GNU 9.3.0
-- The CXX compiler identification is GNU 9.3.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE
-- Found Torch: /workspace/libtorch/lib/libtorch.so
-- Found INTEL_EXT_PT_CPU: TRUE
-- Configuring done
-- Generating done
-- Build files have been written to: /workspace/build

$ ldd example-app
        ...
        libtorch.so => /workspace/libtorch/lib/libtorch.so (0x00007f3cf98e0000)
        libc10.so => /workspace/libtorch/lib/libc10.so (0x00007f3cf985a000)
        libintel-ext-pt-cpu.so => /workspace/libtorch/lib/libintel-ext-pt-cpu.so (0x00007f3cf70fc000)
        libtorch_cpu.so => /workspace/libtorch/lib/libtorch_cpu.so (0x00007f3ce16ac000)
        ...
        libdnnl_graph.so.0 => /workspace/libtorch/lib/libdnnl_graph.so.0 (0x00007f3cde954000)
        ...

模型库 (仅限 CPU)

已由 Intel 工程师优化的用例可在面向 Intel® 架构的模型库中找到 (分支名称格式为 pytorch-r<版本>-models)。该 GitHub 页面还提供了许多用于基准测试的 PyTorch 用例。只需运行模型库中的脚本,您就可以获得开箱即用的性能优势。

教程

更详细的教程可在 面向 PyTorch* 的 Intel® 扩展程序 官方文档中找到


评价此教程

© Copyright 2024, PyTorch。

使用 Sphinx 构建,主题由 Read the Docs 提供。

文档

访问 PyTorch 的全面开发者文档

查看文档

教程

获取面向初学者和高级开发者的深入教程

查看教程

资源

查找开发资源并获得问题解答

查看资源