如何运行大模型

简介

要想了解一个模型的效果,对模型进行一些评测,或去评估是否能解决业务问题时,首要任务是如何将模型跑起来。目前有较多方式运行模型,提供client或者http能力。

名词解释

浮点数表示法

一个浮点数通常由三部分组成:符号位、指数部分和尾数部分(也称为小数部分或 mantissa)。

  1. 符号位:决定了数的正负。在大多数浮点数格式中,符号位通常占1位,0表示正数,1表示负数。
  2. 指数部分(Exponent):表示数值的大小或缩放因子。在浮点数中,指数部分采用偏移码(bias encoding)来表示,以确保0的特殊处理和指数的正负表示。例如,在IEEE 754标准的单精度(float32)中,指数部分实际占8位,但由于偏移码(通常偏移127),实际的指数范围是从-126到127。
  3. 尾数部分(Mantissa或Fraction):代表小数部分,它是一个小于1的正数,用来精确表示数值的非整数部分。在标准的浮点数表示中,尾数部分总是以1开头(这个1是隐含的,不占用实际的位),然后是若干位来表示其余的数字。例如,在float32中,尾数部分实际有23位(因为隐含了一个1),这提供了很高的精度。

以一个具体的例子来说明,假设我们有一个二进制浮点数,格式为1位符号位,8位指数部分,23位尾数部分。一个浮点数的值计算方式大致为:(-1)^符号位 × 1.尾数部分 × 2^(指数部分 - 偏移值)。

torch_dtype

在PyTorch中,torch_dtype参数是一个用于指定张量(tensor)数据类型的选项,通常可用以下取值:

  • auto:自动判断,读取模型目录的config.json中配置的torch_dtype值,如果是bfloat16且当前硬件支持bfloat16,则优先使用这种;判断是否支持float16,不支持才使用float32。
  • torch.bfloat16:1位符号位、8位指数部分、7位尾数,此种类型牺牲了一些精度,但保持了与单精度float32相同的指数范围,这在处理大范围数值和保持动态范围方面非常有利。
  • torch.float16:标准的16位浮点数格式,由1位符号位、5位指数部分、10位小数部分组成。与bfloat16相比,它有更精细的尾数精度,但在指数范围上较窄,这意味着它在处理非常大或非常小的数值时可能不够稳定。
  • torch.float32:单精度浮点数,由1位符号位、8位指数部分(使用偏移编码,偏移值为127)和23位尾数部分组成。
  • torch.float64:由1位符号位、11位指数部分(使用偏移编码,偏移值为1023)和52位尾数部分组成。
  • 其它:torch.int8, unit8, int32, int64等类型。

chat template

基础模型只提供了completion能力,在大模型发展的过程中,很多公司都推出了针对聊天的chat模型,这类模型将用户分为了system, user, assistant角色,将不同角色的输入内容用特定的token分隔开,使得模型能够更好的理解上下文,给出更精确的答复。

此外,模型在训练的时候,就提供了一些数据集,使得system中提供的消息优先级高于user,多模型的安全性也有一定的帮助(避免用户在user message中改变system message对于模型的一些设置)

transformers框架已经原生支持了这一模式,通过执行以下代码帮助拼接prompt

from transformers import AutoModelForCausalLM, AutoTokenizertokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen1.5-7B-Chat")
prompt = "Give me a short introduction to large language model."
messages = [{"role": "system", "content": "You are a helpful assistant."},{"role": "user", "content": prompt}
]
# 这样不进行tokenize测试下效果(直接输出拼接后的string)
# 如果想直接进行tokenize,需要传递参数:tokenize=True(默认就是), return_tensors='pt'
text = tokenizer.apply_chat_template(messages,tokenize=False,add_generation_prompt=True
)

以上代码会去加载模型目录的tokenizer_config.json文件,读取需要的信息,这里以qwen1.5模型为例,需要读取json中的以下字段:

