基于tensorRT的BERT服务部署---填坑记

2020 年 5 月 28 日 AINLP

BERT的出现真是广大NLPer的福音,在很多任务上能取得显著提升。不例外,作者在工作过程中也使用了BERT进行下游任务训练,但在感叹BERT真香的时候,它及其漫长的推断时间让人感到很为难。本文就记录了在使用tensorRT部署BERT时候的各种坑。话不多说,先给下最终模型推断时间对比,然后开始我们的填坑记。(更多内容知乎专栏:NLP杂货铺)

  • 基本依赖

  • 自寻坑路

  • TensorRT

    • 'UFF'模型转换错误

  • BERT in TensorRT

    • 'time out'demo模型特难下载

    • 顺利运行demo推断

    • 'additionaldict'模型中包含训练时的参数

    • 'clssquadoutputweights'模型中参数名称不一致

    • 'ascii'中文读取报错

    • 模型结构与demo不同

    • 'nan'batch大小的配置问题

    • tensorflow与tensorRT的推断时间对比

  • tensorRT server for BERT

    • 'segmentation'cuda与flask的冲突

    • tensorrt模型文件的确认

    • 'deserialize'tensorrtserver版本问题

    • 'CustomEmbLayerNormPluginDynamic'插件缺失

    • config.pbtxt配置文件不对

  • Client

    • tensorrtserver.api下载安装

    • 'dimension'batch大小的配置问题

  • 上线

    • Serialization Error

  • 总结

  • 参考资料

基本依赖

    python

    git

    gpu

    nvidia-docker

    bert的checkout模型

自寻坑路

那天接口调用方告诉我,我的接口超时了要优化下。从使用BERT开始我就知道,总会有这一天的,而现在终于来了。在一开始部署服务的时候,就直接上了GPU,对于一般调用,虽然慢了点,但也不至于超时。但被新业务调用后,处理的样本量明显增加,特别容易出现超时的现象。没办法,自己约的,呸,自己选的路,再艰难也得先看看别人趟的水,然后再决定走不走。既然需求已经提了,我当然立刻行动起来,根据项目特性,先优化了一波流程,让整体速度提升了4倍左右,之前timeout的样例都通过了,先部署起来给下游用。虽然提升了4倍速度,但大样本依然游走在timeout的边缘,如果遇到更大的样本,就...。
为了看看前人趟的水,就来知乎进行了搜索,然后得到了下面几篇文章。

《从零开始学习自然语言处理(NLP)》-BERT推理加速实践(6)【1】
《从零开始学习自然语言处理(NLP)》-BERT模型推理加速总结(5)【2】
加速 BERT 模型有多少种方法?从架构优化、模型压缩到模型蒸馏,最新进展详解!【3】
NVIDIA发布TensorRT 6,突破BERT-Large推理10毫秒大关【4】

从结果看,有这么几种方式:缩短maxseq,合并请求组成大batch,替换模型(蒸馏/缩减层数等),换成float16精度,使用tensorflow的xla,使用tensorRT。缩短maxseq首先被排除了,因为这个项目在处理过程中,要对所有的文本进行处理,缩短seq等于增加了样本量,所以不适合我们项目。组成大batch也不行,我们的一次请求都至少40个样本,在样本量超过40之后,batch的增加与时间的增加基本上是线性的,所以也不适合。至于替换模型,之前尝试过tiny版的albert,速度肯定有提升,但准确率降了5个点,接受不了。后面的几个方法,tensorRT同时包含了所有优点,so,基于tensorRT部署BERT服务,坑从此开始。

TensorRT

tensorRT【5】是什么,不知道,没听过,不管了,先按照说明【6】把tensorrt安装下,在我tensorflow14的docker容器中一顿操作,哎,木报错,顺利安装完。然后需要把模型转为tensorRT形式,顺利找到转tensorflow模型的文档【7】,当然checkout模型是不能直接转的,事先要转为‘frozen TensorFlow model’格式,这个在【7】中也有提示,也可以自行百度/google寻找教程。

'UFF'模型转换错误

顺利转完模型后,需要转为uff文件,这时坑开始来了,出现了一个它认识我我不认识它的错误(这个错误到写文章时都没解决,有一个原因是后来没有走这条路)。只能再去找前人,文章【8】中显示,nvidia专门对BERT进行过优化,是有demo的,一翻波折之后,终于找到了官方demo。

