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

news2024/11/17 7:58:26

相关博客
【自然语言处理】【大模型】大语言模型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 np
  
from time import perf_counter

def 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_time
        latencies.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 transformers

from utils import measure_latency, infer
from transformers import AutoTokenizer, AutoModelForCausalLM

transformers.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 tp

from utils import measure_latency, infer
from transformers import AutoTokenizer, AutoModelForCausalLM

transformers.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 transformers

from utils import measure_latency, infer
from transformers import AutoTokenizer, AutoModelForCausalLM

transformers.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 transformers

from utils import measure_latency, infer
from transformers import AutoTokenizer, AutoModelForCausalLM

transformers.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 transformers

from utils import measure_latency, infer
from transformers import AutoTokenizer, AutoModelForCausalLM

transformers.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.coloradmin.cn/o/390256.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RocksDB 架构

文章目录1、RocksDB 摘要1.1、RocksDB 特点1.2、基本接口1.3、编译2、LSM - Tree2.1、Memtable2.2、WAL2.3、SST2.4、BlockCache3、读写流程3.1、读取流程3.2、写入流程4、LSM-Tree 放大问题4.1、放大问题4.2、compactionRocksDB 是 Facebook 针对高性能磁盘开发开源的嵌入式持…

如何防止用户打开浏览器开发者工具?

大家好&#xff0c;我是前端西瓜哥。作为一名前端开发&#xff0c;在浏览一些网页时&#xff0c;有时会在意一些交互效果的实现&#xff0c;会打开开发者工具查看源码实现。 但有些网站做了防窥探处理&#xff0c;打开开发者工具后&#xff0c;会无法再正常进行网页的操作。 …

Jeston与Px4(四)

ROS控制PX4 上一节里我们已经将mavros和仿真gazebo搭建完毕&#xff0c;这一节将通过ros来实现对接PX4固件的目标 文章目录ROS控制PX41、搭建PX4开发固件环境1、搭建PX4开发固件环境 “永远不要使用sudo来修复权限问题&#xff0c;否则会带来更多的权限问题&#xff0c;需要重…

PMP项目管理引论介绍

目录1. 指南概述和目的1.1 项目管理标准1.2 道德与专业行为规范2 基本要素2.1 项目2.2 项目管理的重要性2.3 项目、项目集、项目组合以及运营管理之间的关系2.3.1 概述2.3.2. 项目组合与项目集管理2.3.3. 运营管理2.3.4. 组织级项目管理和战略2.3.5. 项目管理2.3.6. 运营管理与…

下载BSP并编译内核

前提&#xff1a;用到的开发板100ask_imx6ull 下载BSP 100ask_imx6ull 开发板的 BSP 都保存在 Git 站点上&#xff0c;通过 repo 命令进行统一管理。配置 repo git config --global user.email "user100ask.com" book100ask:~$ git config --global user.name &qu…

spring源码篇(3)——bean的加载和创建

spring-framework 版本&#xff1a;v5.3.19 文章目录bean的加载bean的创建总结getBean流程createBean流程doCreateBean流程bean的加载 beanFactory的genBean最常用的一个实现就是AbstractBeanFactory.getBean()。 以ApplicationContext为例&#xff0c;流程是: ApplicationCon…

01 C语言计算

C语言计算 1、变量 用途&#xff1a;需要存放输入的数据 定义格式&#xff1a;数据类型 变量名&#xff08;用于区分其他变量&#xff09; 变量名格式&#xff1a;只能由字母/下划线/数字构成&#xff0c;首位不能是数字&#xff1b;且变量名不能是标识符 **变量赋值和初始…

Python每日一练(20230305)

目录 1. 正则表达式匹配 ★★★ 2. 寻找旋转排序数组中的最小值 II ★★★ 3. 删除排序链表中的重复元素 II ★★ 1. 正则表达式匹配 给你一个字符串 s 和一个字符规律 p&#xff0c;请你来实现一个支持 . 和 * 的正则表达式匹配。 . 匹配任意单个字符* 匹配零个或多个…

格式化字符串之在栈上修改got表,执行system(“/bin/sh“)