{"chat_template": "{% for message in messages %}{% if loop.first and messages[0]['role'] != 'system' %}{{ '<|im_start|>system\nYou are a helpful assistant.<|im_end|>\n' }}{% endif %}{{'<|im_start|>' + message['role'] + '\n' + message['content'] + '<|im_end|>' + '\n'}}{% endfor %}{% if add_generation_prompt %}{{ '<|im_start|>assistant\n' }}{% endif %}",
}

由于指定了add_generation_prompt=True,生成的拼接后的字符串如下:

<|im_start|>system
You are a helpful assistant.<|im_end|>
<|im_start|>user
Give me a short introduction to large language model.<|im_end|>
<|im_start|>assistant

CUDA_VISIBLE_DEVICES

在 PyTorch 中,你可以使用 CUDA_VISIBLE_DEVICES 环境变量来指定可见的 GPU 设备。这个环境变量的值是一个以逗号分隔的 GPU 设备索引列表,可以是单个索引,也可以是多个索引组成的列表。

export CUDA_VISIBLE_DEVICES=0,1  # 只使用 GPU 0 和 GPU 1
export CUDA_VISIBLE_DEVICES=0  # 只使用 GPU 0
# 不使用任何 GPU(将模型运行在 CPU 上)
export CUDA_VISIBLE_DEVICES=
export CUDA_VISIBLE_DEVICES=""  

device_map

device_map 参数是 Hugging Face transformers 库中一种用于控制模型在多个设备上分配的参数。它可以让你明确指定模型的哪些部分应该分配到哪个设备上,以优化模型的性能和内存使用。可以取以下值:

  • auto:自动选择合适的设备来分配模型,根据系统的可用资源和模型的大小智能选择设备。目前auto和balanced效果一样,但后续可能会修改。
  • balanced:均匀地将模型分配到所有可用设备上,以平衡内存使用。
  • balanced_low_0:将模型均匀地分配到除第一个 GPU 外的所有 GPU 上,并且只将不能放入其他 GPU 的部分放在 GPU 0 上。
  • sequential:将模型层按顺序分配到多个设备上,模型的第一层分配给第一个设备,第二层分配给第二个设备,依此类推。当模型层数超过可用设备数量时,会循环回到第一个设备再次分配模型层。
  • 自定义映射:你还可以提供一个字典,明确指定每个模型层应该分配到哪个设备上。

查看设备分配的情况

# 查看主设备
model = AutoModelForCausalLM.from_pretrained(model_name, device_map="auto")
print(model.device)# 查看每一层所在的设备
model = AutoModelForCausalLM.from_pretrained(model_name, device_map="auto")
for name, param in model.named_parameters():print(name, param.device)

max_memory

