【自然语言处理】【大模型】大语言模型BLOOM推理工具测试

news/2024/5/20 5:11:14/文章来源:https://blog.csdn.net/bqw18744018044/article/details/129351831

相关博客
【自然语言处理】【大模型】大语言模型BLOOM推理工具测试
【自然语言处理】【大模型】GLM-130B:一个开源双语预训练语言模型
【自然语言处理】【大模型】用于大型Transformer的8-bit矩阵乘法介绍
【自然语言处理】【大模型】BLOOM:一个176B参数且可开放获取的多语言模型
【自然语言处理】【大模型】PaLM:基于Pathways的大语言模型
【自然语言处理】【chatGPT系列】大语言模型可以自我改进
【自然语言处理】【ChatGPT系列】WebGPT:基于人类反馈的浏览器辅助问答
【自然语言处理】【ChatGPT系列】FLAN:微调语言模型是Zero-Shot学习器
【自然语言处理】【ChatGPT系列】ChatGPT的智能来自哪里?
【自然语言处理】【ChatGPT系列】大模型的涌现能力

​ BLOOM的原理见【自然语言处理】【大模型】BLOOM:一个176B参数且可开放获取的多语言模型

​ BLOOM是由HuggingFace推出的大模型,其参数量达到176B(GPT-3是175B)。目前超过100B参数量且能够支持中文的开源大模型只有BLOOM和GLM-130B。由于HuggingFace是著名开源工具Transformers的开发公司,很多推理工具都会支持Transformers中的模型。

​ LLM(大语言模型)推理的两个问题:(1) 单张显卡无法容纳整个模型;(2) 推理速度太慢。本文初步整理了一些推理大模型的工具和代码,并简单测试了推理速度。下面是本文测试的一些背景:

  • 目前是2023年2月

  • 使用7B模型bloom-7b1-mt

  • 4张3090(但在实际推理中仅使用2张3090)

  • 依赖包的版本

    transformers==4.26.0
    tensor-parallel==1.0.24
    deepspeed==0.7.7
    bminf==2.0.1
    

零、辅助函数

# utils.py
import numpy as npfrom time import perf_counterdef measure_latency(model, tokenizer, payload, device, generation_args={}):input_ids = tokenizer(payload, return_tensors="pt").input_ids.to(device)latencies = []# 预热for _ in range(2):_ =  model.generate(input_ids, **generation_args)# 统计时间for _ in range(10):start_time = perf_counter()_ = model.generate(input_ids, **generation_args)latency = perf_counter() - start_timelatencies.append(latency)# 计算统计量time_avg_ms = 1000 * np.mean(latencies) # 延时均值time_std_ms = 1000 * np.std(latencies) # 延时方差time_p95_ms = 1000 * np.percentile(latencies,95) # 延时的95分位数return f"P95延时 (ms) - {time_p95_ms}; 平均延时 (ms) - {time_avg_ms:.2f} +\- {time_std_ms:.2f};"def infer(model, tokenizer, payload, device):input_ids = tokenizer(payload, return_tensors="pt").input_ids.to(device)logits = model.generate(input_ids, num_beams=1, max_length=512)out = tokenizer.decode(logits[0].tolist())return out

一、层并行

​ BLOOM是Huggingface开发的,所以在transformers库中提供了支持。具体来说,在使用from_pretrained加载模型时,指定参数devce_map即可。其通过将模型的不同层放置在不同的显卡上,从而将单个大模型分拆至多张卡上(流水线并行也会将层分拆,然后采用流水线的方式训练模型)。下面是调用的示例代码:

# layer_parallel_test.py
import os
import transformersfrom utils import measure_latency, infer
from transformers import AutoTokenizer, AutoModelForCausalLMtransformers.logging.set_verbosity_error()
os.environ['CUDA_VISIBLE_DEVICES'] = "0,1"def run():model_name = "bigscience/bloomz-7b1-mt"payload = """参考下面的文章,然后用与文章相同的语言回答问题: 段落:当细菌突破免疫系统的防御而开始增生时,疾病会由结核菌感染进展到症状明显的结核病。在原发型结核病 (占 1-5% 的比例),这种现象会在感染刚开始的时候很快的发生。然而>多数人感染模式为潜伏结核感染,通常没有明显症状。在5-10%潜伏结合感染的案例中,这些休眠的细菌经常会在感染后数年的时间制造出活动的结核。 问题:What is the next stage after TB infection?"""tokenizer = AutoTokenizer.from_pretrained(model_name)model = AutoModelForCausalLM.from_pretrained(model_name, device_map="auto")model = model.eval()out = infer(model, tokenizer, payload, model.device)print("="*70+" 模型输入输出 "+"="*70)print(f"模型输入: {payload}")print(f"模型输出: {out}")print("\n\n"+"="*70+" 模型延时测试 "+"="*70)print(measure_latency(model, tokenizer, payload, model.device))print("\n\n"+"="*70+" 显存占用 "+"="*70)print(os.system("nvidia-smi"))if __name__ == "__main__":run()pass