BERT in TensorRT

在tensortRT的官方github上一开始并没有找到BERT的demo,后来发现在5.1与6.0分支【9】中都有BERT的demo,聪明的我认为新版本应该更好些(也许选择5.1,会少走一些弯路,但我不想再去找坑了),于是重新开始了寻坑之旅,这样第一行代码出现了:

  
  
    
  1. git clone -b release/6.0 https://github.com/NVIDIA/TensorRT.git

根据【9】中python的提示,依次运行:

  
  
    
  1. cd TensorRT/demo/BERT

  2. sh python/create_docker_container.sh

'time out'demo模型特难下载

在TensorRT/demo/BERT/python目录下有readme说明文档,根据说明准备环境,第一步克隆代码已经完成,第二步建立镜像,时间稍微有点久,但还算顺利,第三步在镜像中编译插件/下载调试过的模型(因为是完整的demo,所以模型都是有demo的),其中模型下载可以根据需求选择base/large,maxseq的大小,以及float32/float16精度,插件编译得还比较顺利,就是模型下载得太慢了,十几k每秒,也不知道多大,那就等着,自己再去看看不知道是什么的TensorRT。直到下班,还没下好,没事明天早上再来看,结果第二天过来看,告诉我下载失败,好吧重新下,5个小时后又下载失败,好吧重新下......终于下载了3天得到了basefp16_384的模型。反应慢的我这时候想起,我们项目中的长度是128,最好弄个128的模型,这样方便对比推断的时间,所以在后台重新下载128的模型,自己先用384模型跑完demo的后续流程(事实上,一直到部署结束,都没能再成功下载过一个模型,想想当时能成功下载384的模型,真的是幸运)。

顺利运行demo推断

然后根据文档,顺利执行了"Building an Engine"与"Running Inference"两个步骤,运行时间有些波动,最快大概再2.4ms一个,鉴于长度是384,与官方说的128长度2.2ms一个基本吻合了。这个时候的我,仿佛已经完成了模型加速,幸福的表情难以言表。

'additional_dict'模型中包含训练时的参数

虽然说128长度的demo模型一直下不成功,但发现384的模型其实就是个checkout形式的tensorflow模型,所以就直接拿我们自己训练好的checkout模型来转换。开始转化模型:

  
  
    
  1. python python/bert_builder.py -m /workspace/models/fine-tuned/bert_tf_v2_base_fp32_128_v2/model.ckpt-6001 -o bert_base_128.engine -b 1 -s 128 -c /workspace/models/fine-tuned/bert_tf_v2_base_fp16_128_v2

在短暂的等待之后,就迎来了ERROR!

报错表示,在模型数据加载过程中,出现了不支持的数据类型,于是在bert_builder.py的252/253行加入了代码:

  
  
    
  1. print(pn) # 打印参数名称

  2. print(type(tensor)) # 打印参数类型

再次运行后发现,一个叫"signalearlystopping/STOP"的参数是布尔形式,这是在训练过程中用到的,所以将237行改为:

  
  
    
  1. param_names = [key for key in sorted(tensor_dict) if 'early_stop' not in key and 'adam' not in key and 'global_step' not in key and 'pooler' not in key]

'clssquadoutput_weights'模型中参数名称不一致

顺利解决了上面的bug,再次运行后,比上次多等待了一眨眼,就得到了一个全新的ERROR!

报错表示,参数中没有一个叫"clssquadoutput_weights"的,demo是squad的一个样例,而我的是二分类下游任务,最后输出层参数名称不一致,根据上面打印的参数名字(不同的下游任务或者训练代码,最后层的参数名字都可能不同),将217/218行代码修改为:

  
  
    
  1. W_out = init_dict["output_weights"]

  2. B_out = init_dict["output_bias"]

然后再次运行,没有报错,进入了相对较长的等待。当"Saving Engine to bertbase128.engine Done."出现的时候,这个时候的我,仿佛已经完成了模型加速,幸福的表情难以言表。

'ascii'中文读取报错

赶紧以葫芦画瓢(将文档与问题都用文件的形式提供),也运行一次推断:

  
  
    
  1. python python/bert_inference.py -e bert_base_128.engine -pf "p.txt" -qf "q.txt" -v /workspace/models/fine-tuned/bert_tf_v2_base_fp32_128_v2/vocab.txt