当模型在多个设备上运行时,max_memory 参数可以帮助你限制每个设备上模型的内存使用,以防止内存溢出或超出系统资源限制。你可以提供一个字典,将设备名称(例如 "cuda:0""cuda:1""cpu")映射到相应的最大内存使用量(例如 "10GB""20GB""10240MB"

max_memory = {0:'5GB', 1:'13GB'}
model = AutoModelForCausalLM.from_pretrained(model_name, device_map="auto", max_memory=max_memory)

查看每个卡的gpu使用情况和能分配的最大内存

# 这里的gpu_id是基于CUDA_VISIBLE_DEVICES可见设备,不是实际的卡位置
num_gpus = torch.cuda.device_count()
for gpu_id in range(num_gpus):torch.cuda.set_device(gpu_id)allocated_memory = torch.cuda.memory_allocated(gpu_id)max_memory_allocated = torch.cuda.max_memory_allocated(gpu_id)print(f"GPU {gpu_id}: Allocated Memory: {allocated_memory / 1024**3:.2f} GB, Max Allocated Memory: {max_memory_allocated / 1024**3:.2f} GB")

下载模型

驱动下载:https://www.nvidia.com/Download/index.aspx?lang=en-us

可以通过以下网站搜索模型:

  • https://huggingface.co (基于transformers架构模型的官方地址,一般新模型这里第一时间商家,可能需要翻墙)

  • https://hf-mirror.com (huggingface的镜像站)

  • https://www.modelscope.cn (阿里云推出的一个模型开放平台,国内下载速度较快,但是更新可能不是太及时)

设置pip镜像站:export PIP_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simple

运行模型的时候,如果模型不存在会自动去下载模型,你也可以提前通过以下方式将模型下载好:

通过hugging face下载

pip install huggingface_hub
# 设置镜像站
export HF_ENDPOINT=https://hf-mirror.com
# 修改模型下载的目录(可选,默认是:~/.cache/huggingface/hub)
export HF_HUB_CACHE=/data/modelscope
# 需要授权的仓库需要登录(可选:https://huggingface.co/settings/tokens)
huggingface-cli login --token <your hugging face token>
# 下载qwen1.5-7b-chat模型
huggingface-cli download --resume-download Qwen/Qwen1.5-7B-Chat

通过modelscope下载

pip install modelscope
# 修改模型下载的目录(可选,默认是:~/.modelscope)
export MODELSCOPE_CACHE=/data/modelscope# python3
from modelscope import snapshot_download
model_dir = snapshot_download('qwen/Qwen1.5-7B-Chat')

运行模型

为了支持模型的版本控制、快速下载和增量更新,huggingface下载的模型结构blobsrefssnapshot几个目录:

  • blobs: 这个目录存储了模型的实际权重数据和其他二进制文件。这些文件通常很大,包含了模型训练得到的参数。每个blob可以看作是一个独立的数据块,这样设计有利于分块下载和缓存,特别是在更新模型时,如果只有少量更改,用户只需下载变化的部分。

  • refs: 这部分涉及到版本控制。它存储了指向特定模型版本的引用,包括提交哈希(commit hashes)或者其他版本标识符。这使得用户可以明确地指定使用模型的哪个版本,同时也方便开发者维护模型的历史变更。

  • snapshot: 这个目录通常包含了一个模型版本的快照,它是一个特定时间点模型的状态。快照通常包含了指向blobs中具体权重文件的指针,确保了模型的完整下载和加载。以commit id作为文件夹。

modelscope下载下来的模型文件并没有按照这个规则,它直接存储的是模型的检查点(checkpoint,包含权重文件、状态、配置等),加载modelscope下载的模型,需要导入modelscope相应的包,如:

# huggingface 风格
from transformers import AutoModelForCausalLM, AutoTokenizer# modelscope 风格
from modelscope import AutoModelForCausalLM, AutoTokenizer

也可以直接将模型的目录作为checkpoint_path参数传入,这样huggingface就会作为checkpoint去加载模型,而不是去下载。

import os
from transformers import AutoModelForCausalLM, AutoTokenizer# modelscope下载模型的存储目录,这里以qwen1.5-7b-chat作为示例
checkpoint_path = os.getenv('MODELSCOPE_CACHE') + "/qwen/Qwen1___5-7B-Chat"
model = AutoModelForCausalLM.from_pretrained(checkpoint_path, torch_dtype="auto", device_map="auto").eval()
tokenizer = AutoTokenizer.from_pretrained(checkpoint_path)

阻塞运行模型

模型下载页面一般提供了运行模型的测试代码,有些在github仓库中提供了运行示例。

from transformers import AutoModelForCausalLM, AutoTokenizer
device = "cuda"  # the device to load the model ontocheckpoint_path = "Qwen/Qwen1.5-7B-Chat"
model = AutoModelForCausalLM.from_pretrained(checkpoint_path,torch_dtype="auto",device_map="auto"
).eval()
tokenizer = AutoTokenizer.from_pretrained(checkpoint_path)prompt = "Give me a short introduction to large language model."
messages = [{"role": "system", "content": "You are a helpful assistant."},{"role": "user", "content": prompt}
]
text = tokenizer.apply_chat_template(messages,tokenize=False,add_generation_prompt=True
)
model_inputs = tokenizer([text], return_tensors="pt").to(device)generated_ids = model.generate(model_inputs.input_ids,max_new_tokens=512
)
generated_ids = [output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)
]response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
print(response)

流式运行模型