模型的时延结果:

P95延时 (ms) - 118.402308691293; 平均延时 (ms) - 117.72 +- 0.58;

显存占用:

请添加图片描述

二、张量并行

​ 张量并行是将矩阵乘法进行分块,从而将大矩阵拆分为更小的矩阵,这样就能把不同的矩阵放置在不同的显卡上。(具体原理会在后续的文章中介绍)

​ 这里使用开源工具包tensor_parallel来实现。

# tensor_parallel_test.py
import os
import transformers
import tensor_parallel as tpfrom utils import measure_latency, infer
from transformers import AutoTokenizer, AutoModelForCausalLMtransformers.logging.set_verbosity_error()
os.environ['CUDA_VISIBLE_DEVICES'] = "0,1"def run():model_name = "bigscience/bloomz-7b1-mt"payload = """参考下面的文章,然后用与文章相同的语言回答问题: 段落:当细菌突破免疫系统的防御而开始增生时,疾病会由结核菌感染进展到症状明显的结核病。在原发型结核病 (占 1-5% 的比例),这种现象会在感染刚开始的时候很快的发生。然而>多数人感染模式为潜伏结核感染,通常没有明显症状。在5-10%潜伏结合感染的案例中,这些休眠的细菌经常会在感染后数年的时间制造出活动的结核。 问题:What is the next stage after TB infection?"""tokenizer = AutoTokenizer.from_pretrained(model_name)model = AutoModelForCausalLM.from_pretrained(model_name, low_cpu_mem_usage=True)model = tp.tensor_parallel(model, ["cuda:0", "cuda:1"])model = model.eval()out = infer(model, tokenizer, payload, model.device)print("="*70+" 模型输入输出 "+"="*70)print(f"模型输入: {payload}")print(f"模型输出: {out}")print("\n\n"+"="*70+" 模型延时测试 "+"="*70)print(measure_latency(model, tokenizer, payload, model.device))print("\n\n"+"="*70+" 显存占用 "+"="*70)print(os.system("nvidia-smi"))if __name__ == "__main__":run()pass

模型的时延结果:

P95延时 (ms) - 91.34029923006892; 平均延时 (ms) - 90.66 +- 0.46;

显存占用:

请添加图片描述

三、模型量化

​ 原理见【自然语言处理】【大模型】用于大型Transformer的8-bit矩阵乘法介绍。

​ 量化是一种常见的模型压缩技术,核心思想是将模型参数从高精度转换为低精度。在BLOOM上使用8-bit量化只需要在调用from_pretrained时,设置参数load_in_8bit=True, device_map="auto"

​ (注:bloom在实现量化时,会按照是否超越阈值来分拆矩阵,然后对低于阈值的模型参数进行量化,这会拖慢推理速度)

# int8_test.py
import os
import transformersfrom utils import measure_latency, infer
from transformers import AutoTokenizer, AutoModelForCausalLMtransformers.logging.set_verbosity_error()
os.environ['CUDA_VISIBLE_DEVICES'] = "0,1"def run():model_name = "bigscience/bloomz-7b1-mt"payload = """参考下面的文章,然后用与文章相同的语言回答问题: 段落:当细菌突破免疫系统的防御而开始增生时,疾病会由结核菌感染进展到症状明显的结核病。在原发型结核病 (占 1-5% 的比例),这种现象会在感染刚开始的时候很快的发生。然而>多数人感染模式为潜伏结核感染,通常没有明显症状。在5-10%潜伏结合感染的案例中,这些休眠的细菌经常会在感染后数年的时间制造出活动的结核。 问题:What is the next stage after TB infection?"""max_memory_mapping = {0: "24GB", 1: "0GB"}tokenizer = AutoTokenizer.from_pretrained(model_name)model = AutoModelForCausalLM.from_pretrained(model_name, load_in_8bit=True, device_map="auto", max_memory=max_memory_mapping)model = model.eval()out = infer(model, tokenizer, payload, model.device)print("="*70+" 模型输入输出 "+"="*70)print(f"模型输入: {payload}")print(f"模型输出: {out}")print("\n\n"+"="*70+" 模型延时测试 "+"="*70)print(measure_latency(model, tokenizer, payload, model.device))print("\n\n"+"="*70+" 显存占用 "+"="*70)print(os.system("nvidia-smi"))if __name__ == "__main__":run()pass

