首页 > 其他分享 >transformers 推理 Qwen2.5 等大模型技术细节详解(二)AutoModel 初始化和模型加载(免费送新书)

transformers 推理 Qwen2.5 等大模型技术细节详解(二)AutoModel 初始化和模型加载(免费送新书)

时间:2024-10-27 16:33:13浏览次数:5  
标签:... transformers 技术细节 Qwen2.5 模型 model config pretrained

接上文:transformers 推理 Qwen2.5 等大模型技术细节详解(一)transformers 包和对象加载

老牛同学和大家通过 Transformers 框架的一行最常见代码from transformers import AutoModelForCausalLM,走读了transformers 包初始化代码的整个流程。从中体会到了dummy对象、LazyModule延迟模块和按需加载、API 简化使用等这些transformers 包的设计美学,为我们设计超大 Python 包提供了很好的借鉴思路。

本文是使用 Transformers 推理 LLM 技术细节的第 2 篇文章,我们将基于 Qwen2.5 大模型,通过模型配置和from_pretrained代码,了解AutoModel模型初始化的技术细节:

  1. 环境准备:配置虚拟环境,下载 Qwen2.5 模型文件
  2. Qwen2.5 模型配置文件config.json各个配置项说明,并介绍AutoConfig加载文件到Qwen2Config配置
  3. 走读AutoModelForCausalLM.from_pretrained方法代码,详细介绍模型初始化流程
  4. 在最后,老牛同学又来搞个小活动,免费包邮送几本新书给大家,期望大家踊跃参与

Transformers推理核心流程

在以上 Transformers 框架推理 LLM 的核心框架代码中,我们本次将走读的代码是from_pretrained方法:

from transformers import AutoModelForCausalLM
model = AutoModelForCausalLM.from_pretrained(
    model_dir,
    torch_dtype="auto",
    device_map="auto",
    local_files_only=True,
)

环境准备:配置虚拟环境和下载 Qwen2.5 模型文件

【配置虚拟环境】 在上一篇我们已经配置好了虚拟环境,老牛同学就只简单罗列一下配置脚本:

# Python虚拟环境名:Qwen2.5,版本号:3.10
conda create -n Qwen2.5 python=3.10 -y

# 激活虚拟环境
conda activate Qwen2.5

# 下载Python依赖包
pip install torch
pip install "transformers>=4.43.1"
pip install "accelerate>=0.26.0"

【下载 Qwen2.5 模型文件】 老牛同学存放模型文件目录:Qwen2.5-1.5B-Instruct

# Git大文件系统
git lfs install

# 下载模型文件
git clone https://www.modelscope.cn/qwen/Qwen2.5-1.5B-Instruct.git Qwen2.5-1.5B-Instruct

若下载过程中异常中断,可以通过git lfs install命令继续下载:

# 切换到Git目录
cd Qwen2.5-1.5B-Instruct

# 中断继续下载
git lfs install
git lfs pull

下载完成,可以看到如下文件结构:

Qwen2.5模型文件结构

针对本文大模型初始化来说,我们重点关注config.json模型配置文件和model.safetensors模型文件:

  1. model.safetensors文件是模型文件(主要为权重参数数据),它存储了验证文件完整性的校验和、模型张量元数据和张量权重参数等。我们将在代码流程中详细说明这些数据。
  2. config.json文件是模型的配置文件,包括了模型框架、训练设置、各种超参数等信息:

Qwen2.5模型参数配置

config.json参数详解和 AutoConfig 初始化

老牛同学对config.json文件中的每个参数进行简单说明:

