即刻体验!在飞桨 x Graphcore IPU上运行训练与推理任务 | 洞见AI硬件

飞桨框架(PaddlePaddle)现在可以支持Graphcore的IPU处理器了!在过去的几个月里, 通过飞桨研发团队与Graphcore China CE团队的不懈努力,已经初步完成了IPU与飞桨框架的适配工作。目前,用户可以在飞桨框架选择IPU硬件作为后端做深度学习的训练或推理任务。

本篇文章中,我们会详细演示基于Graphcore IPU的安装、训练和推理流程;本期的第二篇文章『飞桨 x Graphcore IPU适配方案深度解读与硬件介绍 』中,我们还会进一步介绍飞桨与Graphcore的适配初衷、适配的方案设计,以及关于Graphcore IPU的详细解读。

关于GraphCore

与飞桨的合作

Graphcore在2016年成立于英国,其智能处理器(IPU)硬件和Poplar软件帮助创新者在机器智能方面实现了新突破。IPU是第一个专为机器智能设计的处理器,与通常用于人工智能的其他计算硬件相比,具有显著的性能优势。

飞桨框架通过与Graphcore的适配合作,可以让广大开发者以极低的学习成本即可使用Graphcore出众的软硬件产品,真正做到以灵活的硬件后端和完善的功能助力开发者快速实现AI想法,上线AI业务,帮助越来越多的行业完成AI赋能,实现产业智能化升级。

在本期的第二篇文章中,会有更多关于本次适配架构的说明,以及关于Graphcore IPU的详细解读。

e76779415709588ae72e03feeec20580.png


如何开始 

(How to get started)


环境准备

Graphcore的Poplar SDK对硬件、操作系统以及软件环境均有一定的要求,具体参见:https://docs.graphcore.ai/projects/sdk-overview/en/latest/overview.html#requirements

通过源码编译安装

(1)下载源码

git clone -b paddle_bert_release https://github.com/graphcore/Paddle.git

(2)构建 Docker 镜像

docker build -t paddlepaddle/paddle:dev-ipu-2.3.0 \
-f tools/dockerfile/Dockerfile.ipu .

(3)创建并运行 Docker container

IPU依赖于ipu.conf配置文件进行分区,需要有可用的ipu.conf才能获取IPU设备。如果没有ipu.conf,可参考如下命令生成。

# 例:生成POD16(16个IPU)配置文件:
vipu create partition ipu --size 16
ipu.conf将会生成在以下路径:
ls ~/.ipuof.conf.d/

(4)启动Docker并编译环境

请将以下命令的${HOST_IPUOF_PATH}替换成host中ipu.conf的绝对路径。

docker run --ulimit memlock=-1:-1 --net=host --cap-add=IPC_LOCK \
--device=/dev/infiniband/ --ipc=host --name paddle-ipu-dev \
-v ${HOST_IPUOF_PATH}:/ipuof \
-e IPUOF_CONFIG_PATH=/ipuof/ipu.conf \
-it paddlepaddle/paddle:dev-ipu-2.3.0 bash

【注意:之后的操作均在container内执行。】

(5)(可选)验证IPU设备

通过以下命令可以查看当前全部IPU设备,以及正在使用的IPU设备ID

gc-monitor

出现以下图片说明正常获取IPU设备。如果没办法获取IPU设备,请检查是否提供正确的ipu.conf。

d0e6d01e52e773c7b0286248e54071c4.png

(6)编译飞桨框架

git clone -b paddle_bert_release https://github.com/graphcore/Paddle.git

cd Paddle 

cmake -DPYTHON_EXECUTABLE=/usr/bin/python \
-DWITH_PYTHON=ON -DWITH_IPU=ON -DPOPLAR_DIR=/opt/poplar \
-DPOPART_DIR=/opt/popart -G "Unix Makefiles" -H`pwd` -B`pwd`/build   

cmake --build \`pwd`/build --config Release --target paddle_python -j$(nproc)

(7)安装wheel包

pip install -U build/python/dist/paddlepaddle-0.0.0-cp37-cp37m-linux_x86_64.whl

(8)验证安装

python -c "import paddle; print(paddle.fluid.is_compiled_with_ipu())"

预期得到以下结果:

> True

目前Graphcore的IPU支持通过飞桨框架做大规模的模型训练任务,也支持通过Paddle Inference库执行高性能的推理任务。

BERT-Base 训练体验

Demo示例获取:

https://github.com/graphcore/portfolio-examples/tree/master/paddlepaddle/bert-base

Bert-Base Training 包含以下任务:

- phase1: sequence_length=128预训练
- phase2: sequence_length=384预训练
- SQuAD fine-tune
- SQuAD validation

数据准备

(1)预训练数据生成

git clone https://github.com/NVIDIA/DeepLearningExamples.git

cd DeepLearningExamples/TensorFlow/LanguageModeling/BERT

bash scripts/docker/build.sh

打开脚本并修改生成数据的配置

cd data/ 
vim create_datasets_from_start.sh

