我们刚刚发布了Poplar SDK 1.4和首次产品化发布的面向IPU的PyTorch。
我们的连接库被称为PopTorch,它将IPU-M2000平台的性能与PyTorch的开发人员可访问性结合在了一起。
这种紧密耦合的解决方案允许用户只更改几行代码即可在IPU上运行标准PyTorch程序:
import torch
import poptorch
在向PyTorch开发人员开放Graphcore技术时,我们把为下一代模型的需求而设计的最先进的AI计算平台与已经成为机器智能创新代名词的框架整合在了一起。
对于PyTorch的支持最早于2020年初提供试用版本。此后,它根据开发人员的反馈进行了广泛的改进,因此此次发行的版本不仅是团队合作的成果,也是更广泛的PyTorch社区的成果。
开源
我们继续秉承以社区为中心的产品开发主题,正在开放面向IPU的PyTorch源代码,其代码可在GitHub上获得。一旦接受我们的贡献者许可协议(CLA),就可以通过标准的GitHub拉取请求做出贡献。
除了帮助完善和加速面向IPU的PyTorch的进化外,开放源代码还使开发人员可以深入研究我们的代码,从而了解Graphcore更广泛的硬件和软件产品是如何运作的。
我们对开源的承诺延伸到Poplar软件栈,包括Poplar库(PopLibs™)、PopART™和面向IPU的TensorFlow端口。
主要功能
面向IPU的PyTorch是PyTorch程序的简单包装层,使这些程序可以在Graphcore IPU上运行模型,以进行训练和推理。
当使用多个IPU时,各个层都包裹在一个IPU帮助程序中,该IPU帮助程序指定了目标IPU。然后通过PopART对模型进行并行化。
PyTorch模型通过Graphcore的软件栈传递下来,通过计算图编译器。计算图编译器对工作负载进行调度,以在可用IPU上执行。
面向IPU的PyTorch接口库支持开发人员在其他硬件平台上所熟知的流行功能,并具有一些附加功能:
- 支持推理和训练
- 数据和模型的并行支持,模型复制到最多64个IPU
- 优化的主机数据加载器支持
- 具有FLOAT32、FLOAT16、INT32、INT64和BOOL数据类型的FP32.32、FP16.32、FP16.16精度
- 支持流行的优化器、SGD、RMSprop、AdamW、LAMB以及支持float16模型的功能,例如损耗缩放
- 广泛的PyTorch损失函数覆盖范围,支持任意损失函数
- 多卷积支持
- 实施定制优化运算符的能力
- 面向IPU的PyTorch Docker容器
- Graphcore的PopVision分析工具提供的全面支持
- 可从https://github.com/graphcore/examples获取示例和教程
Poplar SDK 1.4的其他功能
除了面向IPU的PyTorch的产品化版本的发布和开源,我们的Poplar SDK 1.4还提供了许多其他功能,包括:
- Poplar编译器的重大优化,以减少编译时间,加快开发速度。通过Kernel级别的优化以利用MK2 IPU架构优势实现更大的批尺寸和更大的模型覆盖范围
- 优化的分布式部署工具,包括分布式配置库,可改善跨多个IPU-POD系统的数据并行应用的横向扩展
- 新的PopVision系统分析器可以更好地理解和优化大型分布式系统
- 更详细的报告功能,可以更好地了解和优化PopVision计算图分析工具2.2中的模型
- 额外的ONNX运算器覆盖和模型支持
Poplar SDK 1.4中的试用功能
- 使用动态/可重新配置的稀疏性模式更新的稀疏性Kernel库
- 对于CentOS 8的支持
- 对于Ubuntu 20.04的支持
PyTorch入门
面向IPU的PyTorch旨在最大程度减少PyTorch模型所需手动改动。此示例显示了IPU上使用标准预训练的BERT PyTorch模型执行推理所需的代码更改(以注释形式)。
<?php
# Use huggingface transformer library
import transformers
import torch
import poptorch
...
# Pre-trained model and tokenizer.
tokenizer = transformers.BertTokenizer.from_pretrained(
'mrm8488/bert-medium-finetuned-squadv2', return_token_type_ids=True)
model = transformers.BertForQuestionAnswering.from_pretrained(
'mrm8488/bert-medium-finetuned-squadv2')
# Read context/questions from file. Pad last batch with empty question if required
context = context_file.read()
questions = questions_file.readlines()
questions = [q.rstrip() for q in questions]
questions += [""] * (len(questions) % options.batch_size)
num_questions = len(questions)
# Pipeline the model over two IPUs.
model.bert.embeddings.position_embeddings = poptorch.BeginBlock(
layer_to_call=model.bert.embeddings.position_embeddings, ipu_id=1)
# Wrap PyTorch model inside a PopTorch InferenceModel. This will make the model run on the IPU.
opts = poptorch.Options().deviceIterations(batch_size)
inference_model = poptorch.inferenceModel(model, options=opts)
# Process inputs in batches.
for batch_idx in range(num_batches):
# Use tokenizer to get input and then convert to PyTorch tensors.
input_pairs = [(questions[batch_size*batch_idx + i], context) for i in range(batch_size)]
batched_encoding = tokenizer.batch_encode_plus(input_pairs, max_length=110,
pad_to_max_length='right')
input_batch = torch.tensor(batched_encoding["input_ids"])
attention_batch = torch.tensor(batched_encoding["attention_mask"])
# Execute on IPU.
start_score_pop, end_scores_pop = inference_model(input_batch, attention_batch)
# Process outputs.
for i, (start_score, end_score) in enumerate(zip(start_score_pop, end_scores_pop)):
answer_start, answer_stop = start_score.argmax(), end_score.argmax()
answer_ids = input_batch[i][answer_start:answer_stop + 1]
answer_tokens = tokenizer.convert_ids_to_tokens(answer_ids, skip_special_tokens=True)
answer = tokenizer.convert_tokens_to_string(answer_tokens)
print(f"Question: {questions[batch_size*batch_idx + i]}")
print(f"Answer: {answer}")
PyTorch模型的支持和性能
我们今天还发布了IPU-M2000系统的新的benchmark,包括一些PyTorch的训练和推理结果。我们还在GitHub上提供了一系列模型的参考实施。在大多数情况下,模型只需要很少的代码更改即可运行IPU系统。我们将定期在我们的网站上添加更多基于PyTorch的性能结果,并在GitHub上添加代码示例,敬请定期查阅。
下方视频中涵盖了一个面向IPU的简单PyTorch教程:
其他PyTorch上面的IPU资源