题目自取&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1sZyC-d47cnrjQ0rmRNLbSg?pwdiung 提取码&#xff1a;iung 这是一题改got表的格式化字符串的例题 这里介绍下pwntools里的一个脚本 fmtstr_payload&#xff1a; 举个例子&#xff0c; payload fmtstr_payl…

谷歌浏览器被hao123网页(或其他网页)劫持了,怎么办?(已解决)

文章目录1、前言2、解决方案2.1、方案一&#xff1a;删除目标内容2.2、方案二&#xff1a;修改浏览器启动时内容2.3、方案三&#xff1a;重命名2.4、方案四&#xff1a;修改WMI脚本2.5、方案五&#xff1a;火绒修复3、总结1、前言 今天打开chrome浏览器&#xff0c;莫名转到hao…

【CMU15-445数据库】bustub Project #2:B+ Tree(下)

Project 2 最后一篇&#xff0c;讲解 B 树并发控制的实现。说实话一开始博主以为这块内容不会很难&#xff08;毕竟有 Project 1 一把大锁摆烂秒过的历史x&#xff09;&#xff0c;但实现起来才发现不用一把大锁真的极其痛苦&#xff0c;折腾了一周多才弄完。 本文分基础版算法…

【uni-app教程】八、UniAPP Vuex 状态管理

八、UniAPP Vuex 状态管理 概念 Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态&#xff0c;并以相应的规则保证状态以一种可预测的方式发生变化。 应用场景 Vue多个组件之间需要共享数据或状态。 关键规则 State&#xff1a…

Linux系统配置nginx

下载安装包wget -c http://nginx.org/download/nginx-1.19.1.tar.gz安装gcc安装包yum install gcc-c安装pre-devel依赖库yum -y install pcre-devel安装openssl依赖库yum -y install openssl openssl-devel解压tar -zxvf 目录名 nginx-1.23.1.tar.gz -C 另外一个目录&#xff0…

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

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

基于Vue3和element-plus实现一个完整的登录功能

先看一下最终要实现的效果:登录页面:注册页面:(1)引入element-plus组件库引入组件库的方式有好多种,在这里我就在main.js全局引入了.npm i element-plus -Smain.js中代码:import { createApp } from "vue"; //element-plus import ElementPlus from "element-pl…

Linux基础篇(七)-- 用户管理

1 创建普通用户 1、创建用户 在 Linux 系统里&#xff0c;root 账户&#xff08;超级管理员&#xff09;拥有整个系统至高无上的权限&#xff0c;比如新建和添加用户。一般我们登录系统时都是以普通账户的身份登录的&#xff0c;要创建用户需要 root 权限&#xff0c;…

项目:手把手实现高并发内存池

一.前言&#xff08;一&#xff09;.项目简介高并发内存池&#xff08;ConCurrentMemoryPool&#xff09;&#xff0c;其原型是google的开源项目tcmalloc。全称是thread-cache-malloc&#xff0c;即线程缓存malloc。应用场景是多线程环境下管理内存&#xff0c;相较于malloc库函…

Mysql数据库的(超详细)安装及环境变量的配置

一、 下载MySQL Mysql官网下载地址&#xff1a;https://downloads.mysql.com/archives/installer/ 1. 选择需要的版本点击Download进行下载 本篇文章选择的8.0.26版本 二、 安装MySQL 1. 选择设置类型 双击运行mysql-installer-community-8.0.26.msi&#xff0c;这里选择是…

GoldenGate(OGG)高可用XAG介绍

XAG介绍: Oracle Grid Infrastructure提供了高可用组件去管理实现集群上面服务的高可用&#xff0c;Oracle Grid Infrastructure agent&#xff08;XAG&#xff09;是Oracle Grid Infrastructure的一个管理组件&#xff0c;通过接口AGCTL在Oracle RAC集群上为应用程序(GoldenG…

【14】linux命令每日分享——userdel删除账号

大家好&#xff0c;这里是sdust-vrlab&#xff0c;Linux是一种免费使用和自由传播的类UNIX操作系统&#xff0c;Linux的基本思想有两点&#xff1a;一切都是文件&#xff1b;每个文件都有确定的用途&#xff1b;linux涉及到IT行业的方方面面&#xff0c;在我们日常的学习中&…