网站首页 > 技术文章 正文
全文共3510字,预计学习时长7分钟
图片来源:unsplash.com/@thoughtcatalog
本文将介绍一款基于OpenAI的新NLP文本编写APP——GPT-2,旨在随时随地和用户一起写作。
这是一款全新的创造性文本编辑器APP。与传统文本编辑器不同,这款APP的NLP模型可以完成用户要求的句子,并为“用机器写作”带来全新的维度。该APP基于GPT-2(OpenAI的语言模型),可以生成在语法意义上准确无误的句子和连贯的文字段落。
在GPT-2的帮助下讲故事
该演示现已在
https://transformer.huggingface.co上发布。
用transformer写作就像用计算器写微积分。
这个模型是NLP最新趋势的一部分,在对特定任务进行微调时,该模型用于创建大型的语言模型,从而使各项任务圆满完成。这使得具有大量参数(GPT-2 Large或Grover的参数多达15亿个)的Transformer模型由于其重量而很难处理。
APP为用户提供两种型号:小型GPT-2和中型GPT-2。两种型号同时加载到计算机的RAM中共需2.4 GB内存。
当前存在的问题
注意:这里的方法针对无法执行批量推理的模型。对于可以进行批量推理的模型,如我们使用的模型,可能不需要显示的解决方法。
这个APP设置了一些限制,以便用户拥有愉悦的使用感。如反应时间要尽可能短,并生成足够长的句子。每次运行时,系统必须提供几种可能的结果,以便用户从中做出选择,这会使生成的数据量增加两倍之多。因此,该APP的目标是尽可能优化计算,利用GPU高度并行性的特点创建工作流程。
设置工作区
构建一个服务器端API,与前端APP连接。该API将负责处理生成句子所需的计算。因为大多数NLP模型都是现成的,所以使用Python来完成这项任务。其他低级语言(如C++或Rust)更适合以性能为导向的后端。
使用falcon(
https://falconframework.org/)作为Web服务器(任何其他HTTP框架也可以使用),与gunicorn(https://gunicorn.org/)一起运行实例并平衡负载。GPT-2 Pytorch(
https://github.com/huggingface/pytorch-pretrained-BERT)运行是该项目的支柱。如果你对类似的例子感兴趣,可参见示例目录(
https://github.com/huggingface/pytorch-pretrained-BERT/tree/master/examples)中的一些示例。
Gunicorn可以设立独立运行APP的“workers”,有效平衡不同worker的负载。可以参见官方的Gunicorn文档(
http://docs.gunicorn.org/en/stable/design.html),精确了解它们是如何工作的。
三种方式自动完成
在每次自动完成的请求中,我们都希望API可能生成三个不同的句子。这些句子将呈现给终端用户,最终用户将在三者中选择一个。这是设计的重要部分,API必须反映这一点。这三个句子应该同时出现,每次自动完成后,最好只向服务器发送一个请求。
最简单的方法是使用在后台加载模型的单个worker:
Na"ive API
使用这种体系结构,每个请求都将按顺序处理,并且模型将被提示,在响应传入请求之前生成三个不同的句子。
可以通过添加更多工作人员来轻松扩展此基础架构,同时牢记:每个工作人员会根据GPU的使用情况在RAM或VRAM中加载模型。
Multi-worker na"ive API
使用这种方法意味着加载模型并对其进行操作的过程,以请求生成三个不同的句子。如果模型能执行批量推理,就可以一次生成三个句子。但是,如果不能执行批量推理,则需要单独生成每个句子——从而导致三次模型迭代。因为批量推断需要一些更具设计性的方法,所以后面将考虑其无法进行的情况。
在计算自动完成的最短响应时间时,最好将这三个迭代并行化。幸运的是,Python使用户可以访问在场景中使用的几个并行化选项:
· 多线程(线程)
· 多进程(子进程或多进程)
· 不同的Web服务器作为一种多处理形式
多线程
传送门:
https://docs.python.org/3/library/threading.html
Python中的多线程通常使用线程类来完成,该线程允许程序创建多个线程,每个线程都会继续执行各自的操作。多线程的问题在于Global Interpreter Lock ( GIL ) 在Python中的工作方式。
如果一个线程访问某个模型对象,那么在第一个线程完成处理之前,其他线程无法访问该对象。因为三个迭代将按顺序处理,所以这种方法类似于在执行过程中根本不使用任何线程。唯一的性能差异将是开始或者连接每个线程所花费的额外时间,不利于实现目标。
如果真的想要使用线程,可以将三个不同的模型加载到RAM中,每个单独的线程使用一个模型。但本文并没有选择那样做,下面将做出进一步解释。
多进程
多进程有两种方式:通过启动完全独立的进程并连接到它们的输入或输出(使用子进程模块)(
https://docs.python.org/3/library/subprocess.html)或者生成可以继承当前Python解释器进程资源的python进程(使用多进程模块可绕过GIL问题)(
https://docs.python.org/3.4/library/multiprocessing.html)。
这里,一个棘手的部分是如何确保模型不必每次计算推理时都加载到RAM中;大型模型需要很长时间才能加载到内存中。
可以选择采用另一种不同的方法。
使用gunicorn负载平衡
该方法的不同之处在于使用gunicorn worker的功能来平行工作。为此,在之前的模型中需添加另一个层。先前定义的体系结构可以接收多个请求,并在几个worker中同时处理这些请求。将此当作优势。最终模型如下。
最终有两个不同型号的Falcon或Gunicorn服务器
当请求从前端APP发送到API时,它将由第一个Web服务器处理。该Web服务器中会有一个运行API的工作程序。此API负责向第二个Web服务器发送三个相同的请求。API发送的请求包含当前上下文(文档中的前一个句子)以及一些有关参数信息(小型或中型模型,特定top_k值等等)。
第二个Web服务器中有多个worker分别处理请求。三个worker将同时分别处理从API收到的各个请求。在API中使用单独线程,以便将请求并行发送到第二个Web服务器而不是顺序发送(HTTP请求 - >没有GIL问题)。
此体系结构具有其他先前提到的方法所不具备的几个优势:
· 可以生成尽可能多的worker,只要模型的数量能适合人类记忆。如果有一个分布式系统,可以将worker分布到不同的GPU中。
· 每个worker在内存中加载一个模型。因此,与每次加载三个模型相比,可能会加载更多模型(更多的计算能力),例如线程方法。
· 作为Web服务器的worker,模型将始终保持在内存中。
· 架构中的每一步都使用了gunicorn的负载平衡。并不是要简单地产生并行运行进程,要想办法确保每个进程处理与其计算能力相关的负载。如果使用两个具有不同计算能力的GPU,而拥有较低计算能力的GPU所造成的瓶颈对另一个GPU的影响不会像在纯多进程程序中那样大。
图2显示了在初始化期间以及向API发送两个并发请求时,体系结构在内存管理方面的表现。
初始化和并发行为
结果
不出所料,与初始顺序系统相比,使用并行系统时,响应时间方面有了很大改进。对一个需要在三个模型迭代中分解的请求进行基准测试,只需三分之一的初始响应时间,实际的本地HTTP请求只需要几百微秒。
该系统特别适用于垂直扩展,因为它能适应系统的内存和计算能力。但是,它不能与可以执行批量推理的模型进行比较,因为这种方法将在内存中存储三个模型,而如果使用批量推理,则只能存储一个模型。
进一步改进
这个系统是为在机器上运行而设计的,所以没有考虑集装箱化或水平扩展。对于需要处理10万用户的完整生产系统而言,这广受欢迎,也必不可少。
另一项改进是使用TorchScript模块。由于在模型中使用了pytorch,所以可以看到它的torchscript版本,在任何编程语言中进行推理。因此,如果想得到最大限度优化,可以用一种非常低级的语言优化一个更好的、更合适的Web服务器。
这个系统已经证明其价值,因为它在4-GPU(K80)机器上运行时,一周之内处理了超过100,000个不同的请求。
留言 点赞 关注
我们一起分享AI学习与发展的干货
- 上一篇: 推荐6套非常热门的微信小程序开源项目
- 下一篇: 一个貌似简单但会难倒高级前端程序员的面试题
猜你喜欢
- 2025-06-03 推荐6套非常热门的微信小程序开源项目
- 2025-06-03 腾讯开源的Markdown编辑器,开箱即用、轻量简洁、易扩展
- 2025-06-03 挖洞经验|UEditor编辑器存储型XSS漏洞
- 2025-06-03 介绍几款表单设计器(anyreport表单设计器)
- 2025-06-03 来了!JavaScript 最强大的 8 个 DOM API
- 2025-06-03 2014年最优秀JavaScript编辑器大盘点
- 2025-06-03 2021年最值得推荐的13个提高开发效率工具,程序员必备
- 2025-06-03 LATEX文本编辑器:MiKTeX 23.10(中文latex编辑器)
- 2025-06-03 所见即所得的 markdown 编辑器:Typora
- 2025-06-03 刚刚发布!Claude 4连续工作7小时,比Cursor、Copilot还猛?
你 发表评论:
欢迎- 498℃几个Oracle空值处理函数 oracle处理null值的函数
- 494℃Oracle分析函数之Lag和Lead()使用
- 493℃Oracle数据库的单、多行函数 oracle执行多个sql语句
- 481℃0497-如何将Kerberos的CDH6.1从Oracle JDK 1.8迁移至OpenJDK 1.8
- 471℃Oracle 12c PDB迁移(一) oracle迁移到oceanbase
- 467℃【数据统计分析】详解Oracle分组函数之CUBE
- 453℃Oracle有哪些常见的函数? oracle中常用的函数
- 446℃最佳实践 | 提效 47 倍,制造业生产 Oracle 迁移替换
- 最近发表
-
- Spring Boot跨域难题终结者:3种方案,从此告别CORS噩梦!
- 京东大佬问我,SpringBoot为什么会出现跨域问题?如何解决?
- 在 Spring Boot3 中轻松解决接口跨域访问问题
- 最常见五种跨域解决方案(常见跨域及其解决方案)
- Java Web开发中优雅应对跨域问题(java跨域问题解决办法)
- Spring Boot解决跨域最全指南:从入门到放弃?不,到根治!
- Spring Boot跨域问题终极解决方案:3种方案彻底告别CORS错误
- Spring Cloud 轻松解决跨域,别再乱用了
- Github 太狠了,居然把 "master" 干掉了
- IntelliJ IDEA 调试 Java 8,实在太香了
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端缓存 (63)
- 前端react (48)
- 前端aes加密 (58)
- 前端脚手架 (56)
- 前端md5加密 (54)
- 前端富文本编辑器 (47)
- 前端路由 (55)
- 前端数组 (65)
- 前端定时器 (47)
- Oracle RAC (73)
- oracle恢复 (76)
- oracle 删除表 (48)
- oracle 用户名 (74)
- oracle 工具 (55)
- oracle 内存 (50)
- oracle 导出表 (57)
- oracle 中文 (51)
- oracle链接 (47)
- oracle的函数 (57)
- 前端调试 (52)
- 前端登录页面 (48)
本文暂时没有评论,来添加一个吧(●'◡'●)