修改line 40 --max_seq_length 512 成--max_seq_length 384修改line 41 -- max_predictions_per_seq 80 成--max_predictions_per_se 56

cd ../ 
bash scripts/data_download.sh wiki_only

运行后将生成sequence_length=128 和 384的输入数据。

(2)准备SQuAD数据集

Stanford Question Answering Dataset (SQuAD) 是一个包含了特定范围内的维基百科内容,规模大且质量高的阅读理解数据集。SQuAD的答案是text span,即以文章原文中的某小一段文字来作为问题的答案,这种形式是首次在同类数据集中提出。

  • Fine-tune dataset:

curl --create-dirs -L https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v1.1.json -o data/squad/train-v1.1.json
  • Validation dataset:

curl --create-dirs -L https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v1.1.json -o data/squad/dev-v1.1.json

PaddleNLP环境准备

本例除了依赖飞桨框架(已在上文中安装),还依赖PaddleNLP做模型构建和数据处理。请按照如下操作安装PaddleNLP:

(1)安装依赖:

pip3.7 install jieba h5py colorlog colorama seqeval multiprocess numpy==1.19.2 paddlefsl==1.0.0 six==1.13.0 wandb

pip3.7 install torch==1.7.0+cpu -f https://download.pytorch.org/whl/cpu/torch_stable.html

pip3.7 install torch-xla@https://storage.googleapis.com/tpu-pytorch/wheels/torch_xla-1.7-cp37-cp37m-linux_x86_64.whl

(2)安装PaddleNLP

pip3.7 install git+https://github.com/graphcore/PaddleNLP.git@paddle_bert_release

开始训练

修改run_stage.sh中的--input_dir为对应的输入数据路径:

  • Phase1: tfrecord(sequence_length=128)文件的存放路径;

  • Phase2: tfrecord(sequence_length=384)文件的存放路径;

  • Fine-tune: train-v1.1.json的存放路径;

  • Validation: dev-v1.1.json的存放路径。

run_stage.sh有4个参数:

  • device: ipu 或 cpu;

  • stage: phase1, phase2, SQuAD或validation;

  • input_pdparams: 导入的pdparams的路径+前缀;

  • output_pdparams: 导出的pdparams的路径+前缀。

【注意:程序中有使用wandb记录运行数据,运行时会弹出如下提示,需要选择对应的模式运行。如果没有wandb账号请输入3。】

Run Phase1:

Phase1不需要导入params,随机初始化权重

./run_stage.sh ipu phase1 _ pretrained_128_model

Run Phase2:

Phase2需要导入phase1训练好的params

./run_stage.sh ipu phase2 pretrained_128_model pretrained_384_model

Run SQuAD fine-tune:

fine-tune需要导入phase2训练好的params

./run_stage.sh ipu SQuAD pretrained_384_model finetune_model

Run validation:

./run_stage.sh ipu validation finetune_model _



BERT-Base

精度与性能 

目前Graphcore的IPU支持通过飞桨框架做大规模的模型训练任务,也支持通过Paddle Inference库执行高性能的推理任务。

BERT训练 (BERT trainning)

Pretrain Phase1 (sequence_length=128):

03c2af5be13ccb44e971793bbf91796d.png

a8c525c6abf09cf04f323e287c344646.png

Pretrain Phase2 (sequence_length=384):

773d9d6eee2500bd123a74643a6b1cbd.png

44403c111a669d933cd5cf81691b839a.png

SQuAD:

a36a3377c3955d375d5b5306c667eb97.png

b26d5bb77961febcc78b4337f6cb109b.png

Paddle Inference 推理 (FP16)

06ee90fd5cebd6a4a29ad2499dfcbd49.png


word2vec推理演示

生成Paddle Inference原生推理库

基于之前的飞桨编译命令增加-DON_INFER=ON,编译完成后将在build目录下生成 paddle_inference_install_dir目录。该目录为Paddle Inference库目录。

cmake -DPYTHON_EXECUTABLE=/usr/bin/python \
-DWITH_PYTHON=ON –DON_INFER=ON -DWITH_IPU=ON -DPOPLAR_DIR=/opt/poplar \
-DPOPART_DIR=/opt/popart -G "Unix Makefiles" -H`pwd` -B`pwd`/build   

cmake --build \`pwd`/build --config Release --target paddle_python -j$(nproc)

#目录如下:

130545295d9de3f4a7edb4e45267b843.png

可参考以下ipu_word2vec_sample.cc使用Paddle Inference库进行推理:

下载模型:

wget -q http://paddle-inference-dist.bj.bcebos.com/word2vec.Inference.model.tar.gz

编写Paddle Inference推理代码

#include <iostream>
#include <vector>
#include <numeric>
#include <string>

#include "paddle/fluid/inference/api/paddle_inference_api.h"
#include "gflags/gflags.h"
#include "glog/logging.h"

DEFINE_string(infer_model, "", "Directory of the inference model.");

using paddle_infer::Config;
using paddle_infer::Predictor;
using paddle_infer::CreatePredictor;

