基于huggingface的transformers的实现,支持不同的模型加载方式native,onnx,jit,libtorch(c++),native c++(fastertransformer和其他c++版实现),tensorRT,tensorflow serving共七种方式。 (1)统一的请求接口设计 核心接口代码如下: #预处理:载入分词器 from transformers import AutoTokenizer tokenizer = AutoTokenizer.from_pretrained('bert-base-uncased') #测试文本 text = '[CLS] In deep [MASK], everything is amazing![SEP]' #分词 tokenized_text = tokenizer.tokenize(text) #token2id indexed_tokens = tokenizer.convert_tokens_to_ids(tokenized_text) #服务请求url='' post(url) 得益于transformers的优雅的接口设计,可以利用两行代码加载分词器,类似的,可以用两行代码加载模型:
(2)不同的inference方式 (2.1)native import torch from transformers import AutoModelForMaskedLM model = AutoModelForMaskedLM.from_pretrained('bert-base-uncased') with torch.no_grad(): output = model(tokens.to(device))[0].detach().cpu() output = torch.softmax(output[0][idx_to_predict], 0) (2.2)onnx
import onnxruntime onnx_session = onnxruntime.InferenceSession(model_path) ort_inputs = {onnx_session.get_inputs()[0].name: tokens} ort_outs = onnx_session.run(None, ort_inputs) output = np.array(ort_outs)[0][0] output = softmax(output[idx_to_predict]) (2.3)jit
model = torch.jit.load(model_path) with torch.no_grad(): output = model(tokens.to(device))[0].detach().cpu() output = torch.softmax(output[0][idx_to_predict], 0) (2.4)libtorch(c++)
(2.5)其他三种方式暂未测试 (3)评测结果
参考资料: (1)https://github.com/LeeJuly30/BERTCpp 转换pytorch的预训练模型到pb文件,用C++去加载 (2)知乎的BERT加速工作:https://github.com/zhihu/cuBERT 上述工作间接参考本工作,工作比较底层(C++/CUDA) (3)《那一年,让我整个人升华的C++BERT项目》 讲述了一个小姐姐用BERT做C++改造的故事: https://www.sohu.com/a/451088664_115128 (4)https://github.com/renatoviolin/BERT-cpp-inference (5)《Pytorch的C++前端和模型部署》 https://zhpmatrix./2019/03/01/c++-with-pytorch/,笔者很久之前的博客 (6)《直观认识torch.jit模块》 https://zhpmatrix./2019/03/09/torch-jit-pytorch/,笔者很久之前的博客 (7)https://github.com/ShannonAI/service-streamer 工程色彩比较浓重的工作 (8)《模型热更新小记》,与本篇主题不直接相关,但是很有意思 https://mp.weixin.qq.com/s?__biz=MjM5ODkzMzMwMQ==&mid=2650422670&idx=4&sn=da643a8b2810865ab30d2f530077ff06&chksm=becdbbd489ba32c2633e41212a8cae5d48f61f9022705e37997a165583c07f9cd1d5fd912718&mpshare=1&scene=23&srcid=0517NRr5yB17vZnPg65pCl4Y&sharer_sharetime=1623916906151&sharer_shareid=0e8353dcb5f53b85da8e0afe73a0021b%23rd (9)微软自家的demo https://github.com/microsoft/onnxruntime/blob/master/onnxruntime/python/tools/transformers/notebooks/PyTorch_Bert-Squad_OnnxRuntime_CPU.ipynb 在该工作中,提供了一些性能测试工具,包括针对ort本身开发的profiler (10)一个更详细的demo https://bbs./blogs/180532 (11)快手异构计算团队基于nvidia的fastertransformer进一步做了底层优化,具体包括:算法融合和重构,混合精度量化,内存管理优化,输入padding移除,GEMM配置优化 https://mp.weixin.qq.com/s?__biz=MzA3MzI4MjgzMw==&mid=2650808102&idx=3&sn=cd8f1de3d64c0bfe0e0ba28a526629df&chksm=84e5db58b392524eafed49dd893d064202faebad4cf80beacde641a25a1616d1e83a51354c26&mpshare=1&scene=23&srcid=0201uAERHZKdbPqvF8ACGrPE&sharer_sharetime=1623921005073&sharer_shareid=0e8353dcb5f53b85da8e0afe73a0021b%23rd (12)微信AI的工作,同样基于nvidia的fastertransformer进一步做底层优化,具体包括:kernel优化(softmax+layernorm),针对可变序列长度的内存分配算法,针对可变序列长度的batch调度器。 https://github.com/Tencent/TurboTransformers 和快手的工作相比,这篇工作更偏向于工程侧服务过程的优化。不过,二者都很强调对可变长度输入的处理。
|
|
来自: 520jefferson > 《模型优化》