很快,就报了一个"ascii"编码的错误(因为读取中文的缘故),在百度之后,执行了下面一行得以解决(本容器中可使用C.UTF-8):

  
  
    
  1. export LANG=C.UTF-8

继续运行后,得到"Running inference in 437.362 Sentences/Sec"(2.286ms),后面还有一个squad相关的错误,直接被我忽略了。这个时候的我,仿佛已经完成了模型加速,幸福的表情难以言表。

模型结构与demo不同

后面我修改了bertinference.py文件(根据自己需要,自行修改),打印出模型分类结果,发现结果是[128,2,1,1]维度的,并且没有做最后的softmax操作,获取第一行数据并softmax,然后发现,结果是错的,什么鬼,摔!
这个错误让我茶饭不思(那两天吃得可好了),以为距离模型加速成功就一步之遥(其实还有好远),结果结果是错的,根本不能用!对着代码查这查那,用着google找这找那,丝毫没有头绪。一股神秘的力量,让我回去看了tensorflow训练BERT下游任务的代码,在我粗略的论文阅读中,以及网络/同事的介绍中,得到的信息都是,取BERT最后一层[CLS]的编码直接进行下游二分类训练(单层全连接+softmax)。但代码中却是,先经过一层全连接+tanh,再接全连接+softmax。根据代码得知,第一层的两参数名叫"bert
poolerdensekernel","bertpoolerdensebias",所以将bertbuild.py原237行修改为:

  
  
    
  1. param_names = [key for key in sorted(tensor_dict) if 'early_stop' not in key and 'adam' not in key and 'global_step' not in key]

在tensorrt-api文档【10】的帮助下,将bertbuild.py中的squadoutput函数修改为:

  
  
    
  1. def squad_output(prefix, config, init_dict, network, input_tensor):

  2. """

  3. Create the squad output

  4. """


  5. idims = input_tensor.shape

  6. assert len(idims) == 5

  7. B, S, hidden_size, _, _ = idims


  8. p_w = init_dict["bert_pooler_dense_kernel"]

  9. p_b = init_dict["bert_pooler_dense_bias"]

  10. #这里其实可以直接取[CLS]的向量进行后续运算,但是没能实现相关功能,就计算了所有的

  11. pool_output = network.add_fully_connected(input_tensor, hidden_size, p_w, p_b)

  12. pool_data = pool_output.get_output(0)

  13. tanh = network.add_activation(pool_data, trt.tensorrt.ActivationType.TANH)

  14. tanh_output = tanh.get_output(0)


  15. W_out = init_dict["output_weights"]

  16. B_out = init_dict["output_bias"]


  17. W = network.add_constant((1, hidden_size, 2), W_out)

  18. dense = network.add_fully_connected(tanh_output, 2, W_out, B_out)

  19. set_layer_name(dense, prefix, "dense")

  20. return dense

在相对较长的等待中,获得了新的engine模型。在运行了自己修改的推断脚本后,得到了正确结果(使用了fp16,所以最后结果在万分位上有所不同,但基本一致了)。这个时候的我,仿佛已经完成了模型加速,幸福的表情难以言表。

'nan'batch大小的配置问题

为了对比下速度,多预测了几个样本,发现报错,可能是因为构建engine的时候batch设置的是1,重新设置为20,再次运行:

  
  
    
  1. python python/bert_builder.py -m /workspace/models/fine-tuned/bert_tf_v2_base_fp32_128_v2/model.ckpt-6001 -o bert_base_128.engine -b 20 -s 128 -c /workspace/models/fine-tuned/bert_tf_v2_base_fp16_128_v2

得到新模型后,推断多个样本时,依然报错,得到的都是nan结果。什么情况,这个batch size参数是摆设吗!(后来我查看过5.1分支的代码,配置有所不同,也许在5.1分支上,直接使用batch size是有作用的)天知道在经过怎样的过程之后,发现engine构建过程中,有过配置设置:

  
  
    
  1. bs1_profile = builder.create_optimization_profile()

  2. set_profile_shape(bs1_profile, 1)

  3. builder_config.add_optimization_profile(bs1_profile)