from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer
from threading import Thread
device = "cuda"  # the device to load the model ontocheckpoint_path = "Qwen/Qwen1.5-7B-Chat"
model = AutoModelForCausalLM.from_pretrained(checkpoint_path,torch_dtype="auto",device_map="auto"
).eval()
tokenizer = AutoTokenizer.from_pretrained(checkpoint_path)prompt = "Give me a short introduction to large language model."
messages = [{"role": "system", "content": "You are a helpful assistant."},{"role": "user", "content": prompt}
]
input_ids = tokenizer.apply_chat_template(messages, add_generation_prompt=True, return_tensors='pt').to(device)
streamer = TextIteratorStreamer(tokenizer=tokenizer, skip_prompt=True, timeout=60.0, skip_special_tokens=True)generation_kwargs = dict(input_ids=input_ids, streamer=streamer, max_new_tokens=20)
thread = Thread(target=model.generate, kwargs=generation_kwargs)
thread.start()for new_text in streamer:print(new_text, end='', flush=True)

并行推理

通过并行计算来利用多GPU资源分为两种场景:

  • torch.nn.DataParallel:多个GPU上并行处理数据批次(data batches)来加速训练。它在单个节点上工作,自动将输入数据分割成多个部分,每个部分在不同的GPU上进行前向传播,然后将结果合并。它通常通过模型的复制来实现并行计算,每个GPU上都有一个模型副本。
  • model.parallelize:它不仅在数据层面并行,还在模型层面并行,利用了NCCL等库来协调多GPU间通信,可以对模型的不同层进行并行计算。适用于大型模型的训练,尤其是那些单个GPU内存无法容纳的模型,或者需要在多节点多GPU环境下进行分布式训练的情况。
数据批次并行
import osimport torch
from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer
from threading import Threaddevice = "cuda"  # the device to load the model onto
checkpoint_path = os.getenv('MODELSCOPE_CACHE') + "/qwen/Qwen1___5-7B-Chat"
model = AutoModelForCausalLM.from_pretrained(checkpoint_path,torch_dtype="auto",device_map="auto"
).eval()
if torch.cuda.is_available():num_gpus = torch.cuda.device_count()if num_gpus > 1:print(f"Found {num_gpus} GPUs, model is now parallelized.")model = torch.nn.DataParallel(model)tokenizer = AutoTokenizer.from_pretrained(checkpoint_path)prompt = "Give me a short introduction to large language model."
messages = [{"role": "system", "content": "You are a helpful assistant."},{"role": "user", "content": prompt}
]
input_ids = tokenizer.apply_chat_template(messages, add_generation_prompt=True, return_tensors='pt').to(device)
streamer = TextIteratorStreamer(tokenizer=tokenizer, skip_prompt=True, timeout=60.0, skip_special_tokens=True)generation_kwargs = dict(input_ids=input_ids, streamer=streamer, max_new_tokens=512)
thread = Thread(target=model.generate, kwargs=generation_kwargs)
thread.start()for new_text in streamer:print(new_text, end='', flush=True)
模型&数据批次并行

并不是所有的模型都支持这种方式

import osimport torch
from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer
from threading import Threaddevice = "cuda"  # the device to load the model onto
checkpoint_path = os.getenv('MODELSCOPE_CACHE') + "/qwen/Qwen1___5-7B-Chat"
model = AutoModelForCausalLM.from_pretrained(checkpoint_path,torch_dtype="auto",device_map="auto"
).eval()
if torch.cuda.is_available():num_gpus = torch.cuda.device_count()if num_gpus > 1:print(f"Found {num_gpus} GPUs, model is now parallelized.")model.parallelize()tokenizer = AutoTokenizer.from_pretrained(checkpoint_path)prompt = "Give me a short introduction to large language model."
messages = [{"role": "system", "content": "You are a helpful assistant."},{"role": "user", "content": prompt}
]
input_ids = tokenizer.apply_chat_template(messages, add_generation_prompt=True, return_tensors='pt').to(device)
streamer = TextIteratorStreamer(tokenizer=tokenizer, skip_prompt=True, timeout=60.0, skip_special_tokens=True)generation_kwargs = dict(input_ids=input_ids, streamer=streamer, max_new_tokens=512)
thread = Thread(target=model.generate, kwargs=generation_kwargs)
thread.start()for new_text in streamer:print(new_text, end='', flush=True)

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

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

