当前位置: 首页 > 科技观察

NLP训练推理集成工具(TurboNLPExp)

时间:2023-03-14 13:39:24 科技观察

作者:TurboNLP,腾讯TEG后台工程师介绍在进行NLP任务(序列标注、分类、句子关系判断、生成)训练时,通常使用机器学习框架Pytorch或Tensorflow。在其之上,定义自定义模型的模型和数据预处理。这种方式难以实现模型沉淀、复用和共享,在模型上线时也面临着问题:上线难、延迟高、成本高。TEG-AI平台部-搜索业务中心于2019年底启动,前期经过大量研究,在AllenNLP的基础上自主研发了推理训练集成工具TurboNLP,涵盖训练框架TurboNLP-exp和推理框架TuboNLP-inference、TurboNLP-exp训练框架具有可配置、简单、多框架、多任务、可重用等特点,在其之上可以快速高效地进行NLP实验。TurboNLP-inference推理框架底层支持高效模型推理库BertInference,集成了常用的NLPModel,与TurboNLP-exp无缝兼容,推理性能高(在BERT-base文档分类业务模型上测得,FP6准确率batch_size=64时达到0.275ms/query,seq_len=64,INT8精度达到batch_size=64,seq_len=64达到0.126ms/query的性能)等,NLP训练和推理的集成工具大大简化了训练过程推理,降低任务训练、模型在线等人工成本。本文将主要介绍用于NLP训练和推理的All-in-one工具。背景NLP任务通常由算法研究人员在机器学习框架Pytorch或Tensorflow中使用自定义模型和数据预处理进行训练,然后手动部署到libtorch或tensorflow。这个过程存在以下问题:对现有NLP任务的模型结构和数据预处理重新定义,可重复性高。手动修改模型结构和数据预处理代码,不断调整训练参数,不断试错,造成代码混乱。当模型复杂度(多模型多任务)较高或现有模型需要优化改进时,如果不熟悉模型结构,则需要重新组织Python定义的模型和数据预处理代码。知识积累困难,模型复用共享困难。上线难,C++数据预处理复杂,推理延迟高。基于流程的方式难以提升NLP任务的离线训练和效果实验效率,试错成本高。为了解决以上痛点,在此背景下,我们将NLP训练端打通到推理端,开发了训练框架TurboNLP-exp和推理框架TuboNLP-inference。以下是该框架的整体架构图:训练框架TurboNLP-exp简介TurboNLP-exp具有模块化、可配置、多平台支持、多任务支持、多模型格式导出、C++数据预处理等特点,等。它不仅可以满足研究人员的快速实验,还可以通过配置将模型存放在框架上。后续研究人员通过配置重用和共享知识。TuboNLP-exp具有模型和数据预处理的模块化设计。数据预处理方面,针对同类型NLP任务(序列标注、分类、句子关系判断、生成)的数据预处理基本相同,可以通过复用配置复用已有的数据预处理;对于模型,TurboNLP-exp集成了丰富的子模块:embedder、seq2seq_encoder、seq2vec_encoder、decoder、attention等,通过配置随机构建模型来达到快速实验的目的。TuboNLP-exp统一封装底层机器学习平台(Pytorch和Tensorflow),熟悉不同机器学习平台不影响模型重用、共享和知识积累。TurboNLP-exp支持C++和Python数据预处理。Python数据预处理具有实验调试快的特点,主要服务于训练端。C++数据预处理具有高性能的特点,主要服务于推理端。C++数据预处理和Python具有相同的API接口,研究者可以在训练阶段随意切换C++和Python数据预处理,保证训练端和推理端的数据一致性。推理框架TurboNLP-inferenceTurboNLP-inference可以直接加载TuboNLP-exp导出的模型,根据配置实例化数据预处理。TurboNLP-inference提供了统一的API、完整的文档和示例,可以快速实现模型推理代码,业务代码通过API接口调用推理库等封装。TurboNLP-inference推理框架集成了常用的NLP模型:lstm、encoder-decoder、crf、esim、BERT,底层支持五个推理库:BertInference(BERT推理加速库)、libtorch、tensorflow、TurboTransformers(WXG开源)BERT推理加速库),BertInference-cpu(CPU上的BERT推理加速库)。TurboNLP-exp训练框架TurboNLP-exp训练框架是基于AllenNLP开发的。为了满足算法研究者和推理的业务需求,TurboNLP-exp不断优化,具有行业框架所不具备的特性。下表是TurboNLP-exp在其他行业的表现框架对比:框架难度模块化可配置PytorchTensorflow多任务训练多模型格式导出数据预处理推理PyText难TTTFFFPythonCaffe2执行引擎AllenNLP简单TTTFFFPython简单Python服务TurboNLP-expSimpleTTTTTTPython,C++EfficientTurboNLP-expinference下面将详细介绍我们对TurboNLP-exp所做的优化。模块化和可配置性TurboNLP-exp的高度可配置性源于其合理的模块设计。TurboNLP-exp通过模块化封装,支持模型的任意组合、子模块的扩展等。对于新手,TurboNLP-exp提供了基于界面的配置,数据预处理和模型配置通过可视化界面生成,大大降低了难度入门。数据预处理模块化和可配置数据预处理大致可以分为四个模块:dataset_reader、token_indexer、tokenizer、vocabulary。dataset_reader:负责读取训练数据,使用tokenizers进行分词,使用indexers进行id转换;集成读取多种数据格式:文本分类数据格式、NER数据格式、BERT数据格式等,并支持自定义扩展。token_indexer:负责对token进行索引(根据字典转换id),集成多个索引器:单词索引、词索引、词属性索引等,支持自定义扩展。Tokenizer:负责对文本进行分词,并集成了NLP任务常用的分词器:qqseg、wordpiece、whitespace、character等,并支持自定义扩展。Vocabulary:数据字典,支持从训练数据自动生成并在训练后保存在本地,或者从本地已有的字典文件生成。Vocabulary会以命名空间字典的形式同时保存多个字典(tokens字典、labels等)。模型模块化和可配置模型的模块化设计可以分为三大块:模型、训练器和导出器。model:该模块集成了NLP任务的常用模型:encoder、decoder、embedder等,每个子模型由其他模型组成。这种组合式模块化设计可以很容易地根据配置定义模型。对于同一个NLP-like任务,模型结构基本相同。研究人员可以通过修改配置快速调整模型结构,自定义和扩展子模型。trainer:TurboNLP-exp封装了训练过程中使用的优化器、学习率、评价指标,通过配置修改训练参数,达到快速实验的目的。exporter:该模块集成了各种模型格式的导出:caffe、onnx、pt格式,通过配置定义导出的格式。多平台支持TurboNLP-exp对底层机器学习平台进行了抽象,实现了统一的框架接口来调用底层的pytorch和tensorflow(如下图所示)。框架根据配置选择pytorch或者tensorflow来实现接口。目前pytorch格式是标准格式。Multi-tasktrainingMulti-tasklearning通过模拟人类认知过程的多任务特性,将实体识别、紧凑性等不同类型的任务集成到一个模型中,在共享的预训练语言模型上训练各自的标注层,在训练中,通过各任务域的知识和目标的相互补充,共同提升任务模型的效果。上线时使用相同的底层模型,节省存储和计算资源。目前,多任务处理的需求与日俱增。TurboNLP-exp支持多任务和训练调度方式的多种组合(如下图所示)。TurboNLP-exp的多任务模型具有以下特点:可以通过已有的单任务模型快速组合多任务模型。支持多种组合规则,包括:分享、积累、切分。共享:多个模型共享相同的编码器输出。Accumulation:将每个task的encoder进行累加,输出到每个task的tagger层。shotcut:每个任务的编码器输出将作为下一个任务的编码器输入。支持顺序调度、随机调度、联合调度等多种训练调度方式。顺序和随机调度属于交替训练,可以在多个任务的基础上得到每个任务的最优解,不需要构造统一的输入,比较简单。Co-scheduling属于联合训练,使用统一输入。由于loss会在最后累积,所以寻找多任务综合最优解。用户可以根据实际任务场景,自由配置相应的组合和调度方式,达到多任务处理的最佳效果。多模型格式导出TurboNLP-exp可以导出格式:caffe、onnx、pt,支持直接导出TurboNLP-inference推理框架支持的格式,推理端直接加载,无需复杂的模型转换。数据预处理TurboNLP-exp的数据预处理可以同时支持Python和C++。Python数据预处理主要服务于训练端,C++数据预处理主要服务于推理端,也可以服务于训练端(如下图)。训练端,在数据预处理还在修改调试的时候,使用Python数据预处理快速实验。当Python数据预处理固定后,切换到C++数据预处理,验证数据预处理结果,从而保证训练端和推理端数据的一致性。在推理端,使用与训练端相同的配置,C++数据预处理输出将作为模型输入,C++数据预处理——TurboNLP-data使用多线程和预处理队列来保证数据的低延迟预处理。在BERT-Base的五分类模型上实测,在batch_size=64,seq_len=64的情况下,达到了0.05ms/query的性能。TurboNLP-inference推理框架TurboNLP-inference推理框架与TurboNLP-exp无缝兼容,延迟低,可配置。TurboNLP-inference底层支持五个推理库:BertInference(BERT推理加速库)、libtorch、tensorflow、TurboTransformers(WXG开源BERT推理加速库)、BertInference-cpu(BERT推理加速库onCPU),其中,BertInference是我们基于TensorRT开发的高性能BERT推理库,BertInference-cpu是与intel合作开发的一款CPU上的BERT推理加速库。下面是推理框架TurboNLP-inference和训练框架TurboNLP-exp的集成架构图:TurboNLP-inference具有以下特点:集成了NLP任务常用的模型:lstm、esim、seq2seq_encoder、attention、transformer等。,构建模型结构和模型输入。能够直接加载TurboNLP-exp的导出器导出model.weights模型格式。使用C++数据预处理——TurboNLP-data,自动将数据预处理输出馈入模型输入。推理代码会以C++so包和API的形式嵌入到业务代码中,尽可能少的侵入业务代码,修改灵活方便。业务应用NLP集成工具(TurboNLP-exp训练框架和TurboNLP-inference推理框架)大大简化了从训练到上线模型的流程(如下图),根据业务模型的实际上线流程,手册训练部署需要14.5/人天,使用集成NLP工具仅需4人/天,整体节省**72.4%**人力成本。TurboNLP-inference成功支撑了TEG-AI平台部-搜索业务中心的5个业务:某业务文档分类的BERT模型,FP16精度在batch_size=64,seq_len=64的情况下达到0.290ms/query,本机资源节省97%,上线周期缩短近50%,大大降低了机器和人工成本。判断某业务文本-视频关系的BERT模型,响应延迟降低到原来的2/3,设备资源节省92.8%。某业务的查询重写了BERT-base模型,相比之前大大降低了上线周期和人力成本。一个业务多任务(encoder是BERT,decoder是GRU)模型,在FP16精度的情况下,已经达到了2ms/query的性能。业务的查询不必一直停留在BERT-base模型上,上线周期大大缩短。在FP16精度的情况下,达到了1.1ms/query的性能。TurboNLP-inference的业务表现离不开训练框架的无缝支持和底层高效推理库的支持。最新动态BertInference是TurboNLP-inference的底层高效推理库之一,目前支持INT8推理,优化了Attention计算。我们使用基于BERT的文本分类业务模型和真实在线数据进行了性能测试。结果如下:在batch_size=64,seq_len=64的情况下,性能达到0.126ms/query,INT8相比FP16提升了约**54.2%**。TurboNLP-inference支持INT8标定,可以直接使用现有模型标定。校准过程可以通过配置进行调整。校准过程很简单。标定后的INT8精度可直接用于模型推理。总结与展望NLP集成工具(TurboNLP-exp训练框架和TurboNLP-inference推理框架)在TEGAI工作组内部得到了发展,在预训练模型上也有一些合作应用。同时,我们正积极与AI工作组算力、太极机器学习平台团队积极合作,更好地开放平台上的训练端能力。未来,训练和推理框架也将在TencentNLP的统一协作团队中进化,期待公司更多团队的合作。TurboNLP-inference的BERT推理加速在INT8精度模型的效果上还有进一步提升的空间。目前,它专注于QAT和知识蒸馏。QAT目前在五类BERT-base模型上进行测试。Accuracy只降低了0.8%,加上knowledgedistillation,有望达到Accuracy不失。