为了模型速度,构建过程中只设置了batch size为1,8以及参数值这三个。在google一翻之后,一位大佬说,再读取engine之后,设置使用第二个配置(就是以传入参数为batch size的配置)就可以了,也就是添加一行代码"context.activeoptimizationprofile = 1",很有道理,一运行发现,"out of index"!还是要暴力处理,后来直接注释了其他两个配置,终于运行成功了,batch size在[1,20] 之间都得到了正确结果。这个时候的我,仿佛已经完成了模型加速,幸福的表情难以言表。

tensorflow与tensorRT的推断时间对比

然后就得到了一开始的那张时间对比表,tensorflow是1.14版,float32精度,使用estimator进行预测,tensorrt是6.0版,直接使用python调用:

tensorRT server for BERT

'segmentation'cuda与flask的冲突

python调用成功后,就简单把bert_inference.py程序改成了一个python服务程序,顺利启动服务之后,调用服务接口,惊喜来了:

一个光秃秃的提示(报错位置都没有),反正没得结果。后来一查百度,说这个多为内存不当操作造成,这让我一个半路出家的程序员怎么办!后来仔细排查了报错位置,发现是cuda报出的错,结合这个信息,在面向google编程之后,得知pycuda上下文与http上下文有一些冲突(超过我知识范围了),在初始化cuda的时候不能使用autoinit,得调用一次init一次,

  
  
    
  1. #import pycuda.autoinit #注释掉自动初始化

  2. # 初始化cuda

  3. cuda.init()

  4. device = cuda.Device(0)

  5. ctx = device.make_context()


  6. # 中间所有处理程序


  7. # 结束上下文

  8. ctx.pop()

如上所示,每次调用的时候都得先初始化,经过这样的修改以后,果然跑通了。但耗时了3000ms一个样本,时间足足多了上百倍,还能不能好好地玩耍了。这还不是最关键的,最关键的是,所有的返回结果全部变成了[0.5,0.5],好吧在服务中用python直接调用模型是行不通了(并不是真正的行不通,只是我这个渣渣,cuda也不懂,解决不了这两个问题)。

tensorrt模型文件的确认

这个时候,只能去使用tensorrt server【11】了。根据【11】文档里所说,只要求一个配置文件和模型文件,就可以启动相应的docker服务了。但发现这个server能识别的tensorrt模型文件是一个以.plan结尾的文件,但我只有一个以.engine结尾的模型文件。后面我查阅了百度/gooogle相关文件,都没找到如何将engine转为plan文件,后来只找到一个在tensorrt6.0已经被弃用的方法"writeengineto_file()",但这不能用,而且也不知道写进去的文件是啥类型。后来我搜索了【5】中所有的"plan"字符,终于找到一句话:

Write out the inference engine in a serialized format. This is also called a plan file.

这句话的意思应该就是说,engine跟plan是一个东东(后面确实读取成功了,应该是一个东西,当时还是有猜的成分)。

'deserialize'tensorrtserver版本问题

按照【11】中所讲,我认为下载官方提供的docker来部署最为方便,最主要的是,我发现服务器上已经有一个tensorrt server的镜像了,应该是同事之前下的,下镜像的过程都省掉了。根据【11】中Model相关内容,将模型文件重命名为model.plan,将配置文件修改为(有问题,后面要改):

  
  
    
  1. name: "bert"

  2. platform: "tensorrt_plan"

  3. max_batch_size: 20

  4. input [

  5. {

  6. name: "input0"

  7. data_type: TYPE_INT32

  8. dims: [128]

  9. },

  10. {

  11. name: "input1"

  12. data_type: TYPE_INT32

  13. dims: [128]

  14. },

  15. {

  16. name: "input2"

  17. data_type: TYPE_INT32

  18. dims: [128]

  19. }

  20. ]

  21. output [

  22. {

  23. name: "output0"

  24. data_type: TYPE_FP16

  25. dims:[128,2]

  26. }

  27. ]

根据【11】中的命令,直接运行:

  
  
    
  1. NV_GPU=1 nvidia-docker run --rm --shm-size=1g --ulimit memlock=-1 --ulimit stack=67108864 -p50014:8000 -p50015:8001 -p50016:8002 -v /自己的路径/models:/models nvcr.io/nvidia/tensorrtserver:19.08-py3 trtserver --model-repository=/models