参数名 配置值 参数说明
architectures Qwen2ForCausalLM 模型的架构名称,Qwen2ForCausalLM是 Qwen 推理模型,在模型初始化方式将会实际使用
attention_dropout 0.0 注意力机制中的 Dropout 操作概率,0.0代表不对注意力权重进行随机置零操作,即保留所有的注意力权重
bos_token_id 151643 文本序列开始 Token ID 标记(Begin of Sentence Token ID),代表文本片段开始位置
eos_token_id 151645 文本序列结束 Token ID 标记(End of Sentence Token ID),代表文本片段结束位置
hidden_act silu 模型隐藏层使用SiLU激活函数(其他激活函数:ReLU,Tanh,Sigmoid 等)
hidden_size 1536 隐藏层的维度(或每个隐藏层中神经元的数量),数值越大意味着模型能学习更复杂的特征和模式
initializer_range 0.02 模型训练时初始化权重的标准差,0.02代表权重从均值为 0、标准差为 0.02 的正态分布中随机初始化
intermediate_size 8960 前馈神经网络中间层的维度,通常要比hidden_size大得多,用于增加模型学习能力
max_position_embeddings 32768 模型可以处理的最大序列长度,32768代表模型可以处理最长为 32768 个 Token 的输入序列
max_window_layers 21 模型在处理长序列时,最多可以应用多少层的滑动窗口策略,即可以对长序列进行多少次分隔和处理
model_type qwen2 Qwen2 模型类型标识,用于映射 Qwen2Config 和 Qwen2ForCausalLM 等实际类
num_attention_heads 12 多头注意力机制中注意力头的数量,12代表每个隐藏层中使用 12 个注意力头
num_hidden_layers 28 模型隐藏层的数量
num_key_value_heads 2 多头自注意力机制中键(Key)和值(Value)的注意力头数量,共12个注意头而键值只有2个头,则意味着查询(Query)头可以共享相同的键和值头
rms_norm_eps 1e-06 使用 RMSNorm 归一化技术处理,分母增加一个极小值,避免除以零的情况,保证归一化的有效性
rope_theta 1000000.0 RoPE 旋转位置编码的周期性因子,用于捕捉长距离依赖关系,提高模型的数值稳定性
sliding_window 32768 模型在处理长序列时采用的滑动窗口序列长度,即通过滑动窗口的方式处理超过max_position_embeddings的长序列策略
tie_word_embeddings true 模型的输入和输出层之间共享词嵌入矩阵标识
torch_dtype bfloat16 模型权重采用 bfloat16 浮点数格式(1 位符号位+8 位指数位+7 位尾数位),它区别于 float16 半精度浮点数格式(1 位符号位 5 位指数位+10 位尾数位),通过增加指数位数以提高数字精度
transformers_version 4.43.1 Transformers 推理模型的版本号,通常是指最低版本,pip install "transformers>=4.43.1",我们依赖包版本为4.45.1
use_cache true 模型推理过程中使用缓存机制标识,用于缓存中间结果,避免重复计算
use_sliding_window false 模型处理长序列时是否使用滑动窗口机制,false代表禁用滑动窗口机制,则意味着模型将尝试一次性处理整个长序列,可能会导致内存占用和计算复杂度增加
vocab_size 151936 模型词汇表的大小,AutoTokenizer 我们将会介绍

特别注意:在上述配置参数中,use_sliding_window = false意味着模型禁用滑动窗口机制,即sliding_window = 32768参数设置不生效,也就是模型能够处理的最大序列长度为max_position_embeddings = 32768个 Token,超过这个长度的序列将无法正确处理;如果我们需要处理接近或超过32768 个 Token 的长序列,建议启用滑动窗口机制(use_sliding_window = true)!

模型配置参数,我们可以通过AutoConfig进行加载和打印出各个参数项:

import os
from transformers import AutoConfig

# 加载配置文件
config_path = os.path.join('D:', os.path.sep, 'ModelSpace', 'Qwen2.5', 'Qwen2.5-1.5B-Instruct', 'config.json')
config = AutoConfig.from_pretrained(config_path)

# 查看词汇表大小,输出: 151936
print(config.vocab_size)

# 查看配置所有内容
print(config)

最终输出结果如下,config返回结果为Qwen2Config实例:

Qwen2Config配置内容

