生活中不少經驗告訴咱們,不少狀況下,一些「專用」的東西,每每比「通用」的在執行具體任務時效果更好,例如爲了分擔 CPU 負載,實現更強圖形處理性能,電腦開始配置專用的圖形處理器 GPU。這兩年,隨着機器學習技術的火熱,人們發現,用 GPU 來進行 ML 模型的訓練也是一種比較好的作法,速度更快,性能更強。python
然而畢竟 GPU 誕生的本意就是用於處理計算機圖像的,並不是「AI」專用,那麼有沒有專供機器學習使用的芯片,能夠實現比 GPU 訓練更快的速度,以及更低的成本?git
2019年末進行的年度 AWS re:Invent 大會上,最使人激動的新發布之一就是正式推出 AWS 本身設計和打造的 Inferentia 芯片,以更低成本提供更高性能的機器學習推理能力。github
機器學習推理是使用通過訓練的模型作出預測的流程。經統計,在機器學習應用程序中,推理最多可以佔到總成本的90%。其緣由有二:緩存
對於機器學習推理而言,AWS Inferentia 芯片的優點能夠總結爲:高性能,低延遲,高易用。網絡
基於 AWS Inferentia 芯片,AWS 在雲端提供了 EC2 Inf1 實例,將 Inferentia 芯片與 AWS Nitro 虛擬化管理程序、最新的第二代定製 Intel Xeon 可擴展處理器,以及高達 100Gbps 的網絡相結合,以實現高吞吐量推理。這一配置使 Inf1 實例提供了 Amazon EC2 G4 實例3倍的吞吐量和40%推理成本的下降(基於使用 TensorFlow 端到端運行 BERT 模型的結果)。session
Inf1 實例的規格以下表所示。
app
使用 AWS Inferentia 進行機器學習的典型流程以下圖所示。一般,咱們會在 GPU 實例上訓練機器學習模型,以後把訓練好的模型利用 AWS Neuron 從新編譯,而後將此模型交付給 Inf1 實例(AWS Inferentia 芯片)執行機器學習推理。框架
下面,咱們經過一個樣例來看看如何使用 AWS Neuron 在 AWS Inferentia 芯片上進行機器學習推理。curl
在這裏,咱們會用到 AWS Deep Learning AMI,它能夠在 Amazon EC2 上一鍵式安裝機器學習的各類框架工具,從而加快在雲中進行機器學習的速度。最新的 Deep Learning AMI 已支持 AWS Inferentia,並附帶 AWS Neuron 開發所需的工具包(Neuron SDK)。機器學習
咱們在 us-west-2 區域以 Deep Learning AMI (Ubuntu 18.04) Version 27.0 – ami-008d8ed4bd7dc2485 作爲系統鏡像,啓動 Inf1.2xlarge 實例。啓動 Inf1 實例後,使用如下命令升級到最新版 Neuron 運行時環境和工具包:
$ sudo apt-get update $ sudo apt-get install aws-neuron-runtime $ sudo apt-get install aws-neuron-tools
隨後咱們就能用 neuron-ls 命令顯示 Inf1 實例上的 Inferentia 芯片數量和信息:
$ neuron-ls +--------------+---------+--------+-----------+-----------+------+------+ | PCI BDF | LOGICAL | NEURON | MEMORY | MEMORY | EAST | WEST | | | ID | CORES | CHANNEL 0 | CHANNEL 1 | | | +--------------+---------+--------+-----------+-----------+------+------+ | 0000:00:1f.0 | 0 | 4 | 4096 MB | 4096 MB | 0 | 0 | +--------------+---------+--------+-----------+-----------+------+------+
在輸出的表格中,第一列顯示了 PCI 總線設備功能 ID。第二列顯示分配給設備的邏輯 ID。這個邏輯 ID 在 Neuron 運行時守護進程 (Runtime Daemon)(Neuron rtd)配置期間使用。第三列顯示可用的 Neuron Core 數量。最後兩列顯示與任何其餘 Inferentia 設備的鏈接。
由於咱們選擇的 Inf1.2xlarge 只有一個 Inferentia 芯片,因此這兩列爲空(若是啓動 Inf1.6xlarge 或 Inf1.24xlarge 這兩種帶有多個 Inferentia 芯片的實例,這兩列會顯示 Inferentia 芯片的互聯信息)。
搭建好環境後,來看一下如何使用 AWS Neuron 和 Tensorflow 進行深度學習推理。整個過程分爲兩個階段:編譯階段和推理階段。
在第一階段,咱們將編譯 TensorFlow Neuron 中預訓練的 Keras ResNet50 模型,並將其導出爲 SavedModel,一種 TensorFlow 模型的交換格式。
首先激活 TensorFlow-Neuron conda 虛擬環境。使用虛擬環境可以確保在使用深度學習框架時對包的管理有最佳的靈活性,這也是深度學習的一個最佳實踐。
$ source activate aws_neuron_tensorflow_p36
隨後使用如下命令更新 Neuron 包到最新版本:
$ conda update tensorflow-neuron
接下來,建立一個名爲 tensorflow_compile_resnet50.py 的 Python 腳本,此 Python 腳本使用 AWS Neuron 編譯 Keras ResNet50 模型,並將其導出爲 TensorFlow SavedModel 格式。
import os import time import shutil import tensorflow as tf import tensorflow.neuron as tfn import tensorflow.compat.v1.keras as keras from tensorflow.keras.applications.resnet50 import ResNet50 from tensorflow.keras.applications.resnet50 import preprocess_input # Create a workspace WORKSPACE = './ws_resnet50' os.makedirs(WORKSPACE, exist_ok=True) # Prepare export directory (old one removed) model_dir = os.path.join(WORKSPACE, 'resnet50') compiled_model_dir = os.path.join(WORKSPACE, 'resnet50_neuron') shutil.rmtree(model_dir, ignore_errors=True) shutil.rmtree(compiled_model_dir, ignore_errors=True) # Instantiate Keras ResNet50 model keras.backend.set_learning_phase(0) model = ResNet50(weights='imagenet') # Export SavedModel tf.saved_model.simple_save( session = keras.backend.get_session(), export_dir = model_dir, inputs = {'input': model.inputs[0]}, outputs = {'output': model.outputs[0]}) # Compile using Neuron tfn.saved_model.compile(model_dir, compiled_model_dir, compiler_args =['--num-neuroncores', '4']) # Prepare SavedModel for uploading to Inf1 instance shutil.make_archive(compiled_model_dir, 'zip', WORKSPACE, 'resnet50_neuron')
這裏有兩點須要注意:
隨後使用如下命令編譯模型:
$ python tensorflow_compile_resnet50.py
編譯過程大約須要幾分鐘時間,輸出應包含以下信息:
... INFO:tensorflow:fusing subgraph neuron_op_d6f098c01c780733 with neuron-cc INFO:tensorflow:Number of operations in TensorFlow session: 4638 INFO:tensorflow:Number of operations after tf.neuron optimizations: 556 INFO:tensorflow:Number of operations placed on Neuron runtime: 554 INFO:tensorflow:Successfully converted ./ws_resnet50/resnet50 to ./ws_resnet50/resnet50_neuron ...
編譯後,保存的模型以壓縮格式存儲在 ws_resnet50/resnet50_neuron.zip,使用如下命令解壓縮模型:
$ unzip ws_resnet50/resnet50_neuron.zip -d .
在第二階段,咱們會使用在第一階段編譯的推理模型在示例圖像上運行推理。
首先,下載一幅用於推理的示例圖像:
$ curl -O https://raw.githubusercontent.com/awslabs/mxnet-model-server/master/docs/images/kitten_small.jpg
隨後建立一個名爲 tensorflow_infer_resnet50.py 的 Python 腳本,該腳本包含如下內容,使用在第一階段編譯好的模型在 AWS Inferentia 上進行推理。
import os import numpy as np import tensorflow as tf from tensorflow.keras.preprocessing import image from tensorflow.keras.applications import resnet50 # Create input from image img_sgl = image.load_img('kitten_small.jpg', target_size=(224, 224)) img_arr = image.img_to_array(img_sgl) img_arr2 = np.expand_dims(img_arr, axis=0) img_arr3 = resnet50.preprocess_input(img_arr2) # Load model COMPILED_MODEL_DIR = './resnet50_neuron/' predictor_inferentia = tf.contrib.predictor.from_saved_model(COMPILED_MODEL_DIR) # Run inference model_feed_dict={'input': img_arr3} infa_rslts = predictor_inferentia(model_feed_dict); # Display results print(resnet50.decode_predictions(infa_rslts["output"], top=5)[0])
這樣,咱們就可使用如下命令運行推理操做:
$ python tensorflow_infer_resnet50.py
輸出應該以下所示:
... [('n02123045', 'tabby', 0.6918919), ('n02127052', 'lynx', 0.12770271), ('n02123159', 'tiger_cat', 0.08277027), ('n02124075', 'Egyptian_cat', 0.06418919), ('n02128757', 'snow_leopard', 0.009290541)]
經過上述樣例,咱們看到了使用 AWS Neuron SDK 在 AWS Inferentia 芯片上進行機器學習推理的全過程,也但願藉此可以幫助你們把更多的機器學習應用在雲端部署以得到最佳的體驗。