您当前的位置:首页 >> 动态 >  >> 
天天视点!20230423大模型上手笔记

时间:2023-04-23 11:19:16    来源:哔哩哔哩

背景

AI最近又开始火了尝试上手玩玩,我水平还停留在MNIST入门阶段,哪写的不对欢迎大佬指正。

基本概念

模型是一个或一组文件,里面存储了权值的集合,理论上就是一堆浮点数的集合。

模型的生成过程叫做训练,执行过程叫做推理。训练过程中和训练好后的模型可以持久化到硬盘中,结合结构信息可以反向序列化加载到硬件中。


(资料图片仅供参考)

默认的浮点数精度一般是32bit浮点(32fp,32bit,4byte),  半精度.half()就是16bit(16fp,16bit,2byte)

量化说的是把浮点数据继续缩减空间,4bit定点(int4,0.5byte),8bit定点(int8,1byte)

文本是可以转换成高维向量表示的,向量的每个维度都可以用浮点数表达,transformer模型计算(推理)的过程实际是对输入的向量进行补全。

和AI对话只是表现形式,本质上是根据上文猜测下文在概率上最大可能性的结果并进行补全,重复进行这个过程直到长度上限或终止符,然后再以对话形式展现。

huggingface提供了大量模型和数据可供下载,常见的模型是pytorch生成的,格式上大多是一个或多个bin文件,加上一个index.json。

至于模型是怎么训练的暂时还不是很清楚,这种格式能否以更可视化的方式获取信息也不知道。(有没有一种方式能自动计算当前硬件资源,给出合理的模型加载方式呢?)

huggingface同时提供了常用的python库可以方便的自定义模型结构、加载预训练的模型,利用accelerate库可以把模型拆开加载到不同的设备。

nvidia-smi可以看到显卡的显存占用,使用watch -n 1 -c nvidia-smi可以实时监控显存。

工程结构

目前见到的几个模型的项目工程结构从上到下一般为

web-ui(可选):自己手写或者从其他地方抄,常见的是gradio,server_name可以指定监听IP(和其他的软件一样,设置成127.0.0.1仅限本地访问,设置成0.0.0.0监听所有网卡地址), server_port可以指定监听端口,一般不要开启share=True否则会发布到公网

示例代码demo: 一般从github下,里面经常包含一个model(s)的目录

模型本身+模型配置(可选) : 一般从huggingface下,内容会和github有部分重叠。我暂时粗暴的把模型以外的东西复制到model(s)下一份方便python中引用和修改,模型本体存别处

conda虚拟环境:使用conda可以做到和venv、nvm类似的方式管理虚拟环境并相互隔离,包含pytorch底层和其他的python依赖

模型加载技巧记录

huggingface提供了众多抽象好的预训练模型结构,可以通过mixin等方式复用

from_pretrained是个使用python动态实现的模型加载器,内部会动态实例化预训练的模型,直接追踪我没找到链路,但可以通过type(model)的方式获取运行时类名从而debug到真实的模型实现类

from_pretrained参数支持设置load_in_8bit=True,可以在加载时候进行量化。

这个方法底层实际调用的还是pytorch,pytorch中加载模型可以指定map_location。

加载模型的行为默认是加载到内存,然后再转移到显存中。

如果模型太大无法完全加载到内存会报错,根据报错信息可以定位到/conda/envs/py38/lib/python3.8/site-packages/transformers/modeling_utils.py文件,把map_location="cpu" 全部替换为map_location="cuda" 就能直接加载到显卡而不经过内存

如果正常方式无法加载模型,可以借助accelerate库分开加载一个模型的不同部分到不同的设备

主要的变更是用load_checkpoint_and_dispatch替代from_pretrained,关键参数如下

device_map参数可以指定加载策略,  auto可以自动分割模型来最大化利用硬件,infer_auto_device_map也可以生成device_map

也可以传入dict结构指定每个部分使用什么设备加载cpu是使用RAM加载 disk是使用磁盘加载,数字编号是显卡的编号

打印model.hf_device_map可以看到自动生成的device_map结构

max_momory可以限制每个设备初始加载最多可用的资源,dict的key定义同device_map的value,例如:max_memory = {0: "30GIB", 1: "46GiB", "cpu": "32GiB"}

注意这个参数只是设置加载时候的限制,实际推理过程还需要显存,因此使用此种方式需要注意给显卡预留足够的空间用于推理,剩下的部分用CPU RAM凑。

(做个梦:啥时候显存价格能降低到和硬盘一样啊)

如果device_map中出现了disk,则需要指定offload_folder来指定目录,我一般用f"{model_path}/tmp"

记录

chatglm-6b 成功,但有点弱智还需要调教

stablelm-7b 成功,比chatglm强点有限

codegen-6b 16b 失败,加载不了,推迟

MOSS-plugin 成功,看文档是基于codegen的,理论上代码能力应该还可以才对。但单张显卡无法直接加载,利用cpu分段加载后速度太慢,等待量化模型再测试。

参考

https://gradio.app/docs/

https://github.com/IST-DASLab/gptq

https://github.com/qwopqwop200/GPTQ-for-LLaMa

https://github.com/openai/triton

https://github.com/TimDettmers/bitsandbytes

https://github.com/OpenLMLab/MOSS/issues/35

https://huggingface.co/docs/transformers/main/en/autoclass_tutorial

https://www.zhihu.com/question/362131975/answer/2182682685

https://arxiv.org/pdf/1607.04683.pdf

https://zhuanlan.zhihu.com/p/38328685

https://blog.csdn.net/lai_cheng/article/details/118961420

https://huggingface.co/docs/optimum/concept_guides/quantization

https://huggingface.co/docs/transformers/main/en/main_classes/quantization

https://pytorch.org/docs/stable/quantization.html

https://deepspeed.readthedocs.io/en/latest/memory.html

https://pub.towardsai.net/run-very-large-language-models-on-your-computer-390dd33838bb

https://huggingface.co/docs/accelerate/v0.18.0/en/package_reference/big_modeling

https://huggingface.co/docs/accelerate/v0.18.0/en/usage_guides/big_modeling#designing-a-device-map

https://huggingface.co/docs/accelerate/v0.18.0/en/usage_guides/big_modeling#loading-weights

https://github.com/OpenLMLab/MOSS/issues/38

标签:

读图

X 关闭

X 关闭