是不是感觉有点奇怪,我们并没有Qwen2Config相关配置,但最终结果就有了它?接下来,我们来一起看下代码AutoConfig.from_pretrained流程:

首先,根据我们第 1 篇文章的介绍,我们能快速定位到AutoConfig所在模块为models.auto

_import_structure = {
    # ....
    "models.auto": [
        # ....
        "AutoConfig",
        # ....
    ]
}

然后,我们打开 Transformers 包下 ./models/auto/__init__.py 文件,可以定位到AutoConfig类型所在模块configuration_auto.py

_import_structure = {
    # ...
    "configuration_auto": ["CONFIG_MAPPING", "MODEL_NAMES_MAPPING", "AutoConfig"],
    # ...
}

AutoConfig.from_pretrained方法定义如下,红框代码比较关键:

AutoConfig.from_pretrained方法定义

下面对红框代码进行详细说明:

  1. config_dict, * = PretrainedConfig.get_config_dict(config_path, _)代码行:这行代码逻辑稍微比较简单,就是解析config.jsonJSON 格式文件,返回字典对象
  2. config_class = CONFIG_MAPPING[config_dict["model_type"]]代码行:前面的配置文件,config_dict["model_type"]的结果是qwen2,而CONFIG_MAPPING是一个字典常量,它的定义如下:
CONFIG_MAPPING_NAMES = OrderedDict(
    [
        # ...
        ("qwen2", "Qwen2Config"),
        ("qwen2_audio", "Qwen2AudioConfig"),
        ("qwen2_audio_encoder", "Qwen2AudioEncoderConfig"),
        ("qwen2_moe", "Qwen2MoeConfig"),
        ("qwen2_vl", "Qwen2VLConfig"),
        # ...
    ]
)

因此,这行代码的最终结果config_class内容为Qwen2Config,因此它就是从这里来的。

根据我们第 1 篇文章的介绍,我们快速定位到Qwen2Config类所在模块为 ./models/qwen2/configuration_qwen2.py,它的定义如下:

Qwen2Config类定义

Qwen2Config类的定义我们可以看到:它没有具体方法,因此它的方法均来自PretrainedConfig父类;同时,类构造函数,有vocab_size/hidden_size等命名参数,而这些命名参数,正是前面介绍的config.json配置文件参数项。

  1. return config = class.from_dict(config_dict, _)代码行:最终返回Qwen2Config.from_dict()方法调用,我们打开PretrainedConfig.from_dict()方法:

Qwen2Config实例化

核心代码行config = cls(**config_dict)即实例化Qwen2Config类,入参即config.json的配置项,最终完成了我们最开始的print(config)输出结果闭环。

到这里,我们基本完成了config.json配置项说明和用法,老牛同学整理了AutoConfig.from_pretrained(config_path)代码行的执行流程:

AutoConfig执行流程

AutoModelForCausalLM.from_pretrained 模型加载

我们还是根据第 1 篇文章方法,找到AutoModelForCausalLM所在模块为 ./models/auto/modeling_auto.py,它的定义如下:

class AutoModelForCausalLM(_BaseAutoModelClass):
    _model_mapping = MODEL_FOR_CAUSAL_LM_MAPPING


AutoModelForCausalLM = auto_class_update(AutoModelForCausalLM, head_doc="causal language modeling")

其中,MODEL_FOR_CAUSAL_LM_MAPPING是一个常量字典,存放的是模型类型和模型类的映射关系。根据配置我们可以知道,Qwen2ForCausalLM是实际的模型类:

MODEL_FOR_CAUSAL_LM_MAPPING_NAMES = OrderedDict(
    [
        # ...
        ("qwen2", "Qwen2ForCausalLM"),
        ("qwen2_moe", "Qwen2MoeForCausalLM"),
        # ...
    ]
)

auto_class_update(XXXLM, _)方法是一个非常有趣的方法,这个方法把 _BaseAutoModelClass类的from_configfrom_pretrained方法复制给了XXXLM类。因此,当我们调用XXXLM.from_config或者XXXLM.from_pretrained方法时,方法的内部逻辑与 _BaseAutoModelClass.from_config_BaseAutoModelClass.from_pretrained实际方法一致!