相关文章

谷粒商城实战(029 业务-订单支付模块-支付宝支付2)

Java项目《谷粒商城》架构师级Java项目实战&#xff0c;对标阿里P6-P7&#xff0c;全网最强 总时长 104:45:00 共408P 此文章包含第305p-第p310的内容 代码编写 前端代码 这里使用的是jsp 在这里引用之前配置的各种支付信息 在AlipayConfig.java里 这里是调用阿里巴巴写…

AI大模型日报#0527:豆包大模型披露评测成绩、天工AI日活超100万、AI初创集体跳槽OpenAI

导读&#xff1a;AI大模型日报&#xff0c;爬虫LLM自动生成&#xff0c;一文览尽每日AI大模型要点资讯&#xff01;目前采用“文心一言”&#xff08;ERNIE 4.0&#xff09;、“零一万物”&#xff08;Yi-Large&#xff09;生成了今日要点以及每条资讯的摘要。欢迎阅读&#xf…

PyQt5-新手避坑指南(持续更新)

文章目录 一&#xff0e;前言二&#xff0e;开发环境三&#xff0e;坑1.程序没有详细报错就退出了2.qrc资源文件的使用3.QLabel文字自动换行4.图片自适应大小5.checkbox自定义样式后✓不见了6.多线程 四&#xff0e;记录 一&#xff0e;前言 本篇博客整理了一些初学者容易犯的…

技术贴 | Query 物理计划构建指南

在往期博客《执行器 - Query 执行详解》中&#xff0c;我们介绍到到一条 Query 的 SQL 语句需要经过&#xff1a;词法分析 —— 生成 AST 语法树 —— 生成物理计划。本期博客我们接续上篇讲解一条 Query 语句物理计划的具体结构&#xff0c;以及如何构建物理计划。 物理计划是…

Jmeter环境安装(超级简单)

Jmeter的安装是非常简单的&#xff0c;只需要将下载的安装包解压后&#xff0c;就可以运行了&#xff01;&#xff01; 一、首先要下载Jmeter 1.1、官网下载&#xff1a; 下载最新版&#xff1a;https://jmeter.apache.org/download_jmeter.cgi https://jmeter.apache.org/…

论文阅读》学习了解自己:一个粗略到精细的个性化对话生成的人物感知训练框架 AAAI 2023

《论文阅读》学习了解自己&#xff1a;一个粗略到精细的个性化对话生成的人物感知训练框架 AAAI 2023 前言 简介研究现状任务定义模型架构Learning to know myselfLearning to avoid Misidentification损失函数实验结果消融实验 前言 亲身阅读感受分享&#xff0c;细节画图解释…

代码随想录算法训练营第四十一天 | 理论基础、509. 斐波那契数、70. 爬楼梯、746. 使用最小花费爬楼梯

理论基础 代码随想录 视频&#xff1a;从此再也不怕动态规划了&#xff0c;动态规划解题方法论大曝光 &#xff01;| 理论基础 |力扣刷题总结| 动态规划入门_哔哩哔哩_bilibili 动归五部曲 1.dp数组以及下标的含义 2.递推公式 3.dp数组如何初始化 4.遍历顺序(例如先背包再…

一个程序员的牢狱生涯(40)好事

星期一 好 事 小X州脸上的掌印是谁留下的? 我想起我们排队去小卖铺的时候,号子里有几个人没有出去。头铺应该不会动手的,老汉整天闷着不说话,也不会是他,那就只剩下了大镣!不过小X州这小子也是该他挨打,刚惹了大镣不说,在大家都去小卖铺的时候他还没去,这不是自己上赶…

java_方法重写(覆盖)

