Certamente a maioria dos desenvolvedores de soluções ainda estão na fase de "aprender onde colocar a inteligência artificial". Esta fase é de fato difícil e complicada, porém existem outras situações igualmente difíceis como por exemplo, implantar um modelo treinado de aprendizado profundo (Deep Learning) em produção. Se houver um requisito de baixa latência e alto rendimento, implantar esse sistema pode se tornar um grande problema. Existem várias alternativas. Neste documento trateremos de uma delas por meio do uso do TensorRT, uma biblioteca de baixo nível C++ capaz de absorver modelos já compilados do tensorflow e tratar situações onde é necessário processar muitas imagens em pouco tempo. Vejam o ganho de desempenho no demonstrativo abaixo:

Veja como a mágica aconteçe.
Passo 1. Ambiente
Ubuntu 16.04, Python 2.7, CUDA 9.0 (cudnn 7.0), Tensorflow 1.4+ com GPU. Instale o TensorRT 3.0 (Incluindo Python lib)
Vale citar que o tensorRT integra o tensorflow 1.7 https://developers.googleblog.com/2018/03/tensorrt-integration-with-tensorflow.html
Passo 2. Exportando o modelo do tensorflow parao formato UFF
Vamos usar o modelo compilado da VGG-16 do módulo tf.keras.applications module
# Importa libsimport uffimport tensorflow as tf
# Cria uma sessão TF e grafo VGG-16model = tf.keras.applications.VGG16(include_top=True)
# Inicializa as variáveis e carrega os pessos da rede de um modelo treinadomodel.load_weights('~/.keras/models/vgg16_weights_tf_dim_ordering_tf_kernels.h5')
model_input = model.input.name.strip(':0')model_output = model.output.name.strip(':0')
print(model_input, model_output)# expect(u'input_1', u'predictions/Softmax')
# Obtém a definição do grafograph = tf.get_default_graph().as_graph_def()# Algo semelhante a isso:# node {# name: "input_1"# op: "Placeholder"# attr {# key: "dtype"# value {# type: DT_FLOAT# }# }# attr {# etc...
# Obtém a sessãosess = tf.keras.backend.get_session()
# Congela o grafo e remove os nós que são usados somente para treinamentofrozen_graph = tf.graph_util.convert_variables_to_constants(sess, graph, [model_output])frozen_graph = tf.graph_util.remove_training_nodes(frozen_graph)
# Cria um modelo UFF a partir do grafouff_model = uff.from_tensorflow(frozen_graph, [model_output])dump = open('VGG16.uff', 'wb')dump.write(uff_model)dump.close()
Passo 3. Realizando inferência com tensorRT
import pycuda.driver as cudaimport pycuda.autoinitimport argparse
from keras.preprocessing import imagefrom keras.applications.vgg16 import preprocess_input, decode_predictions
import tensorrt as trtfrom tensorrt.parsers import uffparser
import numpy as npimport matplotlib.pyplot as plt%matplotlib inline
# Função auxiliar para realizar a inferênciadef infer(context, input_img, batch_size):# carrega a engineengine = context.get_engine()assert(engine.get_nb_bindings() == 2)# Cria um vetor de saídadims = engine.get_binding_dimensions(1).to_DimsCHW()elt_count = dims.C() * dims.H() * dims.W() * batch_size# Converte a entrada para o formato Float32input_img = input_img.astype(np.float32)# Alocação de memóriaoutput = cuda.pagelocked_empty(elt_count, dtype=np.float32)
# Alocação de memória na gpud_input = cuda.mem_alloc(batch_size * input_img.size * input_img.dtype.itemsize)d_output = cuda.mem_alloc(batch_size * output.size * output.dtype.itemsize)
bindings = [int(d_input), int(d_output)]
stream = cuda.Stream()
# transfere os dados para a gpucuda.memcpy_htod_async(d_input, input_img, stream)# executa o modelocontext.enqueue(batch_size, bindings, stream.handle, None)# devolve o resultado da prediçãocuda.memcpy_dtoh_async(output, d_output, stream)
#return output
# carrega o modelo no formato UFFuff_model = open('VGG16.uff', 'rb').read()
# Cria o parse do modeloparser = uffparser.create_uff_parser()parser.register_input("input_1", (3, 224, 224), 0)parser.register_output("predictions/Softmax")
# Cria a engine e sessãotrt_logger = trt.infer.ConsoleLogger(trt.infer.LogSeverity.INFO)
engine = trt.utils.uff_to_trt_engine(logger=trt_logger,stream=uff_model,parser=parser,max_batch_size=1, # 1 imagem por vezmax_workspace_size= 1 << 30, # 1 GB GPU memóriadatatype=trt.infer.DataType.FLOAT)
context = engine.create_execution_context()
Passo 4. Testando...
# Carrega e preprocessa a imagemtest_image = image.load_img('imagem.jpg', target_size=(224, 224, 3))test_image = image.img_to_array(test_image)processed_im = preprocess_input(np.expand_dims(test_image, 0))[0, :, :, :]
# prepara a imagem para RT engineprocessed_im = np.transpose(processed_im, axes=(2, 0, 1))processed_im = processed_im.copy(order='C')
# realiza a inferênciaprediction_proba = infer(context, processed_im, 1)
decode_predictions(np.expand_dims(prediction_proba, 0))
Links relevantes:
https://docs.nvidia.com/deeplearning/sdk/tensorrt-api/topics/topics/index.html
https://devblogs.nvidia.com/tensorrt-3-faster-tensorflow-inference/
https://medium.com/@fortyq/tensorrt-becomes-a-valuable-tool-for-data-scientist-64cf1b764df2