void inference(std::string model_path, bool use_ipu, std::vector<float> *out_data) {
//# 1. Create Predictor with a config.
Config config;
config.SetModel(FLAGS_infer_model);
if (use_ipu) {
// ipu_device_num, ipu_micro_batch_size
config.EnableIpu(1, 4);
}
auto predictor = CreatePredictor(config);

//# 2. Prepare input/output tensor.
auto input_names = predictor->GetInputNames();
std::vector<int64_t> data{1, 2, 3, 4};
// For simplicity, we set all the slots with the same data.
for (auto input_name : input_names) {
auto input_tensor = predictor->GetInputHandle(input_name);
input_tensor->Reshape({4, 1});
input_tensor->CopyFromCpu(data.data());
}

//# 3. Run
predictor->Run();

//# 4. Get output.
auto output_names = predictor->GetOutputNames();
auto output_tensor = predictor->GetOutputHandle(output_names[0]);
std::vector<int> output_shape = output_tensor->shape();
int out_num = std::accumulate(output_shape.begin(), output_shape.end(), 1,
std::multiplies<int>());
out_data->resize(out_num);
output_tensor->CopyToCpu(out_data->data());
}

int main(int argc, char *argv[]) {
::GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, true);
std::vector<float> ipu_result;
std::vector<float> cpu_result;
inference(FLAGS_infer_model, true, &ipu_result);
inference(FLAGS_infer_model, false, &cpu_result);
for (size_t i = 0; i < ipu_result.size(); i++) {
CHECK_NEAR(ipu_result[i], cpu_result[i], 1e-6);
}
LOG(INFO) << "Finished";
}

编译生成推理Demo程序

编译方法:

CMakeList.txt:
cmake_minimum_required(VERSION 3.0)
project(cpp_inference_demo CXX C)

include_directories("${PADDLE_LIB}/")
set(PADDLE_LIB_THIRD_PARTY_PATH "${PADDLE_LIB}/third_party/install/")
include_directories("${PADDLE_LIB_THIRD_PARTY_PATH}protobuf/include")
include_directories("${PADDLE_LIB_THIRD_PARTY_PATH}glog/include")
include_directories("${PADDLE_LIB_THIRD_PARTY_PATH}gflags/include")
include_directories("${PADDLE_LIB_THIRD_PARTY_PATH}xxhash/include")
include_directories("${PADDLE_LIB_THIRD_PARTY_PATH}cryptopp/include")
include_directories("${PADDLE_LIB_THIRD_PARTY_PATH}mkldnn/include")
include_directories("${PADDLE_LIB_THIRD_PARTY_PATH}mklml/include")

link_directories("${PADDLE_LIB_THIRD_PARTY_PATH}protobuf/lib")
link_directories("${PADDLE_LIB_THIRD_PARTY_PATH}glog/lib")
link_directories("${PADDLE_LIB_THIRD_PARTY_PATH}gflags/lib")
link_directories("${PADDLE_LIB_THIRD_PARTY_PATH}xxhash/lib")
link_directories("${PADDLE_LIB_THIRD_PARTY_PATH}cryptopp/lib")
link_directories("${PADDLE_LIB_THIRD_PARTY_PATH}ipu")
link_directories("/opt/poplar/lib")
link_directories("/opt/popart/lib")
link_directories("${PADDLE_LIB}/paddle/lib")

set(EXTERNAL_LIB "-lrt -ldl -lpthread")
set(DEPS ${DEPS}
${PADDLE_LIB_THIRD_PARTY_PATH}mkldnn/lib/libdnnl.so.2 
${PADDLE_LIB_THIRD_PARTY_PATH}mklml/lib/libiomp5.so 
paddle_inference paddle_ipu flags
glog gflags protobuf xxhash cryptopp
${EXTERNAL_LIB})
set(CMAKE_CXX_FLAGS "-std=c++11")

add_executable(${DEMO_NAME} ${DEMO_NAME}.cc)
target_link_libraries(${DEMO_NAME} ${DEPS})

编译脚本compile.sh:

【注意:请将${PADDLE_INFERENCE_INSTALL_DIR}替换为对应的Paddle Inference库路径】

#!/bin/bash
mkdir -p build
cd build
rm -rf *

DEMO_NAME=ipu_word2vec_sample
LIB_DIR=${PADDLE_INFERENCE_INSTALL_DIR}
cmake .. -DPADDLE_LIB=${LIB_DIR} -DDEMO_NAME=${DEMO_NAME}
make –j

编译:

./compile.sh

本测例将会分别完成IPU和CPU的推理,并对比两者结果

./ipu_word2vec_sample –-infer_model=word2vec.inference.model

其他Demo体验

MNIST demo

https://github.com/graphcore/Paddle_internal/issues/312

相关资料 (links)

https://www.paddlepaddle.org.cn/

https://github.com/PaddlePaddle/Paddle

2a20581c1270a6a4f48f21ad672a2add.gif

关注公众号,获取更多技术内容~

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值