介绍 现在我们来试一下 代码 父类 package b;public class father_ {//father class//4attributepublic void cry() {System.out.println("小动物叫唤");} } package b; 子类 public class graduate extends father_ {public void cry() {//子类方法//非私有的属性和…

数据访问层设计_4.灵活运用XML Schema

1.XML Schema XML Schema用来描述XML文档合法结构、内容和限制。XML Schema由XML1.0自描述&#xff0c;并且使用了命名空间&#xff0c;有丰富的内嵌数据类型及其强大的数据结构定义功能&#xff0c;充分地改造了并且极大地扩展了DTDs&#xff08;传统描述XML文档结构和内容限…

算法训练营第四十一天 | LeetCode 509 斐波那契数列、LeetCode 70 爬楼梯、LeetCode 746 使用最小花费爬楼梯

LeetCode 509 斐波那契数列 这题动规五部曲都定义得比较明确。首先是dp数组下标&#xff0c;题目中给定F(0) 0说明从0开始&#xff0c;dp[i]直接表示F(i)的值即可。递推公式也直接给出了&#xff0c;也给了开头两个作为递推基础的数值作为初始化依据。遍历顺序也指明是从前往…

有哪些和excel类似或基于excel扩展的软件?

Workfine数字化管理平台是一款易上手、便捷、高效的数字化管理工具&#xff0c;是类excel设计&#xff0c;更容易上手进行企业业务系统的搭建&#xff0c;在信息记录和表格管理方面&#xff0c;比excel更简单易用&#xff0c;在这里&#xff0c;给大家挑几个点展示下~ 首先表格…

oracle碎片整理

1、move碎片整理 1) DECLARE tmp_val VARCHAR2 (500); BEGIN FOR REC IN (SELECT TABLE_NAME FROM USER_TABLES ) LOOP tmp_val:=ALTER TABLE || REC.TABLE_NAME || MOVE; BEGIN EXECUTE IMMEDIATE tmp_val; DBMS_OUTPUT.ENABLE(buffer_size => null); DBMS_OUTPUT.put_l…

一键恢复,U盘被删除文件方法分享

U盘是一种轻巧便携的移动储存工具&#xff0c;在日常的工作以及学习过程中&#xff0c;我们经常性会使用它来传输、备份、存储一些重要文件。然而&#xff0c;随着后期使用频率的增多&#xff0c;会在不同的设备上来回插拔&#xff0c;也就给里面存储文件带来了很大的隐患。比方…

I.MX6ULL的蜂鸣器实验-GPIO输出实验

系列文章目录 I.MX6ULL的蜂鸣器实验 I.MX6ULL的蜂鸣器实验 系列文章目录一、前言二、有源蜂鸣器简介三、硬件原理分析四、程序编写4.1程序编写前提工作4.2程序编写 五、编译下载验证5.1编写 Makefile 和链接脚本5.2编译下载 一、前言 在 I.MX6U-ALPHA 开发板上有一个有源蜂鸣器…

九宫格转圈圈抽奖活动,有加速,减速效果

在线访问demo和代码在底部 代码&#xff0c;复制就可以跑 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><tit…

SpringBootTest测试框架五

示例 package com.xxx;import com.xxx.ut.AbstractBasicTest; import com.xxx.ut.uttool.TestModel; import

Hive操作

–默认路径/user/hive/warehouse. 建数据库不可以指定路径 create database ods_housesys_db; 在ods_housesys_db中建表&#xff0c;指定表路径/user/hdpu/ods_housesys_db/ods_broker。 会自动创建ods_housesys_db/ods_broker两级路径。但是hdpu需要自己创建。 执行语句时要…

强化学习中model-free和model-based

强化学习中model-free和model-based 1.Model-Based 强化学习算法2.Model-Free 强化学习算法3.对比总结 在强化学习&#xff08;Reinforcement Learning, RL&#xff09;中&#xff0c;算法通常分为两大类&#xff1a;model-based 和 model-free。它们的主要区别在于是否显式地构…

Thingsboard规则链:GPS Geofencing Filter节点详解

​​​​​​​ 引言 GPS Geofencing Filter节点具体作用 使用教程 源码浅析 应用场景与案例 物流与运输 农业智能化 城市安全管理 结语 引言 在物联网技术迅速发展的今天&#xff0c;精准的位置服务已成为诸多应用不可或缺的一环。作为物联网平台的佼佼者&…