模型的时延结果:

P95延时 (ms) - 147.89210632443428; 平均延时 (ms) - 143.30 +- 3.02;

显存占用:

请添加图片描述

四、DeepSpeed-Inference

​ DeepSpeed-Inference是分布式训练工具DeepSpeed中用户模型推理的功能。

# deepspeed_test.py
import os
import torch
import deepspeed
import transformersfrom utils import measure_latency, infer
from transformers import AutoTokenizer, AutoModelForCausalLMtransformers.logging.set_verbosity_error()
os.environ['CUDA_VISIBLE_DEVICES'] = "0,1"def run():model_name = "bigscience/bloomz-7b1-mt"payload = """参考下面的文章,然后用与文章相同的语言回答问题: 段落:当细菌突破免疫系统的防御而开始增生时,疾病会由结核菌感染进展到症状明显的结核病。在原发型结核病 (占 1-5% 的比例),这种现象会在感染刚开始的时候很快的发生。然而>多数人感染模式为潜伏结核感染,通常没有明显症状。在5-10%潜伏结合感染的案例中,这些休眠的细菌经常会在感染后数年的时间制造出活动的结核。 问题:What is the next stage after TB infection?"""tokenizer = AutoTokenizer.from_pretrained(model_name)model = AutoModelForCausalLM.from_pretrained(model_name, torch_dtype=torch.float16)model = deepspeed.init_inference(model=model,      # Transformers模型mp_size=2,        # 模型并行数量dtype=torch.float16, # 权重类型(fp16)replace_method="auto", # 让DS自动替换层replace_with_kernel_inject=True, # 使用kernel injector替换)out = infer(model, tokenizer, payload, model.module.device)print("="*70+" 模型输入输出 "+"="*70)print(f"模型输入: {payload}")print(f"模型输出: {out}")print("\n\n"+"="*70+" 模型延时测试 "+"="*70)print(measure_latency(model, tokenizer, payload, model.module.device))print("\n\n"+"="*70+" 显存占用 "+"="*70)print(os.system("nvidia-smi"))if __name__ == "__main__":run()pass

这里不能使用python来自动脚本,需要使用下面的命令:

deepspeed --num_gpus 2 --master_port 60000 deepspeed_test.py

模型的时延结果:

P95延时 (ms) - 31.88958093523979; 平均延时 (ms) - 30.75 +- 0.64;

显存占用:

请添加图片描述

五、BMInf

​ BMInf能够在单张显卡下加载完整的模型,但是推理速度非常慢(应该是利用了Offload技术)。

import os
import bminf
import transformersfrom utils import measure_latency, infer
from transformers import AutoTokenizer, AutoModelForCausalLMtransformers.logging.set_verbosity_error()
os.environ['CUDA_VISIBLE_DEVICES'] = "0,1"def run():model_name = "bigscience/bloomz-7b1-mt"payload = """参考下面的文章,然后用与文章相同的语言回答问题: 段落:当细菌突破免疫系统的防御而开始增生时,疾病会由结核菌感染进展到症状明显的结核病。在原发型结核病 (占 1-5% 的比例),这种现象会在感染刚开始的时候很快的发生。然而>多数人感染模式为潜伏结核感染,通常没有明显症状。在5-10%潜伏结合感染的案例中,这些休眠的细菌经常会在感染后数年的时间制造出活动的结核。 问题:What is the next stage after TB infection?"""tokenizer = AutoTokenizer.from_pretrained(model_name)model = AutoModelForCausalLM.from_pretrained(model_name, low_cpu_mem_usage=True)model = model.eval()model = bminf.wrapper(model, quantization=False, memory_limit=8 << 30)out = infer(model, tokenizer, payload, model.device)print("="*70+" 模型输入输出 "+"="*70)print(f"模型输入: {payload}")print(f"模型输出: {out}")print("\n\n"+"="*70+" 模型延时测试 "+"="*70)print(measure_latency(model, tokenizer, payload, model.device))print("\n\n"+"="*70+" 显存占用 "+"="*70)print(os.system("nvidia-smi"))if __name__ == "__main__":run()pass

模型的时延结果:

P95延时 (ms) - 719.2403690889478; 平均延时 (ms) - 719.05 +- 0.14;

显存占用:

请添加图片描述

六、结论

  • DeepSpeed-Inference的速度是最快的;
  • 张量并行比自带的层并行快一些;
  • 8 bit量化虽然速度慢一些,但是能够实现单卡推理;
  • BMInf虽然速度最慢,但是其可能在不损失模型精度的情况下,单卡推理;

说明

  • 本文并不是这些推理工具的最佳实践,仅是罗列和展示这些工具如何使用;
  • 这些工具从不同的角度来优化模型推理,对于希望进一步了解具体如何实现的人来说,可以阅读源代码;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_77923.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2023-03-05:ffmpeg推送本地视频至lal流媒体服务器(以RTMP为例),请用go语言编写。

2023-03-05&#xff1a;ffmpeg推送本地视频至lal流媒体服务器&#xff08;以RTMP为例&#xff09;&#xff0c;请用go语言编写。 答案2023-03-05&#xff1a; 使用 github.com/moonfdd/ffmpeg-go 库。 先启动lal流媒体服务器软件&#xff0c;然后再执行命令&#xff1a; go…

QT配置安卓环境(保姆级教程)

目录 下载环境资源 JDK1.8 NDK SDK ​安装QT 配置环境 下载环境资源 JDK1.8 介绍JDK是Java开发的核心工具&#xff0c;为Java开发者提供了一套完整的开发环境&#xff0c;包括开发工具、类库和API等&#xff0c;使得开发者可以高效地编写、测试和运行Java应用程序。 下载…

Java分布式解决方案(三)

文章目录&#x1f525;MySQL事务-MySQL中锁的分类&#x1f525;MySQL事务-MySQL中的死锁问题&#x1f525;MySQL事务-MySQL中锁的分类 MySQL中锁的分类 从本质上讲&#xff0c;锁是一种协调多个进程或多个线程对某一资源的访问的机制&#xff0c;MySQL使用锁和MVCC机制实现了…

【博学谷学习记录】超强总结,用心分享|狂野大数据课程【Spark SQL函数定义】的总结分析

5.1 如何使用窗口函数 回顾: 窗口函数格式:分析函数 over(partition by xxx order by xxx [asc|desc] [rows between xxx and xxx])学习的相关分析函数有那些? 第一类: row_number() rank() dense_rank() ntile()第二类: 和聚合函数组合使用 sum() avg() max() min() count…

sklearn使用入门

文章目录1.机器学习1.1 机器学习简介1.2 有监督学习(supervised learning)1.3 无监督学习(unsupervised learning)1.4 半监督学习2. 机器学习工具SKlearn2.1 sklearn2.2 sklearn常用模块2.2.1 分类2.2.2 回归2.2.3 聚类2.2.4 降维2.2.5 模型选择2.2.6 数据预处理2.3 sklearn使用…

ChatGPT vs Bard 背后的技术对比分析和未来发展趋势

ChatGPT vs Bard 背后的技术对比分析和未来发展趋势 目录 ChatGPT vs Bard 背后的技术对比分析和未来发展趋势

SQLI-Labs(3)8-14关【布尔盲注和时间盲注】

目录 第八关 第九关&#xff1a; 第十关 第十一关 第十二关 第十三关 第十四关 第八关 我们用测试语句来测试是否为注入点 从上图中得知存在注入点&#xff0c;那么接下来就是爆列 一共有三列&#xff0c;接下来用union select 和报错注入都试一下发现没有回显点&…

嵌入式安防监控项目——前期知识复习

目录 一、概述 二、C语言 三、数据结构 四、IO进程 五、网络 六、ARM体系结构和接口技术 七、系统移植 八、内核驱动 一、概述 我再报班之前学过51和32&#xff0c;不过都是自学的。报班开始先从应用层入手的&#xff0c;C语言和数据结构。只要是个IT专业的大学这都是必…

cadence专题【1】--多引脚IC如何创建orcad原理图库

cadense下载说明新建工程一、采用传统方式创建1、新建库文件2、放置pin array3、修改管脚信息二、采用电子表格方式创建1、新建库文件2、Ctrlc、Ctrlvcadense下载说明 cadence是目前最流行的EDA&#xff0c;下载装机全交给阿狸狗即可。 浏览器搜索cadence吴川斌或点击链接: ht…

既然有MySQL了,为什么还要有Redis?

目录专栏导读一、同样是缓存&#xff0c;用map不行吗&#xff1f;二、Redis为什么是单线程的&#xff1f;三、Redis真的是单线程的吗&#xff1f;四、Redis优缺点1、优点2、缺点五、Redis常见业务场景六、Redis常见数据类型1、String2、List3、Hash4、Set5、Zset6、BitMap7、Bi…

GDScript 导出变量 (Godot4.0)

概述 导出变量的功能在3.x版本中也是有的&#xff0c;但是4.0版本对其进行了语法上的改进。 导出变量在日常的游戏制作中提供节点的自定义参数化调节功能时非常有用&#xff0c;除此之外还用于自定义资源。 本文是&#xff08;Bilibili巽星石&#xff09;在4.0官方文档《GDScr…

Java学习笔记 --- jQuery

一、jQuery介绍 jQuery&#xff0c;顾名思义&#xff0c;也就是JavaScript和查询&#xff08;Query&#xff09;&#xff0c;它就是辅助JavaScript开发的js类库。它的核心思想是write less&#xff0c;do more&#xff08;写得更少&#xff0c;做得更多&#xff09;&#xff0c…

C语言实现扫雷【详细讲解+全部源码】

扫雷的实现1. 配置运行环境2. 扫雷游戏的初步实现2.1 建立扫雷分布模块2.2 创建名为board的二维数组并进行棋盘初始化2.3 打印棋盘3. 接下来该讨论的事情3.1 布置雷3.2 排查雷3.3 统计坐标周围有几个雷4. 完整扫雷游戏的实现4.1 game.h4.2 game.c4.3 扫雷.c1. 配置运行环境 本游…

信息安全与数学基础-笔记-③一次同余方程

知识目录一次同余方程的解中国剩余定理中国剩余定理的应用一次同余方程的解 本文只研究一次同余方程的解。 f(x) 三 0 (mod m)&#xff0c; 若有一个s能够满足该式子&#xff0c;那么该数字就是该式子的解&#xff0c; 在同余方程式中的解一般写成&#xff1a;x三s (mod m) 同…

04_Apache Pulsar的可视化监控管理、Apache Pulsar的可视化监控部署

1.4.Apache Pulsar的可视化监控管理 1.4.1.Apache Pulsar的可视化监控部署 1.4.Apache Pulsar的可视化监控管理 1.4.1.Apache Pulsar的可视化监控部署 第一步&#xff1a;下载Pulsar-Manager https://archive.apache.org/dist/pulsar/pulsar-manager/pulsar-manager-0.2.0/…

分布式对象存储——Apache Hadoop Ozone

前言 本文隶属于专栏《大数据技术体系》&#xff0c;该专栏为笔者原创&#xff0c;引用请注明来源&#xff0c;不足和错误之处请在评论区帮忙指出&#xff0c;谢谢&#xff01; 本专栏目录结构和参考文献请见大数据技术体系 1. 概述 Ozone是Apache Hadoop项目的子项目&#xf…

嵌入式和Python(二):python初识及其基本使用规则

目录 一&#xff0c;python基本特点 二&#xff0c;python使用说明 ● 两种编程方式 ① 交互式编程 ② 脚本式编程 ● python中文编码 ● python行和缩进 ● python引号 ● python空行 ● python等待用户输入 ① 没有转换变量类型 ② 转换变量类型 ● python变…

Raspbian镜像无头烧录

Raspbian镜像无头烧录1. 源由2. 需求3. 分析4. 步骤4.1 删除tf卡分区内容4.2 balena烧录镜像4.3 配置USB直接登录4.4 配置WiFi 2.4G网络登录4.5 修改登录账号密码4.6 数据同步和弹出tf卡5. 登录5.1 登录异常处理5.2 WiFi 2.4G网络登录5.3 USB直接登录6. 参考资料7. 补充资料这里…

套接字实现TCP

套接字 套接字的意义就是客户端与服务器进行双向通信的端点&#xff0c;如果有不理解点上面套接字三字更近距离了解套接字。 网络套接字与客户连接的特定网络有关的服务端口号&#xff0c;这个端口号允许linux进入特定的端口号的连接转到正确的服务器进程。 套接字通信的建立过…

JVM运行时数据区—程序计数器

JVM中的程序计数寄存器&#xff08;Program Counter Register&#xff09;中&#xff0c;Register的命名源于CPU的寄存器&#xff0c;寄存器存储指令相关的现场信息。CPU只有把数据装载到寄存器才能够运行。JVM中的PC寄存器是对物理PC寄存器的一种抽象模拟。 一个线程对应一个…