VLLMs学习-LLMEngine(模型初始化)

1、VLLM的学习

2. 整体架构的介绍:

csrc的学习:

主要包含CUDA内核的优化

数据流向、测试实例:

Tests主要包含一些模块实例的演示:

所支持的模型:

我们先看Pytorch库中模型的算子:

可以发现Linear层用的都是Pytorch内置的权重torch.nn.Linear;

然后VLLM会将这些权重转换为VLLM内置自己定义的权重

3. 源码解读---vllm 实例:

1. 首先我们看下VLLM的实例代码

VLLMs目前支持同步离线推理和异步离线推理:

2. 从代码层面明确 vllm 的区别:

与HuggingFace上的实例类似,参考连接如下:
https://blog.csdn.net/weixin_57128596/article/details/154795289?spm=1001.2014.3001.5501

以下是 Huggingface 官方的方式:加载模型->编码输入->推理->解码输出

python 复制代码
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch

# 模型名称(Hugging Face 上的 Qwen2-7B 模型)
model_name = "Qwen/Qwen2-7B"

# 1. 加载分词器
tokenizer = AutoTokenizer.from_pretrained(
    model_name,
    trust_remote_code=True,  # Qwen 模型需要信任远程代码
    padding_side="right"     # 右填充(符合中文习惯)
)

# 设置 pad_token(Qwen 模型默认没有 pad_token,需要手动设置)
if tokenizer.pad_token is None:
    tokenizer.pad_token = tokenizer.eos_token


# 方式2:4-bit 量化加载(仅需 ≥8GB 显存,推荐显存不足时使用)
model = AutoModelForCausalLM.from_pretrained(
    model_name,
    trust_remote_code=True,
    torch_dtype=torch.bfloat16,
    device_map="auto",
    load_in_4bit=True,            # 启用 4-bit 量化
    bnb_4bit_quant_type="nf4",    # 量化
    bnb_4bit_compute_dtype=torch.float16
)

# 3. 推理函数(封装成可复用的函数)
def qwen2_inference(prompt, max_new_tokens=512, temperature=0.7):
    """
    Qwen2-7B 推理函数
    :param prompt: 输入提示词
    :param max_new_tokens: 生成的最大新token数
    :param temperature: 生成温度(越高越随机)
    :return: 生成的文本
    """
    # 编码输入
    inputs = tokenizer(
        prompt,
        return_tensors="pt",
        padding=True,
        truncation=True,
        max_length=2048
    ).to(model.device)  # 将输入移到模型所在设备
    
    # 生成回复
    with torch.no_grad():  # 禁用梯度计算,节省显存
        outputs = model.generate(
            **inputs,
            max_new_tokens=max_new_tokens,
            temperature=temperature,
            do_sample=True,  # 采样生成(非贪心)
            pad_token_id=tokenizer.pad_token_id,
            eos_token_id=tokenizer.eos_token_id
        )
    
    # 解码输出(只保留生成的部分,去掉输入)
    response = tokenizer.decode(
        outputs[0][len(inputs["input_ids"][0]):],
        skip_special_tokens=True
    )
    
    return response

# 4. 测试推理
if __name__ == "__main__":
    # 测试提示词
    test_prompt = "请解释一下什么是大语言模型,并用简单的例子说明"
    
    # 执行推理
    print("输入提示:", test_prompt)
    print("="*50)
    response = qwen2_inference(test_prompt)
    print("模型回复:", response)

可以看到 VLLM 直接通过内置的 vllm 库加载模型权重,而分词器本身还是用的 Transformers 的库 AutoTokenizer 加载,目的是对输入分词然后设置Template。

然后直接调用内置的 generate 函数即可。

结论: vllm 主要在 llm 初始化阶段以及推理阶段做了更改。

4. 源码解读-llm的初始化:

输入:

  1. 提示词和随机采样参数(必须)
  2. 其余参数;

参数转换类---EngineArgs:

将传入的参数通过 EngineArgs 进行构造,得到实例化参数 engine_args 。

原因是:模型权重初始化的类 LLMEngine 所需的参数包含模型配置、缓存配置、时间调度机制、Lora、Token采样配置、是否是视觉模型等等(这些参数在后续执行器的初始化中需要用到),如下图所示。

初始化的几个包如下所示:

  • Tokenizer: 分词器,将文本转换为数字 ID,添加 Template。
  • Executor: 基类、单卡GPU、CPU、xxGPU的执行器,如下图所示。
  • init_kv_cache: 缓存优化,涉及 PageAttention。
  • Scheduler: 时间调度器,用于批量处理。

5. 初始化以 GPUExcutor 为例

第一步: 可以看到 llm 初始化的时候需要通过 executor_class() 导入执行器,所需参数包含模型配置、缓存配置、时间调度机制、Lora、Token采样配置等等。

第二步: Executor 主要包含三种 worker 的初始化形式:

以 GPUExecutor 代码为例:

  • 创建worker;
  • 设备worker;
  • 模型加载worker;

    首先是创建worker,create_worker:

    可以发现 Worker 的创建是通过文件路径初始化的:

    可以发现 Worker.py 中又加载了 ModelRunner ,主要用了加载配置、Lora配置、Kv-Cache的配置

    然后 load_model中也用了 modelRunner 类,主要用ModelRunner完成模型的加载和初始化:

ModelRunner层面:

可以发现 ModelRunner 是整个执行流程最底层的层面。

可以发现ModelRunner中的 load_model() 函数,主要包括模型权重加载和转换:

其中模型权重的加载主要在 get_model() 函数中,如下图所示:

点进 get_model()函数中可以发现,主要先通过 get_model_loader()得到加载器:

可以发现 loader有几种初始化的方法,如下图所示:

我们以 DummyModelLoader 为例,发现模型权重加载主要依赖 initialize_model 函数,如下图所示:

点入 initialize_model()函数可以发现,可以获取模型的架构和模型的注册器,因此能够找到加载的模型:

点入 get_model_architecture() 函数可以发现,主要用了模型注册器,自动检查模型的映射:

其中模型注册器 ModelRegistery 会自动检查模型的映射,如下两张图所示:

找到映射后会自动跳转对应的模型类:

跳转到以下模型类:

相关推荐
西岸行者5 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意6 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码6 天前
嵌入式学习路线
学习
毛小茛6 天前
计算机系统概论——校验码
学习
babe小鑫6 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms6 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下6 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。6 天前
2026.2.25监控学习
学习
im_AMBER6 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J6 天前
从“Hello World“ 开始 C++
c语言·c++·学习