直接一个报错"trtserver: unrecognized option '--model-repository=/models'",根据提示,将参数名"--model-repository"改为了"--model-store",然后再运行,就得到了又一个错误:

在一个不知道在哪里的文件,报了一个c++的错误,一筹莫展。根据提示,好像是batch size的问题,也可能是engine文件并不是plan文件导致读错了,也可能是版本问题(tensorrt server跟tensorrt的版本不统一【12】)。针对前面两种情况,试了各种姿势,依然是报这个错,没办法,只能重新下载个docker镜像了。

  
  
    
  1. docker pull nvcr.io/nvidia/tensorrtserver:19.09-py3

当然下载不会一帆风顺的,会有权限错误提示,在【11】中也多次提到,下载docker容器得先有NGC 权限【13】。

'CustomEmbLayerNormPluginDynamic'插件缺失

两个小时之后,下载完毕,然后运行:

  
  
    
  1. NV_GPU=1 nvidia-docker run --rm --shm-size=1g --ulimit memlock=-1 --ulimit stack=67108864 -p50014:8000 -p50015:8001 -p50016:8002 -v /自己的路径/models:/models nvcr.io/nvidia/tensorrtserver:19.09-py3 trtserver --model-repository=/models

大概等了2秒中,有点开心,已经过了上个bug出现的时间,又过了1秒,果然来了个新bug:

读取"CustomEmbLayerNormPluginDynamic"插件错误,这个插件有点眼熟,在bertbuild.py文件里面出现过,在咨询了一波google之后,发现一个类似的问题【14】,在根据bertbuild.py文件,将libbert_plugins.so/libcommon.so(在【9】中build文件夹中,编译之后的)文件拷进docker容器里。进入容器:

  
  
    
  1. NV_GPU=1 nvidia-docker run -it --shm-size=1g --ulimit memlock=-1 --ulimit stack=67108864 -p50014:8000 -p50015:8001 -p50016:8002 -v /自己的路径/models:/models nvcr.io/nvidia/tensorrtserver:19.09-py3 /bin/bash

然后运行:

  
  
    
  1. export LD_PRELOAD=/opt/tensorrtserver/libbert_plugins.so:/opt/tensorrtserver/libcommon.so

so文件位置是自己确定的,然后运行:

  
  
    
  1. trtserver --model-repository=/models

config.pbtxt配置文件不对

这次运行时间更长了,好开心,然后:

根据这个提示,是配置文件有问题,修改后又报错再修改再报错,这样循环几次后,配置文件变成了:

  
  
    
  1. name: "bert"

  2. platform: "tensorrt_plan"

  3. max_batch_size: 20

  4. input [

  5. {

  6. name: "input_ids"

  7. data_type: TYPE_INT32

  8. dims: [128]

  9. },

  10. {

  11. name: "segment_ids"

  12. data_type: TYPE_INT32

  13. dims: [128]

  14. },

  15. {

  16. name: "input_mask"

  17. data_type: TYPE_INT32

  18. dims: [128]

  19. }

  20. ]

  21. output [

  22. {

  23. name: "cls_dense"

  24. data_type: TYPE_FP32

  25. dims: [128, 2, 1, 1]

  26. }

  27. ]

再次运行之后,一直没报错,好像成功了,根据【11】中状态检查,运行了下:

  
  
    
  1. curl localhost:50014/api/status

然后得到了:

哦耶,好像加载成功了,这个时候的我,仿佛已经完成了模型加速,幸福的表情难以言表。

Client

tensorrtserver.api下载安装

看似tensorrt的服务已经成功部署了,现在就需要在我自己的服务内部调用成功了。根据【11】当中关于client的介绍,client的环境可以自己打镜像/编译/下载镜像/下载编译好的结果,琢磨着下载编译好的结果最简单了,所以在【15】中找到了自己需要的版本,直接运行:

  
  
    
  1. wget https://github.com/NVIDIA/tensorrt-inference-server/releases/download/v1.6.0/v1.6.0_ubuntu1804.clients.tar.gz

  2. tar -zxvf v1.6.0_ubuntu1804.clients.tar.gz

然后安装一下:

  
  
    
  1. cd python

  2. pip install tensorrtserver-1.6.0-py2.py3-none-linux_x86_64.whl