auto_class_update方法

接下来,我们来看看 AutoModelForCausalLM.from_pretrained() 的执行逻辑:

model = AutoModelForCausalLM.from_pretrained(
    model_dir,
    torch_dtype="auto",
    device_map="auto",
    local_files_only=True,
)

_BaseAutoModelClass.from_pretrained 方法有点长,老牛同学截图最关键的几行代码:

Qwn2Config加载配置

Qwen2ForCausalLM映射

  1. 模型配置加载:AutoConfig.from_pretrained,结果为Qwen2Config配置类
  2. 通过同样的方式,根据配置文件model_type模型类型映射到实际类,最终执行Qwen2ForCausalLM.from_pretrained方法

Qwen2ForCausalLM类定义:继承Qwen2PreTrainedModel父类,包含了Qwen2Config配置,和Qwen2Model为实际的模型类

Qwen2ForCausalLM类定义

我们继续查看Qwen2PreTrainedModel类:它继承PreTrainedModel类,并没有定义方法。PreTrainedModel类是所有模型的基类,它继承nn.Module类,它定义了from_pretrained()方法:

PreTrainedModel.from_pretrained方法

这个方法代码行超级长,老牛同学把它大致分为以下4 部分

  1. 解析模型文件路径,即我们下载的权重文件:./Qwen2.5-1.5B-Instruct/model.safetensors
elif use_safetensors is not False and os.path.isfile(
    os.path.join(pretrained_model_name_or_path, subfolder, _add_variant(SAFE_WEIGHTS_NAME, variant))
):
    # Load from a safetensors checkpoint
    archive_file = os.path.join(
        pretrained_model_name_or_path, subfolder, _add_variant(SAFE_WEIGHTS_NAME, variant)
    )

# ...省略...

if is_local:
    logger.info(f"loading weights file {archive_file}")
    resolved_archive_file = archive_file

其中,SAFE_WEIGHTS_NAME常量值为model.safetensorsarchive_file变量即为权重文件完整路径,最终赋值给了resolved_archive_file变量。

  1. 解析模型文件,获取模型元数据,模型格式为pt即为 PyTorch 深度学习框架,并加载模型权重:
if (
    is_safetensors_available()
    and isinstance(resolved_archive_file, str)
    and resolved_archive_file.endswith(".safetensors")
):
    with safe_open(resolved_archive_file, framework="pt") as f:
        metadata = f.metadata()

    if metadata.get("format") == "pt":
        pass

# ...省略...

from_pt = not (from_tf | from_flax)

# load pt weights early so that we know which dtype to init the model under
if from_pt:
    if not is_sharded and state_dict is None:
        # Time to load the checkpoint
        state_dict = load_state_dict(resolved_archive_file)
  1. 实例化AutoModelForCausalLM类,model变量即为对象实例:
with ContextManagers(init_contexts):
    # Let's make sure we don't run the init function of buffer modules
    model = cls(config, *model_args, **model_kwargs)

# make sure we use the model's config since the __init__ call might have copied it
config = model.config
  1. 加载模型,并设置模型为推理模式,同时设置模型配置,最后分发模型:
elif from_pt:
    # restore default dtype
    if dtype_orig is not None:
        torch.set_default_dtype(dtype_orig)

    (
        model,
        missing_keys,
        unexpected_keys,
        mismatched_keys,
        offload_index,
        error_msgs,
    ) = cls._load_pretrained_model(
        model,
        state_dict,
        # ...省略...


# ...省略...

# Set model in evaluation mode to deactivate DropOut modules by default
model.eval()

# ...省略...

model.generation_config = GenerationConfig.from_pretrained(
    pretrained_model_name_or_path,
    cache_dir=cache_dir,
    force_download=force_download,
    resume_download=resume_download,
    proxies=proxies,
    local_files_only=local_files_only,
    token=token,
    revision=revision,
    subfolder=subfolder,
    _from_auto=from_auto_class,
    _from_pipeline=from_pipeline,
    **kwargs,
)

# ...省略...

if not is_fsdp_enabled() and not is_deepspeed_zero3_enabled():
    dispatch_model(model, **device_map_kwargs)

最终,当我们执行model = AutoModelForCausalLM.from_pretrained()代码的结果,即为Qwen2ForCausalLM类的实例,它就是 PyTorch 的nn.Module的实例。老牛同学把整个处理流程整理如下:

XXXLM.from_pretrained流程

至此,使用 Transformers 初始化大模型部分就基本结束了,老牛同学在接下来的文章,将与大家一起看看文本AutoTokenizer技术,它也是大模型推理的关键部分~

最后:又来给大家免费包邮送几本新书

前面我们已经举办过 3 次免费包邮送书活动:

  1. ChatTTS 长音频合成和本地部署 2 种方式,让你的“儿童绘本”发声的实战教程(文末有福利)
  2. 使用世界领先的 Qwen2.5-Math 开源模型当 AI 数学老师,让奥数解题辅导父慈子孝(文末有福利)
  3. transformers 推理 Qwen2.5 等大模型技术细节详解(一)transformers 包和对象加载(文末免费送书)

本期,老牛同学继续和出版社朋友合作,举办第 4 次送书福利小活动,新书是:《Python 金融大数据分析快速入门和案例详解

Python 金融大数据分析快速入门和案例详解

本期送书小活动的规则和之前类似,总体如下:

  1. 关注老牛同学微信公众号,因为这是老牛同学公众号关注者的小福利
  2. 在本文的评论区进行留言,留言的点赞数排名前 3 名的朋友,免费包邮获得 1 本书(即:默认送 3 本书)
  3. 若本文的阅读量老牛同学 CSDN 同文的阅读量之和达到了2000(含2000),则留言的点赞数排名前 6 名的朋友均免费包邮送书(即:最多送 6 本书)
  4. 活动时间:2024 年 10 月 27 日到 2024 年 11 月 3 号上午 12 点整(正好 1 周,周末可寄送新书)
  5. 老牛同学不参与本次活动(因为老牛同学默认就有 1 本)

往期推荐文章:

基于 Qwen2.5-Coder 模型和 CrewAI 多智能体框架,实现智能编程系统的实战教程

vLLM CPU 和 GPU 模式署和推理 Qwen2 等大语言模型详细教程

基于 Qwen2/Lllama3 等大模型,部署团队私有化 RAG 知识库系统的详细教程(Docker+AnythingLLM)

使用 Llama3/Qwen2 等开源大模型,部署团队私有化 Code Copilot 和使用教程

基于 Qwen2 大模型微调技术详细教程(LoRA 参数高效微调和 SwanLab 可视化监控)

ChatTTS 长音频合成和本地部署 2 种方式,让你的“儿童绘本”发声的实战教程

transformers 推理 Qwen2.5 等大模型技术细节详解(一)transformers 包和对象加载

微信公众号:老牛同学

标签:...,transformers,技术细节,Qwen2.5,模型,model,config,pretrained
From: https://www.cnblogs.com/obullxl/p/18508576/NTopic2024102601

相关文章

  • 机器学习实战:想精准预测石油日产气量?ARIMA模型是你不可错过的“神助攻”!
    在当今能源领域,石油日产气量犹如一颗跳动的心脏,牵动着全球经济、能源战略以及无数相关产业的神经。准确地预测石油日产气量,就如同掌握了一把开启能源未来大门的神秘钥匙。而今天,我们要深入探讨的是一种强大的预测工具——ARIMA模型,它在石油日产气量预测方面正展现出令人惊叹的......
  • 反演法控制(简单数学模型逐步推导)
    反演法(backstepping)设计思想是将复杂非线性的系统分解成不超过系统阶数的子系统,然后为每一个子系统分别设计Lyapunov函数和中间虚拟控制量,一直后退到整个系统,直到完成整个控制律的设计。解法:1,控制系统方程的导数最高阶次为n阶,含有系统输入项2,从0次阶逐级设计到n阶,其中用误......
  • 【保姆级教程】从Yolov8训练模型到转化Onnx再转换为Rknn以及板端部署全记录
    目录一、文件准备二、Yolov8训练自己的数据集1.准备数据集2.处理数据3.环境配置4.下载权重文件5.开始训练三、.PT转换为.ONNX四、.ONNX转换为.RKNN1.虚拟机配置2.rknn转换环境配置安装转换环境RKNN转换五、板端部署1.烧录系统2.环境配置3.进行识别六、踩坑笔记Imp......
  • IEEE33节点案例-计及风电出力不确定性的网架重构优化模型/配电网故障恢复重构(Matlab)
    随着能源转型的持续推进,以风电和光伏为首的新能源场站被大规模接入电力系统中,给电力系统安全防御体系带来了严峻挑战。分析电力系统发生大停电事故后的网架重构过程对减少由大停电事故带来的社会影响和经济损失有重要意义。计及风电出力的网架重构优化模型必须考虑风电场和......
  • fbprophet时序模型和LSTM有什么优劣么
    fbprophet时序模型优点:1、易用性;2、灵活性;3、内置节假日效应等。fbProphet缺点:1、简单性;2、依赖性。LSTM的优势:1、学习复杂模式;2、适用于各自数据;3、模型调整。LSTM的劣势:1、计算复杂;2、难以理解;3、过拟合风险。LSTM模型通常需要更多的计算资源和时间来训练。一、fbprophet优......
  • 只需初中数学知识就能理解人工智能大语言模型51
    全面解释人工智能LLM模型的真实工作原理(一)人工智能#大语言模型LLM#机器学习ML#深度学习#数据挖掘序言:为了帮助更多人理解,我们将分成若干小节来讲解大型语言模型(LLM)的真实工作原理,从零开始,不需额外知识储备,只需初中数学基础(懂加法和乘法就行)。本文包含理解LLM所需的全部知......
  • 全面解释人工智能LLM模型的真实工作原理(二)
    前一篇:《全面解释人工智能LLM模型的真实工作原理(一)》序言:在上一篇文章中,我们从原理上构建了一个识别“叶子”和“花朵”的神经网络,并详细讲解了它的工作过程。这包括对输入数字逐个与权重相乘后求和,加上偏置值,最后通过非线性处理和统计分布计算来得出输出。这些操作使用了简......
  • 全面解释人工智能LLM模型的真实工作原理(二)
    前一篇:《全面解释人工智能LLM模型的真实工作原理(一)》序言:在上一篇文章中,我们从原理上构建了一个识别“叶子”和“花朵”的神经网络,并详细讲解了它的工作过程。这包括对输入数字逐个与权重相乘后求和,加上偏置值,最后通过非线性处理和统计分布计算来得出输出。这些操作使用了简单的......
  • Python实现ARIMA的神经网络模型
    以下是一个使用Python实现ARIMA(自回归移动平均模型)的简单示例代码。在运行代码之前,请确保已经安装了pandas、numpy和statsmodels库。importnumpyasnpimportpandasaspdfromstatsmodels.tsa.arima.modelimportARIMAimportmatplotlib.pyplotasplt#生成一些......
  • 基于RBF神经网络的双参数自适应光储VSG构网逆变器MATLAB仿真模型
    “电气仔推送”获得资料(专享优惠)模型简介此模型源侧部分采用光伏发电系统与混合储能系统(蓄电池+超级电容),并网逆变器采用虚拟同步发电机(VSG)控制,为系统提供惯量阻尼支撑。同时对VSG控制部分进行了改进,采用RBF径向基神经网络对虚拟惯量及虚拟阻尼进行自适应控制,自适应方法完全复......