'dimension'batch大小的配置问题

有了依赖环境之后,根据【11】中的python api,成功地将模型调用添加到我的服务中去,最后调用测试,这个时候的我,仿佛已经完成了模型加速,幸福的表情难以言:

根据报错提示,是batch size不对,将样本数量换成20后,果然运行正确了。为什么直接用python调用模型的时候,样本数只要小于batch size就可以了!后来我将bertbuild.py文件的"setprofile_shape"函数改为了:

  
  
    
  1. def set_profile_shape(profile, batch_size):

  2. maxshape = (batch_size, S)

  3. minshape = (1, S)

  4. optshape = (batch_size, S) # 这个batch的大小在最大和最小之间就可以,可以相等

  5. profile.set_shape("input_ids", min=shape, opt=shape, max=shape)

  6. profile.set_shape("segment_ids", min=shape, opt=shape, max=shape)

  7. profile.set_shape("input_mask", min=shape, opt=shape, max=shape)

其中"set_shape"等函数的含义可以在文档【10】中找到,修改后,又将全流程走了一遍,构建engine,部署tensorrt server,运行client,然后我真的完成了了模型加速,幸福的表情一言难尽!最后测试20个样本调用服务的时间是15ms左右,比python直接调用延迟了5ms左右。

上线

Serialization Error

果然,我还是笑得太早,太年轻了。刚把服务推到测试上,就来了惊喜:

一看错误,模型加载错误,什么情况,我不是已经跑通了吗?经过一系列查询之后,发现tensorrt在不同GPU(主要根据计算能力分类)上编译的模型是不能通用的,我之前在调研机上跑的,GPU型号是V100(计算能力7.0),而测试机上是P4(计算能力6.1),在V100上编译的模型不能再P4使用,根据github上前辈提示,在CMakeLists.txt文件的第21行添加:

  
  
    
  1. -gencode arch=compute_60,code=sm_60 \

这样就可以在P4上进行编译了,后来验证P4上的模型可以在P100的机器上跑通。当然编译的过程显然不能一帆风顺,中间出现了out of memory的问题,后来测试发现,大概需要5800M的显存才能编译成功。线上的GPU是P100的,顺利运行了新编译的模型,心里终于微微一笑;bert在V100上的运行速度大概是P100的5倍,而且nvidia主要在T4跟V100上优化bert推断的,而且模型转换时P100上不能使用float16精度模式(只能用float32),所以新编译的模型效率提高有限;想到新编译的模型比tensorflow的效率只提高了30%左右,感觉之前的努力突然不香了。

总结

压力/需求使人进步,如果没有"time out"报错,我在部署完gpu版的BERT模型就结束了,这不,硬着头皮也要上,从完全没有听过tensorrt到成功部署bert,大概用了两周多时间。虽然现在对tensorrt依然只是了解皮毛,对cuda编程更是两眼一抹黑,但没关系,有了这个开端,后面慢慢学。
在部署过程中,百度/google/知乎各种找教程,都没有找到部署BERT的详细过程,也为了提升自身,写下自己遇到的坑,以及部分解决办法,供大家一起交流进步。

参考资料(阅读原文查看参考资料链接)

【1】《从零开始学习自然语言处理(NLP)》-BERT推理加速实践(6)
【2】《从零开始学习自然语言处理(NLP)》-BERT模型推理加速总结(5)
【3】加速 BERT 模型有多少种方法?从架构优化、模型压缩到模型蒸馏,最新进展详解!
【4】NVIDIA发布TensorRT 6,突破BERT-Large推理10毫秒大关
【5】What Is TensorRT?
【6】tensorRT的debian方式安装
【7】使用python将tensorflow模型转为tensorRT模型
【8】Real-Time Natural Language Understanding with BERT Using TensorRT
【9】tensorRT6.0分支BERT官方demo
【10】tensorrt-api
【11】NVIDIA TensorRT Inference Server
【12】TensorRT inference server documentation versions
【13】NGC guide
【14】CustomEmbLayerNormPluginDynamic插件加载问题
【15】tensorrt-inference-server/releases

推荐阅读

AINLP年度阅读收藏清单

薅当当羊毛的机会又!双!!叒!!!叕!!!来了

中文命名实体识别工具(NER)哪家强?

学自然语言处理,其实更应该学好英语

斯坦福大学NLP组Python深度学习自然语言处理工具Stanza试用

太赞了!Springer面向公众开放电子书籍,附65本数学、编程、机器学习、深度学习、数据挖掘、数据科学等书籍链接及打包下载

数学之美中盛赞的 Michael Collins 教授,他的NLP课程要不要收藏?

自动作诗机&藏头诗生成器:五言、七言、绝句、律诗全了

模型压缩实践系列之——bert-of-theseus,一个非常亲民的bert压缩方法

这门斯坦福大学自然语言处理经典入门课,我放到B站了

征稿启示 | 稿费+GPU算力+星球嘉宾一个都不少

关于AINLP

AINLP 是一个有趣有AI的自然语言处理社区,专注于 AI、NLP、机器学习、深度学习、推荐算法等相关技术的分享,主题包括文本摘要、智能问答、聊天机器人、机器翻译、自动生成、知识图谱、预训练模型、推荐系统、计算广告、招聘信息、求职经验分享等,欢迎关注!加技术交流群请添加AINLPer(id:ainlper),备注工作/研究方向+加群目的。


登录查看更多
4

相关内容

BERT全称Bidirectional Encoder Representations from Transformers,是预训练语言表示的方法,可以在大型文本语料库(如维基百科)上训练通用的“语言理解”模型,然后将该模型用于下游NLP任务,比如机器翻译、问答。
FPGA加速系统开发工具设计:综述与实践
专知会员服务
63+阅读 · 2020年6月24日
专知会员服务
44+阅读 · 2020年3月6日
BERT技术体系综述论文:40项分析探究BERT如何work
专知会员服务
138+阅读 · 2020年3月1日
Transformer文本分类代码
专知会员服务
116+阅读 · 2020年2月3日
TensorFlow Lite指南实战《TensorFlow Lite A primer》,附48页PPT
专知会员服务
68+阅读 · 2020年1月17日
模型压缩究竟在做什么?我们真的需要模型压缩么?
专知会员服务
27+阅读 · 2020年1月16日
社区分享|如何让模型在生产环境上推理得更快
绝对干货!NLP预训练模型:从transformer到albert
新智元
13+阅读 · 2019年11月10日
使用ONNX+TensorRT部署人脸检测和关键点250fps
极市平台
34+阅读 · 2019年10月22日
基于知识蒸馏的BERT模型压缩
大数据文摘
18+阅读 · 2019年10月14日
使用 Bert 预训练模型文本分类(内附源码)
数据库开发
102+阅读 · 2019年3月12日
手把手教你如何部署深度学习模型
全球人工智能
15+阅读 · 2018年2月5日
How to Fine-Tune BERT for Text Classification?
Arxiv
13+阅读 · 2019年5月14日
Arxiv
8+阅读 · 2019年3月21日
Arxiv
12+阅读 · 2019年2月28日
Music Transformer
Arxiv
5+阅读 · 2018年12月12日
VIP会员
相关VIP内容
FPGA加速系统开发工具设计:综述与实践
专知会员服务
63+阅读 · 2020年6月24日
专知会员服务
44+阅读 · 2020年3月6日
BERT技术体系综述论文:40项分析探究BERT如何work
专知会员服务
138+阅读 · 2020年3月1日
Transformer文本分类代码
专知会员服务
116+阅读 · 2020年2月3日
TensorFlow Lite指南实战《TensorFlow Lite A primer》,附48页PPT
专知会员服务
68+阅读 · 2020年1月17日
模型压缩究竟在做什么?我们真的需要模型压缩么?
专知会员服务
27+阅读 · 2020年1月16日
相关资讯
社区分享|如何让模型在生产环境上推理得更快
绝对干货!NLP预训练模型:从transformer到albert
新智元
13+阅读 · 2019年11月10日
使用ONNX+TensorRT部署人脸检测和关键点250fps
极市平台
34+阅读 · 2019年10月22日
基于知识蒸馏的BERT模型压缩
大数据文摘
18+阅读 · 2019年10月14日
使用 Bert 预训练模型文本分类(内附源码)
数据库开发
102+阅读 · 2019年3月12日
手把手教你如何部署深度学习模型
全球人工智能
15+阅读 · 2018年2月5日
相关论文
Top
微信扫码咨询专知VIP会员